From 58f28cb753edd6f455541564626a8dc51d7c54eb Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Sun, 23 Jun 2024 02:33:30 +0000 Subject: [PATCH] deploy: b2996d4ebbf1f522e53c97729e8a0b4fab8fbe39 --- 404.html | 6 +- adoption/all/index.html | 4 +- adoption/custodial/index.html | 4 +- adoption/desktop/index.html | 4 +- adoption/exchange/index.html | 4 +- adoption/hardware/index.html | 4 +- adoption/infrastructure/index.html | 4 +- adoption/mobile/index.html | 4 +- adoption/web/index.html | 4 +- assets/js/{19.a32238ae.js => 19.a5cb69f8.js} | 2 +- assets/js/{21.ace15d2d.js => 21.09b4c434.js} | 2 +- assets/js/{31.00e676e0.js => 31.dadf64cd.js} | 2 +- assets/js/{37.a5bff0bd.js => 37.4c491801.js} | 2 +- assets/js/{38.2ace5b2d.js => 38.109014d3.js} | 2 +- assets/js/{39.9b478629.js => 39.811be492.js} | 2 +- assets/js/{40.3dbbc631.js => 40.73d2a9e6.js} | 2 +- assets/js/{41.802e975e.js => 41.dd41fb56.js} | 2 +- assets/js/{42.86af1298.js => 42.98efa542.js} | 2 +- assets/js/{46.8a620891.js => 46.5ba99f9c.js} | 2 +- assets/js/{47.5dee4bad.js => 47.70dc63ea.js} | 2 +- assets/js/{48.d82a543b.js => 48.abab73ce.js} | 2 +- assets/js/{49.0ab13c0b.js => 49.cbffab28.js} | 2 +- assets/js/{51.6bd775ae.js => 51.503dcbd1.js} | 2 +- assets/js/{52.c345bff4.js => 52.776c8d09.js} | 2 +- assets/js/{53.bf39d2fb.js => 53.b417d2aa.js} | 2 +- assets/js/{57.64bfd1b2.js => 57.3bf4c76c.js} | 2 +- assets/js/{58.de4ccb60.js => 58.8864ccb6.js} | 2 +- assets/js/{59.7e9a8d23.js => 59.0c9b7bcd.js} | 2 +- assets/js/{60.b17bda16.js => 60.915a8300.js} | 2 +- assets/js/{61.921b17ea.js => 61.db8b79c3.js} | 2 +- assets/js/{62.315ee6d5.js => 62.f686b521.js} | 2 +- assets/js/{63.a6117e34.js => 63.53783e0a.js} | 2 +- assets/js/{64.08ee4767.js => 64.82779c88.js} | 2 +- assets/js/{65.e47b714e.js => 65.71eccdcf.js} | 2 +- assets/js/{66.62fed6f7.js => 66.1ec98713.js} | 2 +- assets/js/{70.da579d90.js => 70.dc8d08ec.js} | 2 +- assets/js/{71.d138f3df.js => 71.b5a740f7.js} | 2 +- assets/js/{72.1c2cf134.js => 72.54663843.js} | 2 +- assets/js/{74.5f8ac53c.js => 74.ae6867a4.js} | 2 +- assets/js/{75.e1920f80.js => 75.c6fe9b95.js} | 2 +- assets/js/{76.aa9e2182.js => 76.04856c41.js} | 2 +- assets/js/{77.c32ccfd5.js => 77.bccb78bf.js} | 2 +- assets/js/{78.1816ce47.js => 78.f4004da3.js} | 2 +- assets/js/{79.1ad39e24.js => 79.e7350423.js} | 2 +- assets/js/{80.914d4500.js => 80.b9017867.js} | 2 +- assets/js/{83.de486fb1.js => 83.be2d0652.js} | 2 +- assets/js/{84.ddbb04c5.js => 84.3ec08e13.js} | 2 +- assets/js/{86.fb094c9b.js => 86.4af6e043.js} | 2 +- assets/js/{88.53b10983.js => 88.c63c0587.js} | 2 +- .../js/{app.cd8846d4.js => app.061d8498.js} | 4 +- bdk-cli/compiler/index.html | 6 +- bdk-cli/concept/index.html | 6 +- bdk-cli/installation/index.html | 6 +- bdk-cli/interface/index.html | 6 +- bdk-cli/introduction/index.html | 6 +- bdk-cli/playground/index.html | 6 +- bdk-cli/regtest/index.html | 6 +- blog/2020/12/hello-world/index.html | 6 +- blog/2020/12/release-v0.2.0/index.html | 6 +- .../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/_2023-q4-update/index.html | 6 +- blog/_2024-q1-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 | 4 +- blog/page/4/index.html | 8 +- 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 +- blog/why-bindings/index.html | 6 +- case-studies/index.html | 4 +- descriptors/index.html | 6 +- .../indexed_tx_graph/struct.ChangeSet.html | 2 +- .../keychain/enum.InsertDescriptorError.html | 2 +- .../bdk_chain/keychain/struct.Balance.html | 4 +- .../bdk_chain/keychain/struct.ChangeSet.html | 2 +- .../struct.MissingGenesisError.html | 2 +- .../bdk_chain/struct.CombinedChangeSet.html | 2 +- .../latest/bdk_chain/struct.DescriptorId.html | 14 +- .../bdk_chain/tx_graph/struct.TxGraph.html | 2 +- .../latest/bdk_coin_select/enum.BnbLimit.html | 2 +- .../enum.ExcessStrategyKind.html | 2 +- .../enum.SelectionConstraint.html | 2 +- .../struct.SelectionError.html | 2 +- .../latest/bdk_esplora/trait.EsploraExt.html | 10 +- .../latest/bdk_esplora/type.Error.html | 2 +- .../latest/bdk_file_store/enum.IterError.html | 2 +- .../struct.AggregateChangesetsError.html | 2 +- .../nightly/latest/bdk_sqlite/enum.Error.html | 2 +- .../bdk_tmp_plan/enum.SigningError.html | 2 +- .../descriptor/enum.Descriptor.html | 8 +- .../descriptor/enum.DescriptorPublicKey.html | 2 +- .../bdk_wallet/descriptor/enum.Legacy.html | 4 +- .../bdk_wallet/descriptor/enum.Segwitv0.html | 4 +- .../descriptor/error/enum.Error.html | 2 +- .../descriptor/policy/enum.PolicyError.html | 2 +- .../bdk/nightly/latest/bdk_wallet/index.html | 42 ++--- .../bdk_wallet/keys/enum.DescriptorKey.html | 12 +- .../keys/enum.DescriptorPublicKey.html | 2 +- .../keys/enum.DescriptorSecretKey.html | 2 +- .../bdk_wallet/keys/enum.ExtendedKey.html | 14 +- .../latest/bdk_wallet/keys/enum.KeyError.html | 4 +- .../keys/enum.ScriptContextEnum.html | 12 +- .../bdk_wallet/keys/fn.any_network.html | 2 +- .../bdk_wallet/keys/fn.mainnet_network.html | 2 +- .../bdk_wallet/keys/fn.merge_networks.html | 2 +- .../bdk_wallet/keys/fn.test_networks.html | 2 +- .../nightly/latest/bdk_wallet/keys/index.html | 2 +- .../bdk_wallet/keys/struct.GeneratedKey.html | 12 +- .../struct.PrivateKeyGenerateOptions.html | 4 +- .../bdk_wallet/keys/trait.DerivableKey.html | 10 +- .../keys/trait.ExtScriptContext.html | 12 +- .../keys/trait.GeneratableDefaultOptions.html | 16 +- .../bdk_wallet/keys/trait.GeneratableKey.html | 30 ++- .../keys/trait.IntoDescriptorKey.html | 10 +- .../bdk_wallet/keys/type.ValidNetworks.html | 2 +- .../wallet/coin_selection/enum.Error.html | 4 +- .../wallet/coin_selection/enum.Excess.html | 4 +- .../coin_selection/fn.decide_change.html | 2 +- .../struct.BranchAndBoundCoinSelection.html | 8 +- .../struct.CoinSelectionResult.html | 8 +- .../struct.LargestFirstCoinSelection.html | 6 +- .../struct.OldestFirstCoinSelection.html | 6 +- .../trait.CoinSelectionAlgorithm.html | 6 +- .../type.DefaultCoinSelectionAlgorithm.html | 2 +- .../wallet/enum.ApplyBlockError.html | 4 +- .../bdk_wallet/wallet/enum.InsertTxError.html | 4 +- .../bdk_wallet/wallet/enum.LoadError.html | 4 +- .../bdk_wallet/wallet/enum.NewError.html | 4 +- .../wallet/enum.NewOrLoadError.html | 4 +- .../wallet/error/enum.BuildFeeBumpError.html | 2 +- .../wallet/error/enum.CreateTxError.html | 2 +- .../error/enum.MiniscriptPsbtError.html | 2 +- .../fn.wallet_name_from_descriptor.html | 2 +- .../latest/bdk_wallet/wallet/index.html | 2 +- .../wallet/signer/enum.SignerError.html | 2 +- .../wallet/signer/enum.SignerId.html | 2 +- .../wallet/signer/struct.SignerWrapper.html | 6 +- .../bdk_wallet/wallet/struct.AddressInfo.html | 6 +- .../bdk_wallet/wallet/struct.Update.html | 4 +- .../bdk_wallet/wallet/struct.Wallet.html | 122 ++++++------ .../bdk_wallet/wallet/trait.IsDust.html | 6 +- .../tx_builder/enum.AddForeignUtxoError.html | 4 +- .../wallet/tx_builder/enum.AddUtxoError.html | 4 +- .../tx_builder/enum.ChangeSpendPolicy.html | 12 +- .../wallet/tx_builder/enum.TxOrdering.html | 17 +- .../bdk_wallet/wallet/tx_builder/index.html | 2 +- .../wallet/tx_builder/struct.TxBuilder.html | 75 ++++---- .../bdk_wallet/wallet/type.ChangeSet.html | 2 +- .../example_cli/enum.CoinSelectionAlgo.html | 2 +- docs-rs/bdk/nightly/latest/search-index.js | 14 +- .../bdk_wallet/bdk_wallet-desc-0-.js | 2 +- .../src/bdk_esplora/blocking_ext.rs.html | 2 - .../latest/src/bdk_wallet/keys/mod.rs.html | 58 +++++- .../bdk_wallet/wallet/coin_selection.rs.html | 176 +++++++++--------- .../latest/src/bdk_wallet/wallet/mod.rs.html | 52 +++++- .../src/bdk_wallet/wallet/signer.rs.html | 2 +- .../src/bdk_wallet/wallet/tx_builder.rs.html | 68 +++++-- .../src/bdk_wallet/wallet/utils.rs.html | 120 +++++++++++- .../struct.BranchAndBoundCoinSelection.js | 2 +- examples/index.html | 6 +- foundation/about/index.html | 4 +- foundation/grantees/index.html | 4 +- foundation/grants/index.html | 4 +- foundation/index.html | 4 +- foundation/supporters/index.html | 4 +- getting-started/index.html | 6 +- index.html | 4 +- sitemap.xml | 2 +- 258 files changed, 1051 insertions(+), 773 deletions(-) rename assets/js/{19.a32238ae.js => 19.a5cb69f8.js} (99%) rename assets/js/{21.ace15d2d.js => 21.09b4c434.js} (98%) rename assets/js/{31.00e676e0.js => 31.dadf64cd.js} (99%) rename assets/js/{37.a5bff0bd.js => 37.4c491801.js} (92%) rename assets/js/{38.2ace5b2d.js => 38.109014d3.js} (87%) rename assets/js/{39.9b478629.js => 39.811be492.js} (88%) rename assets/js/{40.3dbbc631.js => 40.73d2a9e6.js} (86%) rename assets/js/{41.802e975e.js => 41.dd41fb56.js} (97%) rename assets/js/{42.86af1298.js => 42.98efa542.js} (96%) rename assets/js/{46.8a620891.js => 46.5ba99f9c.js} (99%) rename assets/js/{47.5dee4bad.js => 47.70dc63ea.js} (98%) rename assets/js/{48.d82a543b.js => 48.abab73ce.js} (99%) rename assets/js/{49.0ab13c0b.js => 49.cbffab28.js} (99%) rename assets/js/{51.6bd775ae.js => 51.503dcbd1.js} (99%) rename assets/js/{52.c345bff4.js => 52.776c8d09.js} (99%) rename assets/js/{53.bf39d2fb.js => 53.b417d2aa.js} (99%) rename assets/js/{57.64bfd1b2.js => 57.3bf4c76c.js} (99%) rename assets/js/{58.de4ccb60.js => 58.8864ccb6.js} (99%) rename assets/js/{59.7e9a8d23.js => 59.0c9b7bcd.js} (99%) rename assets/js/{60.b17bda16.js => 60.915a8300.js} (99%) rename assets/js/{61.921b17ea.js => 61.db8b79c3.js} (99%) rename assets/js/{62.315ee6d5.js => 62.f686b521.js} (99%) rename assets/js/{63.a6117e34.js => 63.53783e0a.js} (99%) rename assets/js/{64.08ee4767.js => 64.82779c88.js} (99%) rename assets/js/{65.e47b714e.js => 65.71eccdcf.js} (99%) rename assets/js/{66.62fed6f7.js => 66.1ec98713.js} (99%) rename assets/js/{70.da579d90.js => 70.dc8d08ec.js} (99%) rename assets/js/{71.d138f3df.js => 71.b5a740f7.js} (99%) rename assets/js/{72.1c2cf134.js => 72.54663843.js} (99%) rename assets/js/{74.5f8ac53c.js => 74.ae6867a4.js} (99%) rename assets/js/{75.e1920f80.js => 75.c6fe9b95.js} (99%) rename assets/js/{76.aa9e2182.js => 76.04856c41.js} (99%) rename assets/js/{77.c32ccfd5.js => 77.bccb78bf.js} (98%) rename assets/js/{78.1816ce47.js => 78.f4004da3.js} (99%) rename assets/js/{79.1ad39e24.js => 79.e7350423.js} (98%) rename assets/js/{80.914d4500.js => 80.b9017867.js} (99%) rename assets/js/{83.de486fb1.js => 83.be2d0652.js} (88%) rename assets/js/{84.ddbb04c5.js => 84.3ec08e13.js} (98%) rename assets/js/{86.fb094c9b.js => 86.4af6e043.js} (99%) rename assets/js/{88.53b10983.js => 88.c63c0587.js} (97%) rename assets/js/{app.cd8846d4.js => app.061d8498.js} (66%) diff --git a/404.html b/404.html index 2e9a9049a4..2c065a4abd 100644 --- a/404.html +++ b/404.html @@ -15,7 +15,7 @@ - + @@ -39,7 +39,7 @@ Blog GitHub - (opens new window)

404 - Not Found

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

404 - Not Found

That's a Four-Oh-Four.
Take me home.
- + diff --git a/adoption/all/index.html b/adoption/all/index.html index f8152b3e70..4bb3a7e169 100644 --- a/adoption/all/index.html +++ b/adoption/all/index.html @@ -29,7 +29,7 @@ - + @@ -82,6 +82,6 @@
BDK Foundation
- + diff --git a/adoption/custodial/index.html b/adoption/custodial/index.html index b76a9a5281..21259f0399 100644 --- a/adoption/custodial/index.html +++ b/adoption/custodial/index.html @@ -29,7 +29,7 @@ - + @@ -82,6 +82,6 @@
BDK Foundation
- + diff --git a/adoption/desktop/index.html b/adoption/desktop/index.html index d5dd7d5a38..255c460467 100644 --- a/adoption/desktop/index.html +++ b/adoption/desktop/index.html @@ -29,7 +29,7 @@ - + @@ -82,6 +82,6 @@
BDK Foundation
- + diff --git a/adoption/exchange/index.html b/adoption/exchange/index.html index 41ec08c375..df75d7174f 100644 --- a/adoption/exchange/index.html +++ b/adoption/exchange/index.html @@ -29,7 +29,7 @@ - + @@ -82,6 +82,6 @@
BDK Foundation
- + diff --git a/adoption/hardware/index.html b/adoption/hardware/index.html index 83586e3cf4..c41e358183 100644 --- a/adoption/hardware/index.html +++ b/adoption/hardware/index.html @@ -29,7 +29,7 @@ - + @@ -84,6 +84,6 @@
BDK Foundation
- + diff --git a/adoption/infrastructure/index.html b/adoption/infrastructure/index.html index dd9a9b7b54..f21d5d2cb7 100644 --- a/adoption/infrastructure/index.html +++ b/adoption/infrastructure/index.html @@ -29,7 +29,7 @@ - + @@ -78,6 +78,6 @@
BDK Foundation
- + diff --git a/adoption/mobile/index.html b/adoption/mobile/index.html index fd6d508b5d..0b2ad0c9c2 100644 --- a/adoption/mobile/index.html +++ b/adoption/mobile/index.html @@ -29,7 +29,7 @@ - + @@ -84,6 +84,6 @@
BDK Foundation
- + diff --git a/adoption/web/index.html b/adoption/web/index.html index 5857bd4adb..dde1cbeee3 100644 --- a/adoption/web/index.html +++ b/adoption/web/index.html @@ -29,7 +29,7 @@ - + @@ -82,6 +82,6 @@
BDK Foundation
- + diff --git a/assets/js/19.a32238ae.js b/assets/js/19.a5cb69f8.js similarity index 99% rename from assets/js/19.a32238ae.js rename to assets/js/19.a5cb69f8.js index 3d15919f54..8231669c01 100644 --- a/assets/js/19.a32238ae.js +++ b/assets/js/19.a5cb69f8.js @@ -1 +1 @@ -(window.webpackJsonp=window.webpackJsonp||[]).push([[19],{355:function(t,a,s){t.exports=s.p+"assets/img/bdk_flutter_complete_app.c74da859.png"},356:function(t,a,s){t.exports=s.p+"assets/img/default_flutter_app.31b31721.png"},357:function(t,a,s){t.exports=s.p+"assets/img/assets_section.b43d75e9.png"},358:function(t,a,s){t.exports=s.p+"assets/img/folder_structure.b2750bd6.png"},359:function(t,a,s){t.exports=s.p+"assets/img/bdk_flutter_title.e4e3484a.png"},360:function(t,a,s){t.exports=s.p+"assets/img/bdk_flutter_tutorial_screen_mnemonic.df703b77.png"},361:function(t,a,s){t.exports=s.p+"assets/img/bdk_flutter_tutorial_screen_createwallet.3b052736.png"},362:function(t,a,s){t.exports=s.p+"assets/img/bdk_flutter_get_balance.bfdf9ced.png"},363:function(t,a,s){t.exports=s.p+"assets/img/bdk_flutter_get_address.5db2e3cc.png"},364:function(t,a,s){t.exports=s.p+"assets/img/bdk_flutter_get_restore.db8e7e55.png"},365:function(t,a,s){t.exports=s.p+"assets/img/bdk_flutter_send.1688372b.png"},411:function(t,a,s){"use strict";s.r(a);var n=s(7),e=Object(n.a)({},(function(){var t=this,a=t._self._c;return a("ContentSlotsDistributor",{attrs:{"slot-key":t.$parent.slotKey}},[a("h2",{attrs:{id:"introduction"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#introduction"}},[t._v("#")]),t._v(" Introduction")]),t._v(" "),a("p",[a("code",[t._v("bdk-flutter")]),t._v(" is the "),a("strong",[t._v("Bitcoin Dev kit")]),t._v("'s "),a("strong",[t._v("Flutter")]),t._v(" library which enables building bitcoin applications for Android and iOS mobile platforms. Using "),a("code",[t._v("bdk-flutter")]),t._v(" is similar to using any other Flutter module. Just do "),a("code",[t._v("flutter pub add bdk_flutter")]),t._v(" and you are ready to code! This is the first tutorial on how to use "),a("code",[t._v("bdk-flutter")]),t._v(", more coming soon, make sure to "),a("a",{attrs:{href:"https://twitter.com/BitcoinZavior",target:"_blank",rel:"noopener noreferrer"}},[t._v("follow"),a("OutboundLink")],1),t._v(" to be notified of new ones. There will also be a "),a("strong",[a("code",[t._v("bdk-flutter")])]),t._v(" focused Livestream on "),a("a",{attrs:{href:"https://www.twitch.tv/bitcoindevelopers",target:"_blank",rel:"noopener noreferrer"}},[t._v("Twitch"),a("OutboundLink")],1),t._v(" on the Bitcoin Developers "),a("a",{attrs:{href:"https://www.youtube.com/channel/UCUq_ZdezVWKPvkWRicAYxLA/videos",target:"_blank",rel:"noopener noreferrer"}},[t._v("YouTube Channel"),a("OutboundLink")],1),t._v(" so make sure to subscribe.")]),t._v(" "),a("p",[t._v("This tutorial will explore "),a("code",[t._v("bdk-flutter")]),t._v(" usage and the API it provides. This guide will walk through the development process and code for making a bitcoin application. The bitcoin application we create will be a non-custodial HD Wallet. The application will have the functionality to create a new wallet or restore from a known mnemonic seed phrase. This application will also be able to interact with the bitcoin network to sync UTXOs from new blocks and broadcast transactions.")]),t._v(" "),a("p",[t._v("The tutorial will focus on bitcoin concepts and "),a("code",[t._v("bdk-flutter")]),t._v(" API. So it will gloss over Flutter and Dart. If you are interested in learning more about Flutter and Dart please refer to the Flutter "),a("a",{attrs:{href:"https://flutter.dev/learn",target:"_blank",rel:"noopener noreferrer"}},[t._v("learning portal"),a("OutboundLink")],1),t._v(". The code for this tutorial is available on the "),a("a",{attrs:{href:"https://github.com/LtbLightning/bdk-flutter-quickstart",target:"_blank",rel:"noopener noreferrer"}},[t._v("LtbLightning GitHub"),a("OutboundLink")],1)]),t._v(" "),a("img",{staticStyle:{display:"block",margin:"0 auto",zoom:"25%"},attrs:{src:s(355)}}),t._v(" "),a("h3",{attrs:{id:"prerequisites"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#prerequisites"}},[t._v("#")]),t._v(" Prerequisites")]),t._v(" "),a("p",[t._v("To use "),a("code",[t._v("bdk-flutter")]),t._v(" in a Flutter App, a Flutter development environment is required. Please refer to resources out there on the internet if you need to set this up, here is one of many good resources to guide you on "),a("a",{attrs:{href:"https://docs.flutter.dev/get-started/install",target:"_blank",rel:"noopener noreferrer"}},[t._v("environment setup"),a("OutboundLink")],1)]),t._v(" "),a("h3",{attrs:{id:"bitcoin-basics"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#bitcoin-basics"}},[t._v("#")]),t._v(" Bitcoin Basics")]),t._v(" "),a("p",[t._v("The bitcoin concepts used in this blog post are detailed and explained very well in external bitcoin resources. Here are some links for reference:")]),t._v(" "),a("p",[a("a",{attrs:{href:"https://github.com/bitcoinbook/bitcoinbook/blob/develop/ch04.asciidoc",target:"_blank",rel:"noopener noreferrer"}},[t._v("Mastering Bitcoin(HD Wallet chapter)"),a("OutboundLink")],1)]),t._v(" "),a("p",[a("a",{attrs:{href:"https://github.com/bitcoin/bitcoin/blob/master/doc/descriptors.md",target:"_blank",rel:"noopener noreferrer"}},[t._v("Bitcoin Output Descriptors from bitcoin GitHub"),a("OutboundLink")],1)]),t._v(" "),a("p",[t._v("Now let's jump into Bitcoin Dev Kit")]),t._v(" "),a("h2",{attrs:{id:"bitcoin-dev-kit-and-bdk-flutter"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#bitcoin-dev-kit-and-bdk-flutter"}},[t._v("#")]),t._v(" Bitcoin Dev Kit and bdk-flutter")]),t._v(" "),a("p",[a("code",[t._v("bdk-flutter")]),t._v(" is "),a("strong",[t._v("Bitcoin Dev kit")]),t._v("'s "),a("strong",[t._v("Flutter")]),t._v(" library for building Bitcoin apps in "),a("strong",[t._v("Flutter")]),t._v(".\nIt encapsulates all of the low-level APIs and methods for BDK and exposes them in a Flutter context. To use BDK in Flutter apps only the "),a("code",[t._v("bdk-flutter")]),t._v(" module is required. "),a("code",[t._v("bdk-flutter")]),t._v(" can be used like any other Flutter library and is available on "),a("a",{attrs:{href:"https://pub.dev/packages/bdk_flutter",target:"_blank",rel:"noopener noreferrer"}},[t._v("pub.dev"),a("OutboundLink")],1)]),t._v(" "),a("h2",{attrs:{id:"getting-started"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#getting-started"}},[t._v("#")]),t._v(" Getting Started")]),t._v(" "),a("p",[t._v("Although we won't delve deep into Flutter we will focus more on bitcoin and "),a("code",[t._v("bdk-flutter")]),t._v(", however, some rudimentary Flutter setup is required, especially a basic Flutter app to add our code.")]),t._v(" "),a("p",[t._v("start by creating a new Flutter project.")]),t._v(" "),a("p",[a("code",[t._v("flutter create bdk-flutter-quickstart")])]),t._v(" "),a("p",[t._v("Once done let's "),a("code",[t._v("cd")]),t._v(" into the new project directory and run the basic Flutter app that's created")]),t._v(" "),a("div",{staticClass:"language-shell extra-class"},[a("pre",{pre:!0,attrs:{class:"language-shell"}},[a("code",[a("span",{pre:!0,attrs:{class:"token builtin class-name"}},[t._v("cd")]),t._v(" bdk-flutter-quickstart\nflutter run\n")])])]),a("p",[t._v("This should start building the app and then launch the app in a simulator. So far we have created a basic Flutter project if this doesn't work then refer to the Flutter development setup guide to troubleshoot.")]),t._v(" "),a("img",{staticStyle:{display:"block",margin:"0 auto",zoom:"25%"},attrs:{src:s(356),alt:"BDK Flutter Quick Start"}}),t._v(" "),a("h2",{attrs:{id:"setting-up-flutter-app-structure"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#setting-up-flutter-app-structure"}},[t._v("#")]),t._v(" Setting up Flutter app structure")]),t._v(" "),a("p",[t._v("Let's set up a very basic app structure. Let's create an "),a("code",[t._v("assets")]),t._v(" folder in the project root and then add new folders "),a("code",[t._v("widgets")]),t._v(", "),a("code",[t._v("screens")]),t._v(", and "),a("code",[t._v("styles")]),t._v(" inside the existing "),a("code",[t._v("lib")]),t._v(" folder.")]),t._v(" "),a("p",[t._v("Paste the following code in your "),a("code",[t._v("pubspec.yaml")]),t._v(" file, assets section.")]),t._v(" "),a("div",{staticClass:"language- extra-class"},[a("pre",[a("code",[t._v("- assets/\n")])])]),a("p",[t._v("Please make sure your assets section looks like the screenshot below.\n"),a("img",{staticStyle:{display:"block",margin:"0 auto",zoom:"60%"},attrs:{src:s(357),alt:"BDK Flutter Quick Start"}})]),t._v(" "),a("p",[t._v("Once done let's run a "),a("code",[t._v("get")]),t._v(" command from the pub tool commands, this will get all the required dependencies for our project.")]),t._v(" "),a("div",{staticClass:"language-shell extra-class"},[a("pre",{pre:!0,attrs:{class:"language-shell"}},[a("code",[t._v("flutter pub get\n")])])]),a("p",[t._v("To make this quick you can download the theme, styled widgets and images used in the tutorial from the repository. The "),a("code",[t._v("theme.dart")]),t._v(" file has the theme we will use and this can be taken from "),a("a",{attrs:{href:"https://github.com/LtbLightning/bdk-flutter-quickstart/blob/master/lib/styles/theme.dart",target:"_blank",rel:"noopener noreferrer"}},[t._v("here"),a("OutboundLink")],1),t._v(" and moved to the styles folder. The "),a("code",[t._v("widgets.dart")]),t._v(" file has the styled widgets we will use and these can be taken from "),a("a",{attrs:{href:"https://github.com/LtbLightning/bdk-flutter-quickstart/blob/master/lib/widgets/widgets.dart",target:"_blank",rel:"noopener noreferrer"}},[t._v("here"),a("OutboundLink")],1),t._v(" and moved to the widgets folder. The image assets can be taken from "),a("a",{attrs:{href:"https://github.com/LtbLightning/bdk-flutter-quickstart/tree/master/assets",target:"_blank",rel:"noopener noreferrer"}},[t._v("here"),a("OutboundLink")],1),t._v(" Alternatively, you can write your theme, widgets and use your images if you intend to style the app differently.")]),t._v(" "),a("p",[t._v("In addition to the the theme, widgets and assets. We also need to create a "),a("code",[t._v("screens")]),t._v(" folder and create a "),a("code",[t._v("home.dart")]),t._v(" file inside it, this will be where most of the code will be added.")]),t._v(" "),a("p",[t._v("Once done the file structure should look like this:")]),t._v(" "),a("img",{staticStyle:{display:"block",margin:"0px auto",zoom:"60%"},attrs:{src:s(358)}}),t._v(" "),a("p",[a("br"),t._v("Locate "),a("code",[t._v("main.dart")]),t._v(" in the project root, this will have the default code added by "),a("code",[t._v("flutter create")]),t._v(", let's delete all contents of "),a("code",[t._v("main.dart")]),t._v(" and replace it with the following code to use "),a("code",[t._v("home.dart")]),t._v(" as our main screen. This will probably crash the app but that's fine, it will be up and running once we add code to "),a("code",[t._v("home.dart")]),t._v(" in the next few steps")]),t._v(" "),a("div",{staticClass:"language-dart extra-class"},[a("pre",{pre:!0,attrs:{class:"language-dart"}},[a("code",[a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// main.dart")]),t._v("\n\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("import")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string-literal"}},[a("span",{pre:!0,attrs:{class:"token string"}},[t._v("'package:bdk_flutter_quickstart/screens/home.dart'")])]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("import")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string-literal"}},[a("span",{pre:!0,attrs:{class:"token string"}},[t._v("'package:bdk_flutter_quickstart/styles/theme.dart'")])]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("import")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string-literal"}},[a("span",{pre:!0,attrs:{class:"token string"}},[t._v("'package:flutter/material.dart'")])]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("void")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("main")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("runApp")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("MyApp")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("MyApp")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("extends")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("StatelessWidget")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("MyApp")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Key")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("?")]),t._v(" key"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("super")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("key"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" key"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// This widget is the root of your application.")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token metadata function"}},[t._v("@override")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Widget")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("build")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("BuildContext")]),t._v(" context"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("MaterialApp")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n debugShowCheckedModeBanner"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token boolean"}},[t._v("false")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n title"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string-literal"}},[a("span",{pre:!0,attrs:{class:"token string"}},[t._v("'BDK-FLUTTER TUTORIAL'")])]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n theme"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("theme")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n home"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Home")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),a("h2",{attrs:{id:"installing-bdk-flutter"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#installing-bdk-flutter"}},[t._v("#")]),t._v(" Installing "),a("code",[t._v("bdk-flutter")])]),t._v(" "),a("p",[t._v("With the Flutter project in place, we can now add "),a("code",[t._v("bdk-flutter")]),t._v(" using "),a("code",[t._v("flutter pub add")]),t._v(".")]),t._v(" "),a("div",{staticClass:"language-shell extra-class"},[a("pre",{pre:!0,attrs:{class:"language-shell"}},[a("code",[t._v("flutter pub "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("add")]),t._v(" bdk_flutter\n")])])]),a("p",[t._v("This will add a line like this to your package's "),a("code",[t._v("pubspec.yaml")]),t._v(" and this will also run an implicit flutter pub get to download "),a("code",[t._v("bdk-flutter")]),t._v(" from "),a("code",[t._v("pub.dev")]),t._v(":")]),t._v(" "),a("div",{staticClass:"language-shell extra-class"},[a("pre",{pre:!0,attrs:{class:"language-shell"}},[a("code",[t._v("dependencies:\n bdk_flutter: ^0.28.2\n")])])]),a("h2",{attrs:{id:"configuring"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#configuring"}},[t._v("#")]),t._v(" Configuring")]),t._v(" "),a("p",[t._v("Make sure your app meets the following requirements for using "),a("code",[t._v("bdk-flutter")])]),t._v(" "),a("p",[a("strong",[t._v("Android")])]),t._v(" "),a("p",[t._v("MinSdkVersion : API 23 or higher.")]),t._v(" "),a("p",[a("strong",[t._v("IOS")])]),t._v(" "),a("p",[t._v("Deployment target: iOS 12.0 or greater.")]),t._v(" "),a("p",[t._v("Locate your Podfile in the ios folder of your project and paste the following code at the beginning")]),t._v(" "),a("div",{staticClass:"language- extra-class"},[a("pre",{pre:!0,attrs:{class:"language-text"}},[a("code",[t._v("platform :ios, '12.0'\n")])])]),a("p",[t._v("After changing the deployment target in your project's "),a("code",[t._v("PodFile")]),t._v(", let's use the following "),a("code",[t._v("command")]),t._v(" to install pod dependencies for iOS.")]),t._v(" "),a("div",{staticClass:"language-shell extra-class"},[a("pre",{pre:!0,attrs:{class:"language-shell"}},[a("code",[a("span",{pre:!0,attrs:{class:"token builtin class-name"}},[t._v("cd")]),t._v(" ios "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&&")]),t._v(" pod "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("install")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&&")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token builtin class-name"}},[t._v("cd")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("..")]),t._v("\n")])])]),a("p",[t._v("Once done, bdk-flutter is installed and configured and ready to be used in our "),a("strong",[t._v("bdk-flutter-quickstart")]),t._v(" App.")]),t._v(" "),a("h2",{attrs:{id:"importing-bdk-flutter"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#importing-bdk-flutter"}},[t._v("#")]),t._v(" Importing "),a("code",[t._v("bdk-flutter")])]),t._v(" "),a("p",[t._v("Locate "),a("code",[t._v("home.dart")]),t._v(" which we added in the setup section and import "),a("code",[t._v("bdk-flutter")]),t._v(" at the top of the file. Create a stateful widget called "),a("code",[t._v("Home")])]),t._v(" "),a("div",{staticClass:"language-dart extra-class"},[a("pre",{pre:!0,attrs:{class:"language-dart"}},[a("code",[a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// screens/home.dart")]),t._v("\n\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("import")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string-literal"}},[a("span",{pre:!0,attrs:{class:"token string"}},[t._v("'package:bdk_flutter/bdk_flutter.dart'")])]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Home")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("extends")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("StatefulWidget")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Home")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Key")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("?")]),t._v(" key"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("super")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("key"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" key"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),a("span",{pre:!0,attrs:{class:"token metadata function"}},[t._v("@override")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("State")]),a("span",{pre:!0,attrs:{class:"token generics"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Home")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("createState")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("_HomeState")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),t._v(" _HomeState "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("extends")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("State")]),a("span",{pre:!0,attrs:{class:"token generics"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Home")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("TextEditingController")]),t._v(" mnemonic "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("TextEditingController")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token metadata function"}},[t._v("@override")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Widget")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("build")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("BuildContext")]),t._v(" context"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Container")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),a("p",[t._v("Before we start using "),a("code",[t._v("bdk-flutter")]),t._v(" let's add some additional imports and also import styles, to create a basic layout to build our home screen")]),t._v(" "),a("div",{staticClass:"language-dart extra-class"},[a("pre",{pre:!0,attrs:{class:"language-dart"}},[a("code",[a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// screens/home.dart")]),t._v("\n\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("import")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string-literal"}},[a("span",{pre:!0,attrs:{class:"token string"}},[t._v("'package:bdk_flutter/bdk_flutter.dart'")])]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("import")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string-literal"}},[a("span",{pre:!0,attrs:{class:"token string"}},[t._v("'package:bdk_flutter_quickstart/widgets/widgets.dart'")])]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("import")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string-literal"}},[a("span",{pre:!0,attrs:{class:"token string"}},[t._v("'package:flutter/cupertino.dart'")])]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("import")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string-literal"}},[a("span",{pre:!0,attrs:{class:"token string"}},[t._v("'package:flutter/material.dart'")])]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Home")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("extends")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("StatefulWidget")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Home")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Key")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("?")]),t._v(" key"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("super")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("key"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" key"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),a("span",{pre:!0,attrs:{class:"token metadata function"}},[t._v("@override")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("State")]),a("span",{pre:!0,attrs:{class:"token generics"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Home")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("createState")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("_HomeState")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),t._v(" _HomeState "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("extends")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("State")]),a("span",{pre:!0,attrs:{class:"token generics"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Home")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n\n "),a("span",{pre:!0,attrs:{class:"token metadata function"}},[t._v("@override")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Widget")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("build")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("BuildContext")]),t._v(" context"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Scaffold")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n resizeToAvoidBottomInset"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token boolean"}},[t._v("true")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n backgroundColor"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Colors")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("white"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("/* AppBar */")]),t._v("\n appBar"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("buildAppBar")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("context"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n body"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("SingleChildScrollView")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n child"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Container")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n padding"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("EdgeInsets")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("symmetric")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("horizontal"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("30")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n child"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Column")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n children"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("/* Balance */")]),t._v("\n\n "),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("/* Create Wallet */")]),t._v("\n\n "),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("/* Send Transaction */")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),a("p",[t._v("We now have an app title section and a structure to hold the rest of our app components.")]),t._v(" "),a("img",{staticStyle:{display:"block",margin:"0 auto",zoom:"33%"},attrs:{src:s(359)}}),t._v(" "),a("h2",{attrs:{id:"calling-bdk-flutter-methods"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#calling-bdk-flutter-methods"}},[t._v("#")]),t._v(" Calling bdk-flutter methods")]),t._v(" "),a("p",[t._v("To call all methods properly from the "),a("code",[t._v("bdk-flutter")]),t._v(" package, first, we need to create state variables to store "),a("code",[t._v("Wallet")]),t._v(" and "),a("code",[t._v("Blockchain")]),t._v(" objects.")]),t._v(" "),a("p",[t._v("Here we use the late keyword to declare both "),a("code",[t._v("Wallet")]),t._v(" and "),a("code",[t._v("Blockchain")]),t._v(". These are non-nullable variables that are initialized after the declaration.")]),t._v(" "),a("div",{staticClass:"language-dart extra-class"},[a("pre",{pre:!0,attrs:{class:"language-dart"}},[a("code",[a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("import")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string-literal"}},[a("span",{pre:!0,attrs:{class:"token string"}},[t._v("'package:bdk_flutter/bdk_flutter.dart'")])]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\nlate "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Wallet")]),t._v(" wallet"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\nlate "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Blockchain")]),t._v(" blockchain"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),a("p",[t._v("The first step in creating a non-custodial bitcoin app is creating a mnemonic seed phrase for the wallet.")]),t._v(" "),a("p",[a("code",[t._v("bdk-flutter")]),t._v(" provides a "),a("code",[t._v("Mnemonic")]),t._v(" class to create a "),a("code",[t._v("Mnemonic")]),t._v(". The "),a("code",[t._v("create")]),t._v(" method is a named constructor and can be used to create a mnemonic, it takes "),a("code",[t._v("WordCount")]),t._v(" as its required parameter.")]),t._v(" "),a("div",{staticClass:"language-dart extra-class"},[a("pre",{pre:!0,attrs:{class:"language-dart"}},[a("code",[a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("var")]),t._v(" res "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Mnemonic")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("create")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("WordCount.Words12")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),a("p",[t._v("We can generate a mnemonic of longer length by passing in a wordCount argument of required length.")]),t._v(" "),a("p",[t._v("To create a mnemonic with a "),a("code",[t._v("WordCount")]),t._v(" of 18 words, we can use "),a("code",[t._v("(WordCount.Words18)")]),t._v("\nRefer to the API docs on "),a("a",{attrs:{href:"https://pub.dev/documentation/bdk_flutter/latest/bdk_flutter/bdk_flutter-library.html",target:"_blank",rel:"noopener noreferrer"}},[t._v("pub.dev"),a("OutboundLink")],1),t._v(" for more details.")]),t._v(" "),a("div",{staticClass:"language-dart extra-class"},[a("pre",{pre:!0,attrs:{class:"language-dart"}},[a("code",[t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("var")]),t._v(" res "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Mnemonic")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("create")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("WordCount.Words18")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// here response is saved as a 'Mnemonic' object")]),t._v("\n")])])]),a("p",[t._v("In order to use this in our Flutter app, we want a button that will generate a mnemonic when clicked, and a text input box to show the generated mnemonic. Let's first create a "),a("code",[t._v("TextEditingController")]),t._v(" for the "),a("code",[t._v("mnemonic")]),t._v(" textfield to store the mnemonic, and an internal "),a("code",[t._v("generateMnemonicHandler")]),t._v(" method which can be called on button click. We will also need a button that will call the internal "),a("code",[t._v("generateMnemonicHandler")]),t._v(" method when clicked. Adding the following code achieves all of this.")]),t._v(" "),a("div",{staticClass:"language-dart extra-class"},[a("pre",{pre:!0,attrs:{class:"language-dart"}},[a("code",[a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Home")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("extends")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("StatefulWidget")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Home")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Key")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("?")]),t._v(" key"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("super")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("key"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" key"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),a("span",{pre:!0,attrs:{class:"token metadata function"}},[t._v("@override")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("State")]),a("span",{pre:!0,attrs:{class:"token generics"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Home")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("createState")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("_HomeState")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),t._v(" _HomeState "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("extends")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("State")]),a("span",{pre:!0,attrs:{class:"token generics"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Home")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n late "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Wallet")]),t._v(" wallet"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n late "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Blockchain")]),t._v(" blockchain"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("TextEditingController")]),t._v(" mnemonic "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("TextEditingController")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Future")]),a("span",{pre:!0,attrs:{class:"token generics"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("void")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("generateMnemonicHandler")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("async")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("var")]),t._v(" res "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Mnemonic")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("create")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("WordCount.Words12")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("setState")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n mnemonic"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("text "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" res"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("asString")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token metadata function"}},[t._v("@override")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Widget")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("build")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("BuildContext")]),t._v(" context"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Scaffold")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n resizeToAvoidBottomInset"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token boolean"}},[t._v("true")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n backgroundColor"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Colors")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("white"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("/* Header */")]),t._v("\n appBar"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("buildAppBar")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("context"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n body"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("SingleChildScrollView")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n child"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Container")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n padding"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("EdgeInsets")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("symmetric")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("horizontal"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("30")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n child"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Column")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n children"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("/* Balance */")]),t._v("\n\n "),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("/* Result */")]),t._v("\n\n\n "),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("/* Create Wallet */")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("StyledContainer")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n child"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Column")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n mainAxisAlignment"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("MainAxisAlignment")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("start"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n crossAxisAlignment"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("CrossAxisAlignment")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("center"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n children"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("SubmitButton")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n text"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string-literal"}},[a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Generate Mnemonic"')])]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n callback"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("async")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("generateMnemonicHandler")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("TextFieldContainer")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n child"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("TextFormField")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n controller"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" mnemonic"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n style"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Theme")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("of")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("context"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("textTheme"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("bodyText1"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n keyboardType"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("TextInputType")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("multiline"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n maxLines"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("5")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n decoration"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("InputDecoration")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n hintText"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string-literal"}},[a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Enter your mnemonic"')])]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("/* Send Transaction Buttons */")]),t._v("\n\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),a("p",[t._v("Now we need to add a component to display the output of our method calls and this will also need a "),a("code",[t._v("displayText")]),t._v(" variable to track our method call response. To achieve this add the following code.")]),t._v(" "),a("div",{staticClass:"language-dart extra-class"},[a("pre",{pre:!0,attrs:{class:"language-dart"}},[a("code",[a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// screens/home.dart")]),t._v("\n\n"),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// add this as another state variable under mnemonic")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("String")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("?")]),t._v(" displayText"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// modify the generateMnemonicHandler method to also set mnemonic as displayText")]),t._v("\n\n "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Future")]),a("span",{pre:!0,attrs:{class:"token generics"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("void")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("generateMnemonicHandler")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("async")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("var")]),t._v(" res "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Mnemonic")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("create")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("WordCount.Words12")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("setState")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n mnemonic"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("text "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" res"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("asString")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n displayText "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" res"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("asString")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),a("p",[t._v("and finally, let's add the component to display the output under "),a("code",[t._v("/* Result */")])]),t._v(" "),a("div",{staticClass:"language-dart extra-class"},[a("pre",{pre:!0,attrs:{class:"language-dart"}},[a("code",[a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// screens/home.dart")]),t._v("\n\n "),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("/* Result */")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// display the component only if displayText has a value")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("ResponseContainer")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("text"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v("displayText "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("?")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("?")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string-literal"}},[a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"No Response"')])]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n")])])]),a("p",[t._v('We should now have a working "Generate Mnemonic" button that displays the new mnemonic')]),t._v(" "),a("img",{staticStyle:{display:"block",margin:"0 auto",zoom:"25%"},attrs:{src:s(360)}}),t._v(" "),a("p",[t._v("A quick recap, we added a button to call a click handler ("),a("code",[t._v("generateMnemonicHandler")]),t._v(") which calls "),a("code",[t._v("generateMnemonic")]),t._v(" API of "),a("code",[t._v("bdk-flutter")]),t._v(". The click handler also sets the state for the app and also updates the "),a("code",[t._v("displayText")]),t._v(" variable to display the output of the call in the display section. We will follow this pattern for the remaining calls to "),a("code",[t._v("bdk-flutter")]),t._v(".")]),t._v(" "),a("h2",{attrs:{id:"creating-a-wallet"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#creating-a-wallet"}},[t._v("#")]),t._v(" Creating a wallet")]),t._v(" "),a("p",[t._v("Before moving on to creating a wallet, let's add a section at the top to display the balance of the wallet.")]),t._v(" "),a("p",[t._v("To display the balance we will need a state variable to store the balance and a display component to display it. We will also be creating a receive address for the wallet so a state variable will be required for the address as well.")]),t._v(" "),a("p",[t._v("Under the "),a("code",[t._v("mnemonic")]),t._v(" and "),a("code",[t._v("displayText")]),t._v(" state variables, let's add one for "),a("code",[t._v("balance")]),t._v(" and one for "),a("code",[t._v("address")])]),t._v(" "),a("div",{staticClass:"language-dart extra-class"},[a("pre",{pre:!0,attrs:{class:"language-dart"}},[a("code",[a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),t._v(" _HomeState "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("extends")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("State")]),a("span",{pre:!0,attrs:{class:"token generics"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Home")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("TextEditingController")]),t._v(" mnemonic "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("TextEditingController")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("String")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("?")]),t._v(" displayText"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("String")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("?")]),t._v(" balance"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("String")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("?")]),t._v(" address"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),a("p",[t._v("Just below "),a("code",[t._v("/* Balance */")]),t._v(" and above "),a("code",[t._v("/* Result */")]),t._v(" add the following UI components to display the balance. We only want to show the balance when it has a value so we will use a null-aware operator "),a("code",[t._v("??")]),t._v(" for a quick "),a("code",[t._v("null")]),t._v(" check and use "),a("code",[t._v("0")]),t._v(" in case of a "),a("code",[t._v("null")]),t._v(" value.")]),t._v(" "),a("div",{staticClass:"language-dart extra-class"},[a("pre",{pre:!0,attrs:{class:"language-dart"}},[a("code",[t._v(" "),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("/* Balance */")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("BalanceContainer")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n text"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string-literal"}},[a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"${balance ?? "')])]),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),a("span",{pre:!0,attrs:{class:"token string-literal"}},[a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"} Sats"')])]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("/* Result */")]),t._v("\n")])])]),a("p",[a("code",[t._v("bdk_flutter")]),t._v(" creates a wallet using output descriptors which define the derivation path to derive addresses and sign transactions. More about output descriptors "),a("a",{attrs:{href:"https://github.com/bitcoin/bitcoin/blob/master/doc/descriptors.md",target:"_blank",rel:"noopener noreferrer"}},[t._v("here"),a("OutboundLink")],1),t._v(". Before creating the "),a("code",[t._v("Wallet")]),t._v(" we need to create a "),a("code",[t._v("descriptor")]),t._v(" object which will be used to generate receive addresses and a "),a("code",[t._v("changeDescriptor")]),t._v(" object to to create change addresses to collect from outgoing transactions.")]),t._v(" "),a("p",[a("code",[t._v("bdk_flutter")]),t._v("'s "),a("code",[t._v("Descriptor")]),t._v(" class has a number of descriptor templates that will help you create a simple wallet.")]),t._v(" "),a("p",[t._v("Let's add some code to create a simple "),a("code",[t._v("wpkh")]),t._v(" descriptor object by using the "),a("code",[t._v("BIP84")]),t._v(" template. This template will create a descriptor in the format "),a("code",[t._v("wpkh(key/84'/{0,1}'/0'/{0,1}/*)")])]),t._v(" "),a("p",[t._v("This descriptor will create receive ("),a("code",[t._v("KeyChainKind.External")]),t._v(") and change descriptor ("),a("code",[t._v("KeyChainKind.Internal")]),t._v(") for a specified mnemonic.")]),t._v(" "),a("div",{staticClass:"language-dart extra-class"},[a("pre",{pre:!0,attrs:{class:"language-dart"}},[a("code",[a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Future")]),a("span",{pre:!0,attrs:{class:"token generics"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("List")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Descriptor")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("getDescriptors")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("String")]),t._v(" mnemonic"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("async")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("final")]),t._v(" descriptors "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token generics"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Descriptor")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("try")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("for")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("var")]),t._v(" e "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("in")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("KeychainKind.External")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("KeychainKind.Internal")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("final")]),t._v(" mnemonicObj "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Mnemonic")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("fromString")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("mnemonic"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("final")]),t._v(" descriptorSecretKey "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("DescriptorSecretKey")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("create")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n network"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Network.Testnet")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n mnemonic"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" mnemonicObj"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("final")]),t._v(" descriptor "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Descriptor")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("newBip84")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n secretKey"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" descriptorSecretKey"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" \n network"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Network.Testnet")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" \n keychain"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" e"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n descriptors"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("add")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("descriptor"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" descriptors"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("on")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Exception")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("catch")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("e"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("setState")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n displayText "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string-literal"}},[a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Error : ')]),a("span",{pre:!0,attrs:{class:"token interpolation"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("${")]),a("span",{pre:!0,attrs:{class:"token expression"}},[t._v("e"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("toString")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")])]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"')])]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("rethrow")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n")])])]),a("p",[t._v("Under the "),a("code",[t._v("address")]),t._v(" state variable, let's add a state variable called "),a("code",[t._v("wallet")]),t._v(" of the type "),a("code",[t._v("Wallet")]),t._v(" for saving the bitcoin wallet.")]),t._v(" "),a("p",[t._v("To create a wallet with "),a("code",[t._v("bdk-flutter")]),t._v(" call the "),a("code",[t._v("create")]),t._v(" constructor with "),a("code",[t._v("descriptor")]),t._v(", "),a("code",[t._v("changeDescriptor")]),t._v(" "),a("code",[t._v("network")]),t._v(", and the "),a("code",[t._v("databaseConfig")]),t._v(". For database, we can use memory as the database by specifying "),a("code",[t._v("DatabaseConfig.memory()")]),t._v("\nFollowing our pattern of a button, click handler and bdk-flutter API call, Let's add an internal method which will serve as the click handler for the \"Create Wallet\" button. We want to see the output of this call so let's use "),a("code",[t._v("setState()")]),t._v(" to set the "),a("code",[t._v("wallet")]),t._v(" object created and the "),a("code",[t._v("displayText")]),t._v(" variable with the wallet's first receive address.")]),t._v(" "),a("div",{staticClass:"language-dart extra-class"},[a("pre",{pre:!0,attrs:{class:"language-dart"}},[a("code",[t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Future")]),a("span",{pre:!0,attrs:{class:"token generics"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("void")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("createOrRestoreWallet")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("String")]),t._v(" mnemonic"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Network")]),t._v(" network"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("String")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("?")]),t._v(" password"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("async")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("try")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("final")]),t._v(" descriptors "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("getDescriptors")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("mnemonic"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("final")]),t._v(" res "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Wallet")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("create")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n descriptor"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" descriptors"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n changeDescriptor"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" descriptors"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n network"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" network"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n databaseConfig"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("DatabaseConfig")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("memory")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("var")]),t._v(" addressInfo "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" res"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("getAddress")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("addressIndex"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("AddressIndex")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("setState")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n address "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" addressInfo"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("address"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n wallet "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" res"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n displayText "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string-literal"}},[a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Wallet Created: ')]),a("span",{pre:!0,attrs:{class:"token interpolation"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("$")]),a("span",{pre:!0,attrs:{class:"token expression"}},[t._v("address")])]),a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"')])]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("on")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Exception")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("catch")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("e"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("setState")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n displayText "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string-literal"}},[a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Error: ')]),a("span",{pre:!0,attrs:{class:"token interpolation"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("${")]),a("span",{pre:!0,attrs:{class:"token expression"}},[t._v("e"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("toString")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")])]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"')])]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),a("p",[t._v("A new button will be required to call "),a("code",[t._v("createOrRestoreWallet()")])]),t._v(" "),a("p",[t._v("Let's add a new button just below the mnemonic "),a("code",[t._v("TextFieldContainer")])]),t._v(" "),a("div",{staticClass:"language-dart extra-class"},[a("pre",{pre:!0,attrs:{class:"language-dart"}},[a("code",[a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("SubmitButton")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n text"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string-literal"}},[a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Create Wallet"')])]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n callback"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("async")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("createOrRestoreWallet")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n mnemonic"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("text"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" \n "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Network.Testnet")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token string-literal"}},[a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"password"')])]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n")])])]),a("p",[t._v("The response returned by "),a("code",[t._v("create()")]),t._v(" is a "),a("code",[t._v("Wallet")]),t._v(" object.")]),t._v(" "),a("p",[t._v("The App should now be creating a wallet when we click "),a("strong",[t._v("Create Mnemonic")]),t._v(" followed by "),a("strong",[t._v("Create Wallet")]),t._v(".")]),t._v(" "),a("img",{staticStyle:{display:"block",margin:"0 auto",zoom:"25%"},attrs:{src:s(361)}}),t._v(" "),a("p",[t._v("Before going forward, we need to create a "),a("code",[t._v("Blockchain")]),t._v(" object as well. The Blockchain object will encapsulate the bitcoin node configuration which the wallet will use for syncing blocks and broadcasting transactions.")]),t._v(" "),a("p",[t._v("Let's add an internal method to create and initialize the "),a("code",[t._v("Blockchain")]),t._v(" object.")]),t._v(" "),a("div",{staticClass:"language-dart extra-class"},[a("pre",{pre:!0,attrs:{class:"language-dart"}},[a("code",[t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Future")]),a("span",{pre:!0,attrs:{class:"token generics"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("void")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("blockchainInit")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("async")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n blockchain "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Blockchain")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("create")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n config"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("BlockchainConfig")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("electrum")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n config"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("ElectrumConfig")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n stopGap"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("10")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n timeout"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("5")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n retry"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("5")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n url"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string-literal"}},[a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"ssl://electrum.blockstream.info:60002"')])]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n validateDomain"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token boolean"}},[t._v("false")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),a("p",[t._v("Here we are initializing the "),a("code",[t._v("late")]),t._v(" non-nullable "),a("code",[t._v("blockchain")]),t._v(" variable, by calling the named constructor "),a("code",[t._v("create")]),t._v(", which takes a "),a("code",[t._v("BlockchainConfig")]),t._v(" object.\nThe bitcoin node specified is an Electrum node and we are specifying the url for Blockstream's public Electrum Testnet servers over SSL.")]),t._v(" "),a("p",[t._v("After creating the "),a("code",[t._v("blockchainInit()")]),t._v(" method, call it from "),a("code",[t._v("createOrRestoreWallet()")]),t._v(", so the "),a("code",[t._v("blockchain")]),t._v(" variable gets initialized before the "),a("code",[t._v("wallet")]),t._v(" is created.")]),t._v(" "),a("p",[t._v("Include the following line of code inside "),a("code",[t._v("createOrRestoreWallet()")]),t._v(" just before calling Wallet.create().")]),t._v(" "),a("div",{staticClass:"language-dart extra-class"},[a("pre",{pre:!0,attrs:{class:"language-dart"}},[a("code",[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("blockchainInit")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("final")]),t._v(" res "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Wallet")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("create")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("\n")])])]),a("p",[a("strong",[t._v("blockChainConfig")]),t._v(": BlockchainConfig is an enum that has 3 values, "),a("code",[t._v("BlockchainConfig.electrum")]),t._v(" for "),a("a",{attrs:{href:"https://github.com/romanz/electrs",target:"_blank",rel:"noopener noreferrer"}},[a("code",[t._v("electrum")]),a("OutboundLink")],1),t._v(" ,"),a("code",[t._v("BlockchainConfig.esplora")]),t._v(" for "),a("a",{attrs:{href:"https://github.com/Blockstream/esplora",target:"_blank",rel:"noopener noreferrer"}},[a("code",[t._v("esplora")]),a("OutboundLink")],1),t._v(" and "),a("code",[t._v("BlockchainConfig.rpc")]),t._v(" .")]),t._v(" "),a("p",[a("code",[t._v("BlockchainConfig.electrum")]),t._v(", "),a("code",[t._v("BlockchainConfig.rpc")]),t._v(" & "),a("code",[t._v("BlockchainConfig.esplora")]),t._v(" has "),a("code",[t._v("ElectrumConfig")]),t._v(" object, "),a("code",[t._v("RpcConfig")]),t._v(" object and "),a("code",[t._v("EsploraConfig")]),t._v(" object, respectively as its parameter.")]),t._v(" "),a("p",[a("strong",[t._v("ElectrumConfig")]),t._v(": This is the object type of "),a("code",[t._v("BlockchainConfig.electrum")]),t._v("'s config that takes a timeout, retry & url as its required parameter.")]),t._v(" "),a("p",[a("strong",[t._v("EsploraConfig")]),t._v(": This is the object type of "),a("code",[t._v("BlockchainConfig.esplora")]),t._v("'s config that takes baseUrl & stopGap as its required parameter.")]),t._v(" "),a("p",[a("strong",[t._v("RpcConfig")]),t._v(": This is the object type of "),a("code",[t._v("BlockchainConfig.rpc")]),t._v("'s config that takes url, network, & walletName as its required parameter. If "),a("code",[t._v("Rpc Blockchain")]),t._v(" has its authentication values inside a cookie file, please pass in cookie path as authCookie parameter, or you can pass in rpc username and password using "),a("code",[t._v("UserPass")]),t._v(" class.")]),t._v(" "),a("p",[t._v("Refer to the readme for a complete list of options for "),a("a",{attrs:{href:"https://github.com/LtbLightning/bdk-flutter#createwallet",target:"_blank",rel:"noopener noreferrer"}},[t._v("createWallet()"),a("OutboundLink")],1)]),t._v(" "),a("h2",{attrs:{id:"utxos-and-balance"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#utxos-and-balance"}},[t._v("#")]),t._v(" UTXOs and balance")]),t._v(" "),a("p",[t._v("With the "),a("code",[t._v("Wallet")]),t._v(" and "),a("code",[t._v("Blockchain")]),t._v(" created, we can now add methods to sync UTXOs and compute balance.")]),t._v(" "),a("p",[a("code",[t._v("Wallet")]),t._v(" has a "),a("code",[t._v("sync")]),t._v(" method to sync all UTXOs belonging to the wallet using the "),a("code",[t._v("Blockchain")]),t._v(" object. Once the wallet sync is complete balance is computed and "),a("code",[t._v("getBalance")]),t._v(" can fetch the balance.")]),t._v(" "),a("p",[t._v("Earlier we have already added a variable for "),a("code",[t._v("balance")]),t._v(". Now we will add buttons to call "),a("code",[t._v("sync")]),t._v(" and "),a("code",[t._v("getBalance")]),t._v(". Just below the Create Wallet button let's add two buttons as follows:")]),t._v(" "),a("div",{staticClass:"language-dart extra-class"},[a("pre",{pre:!0,attrs:{class:"language-dart"}},[a("code",[t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("SubmitButton")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v(" text"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string-literal"}},[a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Sync Wallet"')])]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n callback"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("async")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("syncWallet")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n\n "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("SubmitButton")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v(" callback"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("async")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("getBalance")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n text"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string-literal"}},[a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Get Balance"')])]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n")])])]),a("p",[t._v("Let's add two internal functions for syncing UTXOs and compute balance.")]),t._v(" "),a("div",{staticClass:"language-dart extra-class"},[a("pre",{pre:!0,attrs:{class:"language-dart"}},[a("code",[t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Future")]),a("span",{pre:!0,attrs:{class:"token generics"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("void")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("getBalance")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("async")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("final")]),t._v(" balanceObj "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" wallet"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("getBalance")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("final")]),t._v(" res "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string-literal"}},[a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Total Balance: ')]),a("span",{pre:!0,attrs:{class:"token interpolation"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("${")]),a("span",{pre:!0,attrs:{class:"token expression"}},[t._v("balanceObj"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("total"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("toString")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")])]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"')])]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("print")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("res"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("setState")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n balance "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" balanceObj"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("total"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("toString")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n displayText "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" res"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Future")]),a("span",{pre:!0,attrs:{class:"token generics"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("void")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("syncWallet")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("async")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n wallet"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("sync")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("blockchain"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n")])])]),a("p",[t._v("We should now be able to create a wallet, sync UTXOs, and get the balance")]),t._v(" "),a("img",{staticStyle:{display:"block",margin:"0 auto",zoom:"25%"},attrs:{src:s(362)}}),t._v(" "),a("p",[t._v("We can use a public testnet faucet to send testnet coins to the wallet and check that the UTXO sync and balance fetch are working correctly. Before we do that add one more method to generate a new address we can then use this address to get testnet coins from a faucet.")]),t._v(" "),a("p",[t._v("Let's use the "),a("code",[t._v("address")]),t._v(" variable that was created before for this, we need to add a button for "),a("strong",[t._v("Get Address")]),t._v(" and an internal function to call "),a("code",[t._v("Wallet")]),t._v(" and create a new address. Let's do the following")]),t._v(" "),a("p",[t._v("Add a new "),a("code",[t._v("getNewAddress")]),t._v(" function below the "),a("code",[t._v("syncWallet()")]),t._v(" function:")]),t._v(" "),a("div",{staticClass:"language-dart extra-class"},[a("pre",{pre:!0,attrs:{class:"language-dart"}},[a("code",[t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Future")]),a("span",{pre:!0,attrs:{class:"token generics"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("void")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("getNewAddress")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("async")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("final")]),t._v(" res "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" wallet"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("getAddress")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("addressIndex"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("AddressIndex")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("setState")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n displayText "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" res"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("address"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n address "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" res"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("address"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),a("p",[t._v("And a "),a("strong",[t._v("Get Address")]),t._v(" button below the existing "),a("strong",[t._v("Get Balance")]),t._v(" button:")]),t._v(" "),a("div",{staticClass:"language-dart extra-class"},[a("pre",{pre:!0,attrs:{class:"language-dart"}},[a("code",[t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("SubmitButton")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n callback"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("async")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("getNewAddress")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n text"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string-literal"}},[a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Get Address"')])]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n")])])]),a("p",[t._v("We should now have the following, and "),a("strong",[t._v("Get Address")]),t._v(" will be able to display a new address.")]),t._v(" "),a("img",{staticStyle:{display:"block",margin:"0px auto",zoom:"25%"},attrs:{src:s(363)}}),t._v(" "),a("p",[t._v("Now that we are able to generate a receive address we can get some testnet bitcoin from one of the public "),a("a",{attrs:{href:"https://coinfaucet.eu/en/btc-testnet/",target:"_blank",rel:"noopener noreferrer"}},[t._v("testnet faucets"),a("OutboundLink")],1)]),t._v(" "),a("p",[t._v("After we send and after the transaction is confirmed we will need to sync the wallet before we can see the new balance from the received transaction.")]),t._v(" "),a("h2",{attrs:{id:"restoring-a-wallet"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#restoring-a-wallet"}},[t._v("#")]),t._v(" Restoring a wallet")]),t._v(" "),a("p",[t._v("The "),a("code",[t._v("create")]),t._v(" method creates a wallet using a "),a("code",[t._v("mnemonic")]),t._v(", to restore we can use the same method, we won't need to call "),a("code",[t._v("generateMnemonic")]),t._v(" as we will already have a "),a("code",[t._v("mnemonic")]),t._v(" to restore with.")]),t._v(" "),a("p",[t._v("This text field below the "),a("code",[t._v("Generate Mnemonic")]),t._v(" button will also display the mnemonic variable if we click Generate Mnemonic' button. The generated mnemonic will show up in the text field. We can overwrite it with our mnemonic and doing so will also overwrite the mnemonic state variable. This way the mnemonic displayed will be the one used to create the wallet.")]),t._v(" "),a("p",[t._v("We can now use our mnemonic and use it to restore a wallet. This will come in handy if we have a wallet with testnet bitcoin as these are hard to come by.")]),t._v(" "),a("img",{staticStyle:{display:"block",margin:"0px auto",zoom:"25%"},attrs:{src:s(364)}}),t._v(" "),a("h2",{attrs:{id:"sending-bitcoin"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#sending-bitcoin"}},[t._v("#")]),t._v(" Sending bitcoin")]),t._v(" "),a("p",[t._v("We are now able to receive bitcoin, now its time to add functionality to send a bitcoin transaction.")]),t._v(" "),a("p",[t._v("For making a successful bitcoin transaction "),a("code",[t._v("bdk-flutter")]),t._v(" utilizes a couple of methods. A new unsigned transaction can be created by using TxBuilder](https://github.com/LtbLightning/bdk-flutter#quicksend).")]),t._v(" "),a("p",[t._v("First, we have to initialize the "),a("code",[t._v("TxBuilder")]),t._v(" object and call the "),a("code",[t._v("addRecipient()")]),t._v(" method.\n"),a("code",[t._v("addRecipient()")]),t._v(" takes a "),a("code",[t._v("Script")]),t._v(" object and the transaction "),a("code",[t._v("amount")]),t._v(".")]),t._v(" "),a("div",{staticClass:"language-dart extra-class"},[a("pre",{pre:!0,attrs:{class:"language-dart"}},[a("code",[t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("final")]),t._v(" res "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" txBuilder"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("addRecipient")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("script"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" amount"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),a("p",[t._v("We can create the"),a("code",[t._v("Script")]),t._v(" object by using the "),a("code",[t._v("Address")]),t._v(" class, by specifying the recipient address.")]),t._v(" "),a("div",{staticClass:"language-dart extra-class"},[a("pre",{pre:!0,attrs:{class:"language-dart"}},[a("code",[t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("final")]),t._v(" address "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Address")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("create")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("address"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" addressStr"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("final")]),t._v(" script "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" address"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("scriptPubKey")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("final")]),t._v(" res "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" txBuilder"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("addRecipient")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("script"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" amount"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),a("p",[t._v("We can create a "),a("code",[t._v("psbt")]),t._v(" object by calling the "),a("code",[t._v("finish()")]),t._v(" method using the response object from "),a("code",[t._v("addRecipient()")]),t._v(" method.")]),t._v(" "),a("div",{staticClass:"language-dart extra-class"},[a("pre",{pre:!0,attrs:{class:"language-dart"}},[a("code",[t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("final")]),t._v(" txBuilder "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("TxBuilder")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("final")]),t._v(" address "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Address")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("create")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("address"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" addressStr"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("final")]),t._v(" script "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" address"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("scriptPubKey")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("final")]),t._v(" psbt "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" txBuilder\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("addRecipient")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("script"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" amount"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("feeRate")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("1.0")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("finish")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("wallet"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),a("p",[t._v("This "),a("code",[t._v("psbt")]),t._v(" can be signed later with "),a("a",{attrs:{href:"https://github.com/LtbLightning/bdk-flutter#signtx",target:"_blank",rel:"noopener noreferrer"}},[t._v("sign()"),a("OutboundLink")],1),t._v(" method from the "),a("code",[t._v("Wallet")]),t._v(" and broadcast using "),a("a",{attrs:{href:"https://github.com/LtbLightning/bdk-flutter#broadcasttx",target:"_blank",rel:"noopener noreferrer"}},[t._v("broadcast()"),a("OutboundLink")],1),t._v(" from the "),a("code",[t._v("Blockchain")]),t._v(" .")]),t._v(" "),a("p",[t._v("We will need textfield controllers for the recipient address, amount, and for transaction, these can be added below our existing variable for "),a("code",[t._v("mnemonic")])]),t._v(" "),a("div",{staticClass:"language-dart extra-class"},[a("pre",{pre:!0,attrs:{class:"language-dart"}},[a("code",[t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("TextEditingController")]),t._v(" recipientAddress "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("TextEditingController")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("TextEditingController")]),t._v(" amount "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("TextEditingController")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),a("p",[t._v("Let's make an internal function to send a bitcoin transaction, using "),a("code",[t._v("Wallet")]),t._v(", "),a("code",[t._v("Blockchain")]),t._v(" and "),a("code",[t._v("TxBuilder")]),t._v(".")]),t._v(" "),a("div",{staticClass:"language-dart extra-class"},[a("pre",{pre:!0,attrs:{class:"language-dart"}},[a("code",[t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Future")]),a("span",{pre:!0,attrs:{class:"token generics"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("void")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("sendTx")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("String")]),t._v(" addressStr"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" int amount"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("async")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("try")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("final")]),t._v(" txBuilder "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("TxBuilder")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("final")]),t._v(" address "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Address")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("create")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("address"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" addressStr"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("final")]),t._v(" script "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" address"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("scriptPubKey")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("final")]),t._v(" txBuilderResult "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" txBuilder\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("addRecipient")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("script"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" amount"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("feeRate")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("1.0")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("finish")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("wallet"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("final")]),t._v(" sbt "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" wallet"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("sign")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("psbt"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" txBuilderResult"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("psbt"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("final")]),t._v(" tx "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" sbt"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("extractTx")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" blockchain"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("broadcast")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("tx"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("setState")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n displayText "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string-literal"}},[a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Successfully broadcast ')]),a("span",{pre:!0,attrs:{class:"token interpolation"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("$")]),a("span",{pre:!0,attrs:{class:"token expression"}},[t._v("amount")])]),a("span",{pre:!0,attrs:{class:"token string"}},[t._v(" Sats to ")]),a("span",{pre:!0,attrs:{class:"token interpolation"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("$")]),a("span",{pre:!0,attrs:{class:"token expression"}},[t._v("addressStr")])]),a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"')])]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("on")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Exception")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("catch")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("e"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("setState")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n displayText "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string-literal"}},[a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Error: ')]),a("span",{pre:!0,attrs:{class:"token interpolation"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("${")]),a("span",{pre:!0,attrs:{class:"token expression"}},[t._v("e"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("toString")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")])]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"')])]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n")])])]),a("p",[t._v("Add a new section for send transaction functionality. We will need a "),a("code",[t._v("form")]),t._v(", a "),a("code",[t._v("TextFormField")]),t._v(" for the receiver address and a "),a("code",[t._v("TextFormField")]),t._v(" for the amount to send. We will also need a button to call the "),a("code",[t._v("sendTx")]),t._v(" function.")]),t._v(" "),a("p",[t._v("Before submitting the form we need to make sure all the input fields are valid, for that purpose, we need to initialize a "),a("a",{attrs:{href:"https://api.flutter.dev/flutter/widgets/GlobalKey-class.html",target:"_blank",rel:"noopener noreferrer"}},[a("code",[t._v("GlobalKey")]),a("OutboundLink")],1),t._v(". This can be added above our "),a("code",[t._v("Scaffold")])]),t._v(" "),a("div",{staticClass:"language-dart extra-class"},[a("pre",{pre:!0,attrs:{class:"language-dart"}},[a("code",[a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("final")]),t._v(" _formKey "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("GlobalKey")]),a("span",{pre:!0,attrs:{class:"token generics"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("FormState")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),a("p",[t._v("Let's add the send transaction section and UI components below "),a("code",[t._v("/* Send Transaction */")])]),t._v(" "),a("div",{staticClass:"language-dart extra-class"},[a("pre",{pre:!0,attrs:{class:"language-dart"}},[a("code",[t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("StyledContainer")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n child"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Form")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n key"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" _formKey"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n child"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Column")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n mainAxisAlignment"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("MainAxisAlignment")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("start"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n crossAxisAlignment"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("CrossAxisAlignment")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("center"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n children"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("TextFieldContainer")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n child"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("TextFormField")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n controller"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" recipientAddress"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n validator"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("value"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("value "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("==")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("null")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("||")]),t._v(" value"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("isEmpty"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string-literal"}},[a("span",{pre:!0,attrs:{class:"token string"}},[t._v("'Please enter your address'")])]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("null")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n style"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Theme")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("of")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("context"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("textTheme"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("bodyText1"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n decoration"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("InputDecoration")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n hintText"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string-literal"}},[a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Enter Address"')])]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("TextFieldContainer")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n child"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("TextFormField")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n controller"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" amount"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n validator"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("value"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("value "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("==")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("null")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("||")]),t._v(" value"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("isEmpty"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string-literal"}},[a("span",{pre:!0,attrs:{class:"token string"}},[t._v("'Please enter the amount'")])]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("null")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n keyboardType"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("TextInputType")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("number"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n style"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Theme")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("of")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("context"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("textTheme"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("bodyText1"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n decoration"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("InputDecoration")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n hintText"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string-literal"}},[a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Enter Amount"')])]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("SubmitButton")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n text"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string-literal"}},[a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Send Bit"')])]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n callback"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("async")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("_formKey"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("currentState"),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("!")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("validate")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("sendTx")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("recipientAddress"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("text"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n int"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("parse")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("amount"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("text"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n\n")])])]),a("p",[t._v("We should now be able to send a transaction as long as there is sufficient balance.")]),t._v(" "),a("img",{staticStyle:{display:"block",margin:"0px auto",zoom:"25%"},attrs:{src:s(365)}}),t._v(" "),a("h2",{attrs:{id:"conclusion"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#conclusion"}},[t._v("#")]),t._v(" Conclusion")]),t._v(" "),a("p",[t._v("The App we created can be built and distributed for both iOS and Android thus sharing a code base and reducing development time. The development and coding focused on application-level code for use cases and we did not have to code intricate internal bitcoin protocol-level code or bitcoin node interactions, and transactions. UTXOs and sync-related functionalities were also not required. All this was managed by "),a("code",[t._v("bdk-flutter")]),t._v(" allowing us to focus on the product, functionality, and user journey. This is how "),a("code",[t._v("bdk")]),t._v(" and "),a("code",[t._v("bdk-flutter")]),t._v(" intend to make Rapid Bitcoin Application Development possible by allowing product and application developers to focus on what they know best while "),a("code",[t._v("bdk")]),t._v(" handles bitcoin complexity.")]),t._v(" "),a("p",[a("code",[t._v("bdk-flutter")]),t._v(" intends to expose functionality and APIs from "),a("code",[t._v("bdk")]),t._v(" which has a wide variety of APIs with granular details allowing for many interesting use cases to be implemented. "),a("code",[t._v("bdk-flutter")]),t._v(" and "),a("code",[t._v("bdk")]),t._v(" are constantly updated and enhanced based on feedback from product teams and developers in the bitcoin community.")]),t._v(" "),a("p",[t._v("Stay tuned for more APIs and enhancements coming to "),a("code",[t._v("bdk-flutter")]),t._v(" in the near future. Feature and API requests are most welcome. New blogs and tutorials will be published soon for a more in-depth exploration of "),a("code",[t._v("bdk-flutter")]),t._v(".")]),t._v(" "),a("p",[t._v("In the meantime keep in touch with the project by following us on "),a("a",{attrs:{href:"https://github.com/LtbLightning/bdk-flutter",target:"_blank",rel:"noopener noreferrer"}},[t._v("GitHub"),a("OutboundLink")],1),t._v(" and "),a("a",{attrs:{href:"https://twitter.com/BitcoinZavior",target:"_blank",rel:"noopener noreferrer"}},[t._v("Twitter"),a("OutboundLink")],1)]),t._v(" "),a("h4",{attrs:{id:"references"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#references"}},[t._v("#")]),t._v(" References:")]),t._v(" "),a("ul",[a("li",[a("a",{attrs:{href:"https://github.com/bitcoindevkit",target:"_blank",rel:"noopener noreferrer"}},[t._v("bdk"),a("OutboundLink")],1)]),t._v(" "),a("li",[a("a",{attrs:{href:"https://github.com/LtbLightning/bdk-flutter",target:"_blank",rel:"noopener noreferrer"}},[t._v("bdk-flutter"),a("OutboundLink")],1)]),t._v(" "),a("li",[a("a",{attrs:{href:"https://github.com/LtbLightning/bdk-flutter-quickstart",target:"_blank",rel:"noopener noreferrer"}},[t._v("bdk-flutter-quickstart GitHub Repository"),a("OutboundLink")],1)]),t._v(" "),a("li",[a("a",{attrs:{href:"https://docs.flutter.dev/get-started/install",target:"_blank",rel:"noopener noreferrer"}},[t._v("Setup Flutter Development Environment"),a("OutboundLink")],1)]),t._v(" "),a("li",[a("a",{attrs:{href:"https://github.com/bitcoinbook/bitcoinbook/blob/develop/ch04.asciidoc",target:"_blank",rel:"noopener noreferrer"}},[t._v("Mastering Bitcoin(HD Wallet chapter)"),a("OutboundLink")],1)]),t._v(" "),a("li",[a("a",{attrs:{href:"https://github.com/bitcoin/bitcoin/blob/master/doc/descriptors.md",target:"_blank",rel:"noopener noreferrer"}},[t._v("Bitcoin Output Descriptors from bitcoin GitHub"),a("OutboundLink")],1)]),t._v(" "),a("li",[t._v("Testnet Faucet: "),a("a",{attrs:{href:"https://coinfaucet.eu/en/btc-testnet/",target:"_blank",rel:"noopener noreferrer"}},[t._v("https://coinfaucet.eu/en/btc-testnet/"),a("OutboundLink")],1),t._v(" or "),a("a",{attrs:{href:"https://bitcoinfaucet.uo1.net",target:"_blank",rel:"noopener noreferrer"}},[t._v("https://bitcoinfaucet.uo1.net"),a("OutboundLink")],1)])])])}),[],!1,null,null,null);a.default=e.exports}}]); \ No newline at end of file +(window.webpackJsonp=window.webpackJsonp||[]).push([[19],{365:function(t,a,s){t.exports=s.p+"assets/img/bdk_flutter_complete_app.c74da859.png"},366:function(t,a,s){t.exports=s.p+"assets/img/default_flutter_app.31b31721.png"},367:function(t,a,s){t.exports=s.p+"assets/img/assets_section.b43d75e9.png"},368:function(t,a,s){t.exports=s.p+"assets/img/folder_structure.b2750bd6.png"},369:function(t,a,s){t.exports=s.p+"assets/img/bdk_flutter_title.e4e3484a.png"},370:function(t,a,s){t.exports=s.p+"assets/img/bdk_flutter_tutorial_screen_mnemonic.df703b77.png"},371:function(t,a,s){t.exports=s.p+"assets/img/bdk_flutter_tutorial_screen_createwallet.3b052736.png"},372:function(t,a,s){t.exports=s.p+"assets/img/bdk_flutter_get_balance.bfdf9ced.png"},373:function(t,a,s){t.exports=s.p+"assets/img/bdk_flutter_get_address.5db2e3cc.png"},374:function(t,a,s){t.exports=s.p+"assets/img/bdk_flutter_get_restore.db8e7e55.png"},375:function(t,a,s){t.exports=s.p+"assets/img/bdk_flutter_send.1688372b.png"},411:function(t,a,s){"use strict";s.r(a);var n=s(7),e=Object(n.a)({},(function(){var t=this,a=t._self._c;return a("ContentSlotsDistributor",{attrs:{"slot-key":t.$parent.slotKey}},[a("h2",{attrs:{id:"introduction"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#introduction"}},[t._v("#")]),t._v(" Introduction")]),t._v(" "),a("p",[a("code",[t._v("bdk-flutter")]),t._v(" is the "),a("strong",[t._v("Bitcoin Dev kit")]),t._v("'s "),a("strong",[t._v("Flutter")]),t._v(" library which enables building bitcoin applications for Android and iOS mobile platforms. Using "),a("code",[t._v("bdk-flutter")]),t._v(" is similar to using any other Flutter module. Just do "),a("code",[t._v("flutter pub add bdk_flutter")]),t._v(" and you are ready to code! This is the first tutorial on how to use "),a("code",[t._v("bdk-flutter")]),t._v(", more coming soon, make sure to "),a("a",{attrs:{href:"https://twitter.com/BitcoinZavior",target:"_blank",rel:"noopener noreferrer"}},[t._v("follow"),a("OutboundLink")],1),t._v(" to be notified of new ones. There will also be a "),a("strong",[a("code",[t._v("bdk-flutter")])]),t._v(" focused Livestream on "),a("a",{attrs:{href:"https://www.twitch.tv/bitcoindevelopers",target:"_blank",rel:"noopener noreferrer"}},[t._v("Twitch"),a("OutboundLink")],1),t._v(" on the Bitcoin Developers "),a("a",{attrs:{href:"https://www.youtube.com/channel/UCUq_ZdezVWKPvkWRicAYxLA/videos",target:"_blank",rel:"noopener noreferrer"}},[t._v("YouTube Channel"),a("OutboundLink")],1),t._v(" so make sure to subscribe.")]),t._v(" "),a("p",[t._v("This tutorial will explore "),a("code",[t._v("bdk-flutter")]),t._v(" usage and the API it provides. This guide will walk through the development process and code for making a bitcoin application. The bitcoin application we create will be a non-custodial HD Wallet. The application will have the functionality to create a new wallet or restore from a known mnemonic seed phrase. This application will also be able to interact with the bitcoin network to sync UTXOs from new blocks and broadcast transactions.")]),t._v(" "),a("p",[t._v("The tutorial will focus on bitcoin concepts and "),a("code",[t._v("bdk-flutter")]),t._v(" API. So it will gloss over Flutter and Dart. If you are interested in learning more about Flutter and Dart please refer to the Flutter "),a("a",{attrs:{href:"https://flutter.dev/learn",target:"_blank",rel:"noopener noreferrer"}},[t._v("learning portal"),a("OutboundLink")],1),t._v(". The code for this tutorial is available on the "),a("a",{attrs:{href:"https://github.com/LtbLightning/bdk-flutter-quickstart",target:"_blank",rel:"noopener noreferrer"}},[t._v("LtbLightning GitHub"),a("OutboundLink")],1)]),t._v(" "),a("img",{staticStyle:{display:"block",margin:"0 auto",zoom:"25%"},attrs:{src:s(365)}}),t._v(" "),a("h3",{attrs:{id:"prerequisites"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#prerequisites"}},[t._v("#")]),t._v(" Prerequisites")]),t._v(" "),a("p",[t._v("To use "),a("code",[t._v("bdk-flutter")]),t._v(" in a Flutter App, a Flutter development environment is required. Please refer to resources out there on the internet if you need to set this up, here is one of many good resources to guide you on "),a("a",{attrs:{href:"https://docs.flutter.dev/get-started/install",target:"_blank",rel:"noopener noreferrer"}},[t._v("environment setup"),a("OutboundLink")],1)]),t._v(" "),a("h3",{attrs:{id:"bitcoin-basics"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#bitcoin-basics"}},[t._v("#")]),t._v(" Bitcoin Basics")]),t._v(" "),a("p",[t._v("The bitcoin concepts used in this blog post are detailed and explained very well in external bitcoin resources. Here are some links for reference:")]),t._v(" "),a("p",[a("a",{attrs:{href:"https://github.com/bitcoinbook/bitcoinbook/blob/develop/ch04.asciidoc",target:"_blank",rel:"noopener noreferrer"}},[t._v("Mastering Bitcoin(HD Wallet chapter)"),a("OutboundLink")],1)]),t._v(" "),a("p",[a("a",{attrs:{href:"https://github.com/bitcoin/bitcoin/blob/master/doc/descriptors.md",target:"_blank",rel:"noopener noreferrer"}},[t._v("Bitcoin Output Descriptors from bitcoin GitHub"),a("OutboundLink")],1)]),t._v(" "),a("p",[t._v("Now let's jump into Bitcoin Dev Kit")]),t._v(" "),a("h2",{attrs:{id:"bitcoin-dev-kit-and-bdk-flutter"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#bitcoin-dev-kit-and-bdk-flutter"}},[t._v("#")]),t._v(" Bitcoin Dev Kit and bdk-flutter")]),t._v(" "),a("p",[a("code",[t._v("bdk-flutter")]),t._v(" is "),a("strong",[t._v("Bitcoin Dev kit")]),t._v("'s "),a("strong",[t._v("Flutter")]),t._v(" library for building Bitcoin apps in "),a("strong",[t._v("Flutter")]),t._v(".\nIt encapsulates all of the low-level APIs and methods for BDK and exposes them in a Flutter context. To use BDK in Flutter apps only the "),a("code",[t._v("bdk-flutter")]),t._v(" module is required. "),a("code",[t._v("bdk-flutter")]),t._v(" can be used like any other Flutter library and is available on "),a("a",{attrs:{href:"https://pub.dev/packages/bdk_flutter",target:"_blank",rel:"noopener noreferrer"}},[t._v("pub.dev"),a("OutboundLink")],1)]),t._v(" "),a("h2",{attrs:{id:"getting-started"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#getting-started"}},[t._v("#")]),t._v(" Getting Started")]),t._v(" "),a("p",[t._v("Although we won't delve deep into Flutter we will focus more on bitcoin and "),a("code",[t._v("bdk-flutter")]),t._v(", however, some rudimentary Flutter setup is required, especially a basic Flutter app to add our code.")]),t._v(" "),a("p",[t._v("start by creating a new Flutter project.")]),t._v(" "),a("p",[a("code",[t._v("flutter create bdk-flutter-quickstart")])]),t._v(" "),a("p",[t._v("Once done let's "),a("code",[t._v("cd")]),t._v(" into the new project directory and run the basic Flutter app that's created")]),t._v(" "),a("div",{staticClass:"language-shell extra-class"},[a("pre",{pre:!0,attrs:{class:"language-shell"}},[a("code",[a("span",{pre:!0,attrs:{class:"token builtin class-name"}},[t._v("cd")]),t._v(" bdk-flutter-quickstart\nflutter run\n")])])]),a("p",[t._v("This should start building the app and then launch the app in a simulator. So far we have created a basic Flutter project if this doesn't work then refer to the Flutter development setup guide to troubleshoot.")]),t._v(" "),a("img",{staticStyle:{display:"block",margin:"0 auto",zoom:"25%"},attrs:{src:s(366),alt:"BDK Flutter Quick Start"}}),t._v(" "),a("h2",{attrs:{id:"setting-up-flutter-app-structure"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#setting-up-flutter-app-structure"}},[t._v("#")]),t._v(" Setting up Flutter app structure")]),t._v(" "),a("p",[t._v("Let's set up a very basic app structure. Let's create an "),a("code",[t._v("assets")]),t._v(" folder in the project root and then add new folders "),a("code",[t._v("widgets")]),t._v(", "),a("code",[t._v("screens")]),t._v(", and "),a("code",[t._v("styles")]),t._v(" inside the existing "),a("code",[t._v("lib")]),t._v(" folder.")]),t._v(" "),a("p",[t._v("Paste the following code in your "),a("code",[t._v("pubspec.yaml")]),t._v(" file, assets section.")]),t._v(" "),a("div",{staticClass:"language- extra-class"},[a("pre",[a("code",[t._v("- assets/\n")])])]),a("p",[t._v("Please make sure your assets section looks like the screenshot below.\n"),a("img",{staticStyle:{display:"block",margin:"0 auto",zoom:"60%"},attrs:{src:s(367),alt:"BDK Flutter Quick Start"}})]),t._v(" "),a("p",[t._v("Once done let's run a "),a("code",[t._v("get")]),t._v(" command from the pub tool commands, this will get all the required dependencies for our project.")]),t._v(" "),a("div",{staticClass:"language-shell extra-class"},[a("pre",{pre:!0,attrs:{class:"language-shell"}},[a("code",[t._v("flutter pub get\n")])])]),a("p",[t._v("To make this quick you can download the theme, styled widgets and images used in the tutorial from the repository. The "),a("code",[t._v("theme.dart")]),t._v(" file has the theme we will use and this can be taken from "),a("a",{attrs:{href:"https://github.com/LtbLightning/bdk-flutter-quickstart/blob/master/lib/styles/theme.dart",target:"_blank",rel:"noopener noreferrer"}},[t._v("here"),a("OutboundLink")],1),t._v(" and moved to the styles folder. The "),a("code",[t._v("widgets.dart")]),t._v(" file has the styled widgets we will use and these can be taken from "),a("a",{attrs:{href:"https://github.com/LtbLightning/bdk-flutter-quickstart/blob/master/lib/widgets/widgets.dart",target:"_blank",rel:"noopener noreferrer"}},[t._v("here"),a("OutboundLink")],1),t._v(" and moved to the widgets folder. The image assets can be taken from "),a("a",{attrs:{href:"https://github.com/LtbLightning/bdk-flutter-quickstart/tree/master/assets",target:"_blank",rel:"noopener noreferrer"}},[t._v("here"),a("OutboundLink")],1),t._v(" Alternatively, you can write your theme, widgets and use your images if you intend to style the app differently.")]),t._v(" "),a("p",[t._v("In addition to the the theme, widgets and assets. We also need to create a "),a("code",[t._v("screens")]),t._v(" folder and create a "),a("code",[t._v("home.dart")]),t._v(" file inside it, this will be where most of the code will be added.")]),t._v(" "),a("p",[t._v("Once done the file structure should look like this:")]),t._v(" "),a("img",{staticStyle:{display:"block",margin:"0px auto",zoom:"60%"},attrs:{src:s(368)}}),t._v(" "),a("p",[a("br"),t._v("Locate "),a("code",[t._v("main.dart")]),t._v(" in the project root, this will have the default code added by "),a("code",[t._v("flutter create")]),t._v(", let's delete all contents of "),a("code",[t._v("main.dart")]),t._v(" and replace it with the following code to use "),a("code",[t._v("home.dart")]),t._v(" as our main screen. This will probably crash the app but that's fine, it will be up and running once we add code to "),a("code",[t._v("home.dart")]),t._v(" in the next few steps")]),t._v(" "),a("div",{staticClass:"language-dart extra-class"},[a("pre",{pre:!0,attrs:{class:"language-dart"}},[a("code",[a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// main.dart")]),t._v("\n\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("import")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string-literal"}},[a("span",{pre:!0,attrs:{class:"token string"}},[t._v("'package:bdk_flutter_quickstart/screens/home.dart'")])]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("import")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string-literal"}},[a("span",{pre:!0,attrs:{class:"token string"}},[t._v("'package:bdk_flutter_quickstart/styles/theme.dart'")])]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("import")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string-literal"}},[a("span",{pre:!0,attrs:{class:"token string"}},[t._v("'package:flutter/material.dart'")])]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("void")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("main")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("runApp")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("MyApp")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("MyApp")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("extends")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("StatelessWidget")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("MyApp")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Key")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("?")]),t._v(" key"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("super")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("key"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" key"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// This widget is the root of your application.")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token metadata function"}},[t._v("@override")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Widget")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("build")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("BuildContext")]),t._v(" context"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("MaterialApp")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n debugShowCheckedModeBanner"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token boolean"}},[t._v("false")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n title"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string-literal"}},[a("span",{pre:!0,attrs:{class:"token string"}},[t._v("'BDK-FLUTTER TUTORIAL'")])]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n theme"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("theme")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n home"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Home")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),a("h2",{attrs:{id:"installing-bdk-flutter"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#installing-bdk-flutter"}},[t._v("#")]),t._v(" Installing "),a("code",[t._v("bdk-flutter")])]),t._v(" "),a("p",[t._v("With the Flutter project in place, we can now add "),a("code",[t._v("bdk-flutter")]),t._v(" using "),a("code",[t._v("flutter pub add")]),t._v(".")]),t._v(" "),a("div",{staticClass:"language-shell extra-class"},[a("pre",{pre:!0,attrs:{class:"language-shell"}},[a("code",[t._v("flutter pub "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("add")]),t._v(" bdk_flutter\n")])])]),a("p",[t._v("This will add a line like this to your package's "),a("code",[t._v("pubspec.yaml")]),t._v(" and this will also run an implicit flutter pub get to download "),a("code",[t._v("bdk-flutter")]),t._v(" from "),a("code",[t._v("pub.dev")]),t._v(":")]),t._v(" "),a("div",{staticClass:"language-shell extra-class"},[a("pre",{pre:!0,attrs:{class:"language-shell"}},[a("code",[t._v("dependencies:\n bdk_flutter: ^0.28.2\n")])])]),a("h2",{attrs:{id:"configuring"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#configuring"}},[t._v("#")]),t._v(" Configuring")]),t._v(" "),a("p",[t._v("Make sure your app meets the following requirements for using "),a("code",[t._v("bdk-flutter")])]),t._v(" "),a("p",[a("strong",[t._v("Android")])]),t._v(" "),a("p",[t._v("MinSdkVersion : API 23 or higher.")]),t._v(" "),a("p",[a("strong",[t._v("IOS")])]),t._v(" "),a("p",[t._v("Deployment target: iOS 12.0 or greater.")]),t._v(" "),a("p",[t._v("Locate your Podfile in the ios folder of your project and paste the following code at the beginning")]),t._v(" "),a("div",{staticClass:"language- extra-class"},[a("pre",{pre:!0,attrs:{class:"language-text"}},[a("code",[t._v("platform :ios, '12.0'\n")])])]),a("p",[t._v("After changing the deployment target in your project's "),a("code",[t._v("PodFile")]),t._v(", let's use the following "),a("code",[t._v("command")]),t._v(" to install pod dependencies for iOS.")]),t._v(" "),a("div",{staticClass:"language-shell extra-class"},[a("pre",{pre:!0,attrs:{class:"language-shell"}},[a("code",[a("span",{pre:!0,attrs:{class:"token builtin class-name"}},[t._v("cd")]),t._v(" ios "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&&")]),t._v(" pod "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("install")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&&")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token builtin class-name"}},[t._v("cd")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("..")]),t._v("\n")])])]),a("p",[t._v("Once done, bdk-flutter is installed and configured and ready to be used in our "),a("strong",[t._v("bdk-flutter-quickstart")]),t._v(" App.")]),t._v(" "),a("h2",{attrs:{id:"importing-bdk-flutter"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#importing-bdk-flutter"}},[t._v("#")]),t._v(" Importing "),a("code",[t._v("bdk-flutter")])]),t._v(" "),a("p",[t._v("Locate "),a("code",[t._v("home.dart")]),t._v(" which we added in the setup section and import "),a("code",[t._v("bdk-flutter")]),t._v(" at the top of the file. Create a stateful widget called "),a("code",[t._v("Home")])]),t._v(" "),a("div",{staticClass:"language-dart extra-class"},[a("pre",{pre:!0,attrs:{class:"language-dart"}},[a("code",[a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// screens/home.dart")]),t._v("\n\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("import")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string-literal"}},[a("span",{pre:!0,attrs:{class:"token string"}},[t._v("'package:bdk_flutter/bdk_flutter.dart'")])]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Home")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("extends")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("StatefulWidget")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Home")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Key")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("?")]),t._v(" key"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("super")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("key"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" key"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),a("span",{pre:!0,attrs:{class:"token metadata function"}},[t._v("@override")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("State")]),a("span",{pre:!0,attrs:{class:"token generics"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Home")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("createState")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("_HomeState")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),t._v(" _HomeState "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("extends")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("State")]),a("span",{pre:!0,attrs:{class:"token generics"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Home")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("TextEditingController")]),t._v(" mnemonic "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("TextEditingController")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token metadata function"}},[t._v("@override")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Widget")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("build")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("BuildContext")]),t._v(" context"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Container")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),a("p",[t._v("Before we start using "),a("code",[t._v("bdk-flutter")]),t._v(" let's add some additional imports and also import styles, to create a basic layout to build our home screen")]),t._v(" "),a("div",{staticClass:"language-dart extra-class"},[a("pre",{pre:!0,attrs:{class:"language-dart"}},[a("code",[a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// screens/home.dart")]),t._v("\n\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("import")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string-literal"}},[a("span",{pre:!0,attrs:{class:"token string"}},[t._v("'package:bdk_flutter/bdk_flutter.dart'")])]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("import")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string-literal"}},[a("span",{pre:!0,attrs:{class:"token string"}},[t._v("'package:bdk_flutter_quickstart/widgets/widgets.dart'")])]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("import")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string-literal"}},[a("span",{pre:!0,attrs:{class:"token string"}},[t._v("'package:flutter/cupertino.dart'")])]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("import")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string-literal"}},[a("span",{pre:!0,attrs:{class:"token string"}},[t._v("'package:flutter/material.dart'")])]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Home")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("extends")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("StatefulWidget")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Home")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Key")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("?")]),t._v(" key"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("super")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("key"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" key"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),a("span",{pre:!0,attrs:{class:"token metadata function"}},[t._v("@override")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("State")]),a("span",{pre:!0,attrs:{class:"token generics"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Home")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("createState")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("_HomeState")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),t._v(" _HomeState "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("extends")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("State")]),a("span",{pre:!0,attrs:{class:"token generics"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Home")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n\n "),a("span",{pre:!0,attrs:{class:"token metadata function"}},[t._v("@override")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Widget")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("build")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("BuildContext")]),t._v(" context"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Scaffold")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n resizeToAvoidBottomInset"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token boolean"}},[t._v("true")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n backgroundColor"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Colors")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("white"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("/* AppBar */")]),t._v("\n appBar"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("buildAppBar")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("context"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n body"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("SingleChildScrollView")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n child"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Container")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n padding"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("EdgeInsets")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("symmetric")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("horizontal"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("30")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n child"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Column")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n children"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("/* Balance */")]),t._v("\n\n "),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("/* Create Wallet */")]),t._v("\n\n "),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("/* Send Transaction */")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),a("p",[t._v("We now have an app title section and a structure to hold the rest of our app components.")]),t._v(" "),a("img",{staticStyle:{display:"block",margin:"0 auto",zoom:"33%"},attrs:{src:s(369)}}),t._v(" "),a("h2",{attrs:{id:"calling-bdk-flutter-methods"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#calling-bdk-flutter-methods"}},[t._v("#")]),t._v(" Calling bdk-flutter methods")]),t._v(" "),a("p",[t._v("To call all methods properly from the "),a("code",[t._v("bdk-flutter")]),t._v(" package, first, we need to create state variables to store "),a("code",[t._v("Wallet")]),t._v(" and "),a("code",[t._v("Blockchain")]),t._v(" objects.")]),t._v(" "),a("p",[t._v("Here we use the late keyword to declare both "),a("code",[t._v("Wallet")]),t._v(" and "),a("code",[t._v("Blockchain")]),t._v(". These are non-nullable variables that are initialized after the declaration.")]),t._v(" "),a("div",{staticClass:"language-dart extra-class"},[a("pre",{pre:!0,attrs:{class:"language-dart"}},[a("code",[a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("import")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string-literal"}},[a("span",{pre:!0,attrs:{class:"token string"}},[t._v("'package:bdk_flutter/bdk_flutter.dart'")])]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\nlate "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Wallet")]),t._v(" wallet"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\nlate "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Blockchain")]),t._v(" blockchain"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),a("p",[t._v("The first step in creating a non-custodial bitcoin app is creating a mnemonic seed phrase for the wallet.")]),t._v(" "),a("p",[a("code",[t._v("bdk-flutter")]),t._v(" provides a "),a("code",[t._v("Mnemonic")]),t._v(" class to create a "),a("code",[t._v("Mnemonic")]),t._v(". The "),a("code",[t._v("create")]),t._v(" method is a named constructor and can be used to create a mnemonic, it takes "),a("code",[t._v("WordCount")]),t._v(" as its required parameter.")]),t._v(" "),a("div",{staticClass:"language-dart extra-class"},[a("pre",{pre:!0,attrs:{class:"language-dart"}},[a("code",[a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("var")]),t._v(" res "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Mnemonic")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("create")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("WordCount.Words12")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),a("p",[t._v("We can generate a mnemonic of longer length by passing in a wordCount argument of required length.")]),t._v(" "),a("p",[t._v("To create a mnemonic with a "),a("code",[t._v("WordCount")]),t._v(" of 18 words, we can use "),a("code",[t._v("(WordCount.Words18)")]),t._v("\nRefer to the API docs on "),a("a",{attrs:{href:"https://pub.dev/documentation/bdk_flutter/latest/bdk_flutter/bdk_flutter-library.html",target:"_blank",rel:"noopener noreferrer"}},[t._v("pub.dev"),a("OutboundLink")],1),t._v(" for more details.")]),t._v(" "),a("div",{staticClass:"language-dart extra-class"},[a("pre",{pre:!0,attrs:{class:"language-dart"}},[a("code",[t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("var")]),t._v(" res "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Mnemonic")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("create")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("WordCount.Words18")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// here response is saved as a 'Mnemonic' object")]),t._v("\n")])])]),a("p",[t._v("In order to use this in our Flutter app, we want a button that will generate a mnemonic when clicked, and a text input box to show the generated mnemonic. Let's first create a "),a("code",[t._v("TextEditingController")]),t._v(" for the "),a("code",[t._v("mnemonic")]),t._v(" textfield to store the mnemonic, and an internal "),a("code",[t._v("generateMnemonicHandler")]),t._v(" method which can be called on button click. We will also need a button that will call the internal "),a("code",[t._v("generateMnemonicHandler")]),t._v(" method when clicked. Adding the following code achieves all of this.")]),t._v(" "),a("div",{staticClass:"language-dart extra-class"},[a("pre",{pre:!0,attrs:{class:"language-dart"}},[a("code",[a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Home")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("extends")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("StatefulWidget")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Home")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Key")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("?")]),t._v(" key"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("super")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("key"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" key"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),a("span",{pre:!0,attrs:{class:"token metadata function"}},[t._v("@override")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("State")]),a("span",{pre:!0,attrs:{class:"token generics"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Home")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("createState")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("_HomeState")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),t._v(" _HomeState "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("extends")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("State")]),a("span",{pre:!0,attrs:{class:"token generics"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Home")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n late "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Wallet")]),t._v(" wallet"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n late "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Blockchain")]),t._v(" blockchain"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("TextEditingController")]),t._v(" mnemonic "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("TextEditingController")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Future")]),a("span",{pre:!0,attrs:{class:"token generics"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("void")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("generateMnemonicHandler")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("async")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("var")]),t._v(" res "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Mnemonic")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("create")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("WordCount.Words12")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("setState")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n mnemonic"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("text "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" res"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("asString")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token metadata function"}},[t._v("@override")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Widget")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("build")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("BuildContext")]),t._v(" context"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Scaffold")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n resizeToAvoidBottomInset"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token boolean"}},[t._v("true")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n backgroundColor"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Colors")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("white"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("/* Header */")]),t._v("\n appBar"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("buildAppBar")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("context"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n body"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("SingleChildScrollView")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n child"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Container")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n padding"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("EdgeInsets")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("symmetric")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("horizontal"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("30")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n child"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Column")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n children"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("/* Balance */")]),t._v("\n\n "),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("/* Result */")]),t._v("\n\n\n "),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("/* Create Wallet */")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("StyledContainer")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n child"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Column")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n mainAxisAlignment"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("MainAxisAlignment")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("start"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n crossAxisAlignment"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("CrossAxisAlignment")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("center"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n children"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("SubmitButton")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n text"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string-literal"}},[a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Generate Mnemonic"')])]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n callback"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("async")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("generateMnemonicHandler")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("TextFieldContainer")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n child"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("TextFormField")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n controller"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" mnemonic"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n style"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Theme")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("of")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("context"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("textTheme"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("bodyText1"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n keyboardType"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("TextInputType")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("multiline"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n maxLines"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("5")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n decoration"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("InputDecoration")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n hintText"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string-literal"}},[a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Enter your mnemonic"')])]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("/* Send Transaction Buttons */")]),t._v("\n\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),a("p",[t._v("Now we need to add a component to display the output of our method calls and this will also need a "),a("code",[t._v("displayText")]),t._v(" variable to track our method call response. To achieve this add the following code.")]),t._v(" "),a("div",{staticClass:"language-dart extra-class"},[a("pre",{pre:!0,attrs:{class:"language-dart"}},[a("code",[a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// screens/home.dart")]),t._v("\n\n"),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// add this as another state variable under mnemonic")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("String")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("?")]),t._v(" displayText"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// modify the generateMnemonicHandler method to also set mnemonic as displayText")]),t._v("\n\n "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Future")]),a("span",{pre:!0,attrs:{class:"token generics"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("void")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("generateMnemonicHandler")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("async")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("var")]),t._v(" res "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Mnemonic")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("create")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("WordCount.Words12")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("setState")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n mnemonic"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("text "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" res"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("asString")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n displayText "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" res"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("asString")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),a("p",[t._v("and finally, let's add the component to display the output under "),a("code",[t._v("/* Result */")])]),t._v(" "),a("div",{staticClass:"language-dart extra-class"},[a("pre",{pre:!0,attrs:{class:"language-dart"}},[a("code",[a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// screens/home.dart")]),t._v("\n\n "),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("/* Result */")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// display the component only if displayText has a value")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("ResponseContainer")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("text"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v("displayText "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("?")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("?")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string-literal"}},[a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"No Response"')])]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n")])])]),a("p",[t._v('We should now have a working "Generate Mnemonic" button that displays the new mnemonic')]),t._v(" "),a("img",{staticStyle:{display:"block",margin:"0 auto",zoom:"25%"},attrs:{src:s(370)}}),t._v(" "),a("p",[t._v("A quick recap, we added a button to call a click handler ("),a("code",[t._v("generateMnemonicHandler")]),t._v(") which calls "),a("code",[t._v("generateMnemonic")]),t._v(" API of "),a("code",[t._v("bdk-flutter")]),t._v(". The click handler also sets the state for the app and also updates the "),a("code",[t._v("displayText")]),t._v(" variable to display the output of the call in the display section. We will follow this pattern for the remaining calls to "),a("code",[t._v("bdk-flutter")]),t._v(".")]),t._v(" "),a("h2",{attrs:{id:"creating-a-wallet"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#creating-a-wallet"}},[t._v("#")]),t._v(" Creating a wallet")]),t._v(" "),a("p",[t._v("Before moving on to creating a wallet, let's add a section at the top to display the balance of the wallet.")]),t._v(" "),a("p",[t._v("To display the balance we will need a state variable to store the balance and a display component to display it. We will also be creating a receive address for the wallet so a state variable will be required for the address as well.")]),t._v(" "),a("p",[t._v("Under the "),a("code",[t._v("mnemonic")]),t._v(" and "),a("code",[t._v("displayText")]),t._v(" state variables, let's add one for "),a("code",[t._v("balance")]),t._v(" and one for "),a("code",[t._v("address")])]),t._v(" "),a("div",{staticClass:"language-dart extra-class"},[a("pre",{pre:!0,attrs:{class:"language-dart"}},[a("code",[a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),t._v(" _HomeState "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("extends")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("State")]),a("span",{pre:!0,attrs:{class:"token generics"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Home")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("TextEditingController")]),t._v(" mnemonic "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("TextEditingController")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("String")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("?")]),t._v(" displayText"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("String")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("?")]),t._v(" balance"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("String")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("?")]),t._v(" address"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),a("p",[t._v("Just below "),a("code",[t._v("/* Balance */")]),t._v(" and above "),a("code",[t._v("/* Result */")]),t._v(" add the following UI components to display the balance. We only want to show the balance when it has a value so we will use a null-aware operator "),a("code",[t._v("??")]),t._v(" for a quick "),a("code",[t._v("null")]),t._v(" check and use "),a("code",[t._v("0")]),t._v(" in case of a "),a("code",[t._v("null")]),t._v(" value.")]),t._v(" "),a("div",{staticClass:"language-dart extra-class"},[a("pre",{pre:!0,attrs:{class:"language-dart"}},[a("code",[t._v(" "),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("/* Balance */")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("BalanceContainer")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n text"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string-literal"}},[a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"${balance ?? "')])]),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),a("span",{pre:!0,attrs:{class:"token string-literal"}},[a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"} Sats"')])]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("/* Result */")]),t._v("\n")])])]),a("p",[a("code",[t._v("bdk_flutter")]),t._v(" creates a wallet using output descriptors which define the derivation path to derive addresses and sign transactions. More about output descriptors "),a("a",{attrs:{href:"https://github.com/bitcoin/bitcoin/blob/master/doc/descriptors.md",target:"_blank",rel:"noopener noreferrer"}},[t._v("here"),a("OutboundLink")],1),t._v(". Before creating the "),a("code",[t._v("Wallet")]),t._v(" we need to create a "),a("code",[t._v("descriptor")]),t._v(" object which will be used to generate receive addresses and a "),a("code",[t._v("changeDescriptor")]),t._v(" object to to create change addresses to collect from outgoing transactions.")]),t._v(" "),a("p",[a("code",[t._v("bdk_flutter")]),t._v("'s "),a("code",[t._v("Descriptor")]),t._v(" class has a number of descriptor templates that will help you create a simple wallet.")]),t._v(" "),a("p",[t._v("Let's add some code to create a simple "),a("code",[t._v("wpkh")]),t._v(" descriptor object by using the "),a("code",[t._v("BIP84")]),t._v(" template. This template will create a descriptor in the format "),a("code",[t._v("wpkh(key/84'/{0,1}'/0'/{0,1}/*)")])]),t._v(" "),a("p",[t._v("This descriptor will create receive ("),a("code",[t._v("KeyChainKind.External")]),t._v(") and change descriptor ("),a("code",[t._v("KeyChainKind.Internal")]),t._v(") for a specified mnemonic.")]),t._v(" "),a("div",{staticClass:"language-dart extra-class"},[a("pre",{pre:!0,attrs:{class:"language-dart"}},[a("code",[a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Future")]),a("span",{pre:!0,attrs:{class:"token generics"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("List")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Descriptor")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("getDescriptors")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("String")]),t._v(" mnemonic"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("async")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("final")]),t._v(" descriptors "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token generics"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Descriptor")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("try")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("for")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("var")]),t._v(" e "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("in")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("KeychainKind.External")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("KeychainKind.Internal")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("final")]),t._v(" mnemonicObj "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Mnemonic")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("fromString")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("mnemonic"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("final")]),t._v(" descriptorSecretKey "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("DescriptorSecretKey")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("create")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n network"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Network.Testnet")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n mnemonic"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" mnemonicObj"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("final")]),t._v(" descriptor "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Descriptor")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("newBip84")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n secretKey"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" descriptorSecretKey"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" \n network"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Network.Testnet")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" \n keychain"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" e"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n descriptors"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("add")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("descriptor"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" descriptors"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("on")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Exception")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("catch")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("e"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("setState")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n displayText "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string-literal"}},[a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Error : ')]),a("span",{pre:!0,attrs:{class:"token interpolation"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("${")]),a("span",{pre:!0,attrs:{class:"token expression"}},[t._v("e"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("toString")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")])]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"')])]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("rethrow")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n")])])]),a("p",[t._v("Under the "),a("code",[t._v("address")]),t._v(" state variable, let's add a state variable called "),a("code",[t._v("wallet")]),t._v(" of the type "),a("code",[t._v("Wallet")]),t._v(" for saving the bitcoin wallet.")]),t._v(" "),a("p",[t._v("To create a wallet with "),a("code",[t._v("bdk-flutter")]),t._v(" call the "),a("code",[t._v("create")]),t._v(" constructor with "),a("code",[t._v("descriptor")]),t._v(", "),a("code",[t._v("changeDescriptor")]),t._v(" "),a("code",[t._v("network")]),t._v(", and the "),a("code",[t._v("databaseConfig")]),t._v(". For database, we can use memory as the database by specifying "),a("code",[t._v("DatabaseConfig.memory()")]),t._v("\nFollowing our pattern of a button, click handler and bdk-flutter API call, Let's add an internal method which will serve as the click handler for the \"Create Wallet\" button. We want to see the output of this call so let's use "),a("code",[t._v("setState()")]),t._v(" to set the "),a("code",[t._v("wallet")]),t._v(" object created and the "),a("code",[t._v("displayText")]),t._v(" variable with the wallet's first receive address.")]),t._v(" "),a("div",{staticClass:"language-dart extra-class"},[a("pre",{pre:!0,attrs:{class:"language-dart"}},[a("code",[t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Future")]),a("span",{pre:!0,attrs:{class:"token generics"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("void")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("createOrRestoreWallet")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("String")]),t._v(" mnemonic"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Network")]),t._v(" network"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("String")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("?")]),t._v(" password"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("async")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("try")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("final")]),t._v(" descriptors "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("getDescriptors")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("mnemonic"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("final")]),t._v(" res "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Wallet")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("create")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n descriptor"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" descriptors"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n changeDescriptor"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" descriptors"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n network"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" network"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n databaseConfig"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("DatabaseConfig")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("memory")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("var")]),t._v(" addressInfo "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" res"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("getAddress")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("addressIndex"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("AddressIndex")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("setState")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n address "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" addressInfo"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("address"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n wallet "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" res"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n displayText "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string-literal"}},[a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Wallet Created: ')]),a("span",{pre:!0,attrs:{class:"token interpolation"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("$")]),a("span",{pre:!0,attrs:{class:"token expression"}},[t._v("address")])]),a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"')])]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("on")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Exception")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("catch")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("e"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("setState")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n displayText "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string-literal"}},[a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Error: ')]),a("span",{pre:!0,attrs:{class:"token interpolation"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("${")]),a("span",{pre:!0,attrs:{class:"token expression"}},[t._v("e"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("toString")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")])]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"')])]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),a("p",[t._v("A new button will be required to call "),a("code",[t._v("createOrRestoreWallet()")])]),t._v(" "),a("p",[t._v("Let's add a new button just below the mnemonic "),a("code",[t._v("TextFieldContainer")])]),t._v(" "),a("div",{staticClass:"language-dart extra-class"},[a("pre",{pre:!0,attrs:{class:"language-dart"}},[a("code",[a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("SubmitButton")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n text"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string-literal"}},[a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Create Wallet"')])]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n callback"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("async")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("createOrRestoreWallet")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n mnemonic"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("text"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" \n "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Network.Testnet")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token string-literal"}},[a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"password"')])]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n")])])]),a("p",[t._v("The response returned by "),a("code",[t._v("create()")]),t._v(" is a "),a("code",[t._v("Wallet")]),t._v(" object.")]),t._v(" "),a("p",[t._v("The App should now be creating a wallet when we click "),a("strong",[t._v("Create Mnemonic")]),t._v(" followed by "),a("strong",[t._v("Create Wallet")]),t._v(".")]),t._v(" "),a("img",{staticStyle:{display:"block",margin:"0 auto",zoom:"25%"},attrs:{src:s(371)}}),t._v(" "),a("p",[t._v("Before going forward, we need to create a "),a("code",[t._v("Blockchain")]),t._v(" object as well. The Blockchain object will encapsulate the bitcoin node configuration which the wallet will use for syncing blocks and broadcasting transactions.")]),t._v(" "),a("p",[t._v("Let's add an internal method to create and initialize the "),a("code",[t._v("Blockchain")]),t._v(" object.")]),t._v(" "),a("div",{staticClass:"language-dart extra-class"},[a("pre",{pre:!0,attrs:{class:"language-dart"}},[a("code",[t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Future")]),a("span",{pre:!0,attrs:{class:"token generics"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("void")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("blockchainInit")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("async")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n blockchain "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Blockchain")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("create")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n config"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("BlockchainConfig")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("electrum")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n config"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("ElectrumConfig")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n stopGap"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("10")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n timeout"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("5")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n retry"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("5")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n url"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string-literal"}},[a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"ssl://electrum.blockstream.info:60002"')])]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n validateDomain"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token boolean"}},[t._v("false")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),a("p",[t._v("Here we are initializing the "),a("code",[t._v("late")]),t._v(" non-nullable "),a("code",[t._v("blockchain")]),t._v(" variable, by calling the named constructor "),a("code",[t._v("create")]),t._v(", which takes a "),a("code",[t._v("BlockchainConfig")]),t._v(" object.\nThe bitcoin node specified is an Electrum node and we are specifying the url for Blockstream's public Electrum Testnet servers over SSL.")]),t._v(" "),a("p",[t._v("After creating the "),a("code",[t._v("blockchainInit()")]),t._v(" method, call it from "),a("code",[t._v("createOrRestoreWallet()")]),t._v(", so the "),a("code",[t._v("blockchain")]),t._v(" variable gets initialized before the "),a("code",[t._v("wallet")]),t._v(" is created.")]),t._v(" "),a("p",[t._v("Include the following line of code inside "),a("code",[t._v("createOrRestoreWallet()")]),t._v(" just before calling Wallet.create().")]),t._v(" "),a("div",{staticClass:"language-dart extra-class"},[a("pre",{pre:!0,attrs:{class:"language-dart"}},[a("code",[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("blockchainInit")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("final")]),t._v(" res "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Wallet")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("create")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("\n")])])]),a("p",[a("strong",[t._v("blockChainConfig")]),t._v(": BlockchainConfig is an enum that has 3 values, "),a("code",[t._v("BlockchainConfig.electrum")]),t._v(" for "),a("a",{attrs:{href:"https://github.com/romanz/electrs",target:"_blank",rel:"noopener noreferrer"}},[a("code",[t._v("electrum")]),a("OutboundLink")],1),t._v(" ,"),a("code",[t._v("BlockchainConfig.esplora")]),t._v(" for "),a("a",{attrs:{href:"https://github.com/Blockstream/esplora",target:"_blank",rel:"noopener noreferrer"}},[a("code",[t._v("esplora")]),a("OutboundLink")],1),t._v(" and "),a("code",[t._v("BlockchainConfig.rpc")]),t._v(" .")]),t._v(" "),a("p",[a("code",[t._v("BlockchainConfig.electrum")]),t._v(", "),a("code",[t._v("BlockchainConfig.rpc")]),t._v(" & "),a("code",[t._v("BlockchainConfig.esplora")]),t._v(" has "),a("code",[t._v("ElectrumConfig")]),t._v(" object, "),a("code",[t._v("RpcConfig")]),t._v(" object and "),a("code",[t._v("EsploraConfig")]),t._v(" object, respectively as its parameter.")]),t._v(" "),a("p",[a("strong",[t._v("ElectrumConfig")]),t._v(": This is the object type of "),a("code",[t._v("BlockchainConfig.electrum")]),t._v("'s config that takes a timeout, retry & url as its required parameter.")]),t._v(" "),a("p",[a("strong",[t._v("EsploraConfig")]),t._v(": This is the object type of "),a("code",[t._v("BlockchainConfig.esplora")]),t._v("'s config that takes baseUrl & stopGap as its required parameter.")]),t._v(" "),a("p",[a("strong",[t._v("RpcConfig")]),t._v(": This is the object type of "),a("code",[t._v("BlockchainConfig.rpc")]),t._v("'s config that takes url, network, & walletName as its required parameter. If "),a("code",[t._v("Rpc Blockchain")]),t._v(" has its authentication values inside a cookie file, please pass in cookie path as authCookie parameter, or you can pass in rpc username and password using "),a("code",[t._v("UserPass")]),t._v(" class.")]),t._v(" "),a("p",[t._v("Refer to the readme for a complete list of options for "),a("a",{attrs:{href:"https://github.com/LtbLightning/bdk-flutter#createwallet",target:"_blank",rel:"noopener noreferrer"}},[t._v("createWallet()"),a("OutboundLink")],1)]),t._v(" "),a("h2",{attrs:{id:"utxos-and-balance"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#utxos-and-balance"}},[t._v("#")]),t._v(" UTXOs and balance")]),t._v(" "),a("p",[t._v("With the "),a("code",[t._v("Wallet")]),t._v(" and "),a("code",[t._v("Blockchain")]),t._v(" created, we can now add methods to sync UTXOs and compute balance.")]),t._v(" "),a("p",[a("code",[t._v("Wallet")]),t._v(" has a "),a("code",[t._v("sync")]),t._v(" method to sync all UTXOs belonging to the wallet using the "),a("code",[t._v("Blockchain")]),t._v(" object. Once the wallet sync is complete balance is computed and "),a("code",[t._v("getBalance")]),t._v(" can fetch the balance.")]),t._v(" "),a("p",[t._v("Earlier we have already added a variable for "),a("code",[t._v("balance")]),t._v(". Now we will add buttons to call "),a("code",[t._v("sync")]),t._v(" and "),a("code",[t._v("getBalance")]),t._v(". Just below the Create Wallet button let's add two buttons as follows:")]),t._v(" "),a("div",{staticClass:"language-dart extra-class"},[a("pre",{pre:!0,attrs:{class:"language-dart"}},[a("code",[t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("SubmitButton")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v(" text"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string-literal"}},[a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Sync Wallet"')])]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n callback"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("async")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("syncWallet")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n\n "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("SubmitButton")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v(" callback"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("async")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("getBalance")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n text"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string-literal"}},[a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Get Balance"')])]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n")])])]),a("p",[t._v("Let's add two internal functions for syncing UTXOs and compute balance.")]),t._v(" "),a("div",{staticClass:"language-dart extra-class"},[a("pre",{pre:!0,attrs:{class:"language-dart"}},[a("code",[t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Future")]),a("span",{pre:!0,attrs:{class:"token generics"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("void")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("getBalance")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("async")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("final")]),t._v(" balanceObj "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" wallet"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("getBalance")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("final")]),t._v(" res "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string-literal"}},[a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Total Balance: ')]),a("span",{pre:!0,attrs:{class:"token interpolation"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("${")]),a("span",{pre:!0,attrs:{class:"token expression"}},[t._v("balanceObj"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("total"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("toString")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")])]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"')])]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("print")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("res"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("setState")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n balance "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" balanceObj"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("total"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("toString")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n displayText "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" res"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Future")]),a("span",{pre:!0,attrs:{class:"token generics"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("void")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("syncWallet")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("async")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n wallet"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("sync")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("blockchain"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n")])])]),a("p",[t._v("We should now be able to create a wallet, sync UTXOs, and get the balance")]),t._v(" "),a("img",{staticStyle:{display:"block",margin:"0 auto",zoom:"25%"},attrs:{src:s(372)}}),t._v(" "),a("p",[t._v("We can use a public testnet faucet to send testnet coins to the wallet and check that the UTXO sync and balance fetch are working correctly. Before we do that add one more method to generate a new address we can then use this address to get testnet coins from a faucet.")]),t._v(" "),a("p",[t._v("Let's use the "),a("code",[t._v("address")]),t._v(" variable that was created before for this, we need to add a button for "),a("strong",[t._v("Get Address")]),t._v(" and an internal function to call "),a("code",[t._v("Wallet")]),t._v(" and create a new address. Let's do the following")]),t._v(" "),a("p",[t._v("Add a new "),a("code",[t._v("getNewAddress")]),t._v(" function below the "),a("code",[t._v("syncWallet()")]),t._v(" function:")]),t._v(" "),a("div",{staticClass:"language-dart extra-class"},[a("pre",{pre:!0,attrs:{class:"language-dart"}},[a("code",[t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Future")]),a("span",{pre:!0,attrs:{class:"token generics"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("void")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("getNewAddress")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("async")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("final")]),t._v(" res "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" wallet"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("getAddress")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("addressIndex"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("AddressIndex")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("setState")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n displayText "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" res"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("address"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n address "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" res"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("address"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),a("p",[t._v("And a "),a("strong",[t._v("Get Address")]),t._v(" button below the existing "),a("strong",[t._v("Get Balance")]),t._v(" button:")]),t._v(" "),a("div",{staticClass:"language-dart extra-class"},[a("pre",{pre:!0,attrs:{class:"language-dart"}},[a("code",[t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("SubmitButton")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n callback"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("async")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("getNewAddress")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n text"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string-literal"}},[a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Get Address"')])]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n")])])]),a("p",[t._v("We should now have the following, and "),a("strong",[t._v("Get Address")]),t._v(" will be able to display a new address.")]),t._v(" "),a("img",{staticStyle:{display:"block",margin:"0px auto",zoom:"25%"},attrs:{src:s(373)}}),t._v(" "),a("p",[t._v("Now that we are able to generate a receive address we can get some testnet bitcoin from one of the public "),a("a",{attrs:{href:"https://coinfaucet.eu/en/btc-testnet/",target:"_blank",rel:"noopener noreferrer"}},[t._v("testnet faucets"),a("OutboundLink")],1)]),t._v(" "),a("p",[t._v("After we send and after the transaction is confirmed we will need to sync the wallet before we can see the new balance from the received transaction.")]),t._v(" "),a("h2",{attrs:{id:"restoring-a-wallet"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#restoring-a-wallet"}},[t._v("#")]),t._v(" Restoring a wallet")]),t._v(" "),a("p",[t._v("The "),a("code",[t._v("create")]),t._v(" method creates a wallet using a "),a("code",[t._v("mnemonic")]),t._v(", to restore we can use the same method, we won't need to call "),a("code",[t._v("generateMnemonic")]),t._v(" as we will already have a "),a("code",[t._v("mnemonic")]),t._v(" to restore with.")]),t._v(" "),a("p",[t._v("This text field below the "),a("code",[t._v("Generate Mnemonic")]),t._v(" button will also display the mnemonic variable if we click Generate Mnemonic' button. The generated mnemonic will show up in the text field. We can overwrite it with our mnemonic and doing so will also overwrite the mnemonic state variable. This way the mnemonic displayed will be the one used to create the wallet.")]),t._v(" "),a("p",[t._v("We can now use our mnemonic and use it to restore a wallet. This will come in handy if we have a wallet with testnet bitcoin as these are hard to come by.")]),t._v(" "),a("img",{staticStyle:{display:"block",margin:"0px auto",zoom:"25%"},attrs:{src:s(374)}}),t._v(" "),a("h2",{attrs:{id:"sending-bitcoin"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#sending-bitcoin"}},[t._v("#")]),t._v(" Sending bitcoin")]),t._v(" "),a("p",[t._v("We are now able to receive bitcoin, now its time to add functionality to send a bitcoin transaction.")]),t._v(" "),a("p",[t._v("For making a successful bitcoin transaction "),a("code",[t._v("bdk-flutter")]),t._v(" utilizes a couple of methods. A new unsigned transaction can be created by using TxBuilder](https://github.com/LtbLightning/bdk-flutter#quicksend).")]),t._v(" "),a("p",[t._v("First, we have to initialize the "),a("code",[t._v("TxBuilder")]),t._v(" object and call the "),a("code",[t._v("addRecipient()")]),t._v(" method.\n"),a("code",[t._v("addRecipient()")]),t._v(" takes a "),a("code",[t._v("Script")]),t._v(" object and the transaction "),a("code",[t._v("amount")]),t._v(".")]),t._v(" "),a("div",{staticClass:"language-dart extra-class"},[a("pre",{pre:!0,attrs:{class:"language-dart"}},[a("code",[t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("final")]),t._v(" res "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" txBuilder"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("addRecipient")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("script"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" amount"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),a("p",[t._v("We can create the"),a("code",[t._v("Script")]),t._v(" object by using the "),a("code",[t._v("Address")]),t._v(" class, by specifying the recipient address.")]),t._v(" "),a("div",{staticClass:"language-dart extra-class"},[a("pre",{pre:!0,attrs:{class:"language-dart"}},[a("code",[t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("final")]),t._v(" address "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Address")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("create")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("address"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" addressStr"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("final")]),t._v(" script "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" address"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("scriptPubKey")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("final")]),t._v(" res "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" txBuilder"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("addRecipient")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("script"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" amount"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),a("p",[t._v("We can create a "),a("code",[t._v("psbt")]),t._v(" object by calling the "),a("code",[t._v("finish()")]),t._v(" method using the response object from "),a("code",[t._v("addRecipient()")]),t._v(" method.")]),t._v(" "),a("div",{staticClass:"language-dart extra-class"},[a("pre",{pre:!0,attrs:{class:"language-dart"}},[a("code",[t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("final")]),t._v(" txBuilder "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("TxBuilder")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("final")]),t._v(" address "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Address")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("create")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("address"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" addressStr"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("final")]),t._v(" script "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" address"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("scriptPubKey")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("final")]),t._v(" psbt "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" txBuilder\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("addRecipient")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("script"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" amount"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("feeRate")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("1.0")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("finish")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("wallet"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),a("p",[t._v("This "),a("code",[t._v("psbt")]),t._v(" can be signed later with "),a("a",{attrs:{href:"https://github.com/LtbLightning/bdk-flutter#signtx",target:"_blank",rel:"noopener noreferrer"}},[t._v("sign()"),a("OutboundLink")],1),t._v(" method from the "),a("code",[t._v("Wallet")]),t._v(" and broadcast using "),a("a",{attrs:{href:"https://github.com/LtbLightning/bdk-flutter#broadcasttx",target:"_blank",rel:"noopener noreferrer"}},[t._v("broadcast()"),a("OutboundLink")],1),t._v(" from the "),a("code",[t._v("Blockchain")]),t._v(" .")]),t._v(" "),a("p",[t._v("We will need textfield controllers for the recipient address, amount, and for transaction, these can be added below our existing variable for "),a("code",[t._v("mnemonic")])]),t._v(" "),a("div",{staticClass:"language-dart extra-class"},[a("pre",{pre:!0,attrs:{class:"language-dart"}},[a("code",[t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("TextEditingController")]),t._v(" recipientAddress "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("TextEditingController")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("TextEditingController")]),t._v(" amount "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("TextEditingController")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),a("p",[t._v("Let's make an internal function to send a bitcoin transaction, using "),a("code",[t._v("Wallet")]),t._v(", "),a("code",[t._v("Blockchain")]),t._v(" and "),a("code",[t._v("TxBuilder")]),t._v(".")]),t._v(" "),a("div",{staticClass:"language-dart extra-class"},[a("pre",{pre:!0,attrs:{class:"language-dart"}},[a("code",[t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Future")]),a("span",{pre:!0,attrs:{class:"token generics"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("void")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("sendTx")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("String")]),t._v(" addressStr"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" int amount"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("async")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("try")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("final")]),t._v(" txBuilder "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("TxBuilder")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("final")]),t._v(" address "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Address")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("create")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("address"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" addressStr"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("final")]),t._v(" script "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" address"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("scriptPubKey")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("final")]),t._v(" txBuilderResult "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" txBuilder\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("addRecipient")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("script"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" amount"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("feeRate")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("1.0")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("finish")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("wallet"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("final")]),t._v(" sbt "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" wallet"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("sign")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("psbt"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" txBuilderResult"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("psbt"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("final")]),t._v(" tx "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" sbt"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("extractTx")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" blockchain"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("broadcast")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("tx"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("setState")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n displayText "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string-literal"}},[a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Successfully broadcast ')]),a("span",{pre:!0,attrs:{class:"token interpolation"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("$")]),a("span",{pre:!0,attrs:{class:"token expression"}},[t._v("amount")])]),a("span",{pre:!0,attrs:{class:"token string"}},[t._v(" Sats to ")]),a("span",{pre:!0,attrs:{class:"token interpolation"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("$")]),a("span",{pre:!0,attrs:{class:"token expression"}},[t._v("addressStr")])]),a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"')])]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("on")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Exception")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("catch")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("e"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("setState")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n displayText "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string-literal"}},[a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Error: ')]),a("span",{pre:!0,attrs:{class:"token interpolation"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("${")]),a("span",{pre:!0,attrs:{class:"token expression"}},[t._v("e"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("toString")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")])]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"')])]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n")])])]),a("p",[t._v("Add a new section for send transaction functionality. We will need a "),a("code",[t._v("form")]),t._v(", a "),a("code",[t._v("TextFormField")]),t._v(" for the receiver address and a "),a("code",[t._v("TextFormField")]),t._v(" for the amount to send. We will also need a button to call the "),a("code",[t._v("sendTx")]),t._v(" function.")]),t._v(" "),a("p",[t._v("Before submitting the form we need to make sure all the input fields are valid, for that purpose, we need to initialize a "),a("a",{attrs:{href:"https://api.flutter.dev/flutter/widgets/GlobalKey-class.html",target:"_blank",rel:"noopener noreferrer"}},[a("code",[t._v("GlobalKey")]),a("OutboundLink")],1),t._v(". This can be added above our "),a("code",[t._v("Scaffold")])]),t._v(" "),a("div",{staticClass:"language-dart extra-class"},[a("pre",{pre:!0,attrs:{class:"language-dart"}},[a("code",[a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("final")]),t._v(" _formKey "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("GlobalKey")]),a("span",{pre:!0,attrs:{class:"token generics"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("FormState")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),a("p",[t._v("Let's add the send transaction section and UI components below "),a("code",[t._v("/* Send Transaction */")])]),t._v(" "),a("div",{staticClass:"language-dart extra-class"},[a("pre",{pre:!0,attrs:{class:"language-dart"}},[a("code",[t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("StyledContainer")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n child"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Form")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n key"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" _formKey"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n child"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Column")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n mainAxisAlignment"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("MainAxisAlignment")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("start"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n crossAxisAlignment"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("CrossAxisAlignment")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("center"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n children"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("TextFieldContainer")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n child"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("TextFormField")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n controller"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" recipientAddress"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n validator"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("value"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("value "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("==")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("null")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("||")]),t._v(" value"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("isEmpty"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string-literal"}},[a("span",{pre:!0,attrs:{class:"token string"}},[t._v("'Please enter your address'")])]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("null")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n style"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Theme")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("of")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("context"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("textTheme"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("bodyText1"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n decoration"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("InputDecoration")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n hintText"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string-literal"}},[a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Enter Address"')])]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("TextFieldContainer")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n child"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("TextFormField")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n controller"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" amount"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n validator"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("value"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("value "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("==")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("null")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("||")]),t._v(" value"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("isEmpty"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string-literal"}},[a("span",{pre:!0,attrs:{class:"token string"}},[t._v("'Please enter the amount'")])]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("null")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n keyboardType"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("TextInputType")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("number"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n style"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Theme")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("of")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("context"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("textTheme"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("bodyText1"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n decoration"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("InputDecoration")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n hintText"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string-literal"}},[a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Enter Amount"')])]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("SubmitButton")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n text"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string-literal"}},[a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Send Bit"')])]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n callback"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("async")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("_formKey"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("currentState"),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("!")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("validate")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("sendTx")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("recipientAddress"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("text"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n int"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("parse")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("amount"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("text"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n\n")])])]),a("p",[t._v("We should now be able to send a transaction as long as there is sufficient balance.")]),t._v(" "),a("img",{staticStyle:{display:"block",margin:"0px auto",zoom:"25%"},attrs:{src:s(375)}}),t._v(" "),a("h2",{attrs:{id:"conclusion"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#conclusion"}},[t._v("#")]),t._v(" Conclusion")]),t._v(" "),a("p",[t._v("The App we created can be built and distributed for both iOS and Android thus sharing a code base and reducing development time. The development and coding focused on application-level code for use cases and we did not have to code intricate internal bitcoin protocol-level code or bitcoin node interactions, and transactions. UTXOs and sync-related functionalities were also not required. All this was managed by "),a("code",[t._v("bdk-flutter")]),t._v(" allowing us to focus on the product, functionality, and user journey. This is how "),a("code",[t._v("bdk")]),t._v(" and "),a("code",[t._v("bdk-flutter")]),t._v(" intend to make Rapid Bitcoin Application Development possible by allowing product and application developers to focus on what they know best while "),a("code",[t._v("bdk")]),t._v(" handles bitcoin complexity.")]),t._v(" "),a("p",[a("code",[t._v("bdk-flutter")]),t._v(" intends to expose functionality and APIs from "),a("code",[t._v("bdk")]),t._v(" which has a wide variety of APIs with granular details allowing for many interesting use cases to be implemented. "),a("code",[t._v("bdk-flutter")]),t._v(" and "),a("code",[t._v("bdk")]),t._v(" are constantly updated and enhanced based on feedback from product teams and developers in the bitcoin community.")]),t._v(" "),a("p",[t._v("Stay tuned for more APIs and enhancements coming to "),a("code",[t._v("bdk-flutter")]),t._v(" in the near future. Feature and API requests are most welcome. New blogs and tutorials will be published soon for a more in-depth exploration of "),a("code",[t._v("bdk-flutter")]),t._v(".")]),t._v(" "),a("p",[t._v("In the meantime keep in touch with the project by following us on "),a("a",{attrs:{href:"https://github.com/LtbLightning/bdk-flutter",target:"_blank",rel:"noopener noreferrer"}},[t._v("GitHub"),a("OutboundLink")],1),t._v(" and "),a("a",{attrs:{href:"https://twitter.com/BitcoinZavior",target:"_blank",rel:"noopener noreferrer"}},[t._v("Twitter"),a("OutboundLink")],1)]),t._v(" "),a("h4",{attrs:{id:"references"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#references"}},[t._v("#")]),t._v(" References:")]),t._v(" "),a("ul",[a("li",[a("a",{attrs:{href:"https://github.com/bitcoindevkit",target:"_blank",rel:"noopener noreferrer"}},[t._v("bdk"),a("OutboundLink")],1)]),t._v(" "),a("li",[a("a",{attrs:{href:"https://github.com/LtbLightning/bdk-flutter",target:"_blank",rel:"noopener noreferrer"}},[t._v("bdk-flutter"),a("OutboundLink")],1)]),t._v(" "),a("li",[a("a",{attrs:{href:"https://github.com/LtbLightning/bdk-flutter-quickstart",target:"_blank",rel:"noopener noreferrer"}},[t._v("bdk-flutter-quickstart GitHub Repository"),a("OutboundLink")],1)]),t._v(" "),a("li",[a("a",{attrs:{href:"https://docs.flutter.dev/get-started/install",target:"_blank",rel:"noopener noreferrer"}},[t._v("Setup Flutter Development Environment"),a("OutboundLink")],1)]),t._v(" "),a("li",[a("a",{attrs:{href:"https://github.com/bitcoinbook/bitcoinbook/blob/develop/ch04.asciidoc",target:"_blank",rel:"noopener noreferrer"}},[t._v("Mastering Bitcoin(HD Wallet chapter)"),a("OutboundLink")],1)]),t._v(" "),a("li",[a("a",{attrs:{href:"https://github.com/bitcoin/bitcoin/blob/master/doc/descriptors.md",target:"_blank",rel:"noopener noreferrer"}},[t._v("Bitcoin Output Descriptors from bitcoin GitHub"),a("OutboundLink")],1)]),t._v(" "),a("li",[t._v("Testnet Faucet: "),a("a",{attrs:{href:"https://coinfaucet.eu/en/btc-testnet/",target:"_blank",rel:"noopener noreferrer"}},[t._v("https://coinfaucet.eu/en/btc-testnet/"),a("OutboundLink")],1),t._v(" or "),a("a",{attrs:{href:"https://bitcoinfaucet.uo1.net",target:"_blank",rel:"noopener noreferrer"}},[t._v("https://bitcoinfaucet.uo1.net"),a("OutboundLink")],1)])])])}),[],!1,null,null,null);a.default=e.exports}}]); \ No newline at end of file diff --git a/assets/js/21.ace15d2d.js b/assets/js/21.09b4c434.js similarity index 98% rename from assets/js/21.ace15d2d.js rename to assets/js/21.09b4c434.js index dadb41c55d..7d89efc393 100644 --- a/assets/js/21.ace15d2d.js +++ b/assets/js/21.09b4c434.js @@ -1 +1 @@ -(window.webpackJsonp=window.webpackJsonp||[]).push([[21],{366:function(t,a,s){t.exports=s.p+"assets/img/bdk_rn_complete_app.e382f61c.png"},367:function(t,a,s){t.exports=s.p+"assets/img/default_rn_app.9e60b4fb.png"},368:function(t,a,s){t.exports=s.p+"assets/img/folder_structure.d1c95bd6.png"},369:function(t,a,s){t.exports=s.p+"assets/img/bdk_rn_title.289f266d.png"},370:function(t,a,s){t.exports=s.p+"assets/img/bdk_rn_tutorial_screen_mnemonic.9963c418.png"},371:function(t,a,s){t.exports=s.p+"assets/img/bdk_rn_tutorial_screen_createwallet.916f2610.png"},372:function(t,a,s){t.exports=s.p+"assets/img/bdk_rn_get_balance.75af17bf.png"},373:function(t,a,s){t.exports=s.p+"assets/img/bdk_rn_get_address.4f570fb2.png"},374:function(t,a,s){t.exports=s.p+"assets/img/bdk_rn_get_restore.134b3681.png"},375:function(t,a,s){t.exports=s.p+"assets/img/bdk_rn_send.4e9dbc4a.png"},413:function(t,a,s){"use strict";s.r(a);var n=s(7),e=Object(n.a)({},(function(){var t=this,a=t._self._c;return a("ContentSlotsDistributor",{attrs:{"slot-key":t.$parent.slotKey}},[a("h2",{attrs:{id:"introduction"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#introduction"}},[t._v("#")]),t._v(" Introduction")]),t._v(" "),a("p",[a("code",[t._v("bdk-rn")]),t._v(" is the "),a("strong",[t._v("Bitcoin Dev kit")]),t._v("'s "),a("strong",[t._v("React Native")]),t._v(" library which enables building bitcoin applications for Android and iOS mobile platforms. Using "),a("code",[t._v("bdk-rn")]),t._v(" does not require knowledge of the underlying bitcoin or BDK API. Using "),a("code",[t._v("bdk-rn")]),t._v(" is similar to using any other RN module. Just do "),a("code",[t._v("yarn add bdk-rn")]),t._v(" and you are ready to code! This is the first tutorial on how to use "),a("code",[t._v("bdk-rn")]),t._v(", more coming soon, make sure to "),a("a",{attrs:{href:"https://twitter.com/BitcoinZavior?ref_src=twsrc%5Etfw",target:"_blank",rel:"noopener noreferrer"}},[t._v("follow"),a("OutboundLink")],1),t._v(" to be notified of new ones. In case you missed it, there is a recorded "),a("code",[t._v("bdk-rn")]),t._v(" focused Twitch Livestream available on the "),a("a",{attrs:{href:"https://www.youtube.com/watch?v=gMpWA875go4",target:"_blank",rel:"noopener noreferrer"}},[t._v("Bitcoin Developers"),a("OutboundLink")],1),t._v(" YouTube channel which covers most of this article, make sure to subscribe to Bitcoin Developers "),a("a",{attrs:{href:"https://www.youtube.com/channel/UCUq_ZdezVWKPvkWRicAYxLA/videos",target:"_blank",rel:"noopener noreferrer"}},[t._v("YouTube Channel"),a("OutboundLink")],1),t._v(" for more bitcoin development videos.")]),t._v(" "),a("p",[t._v("In this tutorial, we will explore "),a("code",[t._v("bdk-rn")]),t._v(" usage and the API it provides. This guide will walk through the development process and code for making a bitcoin application. The bitcoin application we create will be a non-custodial HD Wallet. The application will have the functionality to create a new wallet or restore from a known mnemonic seed phrase. This application will also be able to interact with the bitcoin network to sync UTXOs from new blocks and broadcast transactions.")]),t._v(" "),a("p",[t._v("The tutorial will focus on bitcoin and "),a("code",[t._v("bdk-rn")]),t._v(" concepts and API. So it will gloss over React Native aspects. The code for this tutorial is available on the "),a("a",{attrs:{href:"https://github.com/LtbLightning/BdkRnQuickStart",target:"_blank",rel:"noopener noreferrer"}},[t._v("LtbLightning GitHub"),a("OutboundLink")],1)]),t._v(" "),a("img",{staticStyle:{display:"block",margin:"0 auto",zoom:"50%"},attrs:{src:s(366),alt:"BDK RN Quick Start"}}),t._v(" "),a("h3",{attrs:{id:"prerequisites"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#prerequisites"}},[t._v("#")]),t._v(" Prerequisites")]),t._v(" "),a("p",[t._v("In order to use "),a("code",[t._v("bdk-rn")]),t._v(" in a React Native App, a React Native development environment is required. Please refer to resources out there on the internet if you need to set this up, here is one of many good resources to guide you on "),a("a",{attrs:{href:"https://reactnative.dev/docs/environment-setup",target:"_blank",rel:"noopener noreferrer"}},[t._v("environment setup"),a("OutboundLink")],1)]),t._v(" "),a("h3",{attrs:{id:"bitcoin-basics"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#bitcoin-basics"}},[t._v("#")]),t._v(" Bitcoin Basics")]),t._v(" "),a("p",[t._v("The bitcoin concepts used in this blog post are detailed and explained very well in external bitcoin resources. Here are some links for reference:")]),t._v(" "),a("p",[a("a",{attrs:{href:"https://github.com/bitcoinbook/bitcoinbook/blob/develop/ch04.asciidoc",target:"_blank",rel:"noopener noreferrer"}},[t._v("Mastering Bitcoin(HD Wallet chapter)"),a("OutboundLink")],1)]),t._v(" "),a("p",[a("a",{attrs:{href:"https://github.com/bitcoin/bitcoin/blob/master/doc/descriptors.md",target:"_blank",rel:"noopener noreferrer"}},[t._v("Bitcoin Output Descriptors from bitcoin GitHub"),a("OutboundLink")],1)]),t._v(" "),a("p",[t._v("Now let's jump into Bitcoin Dev Kit")]),t._v(" "),a("h2",{attrs:{id:"bitcoin-dev-kit-and-bdk-rn"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#bitcoin-dev-kit-and-bdk-rn"}},[t._v("#")]),t._v(" Bitcoin Dev Kit and bdk-rn")]),t._v(" "),a("p",[a("code",[t._v("bdk-rn")]),t._v(" is a React Native library of Bitcoin Dev Kit(BDK) for building React Native Apps.\nIt encapsulates all of the low-level APIs and methods for BDK and exposes them in a react native context. To use BDK in React Native(RN) apps only the "),a("code",[t._v("bdk-rn")]),t._v(" module is required. "),a("code",[t._v("Bdk-rn")]),t._v(" can be used like any other react native library and is available on "),a("a",{attrs:{href:"https://www.npmjs.com/package/bdk-rn",target:"_blank",rel:"noopener noreferrer"}},[t._v("public package managers(npm and yarn)"),a("OutboundLink")],1),t._v(".")]),t._v(" "),a("h2",{attrs:{id:"getting-started"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#getting-started"}},[t._v("#")]),t._v(" Getting Started")]),t._v(" "),a("p",[t._v("Although we won't delve deep into RN we will focus more on bitcoin and bdk-rn, however, some rudimentary RN setup is required, especially a basic RN app to add our code.")]),t._v(" "),a("p",[t._v("start by creating a new RN project.")]),t._v(" "),a("p",[a("code",[t._v("npx react-native init BdkRnQuickStart")])]),t._v(" "),a("p",[t._v("If this fails in an error on an M1/M2 Mac please use\n"),a("code",[t._v("arch -x86_64 pod install --repo-update")])]),t._v(" "),a("p",[t._v("Once done "),a("code",[t._v("cd")]),t._v(" into the new project directory and run the basic RN app that's created")]),t._v(" "),a("div",{staticClass:"language-shell extra-class"},[a("pre",{pre:!0,attrs:{class:"language-shell"}},[a("code",[a("span",{pre:!0,attrs:{class:"token builtin class-name"}},[t._v("cd")]),t._v(" BdkRnQuickStart\n"),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("yarn")]),t._v(" ios\n")])])]),a("p",[t._v("This should start building the app and launch the app in a simulator. So far we have created a basic RN project if this doesn't work then refer to the React Native development setup guide to troubleshoot.")]),t._v(" "),a("img",{staticStyle:{display:"block",margin:"0 auto",zoom:"25%"},attrs:{src:s(367)}}),t._v(" "),a("h2",{attrs:{id:"setting-up-styles-and-rn-app-structure"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#setting-up-styles-and-rn-app-structure"}},[t._v("#")]),t._v(" Setting up styles and RN app structure")]),t._v(" "),a("p",[t._v("Let's set up a very basic app structure and some RN scaffolding. Let's create an "),a("code",[t._v("src")]),t._v(" folder in the project root and inside it add new folders for "),a("code",[t._v("assets")]),t._v(", "),a("code",[t._v("elements")]),t._v(", "),a("code",[t._v("screens")]),t._v(" and "),a("code",[t._v("styles")])]),t._v(" "),a("p",[t._v("To make this quick you can download the styles and images used in the tutorial from the repository. The image assets, "),a("code",[t._v("Button.tsx")]),t._v(" and "),a("code",[t._v("styles.js")]),t._v(" can be taken from "),a("a",{attrs:{href:"https://github.com/LtbLightning/BdkRnQuickStart/tree/master/src",target:"_blank",rel:"noopener noreferrer"}},[t._v("here"),a("OutboundLink")],1),t._v(" and moved to the folders as shown. Alternatively, you can write your own styles and use your own images if you intend to style the app in a different way.")]),t._v(" "),a("p",[t._v("Create a "),a("code",[t._v("home.js")]),t._v(" file under "),a("code",[t._v("screens")]),t._v(" folder, this will be where we will be adding most of the code.")]),t._v(" "),a("p",[t._v("Once done the project structure should look like this:")]),t._v(" "),a("img",{staticStyle:{display:"block",margin:"0px auto",zoom:"67%"},attrs:{src:s(368)}}),t._v(" "),a("p",[t._v("Locate "),a("code",[t._v("App.js")]),t._v(" in the project root, this will have the default code added by "),a("code",[t._v("react-native init")]),t._v(", let's delete all contents of "),a("code",[t._v("App.js")]),t._v(" and replace it with code to import "),a("code",[t._v("home.js")]),t._v(" as our main screen.")]),t._v(" "),a("div",{staticClass:"language-javascript extra-class"},[a("pre",{pre:!0,attrs:{class:"language-javascript"}},[a("code",[a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// App.js ")]),t._v("\n\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("import")]),t._v(" React "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("from")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[t._v("'react'")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("import")]),t._v(" Home "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("from")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[t._v("'./src/screens/home'")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function-variable function"}},[t._v("App")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),t._v("Home "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("/")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("export")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("default")]),t._v(" App"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),a("p",[t._v("This will probably crash your app in the simulator but that's fine, it will be fixed in the next step.")]),t._v(" "),a("h2",{attrs:{id:"installing-bdk-rn"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#installing-bdk-rn"}},[t._v("#")]),t._v(" Installing "),a("code",[t._v("bdk-rn")])]),t._v(" "),a("p",[t._v("With the RN app project in place, we can now add "),a("code",[t._v("bdk-rn")]),t._v(" using either npm or yarn.")]),t._v(" "),a("p",[t._v("Using npm:")]),t._v(" "),a("div",{staticClass:"language-shell extra-class"},[a("pre",{pre:!0,attrs:{class:"language-shell"}},[a("code",[a("span",{pre:!0,attrs:{class:"token function"}},[t._v("npm")]),t._v(" i "),a("span",{pre:!0,attrs:{class:"token parameter variable"}},[t._v("--save")]),t._v(" bdk-rn\n")])])]),a("p",[t._v("Using yarn:")]),t._v(" "),a("div",{staticClass:"language-shell extra-class"},[a("pre",{pre:!0,attrs:{class:"language-shell"}},[a("code",[a("span",{pre:!0,attrs:{class:"token function"}},[t._v("yarn")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("add")]),t._v(" bdk-rn\n")])])]),a("p",[t._v("[iOS Only] Install pods:")]),t._v(" "),a("div",{staticClass:"language-shell extra-class"},[a("pre",{pre:!0,attrs:{class:"language-shell"}},[a("code",[t._v("npx pod-install\nor\n"),a("span",{pre:!0,attrs:{class:"token builtin class-name"}},[t._v("cd")]),t._v(" ios "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&&")]),t._v(" pod "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("install")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&&")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token builtin class-name"}},[t._v("cd")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("..")]),t._v("\n")])])]),a("p",[t._v("Verify that "),a("code",[t._v("bdk-rn")]),t._v(" has been added to "),a("code",[t._v("package.json")]),t._v(", once done "),a("code",[t._v("bdk-rn")]),t._v(" is installed and ready to be used in our "),a("strong",[t._v("BdkRnQuickStart")]),t._v(" App.")]),t._v(" "),a("h2",{attrs:{id:"importing-bdk-rn"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#importing-bdk-rn"}},[t._v("#")]),t._v(" Importing "),a("code",[t._v("bdk-rn")])]),t._v(" "),a("p",[t._v("Locate "),a("code",[t._v("home.js")]),t._v(" which we added in the setup section and import "),a("code",[t._v("bdk-rn")]),t._v(" and also create an RN functional component.")]),t._v(" "),a("div",{staticClass:"language-javascript extra-class"},[a("pre",{pre:!0,attrs:{class:"language-javascript"}},[a("code",[a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// screens/home.js")]),t._v("\n\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("import")]),t._v(" BdkRn "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("from")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[t._v("'bdk-rn'")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function-variable function"}},[t._v("Home")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("export")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("default")]),t._v(" Home"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),a("p",[t._v("Before we start using "),a("code",[t._v("bdk-rn")]),t._v(" let's add some additional RN component imports, as well as import styles, a button and image assets to create a basic layout to build our home screen.")]),t._v(" "),a("div",{staticClass:"language-jsx extra-class"},[a("pre",{pre:!0,attrs:{class:"language-jsx"}},[a("code",[a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// screens/home.js")]),t._v("\n\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("import")]),t._v(" BdkRn "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("from")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[t._v("'bdk-rn'")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("import")]),t._v(" React"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" Fragment"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" useState "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("from")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[t._v("'react'")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("import")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n ActivityIndicator"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n SafeAreaView"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n ScrollView"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n StatusBar"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n Text"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n TextInput"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n View"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n Image"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("from")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[t._v("'react-native'")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("import")]),t._v(" Button "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("from")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[t._v("'../elements/Button'")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("import")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" styles "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("from")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[t._v("'../styles/styles'")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" bitcoinLogo "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("require")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token string"}},[t._v("'../assets/bitcoin_logo.png'")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" bdkLogo "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("require")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token string"}},[t._v("'../assets/bdk_logo.png'")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function-variable function"}},[t._v("Home")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// BDK-RN method calls and state variables will be added here")]),t._v("\n\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("SafeAreaView")])]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),a("span",{pre:!0,attrs:{class:"token plain-text"}},[t._v("\n ")]),a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("StatusBar")])]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("/>")])]),a("span",{pre:!0,attrs:{class:"token plain-text"}},[t._v("\n ")]),a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("ScrollView")])]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("contentInsetAdjustmentBehavior")]),a("span",{pre:!0,attrs:{class:"token attr-value"}},[a("span",{pre:!0,attrs:{class:"token punctuation attr-equals"}},[t._v("=")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v('"')]),t._v("automatic"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v('"')])]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("contentContainerStyle")]),a("span",{pre:!0,attrs:{class:"token script language-javascript"}},[a("span",{pre:!0,attrs:{class:"token script-punctuation punctuation"}},[t._v("=")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("styles"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("container"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),a("span",{pre:!0,attrs:{class:"token plain-text"}},[t._v("\n ")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("/* Header */")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token plain-text"}},[t._v("\n ")]),a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("View")])]),t._v(" "),a("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("style")]),a("span",{pre:!0,attrs:{class:"token script language-javascript"}},[a("span",{pre:!0,attrs:{class:"token script-punctuation punctuation"}},[t._v("=")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("styles"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("headerSection"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),a("span",{pre:!0,attrs:{class:"token plain-text"}},[t._v("\n ")]),a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Image")])]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("style")]),a("span",{pre:!0,attrs:{class:"token script language-javascript"}},[a("span",{pre:!0,attrs:{class:"token script-punctuation punctuation"}},[t._v("=")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("resizeMode")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[t._v("'stretch'")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("height")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("36")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("width")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("36")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("source")]),a("span",{pre:!0,attrs:{class:"token script language-javascript"}},[a("span",{pre:!0,attrs:{class:"token script-punctuation punctuation"}},[t._v("=")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("bitcoinLogo"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("/>")])]),a("span",{pre:!0,attrs:{class:"token plain-text"}},[t._v("\n ")]),a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Text")])]),t._v(" "),a("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("style")]),a("span",{pre:!0,attrs:{class:"token script language-javascript"}},[a("span",{pre:!0,attrs:{class:"token script-punctuation punctuation"}},[t._v("=")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("styles"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("headerText"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),a("span",{pre:!0,attrs:{class:"token plain-text"}},[t._v("BDK-RN Tutorial")]),a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("")])]),a("span",{pre:!0,attrs:{class:"token plain-text"}},[t._v("\n ")]),a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Image")])]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("style")]),a("span",{pre:!0,attrs:{class:"token script language-javascript"}},[a("span",{pre:!0,attrs:{class:"token script-punctuation punctuation"}},[t._v("=")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("resizeMode")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[t._v("'center'")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("height")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("40")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("width")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("25")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("source")]),a("span",{pre:!0,attrs:{class:"token script language-javascript"}},[a("span",{pre:!0,attrs:{class:"token script-punctuation punctuation"}},[t._v("=")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("bdkLogo"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("/>")])]),a("span",{pre:!0,attrs:{class:"token plain-text"}},[t._v("\n ")]),a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("")])]),a("span",{pre:!0,attrs:{class:"token plain-text"}},[t._v("\n\n ")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("/* Balance */")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token plain-text"}},[t._v("\n\n ")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("/* method call result */")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token plain-text"}},[t._v("\n\n ")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("/* buttons for method calls */")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token plain-text"}},[t._v("\n\n ")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("/* input boxes and send transaction button */")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token plain-text"}},[t._v("\n\n ")]),a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("")])]),a("span",{pre:!0,attrs:{class:"token plain-text"}},[t._v("\n ")]),a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("")])]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("export")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("default")]),t._v(" Home"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),a("p",[t._v("We now have an app title section and a structure to hold the rest of our app components.")]),t._v(" "),a("img",{staticStyle:{display:"block",margin:"0 auto",zoom:"33%"},attrs:{src:s(369)}}),t._v(" "),a("h2",{attrs:{id:"calling-bdk-rn-methods"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#calling-bdk-rn-methods"}},[t._v("#")]),t._v(" Calling "),a("code",[t._v("bdk-rn")]),t._v(" methods")]),t._v(" "),a("p",[t._v("All "),a("code",[t._v("bdk-rn")]),t._v(" methods return a JSON response with data and error properties. All methods return a response as follows:")]),t._v(" "),a("div",{staticClass:"language-javascript extra-class"},[a("pre",{pre:!0,attrs:{class:"language-javascript"}},[a("code",[t._v("Promise"),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),t._v("Response"),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("error")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token boolean"}},[t._v("true")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("|")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token boolean"}},[t._v("false")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// success returns true else false.")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("data")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" string "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("|")]),t._v(" object "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("|")]),t._v(" any"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// output data for the method call.")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),a("p",[t._v("The first step in creating a non-custodial bitcoin app is creating a mnemonic seed phrase for the wallet.")]),t._v(" "),a("p",[a("code",[t._v("bdk-rn")]),t._v(" provides "),a("code",[t._v("generateMnemonic()")]),t._v(" method to create a default 12 word length mnemonic.")]),t._v(" "),a("div",{staticClass:"language-javascript extra-class"},[a("pre",{pre:!0,attrs:{class:"language-javascript"}},[a("code",[a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("import")]),t._v(" BdkRn "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("from")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[t._v("'bdk-rn'")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" response "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" BdkRn"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("generateMnemonic")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" mnemonic "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" response"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("data"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),a("p",[t._v("We can specify a longer length or we can also specify the bits of entropy we need by passing the length or entropy arguments.")]),t._v(" "),a("p",[t._v("To create a mnemonic with an entropy of 256 bits, which will be a 24-word length mnemonic sentence, we can use "),a("code",[t._v("{ entropy: 256 }")]),t._v(".\nRefer to the readme file on "),a("a",{attrs:{href:"https://github.com/LtbLightning/bdk-rn#generatemnemomic",target:"_blank",rel:"noopener noreferrer"}},[t._v("GitHub"),a("OutboundLink")],1),t._v(" for more details.")]),t._v(" "),a("div",{staticClass:"language-javascript extra-class"},[a("pre",{pre:!0,attrs:{class:"language-javascript"}},[a("code",[a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),a("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("data")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" mnemonic"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" BdkRn"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("generateMnemonic")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("entropy")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("256")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// here data is destructured and saved as 'mnemonic'")]),t._v("\n")])])]),a("p",[t._v("In order to use this in our RN app let's create a state variable to store the mnemonic and internal "),a("code",[t._v("generateMnemonic")]),t._v(" method which we can invoke when a button is clicked. We will also need a button which will invoke generateMnemonic when clicked. Adding the following code achieves all of this.")]),t._v(" "),a("div",{staticClass:"language-jsx extra-class"},[a("pre",{pre:!0,attrs:{class:"language-jsx"}},[a("code",[a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// screens/home.js")]),t._v("\n\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function-variable function"}},[t._v("Home")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// BDK-RN method calls and state variables will be added here")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// state variable to store and set mnemonic")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("mnemonic"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" setMnemonic"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("useState")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token string"}},[t._v("''")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// internal method to call bdk-rn to generate mnemonic")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function-variable function"}},[t._v("getMnemonic")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("async")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n\t\t"),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// call bdk-rn to generate mnemonic")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("data"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" BdkRn"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("generateMnemonic")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("length")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("12")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// save generated mnemonic to state variable")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("setMnemonic")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("data"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("SafeAreaView")])]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),a("span",{pre:!0,attrs:{class:"token plain-text"}},[t._v("\n ")]),a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("StatusBar")])]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("/>")])]),a("span",{pre:!0,attrs:{class:"token plain-text"}},[t._v("\n ")]),a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("ScrollView")])]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("contentInsetAdjustmentBehavior")]),a("span",{pre:!0,attrs:{class:"token attr-value"}},[a("span",{pre:!0,attrs:{class:"token punctuation attr-equals"}},[t._v("=")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v('"')]),t._v("automatic"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v('"')])]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("contentContainerStyle")]),a("span",{pre:!0,attrs:{class:"token script language-javascript"}},[a("span",{pre:!0,attrs:{class:"token script-punctuation punctuation"}},[t._v("=")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("styles"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("container"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),a("span",{pre:!0,attrs:{class:"token plain-text"}},[t._v("\n ")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("/* Header */")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token plain-text"}},[t._v("\n ")]),a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("View")])]),t._v(" "),a("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("style")]),a("span",{pre:!0,attrs:{class:"token script language-javascript"}},[a("span",{pre:!0,attrs:{class:"token script-punctuation punctuation"}},[t._v("=")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("styles"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("headerSection"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),a("span",{pre:!0,attrs:{class:"token plain-text"}},[t._v("\n ")]),a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Image")])]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("style")]),a("span",{pre:!0,attrs:{class:"token script language-javascript"}},[a("span",{pre:!0,attrs:{class:"token script-punctuation punctuation"}},[t._v("=")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("resizeMode")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[t._v("'stretch'")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("height")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("36")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("width")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("36")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("source")]),a("span",{pre:!0,attrs:{class:"token script language-javascript"}},[a("span",{pre:!0,attrs:{class:"token script-punctuation punctuation"}},[t._v("=")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("bitcoinLogo"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("/>")])]),a("span",{pre:!0,attrs:{class:"token plain-text"}},[t._v("\n ")]),a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Text")])]),t._v(" "),a("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("style")]),a("span",{pre:!0,attrs:{class:"token script language-javascript"}},[a("span",{pre:!0,attrs:{class:"token script-punctuation punctuation"}},[t._v("=")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("styles"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("headerText"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),a("span",{pre:!0,attrs:{class:"token plain-text"}},[t._v("BDK-RN Tutorial")]),a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("")])]),a("span",{pre:!0,attrs:{class:"token plain-text"}},[t._v("\n ")]),a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Image")])]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("style")]),a("span",{pre:!0,attrs:{class:"token script language-javascript"}},[a("span",{pre:!0,attrs:{class:"token script-punctuation punctuation"}},[t._v("=")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("resizeMode")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[t._v("'center'")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("height")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("40")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("width")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("25")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("source")]),a("span",{pre:!0,attrs:{class:"token script language-javascript"}},[a("span",{pre:!0,attrs:{class:"token script-punctuation punctuation"}},[t._v("=")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("bdkLogo"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("/>")])]),a("span",{pre:!0,attrs:{class:"token plain-text"}},[t._v("\n ")]),a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("")])]),a("span",{pre:!0,attrs:{class:"token plain-text"}},[t._v("\n\n ")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("/* Balance */")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token plain-text"}},[t._v("\n\n ")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("/* method call result */")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token plain-text"}},[t._v("\n\n ")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("/* buttons for method calls */")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token plain-text"}},[t._v("\n ")]),a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("View")])]),t._v(" "),a("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("style")]),a("span",{pre:!0,attrs:{class:"token script language-javascript"}},[a("span",{pre:!0,attrs:{class:"token script-punctuation punctuation"}},[t._v("=")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("styles"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("methodSection"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),a("span",{pre:!0,attrs:{class:"token plain-text"}},[t._v("\n ")]),a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Button")])]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("title")]),a("span",{pre:!0,attrs:{class:"token attr-value"}},[a("span",{pre:!0,attrs:{class:"token punctuation attr-equals"}},[t._v("=")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v('"')]),t._v("Generate Mnemonic"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v('"')])]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("style")]),a("span",{pre:!0,attrs:{class:"token script language-javascript"}},[a("span",{pre:!0,attrs:{class:"token script-punctuation punctuation"}},[t._v("=")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("styles"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("methodButton"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("onPress")]),a("span",{pre:!0,attrs:{class:"token script language-javascript"}},[a("span",{pre:!0,attrs:{class:"token script-punctuation punctuation"}},[t._v("=")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("getMnemonic"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("/>")])]),a("span",{pre:!0,attrs:{class:"token plain-text"}},[t._v("\n ")]),a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("")])]),a("span",{pre:!0,attrs:{class:"token plain-text"}},[t._v("\n\n ")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("/* input boxes and send transaction button */")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token plain-text"}},[t._v("\n ")]),a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("")])]),a("span",{pre:!0,attrs:{class:"token plain-text"}},[t._v("\n ")]),a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("")])]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),a("p",[t._v("Now we need to add a component to display the output of our method calls and this will also need a state variable to track our method call response. To achieve this add the following code.")]),t._v(" "),a("div",{staticClass:"language-javascript extra-class"},[a("pre",{pre:!0,attrs:{class:"language-javascript"}},[a("code",[a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// screens/home.js")]),t._v("\n\n"),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// add this as another state variable under mnemonic")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("displayText"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" setDisplayText"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("useState")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token string"}},[t._v("''")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// modify the generateMnenomic method to also set mnemonic as displayText")]),t._v("\n\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function-variable function"}},[t._v("getMnemonic")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("async")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("data"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" BdkRn"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("generateMnemonic")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("length")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("12")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("network")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[t._v("'testnet'")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("setMnemonic")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token constant"}},[t._v("JSON")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("stringify")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("data"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("setDisplayText")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token constant"}},[t._v("JSON")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("stringify")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("data"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),a("p",[t._v("and finally, let's add the component to display the output under "),a("code",[t._v("{/* method call result */}")])]),t._v(" "),a("div",{staticClass:"language-jsx extra-class"},[a("pre",{pre:!0,attrs:{class:"language-jsx"}},[a("code",[a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// screens/home.js")]),t._v("\n\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("/* method call result */")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\t"),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// display the component only if displayText has a value")]),t._v("\n\t"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("displayText "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&&")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("View")])]),t._v(" "),a("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("style")]),a("span",{pre:!0,attrs:{class:"token script language-javascript"}},[a("span",{pre:!0,attrs:{class:"token script-punctuation punctuation"}},[t._v("=")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("styles"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("responseSection"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),a("span",{pre:!0,attrs:{class:"token plain-text"}},[t._v("\n ")]),a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Text")])]),t._v(" "),a("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("style")]),a("span",{pre:!0,attrs:{class:"token script language-javascript"}},[a("span",{pre:!0,attrs:{class:"token script-punctuation punctuation"}},[t._v("=")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("styles"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("responseText"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),t._v(" "),a("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("selectable")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),a("span",{pre:!0,attrs:{class:"token plain-text"}},[t._v("\n Response:\n ")]),a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("")])]),a("span",{pre:!0,attrs:{class:"token plain-text"}},[t._v("\n ")]),a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Text")])]),t._v(" "),a("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("selectable")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("displayText"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("")])]),a("span",{pre:!0,attrs:{class:"token plain-text"}},[t._v("\n ")]),a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("")])]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),a("p",[t._v('We should now have a working" Generate Mnemonic" button which displays the new mnemonic')]),t._v(" "),a("img",{staticStyle:{display:"block",margin:"0 auto",zoom:"50%"},attrs:{src:s(370)}}),t._v(" "),a("p",[t._v("A quick recap, we added a button to trigger a call to a method. We created a button click event handler to call bdk-rn. Set the display state variable to display the output of the call in the display section. We will follow this pattern for the remaining calls to bdk-rn.")]),t._v(" "),a("h2",{attrs:{id:"creating-a-wallet"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#creating-a-wallet"}},[t._v("#")]),t._v(" Creating a wallet")]),t._v(" "),a("p",[t._v("Before moving on to creating a wallet, let's add a section at the top to display the balance of the wallet.")]),t._v(" "),a("p",[t._v("To display the balance we will need a state variable to store the balance and a display section to display it.")]),t._v(" "),a("p",[t._v("Under the "),a("code",[t._v("mnemonic")]),t._v(" and "),a("code",[t._v("displayText")]),t._v(" variables, let's add one for "),a("code",[t._v("balance")]),t._v(" as well")]),t._v(" "),a("div",{staticClass:"language-jsx extra-class"},[a("pre",{pre:!0,attrs:{class:"language-jsx"}},[a("code",[t._v("\t"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function-variable function"}},[t._v("Home")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n\t\t"),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// BDK-RN method calls and state variables will be added here")]),t._v("\n \t"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("mnemonic"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" setMnemonic"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("useState")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token string"}},[t._v("''")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n \t"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("displayText"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" setDisplayText"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("useState")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token string"}},[t._v("''")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n \t"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("balance"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" setBalance"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("useState")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),a("p",[t._v("And we will shortly need a "),a("code",[t._v("wallet")]),t._v(" and "),a("code",[t._v("syncResponse")]),t._v(" as well so add these too.")]),t._v(" "),a("div",{staticClass:"language-jsx extra-class"},[a("pre",{pre:!0,attrs:{class:"language-jsx"}},[a("code",[t._v("\t"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function-variable function"}},[t._v("Home")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n\t\t"),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// BDK-RN method calls and state variables will be added here")]),t._v("\n \t"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("mnemonic"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" setMnemonic"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("useState")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token string"}},[t._v("''")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n \t"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("displayText"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" setDisplayText"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("useState")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token string"}},[t._v("''")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n \t"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("balance"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" setBalance"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("useState")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("wallet"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" setWallet"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("useState")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n \t"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("syncResponse"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" setSyncResponse"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("useState")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),a("p",[t._v("Now we need some "),a("code",[t._v("jsx")]),t._v(" code to display the balance.")]),t._v(" "),a("p",[t._v("Just below "),a("code",[t._v("{/* Balance */}")]),t._v(" and above "),a("code",[t._v("{*/ method call result */}")]),t._v(" add the following UI components to display the balance. We only want to show the balance when it has a value so we will use a tertiary operator for a quick check.")]),t._v(" "),a("div",{staticClass:"language-jsx extra-class"},[a("pre",{pre:!0,attrs:{class:"language-jsx"}},[a("code",[t._v("\t\t\t\t"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("/* Balance */")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\t\t\t\t"),a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("View")])]),t._v(" "),a("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("style")]),a("span",{pre:!0,attrs:{class:"token script language-javascript"}},[a("span",{pre:!0,attrs:{class:"token script-punctuation punctuation"}},[t._v("=")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("styles"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("balanceSection"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),a("span",{pre:!0,attrs:{class:"token plain-text"}},[t._v("\n ")]),a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Text")])]),t._v(" "),a("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("style")]),a("span",{pre:!0,attrs:{class:"token script language-javascript"}},[a("span",{pre:!0,attrs:{class:"token script-punctuation punctuation"}},[t._v("=")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("styles"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("balanceText"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),t._v(" "),a("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("selectable")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),a("span",{pre:!0,attrs:{class:"token plain-text"}},[t._v("\n ")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),a("span",{pre:!0,attrs:{class:"token string"}},[t._v("'Balance: '")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token plain-text"}},[t._v("\n ")]),a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("")])]),a("span",{pre:!0,attrs:{class:"token plain-text"}},[t._v("\n ")]),a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Text")])]),t._v(" "),a("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("selectable")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("balance "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("?")]),t._v(" balance "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[t._v("'0'")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token plain-text"}},[t._v(" Sats")]),a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("")])]),a("span",{pre:!0,attrs:{class:"token plain-text"}},[t._v("\n ")]),a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("")])]),t._v("\n\t\t\t\t"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("/* method call result */")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),a("p",[t._v("We will next add code to create a wallet.")]),t._v(" "),a("p",[t._v("To create a wallet the simple approach is to call "),a("code",[t._v("createWallet()")]),t._v(" method with "),a("code",[t._v("mnemonic")]),t._v(" , "),a("code",[t._v("password")]),t._v(" and "),a("code",[t._v("network")]),t._v(".\nLet's add another click event handler below where we have the "),a("code",[t._v("getMnemonic()")]),t._v(" method\nWe want to see the response to this call so let's use "),a("code",[t._v("setDisplayText()")]),t._v(" to see the output")]),t._v(" "),a("div",{staticClass:"language-javascript extra-class"},[a("pre",{pre:!0,attrs:{class:"language-javascript"}},[a("code",[t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function-variable function"}},[t._v("createWallet")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("async")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" data "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" BdkRn"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("createWallet")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("mnemonic")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" mnemonic"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("password")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[t._v("'password'")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("network")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[t._v("'testnet'")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("setWallet")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("data"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("setDisplayText")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token constant"}},[t._v("JSON")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("stringify")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("data"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),a("p",[t._v("A new button will be required to trigger "),a("code",[t._v("createWallet")])]),t._v(" "),a("p",[t._v("Let's add a new button just above "),a("code",[t._v("{/* input boxes and send transaction button */}")])]),t._v(" "),a("div",{staticClass:"language-jsx extra-class"},[a("pre",{pre:!0,attrs:{class:"language-jsx"}},[a("code",[t._v("\t\t\t\t"),a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Button")])]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("title")]),a("span",{pre:!0,attrs:{class:"token attr-value"}},[a("span",{pre:!0,attrs:{class:"token punctuation attr-equals"}},[t._v("=")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v('"')]),t._v("Create Wallet"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v('"')])]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("style")]),a("span",{pre:!0,attrs:{class:"token script language-javascript"}},[a("span",{pre:!0,attrs:{class:"token script-punctuation punctuation"}},[t._v("=")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("styles"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("methodButton"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("onPress")]),a("span",{pre:!0,attrs:{class:"token script language-javascript"}},[a("span",{pre:!0,attrs:{class:"token script-punctuation punctuation"}},[t._v("=")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("createWallet"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("/>")])]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("")])]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("/* input boxes and send transaction button */")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),a("p",[t._v("The response returned by "),a("code",[t._v("createWallet")]),t._v(" is a new address for the created wallet.")]),t._v(" "),a("div",{staticClass:"language-javascript extra-class"},[a("pre",{pre:!0,attrs:{class:"language-javascript"}},[a("code",[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token string-property property"}},[t._v('"data"')]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token string-property property"}},[t._v('"address"')]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"tb1qxg8g8cdzgs09cttu3y7lc33udqc4wsesunjnhe"')]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token string-property property"}},[t._v('"error"')]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token boolean"}},[t._v("false")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),a("p",[t._v("The App should now be creating a wallet when we click "),a("strong",[t._v("Create Mnemonic")]),t._v(" followed by "),a("strong",[t._v("Create Wallet")]),t._v(".")]),t._v(" "),a("img",{staticStyle:{display:"block",margin:"0 auto",zoom:"50%"},attrs:{src:s(371)}}),t._v(" "),a("p",[t._v("The wallet created is a HD wallet and the address displayed is the 0 index address for the wallet. The path used by default is 84'/1'/0'/0/* for addresses and 84'/1'/0'/1/* for change.")]),t._v(" "),a("p",[t._v("As we specified "),a("code",[t._v("testnet")]),t._v(" and did not specify "),a("code",[t._v("blockChainName")]),t._v(" and "),a("code",[t._v("blockChainConfigUrl")]),t._v(" a default testnet server will be used as the bitcoin node, "),a("code",[t._v("ssl://electrum.blockstream.info")]),t._v(" is the default url used for testnet.")]),t._v(" "),a("p",[t._v("Using "),a("code",[t._v("mnemonic")]),t._v(" is a quick way to create a new wallet with "),a("code",[t._v("bdk-rn")]),t._v(". The "),a("code",[t._v("createWallet()")]),t._v(" method in "),a("code",[t._v("bdk-rn")]),t._v(" has many optional arguments to configure the wallet. In addition to mnemonic, a wallet can also be created with a descriptor. If a descriptor is passed as an argument the wallet will be created using the descriptor. When using a descriptor, arguments for network, password and mnemonic are not required. "),a("code",[t._v("bdk-rn")]),t._v(" has a "),a("code",[t._v("createDescriptor()")]),t._v(" method to create a descriptor. More about output descriptors "),a("a",{attrs:{href:"https://github.com/bitcoin/bitcoin/blob/master/doc/descriptors.md",target:"_blank",rel:"noopener noreferrer"}},[t._v("here"),a("OutboundLink")],1),t._v(". Refer to the "),a("a",{attrs:{href:"https://github.com/LtbLightning/bdk-rn#createdescriptor",target:"_blank",rel:"noopener noreferrer"}},[t._v("readme"),a("OutboundLink")],1),t._v(" for all options available when creating output descriptors with "),a("code",[t._v("bdk-rn")])]),t._v(" "),a("div",{staticClass:"language-javascript extra-class"},[a("pre",{pre:!0,attrs:{class:"language-javascript"}},[a("code",[a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// using a descriptor to create wallet ")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" response "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" BdkRn"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("createWallet")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("descriptor")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token string"}},[t._v("'tprv8ZgxMBicQKsPd3G66kPkZEuJZgUK9QXJRYCwnCtYLJjEZmw8xFjCxGoyx533AL83XFcSQeuVmVeJbZai5RTBxDp71Abd2FPSyQumRL79BKw'")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),a("p",[t._v("Other arguments for "),a("code",[t._v("createWallet()")]),t._v(" are:")]),t._v(" "),a("p",[a("strong",[t._v("blockChainName")]),t._v(": Blockchain backend to use, like "),a("a",{attrs:{href:"https://github.com/romanz/electrs",target:"_blank",rel:"noopener noreferrer"}},[a("code",[t._v("electrum")]),a("OutboundLink")],1),t._v(", "),a("a",{attrs:{href:"https://github.com/Blockstream/esplora",target:"_blank",rel:"noopener noreferrer"}},[a("code",[t._v("esplora")]),a("OutboundLink")],1),t._v(", "),a("code",[t._v("compact-filters")]),t._v(" ("),a("a",{attrs:{href:"https://github.com/bitcoin/bips/blob/master/bip-0157.mediawiki",target:"_blank",rel:"noopener noreferrer"}},[t._v("BIP157"),a("OutboundLink")],1),t._v(") and Bitcoin Core. "),a("code",[t._v("bdk-rn")]),t._v(" at the moment doesn't support compact-filters and Bitcoin Core, this will be added shortly in a future release.")]),t._v(" "),a("p",[a("strong",[t._v("blockChainConfigUrl")]),t._v(": This is the url of the specified bitcoin node this should match the chain and the type of blockchain specified as "),a("strong",[t._v("blockChainName")])]),t._v(" "),a("p",[t._v("Refer to "),a("a",{attrs:{href:"https://github.com/LtbLightning/bdk-rn#createwallet",target:"_blank",rel:"noopener noreferrer"}},[t._v("readme"),a("OutboundLink")],1),t._v(" for a complete list of options for "),a("code",[t._v("createWallet")])]),t._v(" "),a("h2",{attrs:{id:"utxos-and-balance"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#utxos-and-balance"}},[t._v("#")]),t._v(" UTXOs and balance")]),t._v(" "),a("p",[t._v("With the wallet created, we can now add methods to sync UTXOs compute balance.")]),t._v(" "),a("p",[a("code",[t._v("bdk-rn")]),t._v(" has a "),a("code",[t._v("syncWallet")]),t._v(" method to sync all UTXOs belonging to the wallet with the bitcoin network, the specified "),a("code",[t._v("blockChainName")]),t._v(" and "),a("code",[t._v("blockChainConfigUrl")]),t._v(" is used to sync. Once the wallet sync is complete balance is computed and "),a("code",[t._v("getBalance")]),t._v(" can fetch the balance.")]),t._v(" "),a("p",[t._v("Earlier we have aleady added state variables for"),a("code",[t._v("syncResponse")]),t._v("and "),a("code",[t._v("balance")]),t._v(". Now we will add buttons to call "),a("code",[t._v("syncWallet")]),t._v(" and "),a("code",[t._v("getBalance")]),t._v(". Just below the Create Wallet button lets add two buttons as follows:")]),t._v(" "),a("div",{staticClass:"language-jsx extra-class"},[a("pre",{pre:!0,attrs:{class:"language-jsx"}},[a("code",[t._v(" "),a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Button")])]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("title")]),a("span",{pre:!0,attrs:{class:"token attr-value"}},[a("span",{pre:!0,attrs:{class:"token punctuation attr-equals"}},[t._v("=")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v('"')]),t._v("Sync Wallet"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v('"')])]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("style")]),a("span",{pre:!0,attrs:{class:"token script language-javascript"}},[a("span",{pre:!0,attrs:{class:"token script-punctuation punctuation"}},[t._v("=")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("styles"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("methodButton"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("onPress")]),a("span",{pre:!0,attrs:{class:"token script language-javascript"}},[a("span",{pre:!0,attrs:{class:"token script-punctuation punctuation"}},[t._v("=")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("syncWallet"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("/>")])]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Button")])]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("title")]),a("span",{pre:!0,attrs:{class:"token attr-value"}},[a("span",{pre:!0,attrs:{class:"token punctuation attr-equals"}},[t._v("=")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v('"')]),t._v("Get Balance"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v('"')])]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("style")]),a("span",{pre:!0,attrs:{class:"token script language-javascript"}},[a("span",{pre:!0,attrs:{class:"token script-punctuation punctuation"}},[t._v("=")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("styles"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("methodButton"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("onPress")]),a("span",{pre:!0,attrs:{class:"token script language-javascript"}},[a("span",{pre:!0,attrs:{class:"token script-punctuation punctuation"}},[t._v("=")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("getBalance"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("/>")])]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("")])]),t._v("\n")])])]),a("p",[t._v("And two click handlers below createWallet:")]),t._v(" "),a("div",{staticClass:"language-javascript extra-class"},[a("pre",{pre:!0,attrs:{class:"language-javascript"}},[a("code",[t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function-variable function"}},[t._v("syncWallet")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("async")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" data "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" BdkRn"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("syncWallet")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("setSyncResponse")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("data"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("setDisplayText")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token constant"}},[t._v("JSON")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("stringify")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("data"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function-variable function"}},[t._v("getBalance")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("async")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" data "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" BdkRn"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("getBalance")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("setBalance")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("data"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("setDisplayText")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("data"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n")])])]),a("p",[t._v("We should now be able to create a wallet, sync UTXOs and get balance")]),t._v(" "),a("img",{staticStyle:{display:"block",margin:"0 auto",zoom:"50%"},attrs:{src:s(372)}}),t._v(" "),a("p",[t._v("We can use a public testnet faucet to send testnet coins to the wallet and check that the UTXO sync and balance fetch are working correctly. Before we do that add one more method to generate a new address we can then use this address to get testnet coins from a faucet.")]),t._v(" "),a("p",[t._v("Let's add a state variable for "),a("code",[t._v("address")]),t._v(", a button for "),a("strong",[t._v("Get Address")]),t._v(" and a click event handler to call "),a("code",[t._v("bdk-rn")]),t._v(" and create a new address. Let's do the following")]),t._v(" "),a("p",[t._v("Add "),a("code",[t._v("address")]),t._v(" and "),a("code",[t._v("setAddress")]),t._v(" state variables below balance and "),a("code",[t._v("setBalance")]),t._v(":")]),t._v(" "),a("div",{staticClass:"language-javascript extra-class"},[a("pre",{pre:!0,attrs:{class:"language-javascript"}},[a("code",[t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("address"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" setAddress"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("useState")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),a("p",[t._v("A new "),a("code",[t._v("getAddress")]),t._v(" click event handler below "),a("code",[t._v("getBalance")]),t._v(" click event handler:")]),t._v(" "),a("div",{staticClass:"language-javascript extra-class"},[a("pre",{pre:!0,attrs:{class:"language-javascript"}},[a("code",[t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function-variable function"}},[t._v("getAddress")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("async")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" data "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" BdkRn"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("getNewAddress")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("setAddress")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("data"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("setDisplayText")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("data"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),a("p",[t._v("And a Get Address button below the existing Get Balance button:")]),t._v(" "),a("div",{staticClass:"language-jsx extra-class"},[a("pre",{pre:!0,attrs:{class:"language-jsx"}},[a("code",[a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Button")])]),t._v("\n\t"),a("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("title")]),a("span",{pre:!0,attrs:{class:"token attr-value"}},[a("span",{pre:!0,attrs:{class:"token punctuation attr-equals"}},[t._v("=")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v('"')]),t._v("Get Address"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v('"')])]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("style")]),a("span",{pre:!0,attrs:{class:"token script language-javascript"}},[a("span",{pre:!0,attrs:{class:"token script-punctuation punctuation"}},[t._v("=")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("styles"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("methodButton"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("onPress")]),a("span",{pre:!0,attrs:{class:"token script language-javascript"}},[a("span",{pre:!0,attrs:{class:"token script-punctuation punctuation"}},[t._v("=")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("getAddress"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("/>")])]),t._v("\n")])])]),a("p",[t._v("We should now have the following, and Get Address will be able to display a new address.")]),t._v(" "),a("img",{staticStyle:{display:"block",margin:"0px auto",zoom:"50%"},attrs:{src:s(373)}}),t._v(" "),a("p",[t._v("Now that we are able to generate a receive address we can get some testnet bitcoin from one of the public "),a("a",{attrs:{href:"https://coinfaucet.eu/en/btc-testnet/",target:"_blank",rel:"noopener noreferrer"}},[t._v("testnet faucets"),a("OutboundLink")],1)]),t._v(" "),a("p",[t._v("After we send and after the transaction is confirmed we will need to sync the wallet before we can see the new balance from the received transaction.")]),t._v(" "),a("h2",{attrs:{id:"restoring-wallet"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#restoring-wallet"}},[t._v("#")]),t._v(" Restoring wallet")]),t._v(" "),a("p",[t._v("The "),a("code",[t._v("createWallet")]),t._v(" method creates a wallet using a "),a("code",[t._v("mnemonic")]),t._v(", in order to restore we can use the same method, we won't need to call "),a("code",[t._v("generateMnemonic")]),t._v(" as we will already have a "),a("code",[t._v("mnemonic")]),t._v(" to restore with.")]),t._v(" "),a("p",[t._v("Let's add an input box to enter our own "),a("code",[t._v("mnemonic")]),t._v(", we will use the "),a("code",[t._v("mnemonic")]),t._v(" entered in the input box to create a wallet.")]),t._v(" "),a("p",[t._v("Let's add an input box for "),a("code",[t._v("mnemonic")]),t._v(" below the Generate Mnemonic button.")]),t._v(" "),a("div",{staticClass:"language-jsx extra-class"},[a("pre",{pre:!0,attrs:{class:"language-jsx"}},[a("code",[a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("TextInput")])]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("style")]),a("span",{pre:!0,attrs:{class:"token script language-javascript"}},[a("span",{pre:!0,attrs:{class:"token script-punctuation punctuation"}},[t._v("=")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("styles"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("input"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("multiline")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("value")]),a("span",{pre:!0,attrs:{class:"token script language-javascript"}},[a("span",{pre:!0,attrs:{class:"token script-punctuation punctuation"}},[t._v("=")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("mnemonic"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("onChangeText")]),a("span",{pre:!0,attrs:{class:"token script language-javascript"}},[a("span",{pre:!0,attrs:{class:"token script-punctuation punctuation"}},[t._v("=")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("setMnemonic"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("textAlignVertical")]),a("span",{pre:!0,attrs:{class:"token attr-value"}},[a("span",{pre:!0,attrs:{class:"token punctuation attr-equals"}},[t._v("=")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v('"')]),t._v("top"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v('"')])]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("/>")])]),t._v("\n")])])]),a("p",[t._v("This code will also display the mnemonic state variable in the input box, if we click Generate Mnemonic the generated mnemonic will show up in the input box. We can overwrite it with our own mnemonic and doing so will also overwrite the mnemonic state variable. This way the mnemonic displayed will be the one used to create the wallet.")]),t._v(" "),a("p",[t._v("we are already using the mnemonic state variable in the "),a("code",[t._v("createWallet")]),t._v(" Method so no other changes are required.")]),t._v(" "),a("p",[t._v("We can now use our own mnemonic and use it to restore a wallet. This will come in handy if we have a wallet with testnet bitcoin as these are hard to come by.")]),t._v(" "),a("img",{staticStyle:{display:"block",margin:"0px auto",zoom:"50%"},attrs:{src:s(374)}}),t._v(" "),a("h2",{attrs:{id:"sending-bitcoin"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#sending-bitcoin"}},[t._v("#")]),t._v(" Sending bitcoin")]),t._v(" "),a("p",[t._v("We are now able to receive bitcoin, time to add functionality to send as well.")]),t._v(" "),a("p",[a("code",[t._v("bdk-rn")]),t._v(" has a number of transaction-related methods to enable varied use cases. A new send transaction can be created and broadcast using "),a("a",{attrs:{href:"https://github.com/LtbLightning/bdk-rn#quicksend",target:"_blank",rel:"noopener noreferrer"}},[t._v("quickSend()"),a("OutboundLink")],1),t._v(". If required an unsigned transaction can be created using "),a("a",{attrs:{href:"https://github.com/LtbLightning/bdk-rn#createtransaction",target:"_blank",rel:"noopener noreferrer"}},[t._v("createTransaction()"),a("OutboundLink")],1),t._v(" , this can be signed later with "),a("a",{attrs:{href:"https://github.com/LtbLightning/bdk-rn#signtransaction",target:"_blank",rel:"noopener noreferrer"}},[t._v("signTransactioin()"),a("OutboundLink")],1),t._v(" method and broadcast using "),a("a",{attrs:{href:"https://github.com/LtbLightning/bdk-rn#broadcasttransaction",target:"_blank",rel:"noopener noreferrer"}},[t._v("broadcastTransaction()"),a("OutboundLink")],1),t._v(". There are also methods to query transactions by pending or confirmed status and all transactions. Please refer to "),a("code",[t._v("bdk-rn")]),t._v(" "),a("a",{attrs:{href:"https://github.com/LtbLightning/bdk-rn/blob/main/README.md#gettransactions",target:"_blank",rel:"noopener noreferrer"}},[t._v("readme"),a("OutboundLink")],1),t._v(" for more details on all the methods.")]),t._v(" "),a("p",[t._v("We will need state variables for recipient address and amount as well as for transaction, these can be added below our existing variables for syncResponse and address")]),t._v(" "),a("div",{staticClass:"language-javascript extra-class"},[a("pre",{pre:!0,attrs:{class:"language-javascript"}},[a("code",[t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("syncResponse"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" setSyncResponse"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("useState")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("address"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" setAddress"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("useState")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("transaction"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" setTransaction"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("useState")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("recipient"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" setRecipient"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("useState")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token string"}},[t._v("''")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("amount"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" setAmount"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("useState")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),a("p",[t._v("A click event handler for send button, we will use the "),a("a",{attrs:{href:"https://github.com/LtbLightning/bdk-rn#quicksend",target:"_blank",rel:"noopener noreferrer"}},[a("code",[t._v("quickSend()")]),a("OutboundLink")],1),t._v(" method to send specified amount in sats to address.")]),t._v(" "),a("div",{staticClass:"language-javascript extra-class"},[a("pre",{pre:!0,attrs:{class:"language-javascript"}},[a("code",[t._v("\t"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function-variable function"}},[t._v("sendTx")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("async")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" data "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" BdkRn"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("quickSend")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("address")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" recipient"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("amount")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" amount"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("setTransaction")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("data"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("setDisplayText")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token constant"}},[t._v("JSON")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("stringify")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("data"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),a("p",[t._v("Add a new section for send transaction functionality. We will need an input box for the receiver address and an input box for the amount to send. We will also need a button to trigger the transaction.")]),t._v(" "),a("p",[t._v("Let's add the send transaction section and UI components below "),a("code",[t._v("{/* input boxes and send transaction button */}")])]),t._v(" "),a("div",{staticClass:"language-jsx extra-class"},[a("pre",{pre:!0,attrs:{class:"language-jsx"}},[a("code",[t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("/* input boxes and send transaction button */")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("View")])]),t._v(" "),a("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("style")]),a("span",{pre:!0,attrs:{class:"token script language-javascript"}},[a("span",{pre:!0,attrs:{class:"token script-punctuation punctuation"}},[t._v("=")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("styles"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("sendSection"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),a("span",{pre:!0,attrs:{class:"token plain-text"}},[t._v("\n ")]),a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Fragment")])]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),a("span",{pre:!0,attrs:{class:"token plain-text"}},[t._v("\n ")]),a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("TextInput")])]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("style")]),a("span",{pre:!0,attrs:{class:"token script language-javascript"}},[a("span",{pre:!0,attrs:{class:"token script-punctuation punctuation"}},[t._v("=")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("styles"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("input"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("placeholder")]),a("span",{pre:!0,attrs:{class:"token attr-value"}},[a("span",{pre:!0,attrs:{class:"token punctuation attr-equals"}},[t._v("=")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v('"')]),t._v("Recipient Address"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v('"')])]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("onChangeText")]),a("span",{pre:!0,attrs:{class:"token script language-javascript"}},[a("span",{pre:!0,attrs:{class:"token script-punctuation punctuation"}},[t._v("=")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("setRecipient"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("/>")])]),a("span",{pre:!0,attrs:{class:"token plain-text"}},[t._v("\n ")]),a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("TextInput")])]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("style")]),a("span",{pre:!0,attrs:{class:"token script language-javascript"}},[a("span",{pre:!0,attrs:{class:"token script-punctuation punctuation"}},[t._v("=")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("styles"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("input"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("placeholder")]),a("span",{pre:!0,attrs:{class:"token attr-value"}},[a("span",{pre:!0,attrs:{class:"token punctuation attr-equals"}},[t._v("=")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v('"')]),t._v("Amount (in sats)"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v('"')])]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("onChangeText")]),a("span",{pre:!0,attrs:{class:"token script language-javascript"}},[a("span",{pre:!0,attrs:{class:"token script-punctuation punctuation"}},[t._v("=")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),a("span",{pre:!0,attrs:{class:"token parameter"}},[t._v("e")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("setAmount")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("parseInt")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("e"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("/>")])]),a("span",{pre:!0,attrs:{class:"token plain-text"}},[t._v("\n ")]),a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Button")])]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("title")]),a("span",{pre:!0,attrs:{class:"token attr-value"}},[a("span",{pre:!0,attrs:{class:"token punctuation attr-equals"}},[t._v("=")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v('"')]),t._v("Send Transaction"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v('"')])]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("style")]),a("span",{pre:!0,attrs:{class:"token script language-javascript"}},[a("span",{pre:!0,attrs:{class:"token script-punctuation punctuation"}},[t._v("=")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("styles"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("methodButton"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("onPress")]),a("span",{pre:!0,attrs:{class:"token script language-javascript"}},[a("span",{pre:!0,attrs:{class:"token script-punctuation punctuation"}},[t._v("=")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("sendTx"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("/>")])]),a("span",{pre:!0,attrs:{class:"token plain-text"}},[t._v("\n ")]),a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("")])]),a("span",{pre:!0,attrs:{class:"token plain-text"}},[t._v("\n ")]),a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("")])]),t._v("\n")])])]),a("p",[t._v("We should now be able to send a transaction as long as there is sufficient balance.")]),t._v(" "),a("img",{staticStyle:{display:"block",margin:"0px auto",zoom:"50%"},attrs:{src:s(375)}}),t._v(" "),a("h2",{attrs:{id:"conclusion"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#conclusion"}},[t._v("#")]),t._v(" Conclusion")]),t._v(" "),a("p",[t._v("The App we created can be built and distributed for both iOS and Android thus sharing a code base and reducing development time. The development and coding focused on application-level code for use cases and we did not have to code intricate internal bitcoin protocol-level code or bitcoin node interactions, and transactions. UTXOs and sync-related functionalities were also not required. All this was managed by "),a("code",[t._v("bdk-rn")]),t._v(" allowing us to focus on the product, functionality and user journey. This is how "),a("code",[t._v("bdk")]),t._v(" and "),a("code",[t._v("bdk-rn")]),t._v(" intend to make Rapid Bitcoin Application Development possible by allowing product and application developers to focus on what they know best while "),a("code",[t._v("bdk")]),t._v(" handles bitcoin complexity.")]),t._v(" "),a("p",[a("code",[t._v("bdk-rn")]),t._v(" intends to expose functionality and APIs from "),a("code",[t._v("bdk")]),t._v(" which has a wide variety of API with granular details allowing for many interesting use cases to be implemented. "),a("code",[t._v("bdk-rn")]),t._v(" and "),a("code",[t._v("bdk")]),t._v(" are constantly updated and enhanced based on feedback from product teams and developers in the bitcoin community.")]),t._v(" "),a("p",[t._v("Stay tuned for more APIs and enhancements coming to "),a("code",[t._v("bdk-rn")]),t._v(" in the near future. Feature and API requests are most welcome. New blogs and tutorials will be published soon for a more in-depth exploration of bdk-rn.")]),t._v(" "),a("p",[t._v("In the meantime keep in touch with the project by following on "),a("a",{attrs:{href:"https://github.com/LtbLightning/bdk-rn",target:"_blank",rel:"noopener noreferrer"}},[t._v("GitHub"),a("OutboundLink")],1),t._v(" and "),a("a",{attrs:{href:"https://twitter.com/BitcoinZavior",target:"_blank",rel:"noopener noreferrer"}},[t._v("Twitter"),a("OutboundLink")],1)]),t._v(" "),a("h4",{attrs:{id:"references"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#references"}},[t._v("#")]),t._v(" References:")]),t._v(" "),a("ul",[a("li",[a("a",{attrs:{href:"https://github.com/bitcoindevkit",target:"_blank",rel:"noopener noreferrer"}},[t._v("bdk"),a("OutboundLink")],1)]),t._v(" "),a("li",[a("a",{attrs:{href:"https://github.com/LtbLightning/bdk-rn",target:"_blank",rel:"noopener noreferrer"}},[t._v("bdk-rn"),a("OutboundLink")],1)]),t._v(" "),a("li",[a("a",{attrs:{href:"https://www.youtube.com/watch?v=gMpWA875go4",target:"_blank",rel:"noopener noreferrer"}},[t._v("Bitcoin Developers YouTube"),a("OutboundLink")],1)]),t._v(" "),a("li",[a("a",{attrs:{href:"https://github.com/LtbLightning/BdkRnQuickStart",target:"_blank",rel:"noopener noreferrer"}},[t._v("BdkRnQuickStart App GitHub Repository"),a("OutboundLink")],1)]),t._v(" "),a("li",[a("a",{attrs:{href:"https://reactnative.dev/docs/environment-setup",target:"_blank",rel:"noopener noreferrer"}},[t._v("Setup React Native Development Environment"),a("OutboundLink")],1)]),t._v(" "),a("li",[a("a",{attrs:{href:"https://github.com/bitcoinbook/bitcoinbook/blob/develop/ch04.asciidoc",target:"_blank",rel:"noopener noreferrer"}},[t._v("Mastering Bitcoin(HD Wallet chapter)"),a("OutboundLink")],1)]),t._v(" "),a("li",[a("a",{attrs:{href:"https://github.com/bitcoin/bitcoin/blob/master/doc/descriptors.md",target:"_blank",rel:"noopener noreferrer"}},[t._v("Bitcoin Output Descriptors from bitcoin GitHub"),a("OutboundLink")],1)]),t._v(" "),a("li",[t._v("Testnet Faucet: "),a("a",{attrs:{href:"https://coinfaucet.eu/en/btc-testnet/",target:"_blank",rel:"noopener noreferrer"}},[t._v("https://coinfaucet.eu/en/btc-testnet/"),a("OutboundLink")],1),t._v(" or "),a("a",{attrs:{href:"https://bitcoinfaucet.uo1.net",target:"_blank",rel:"noopener noreferrer"}},[t._v("https://bitcoinfaucet.uo1.net"),a("OutboundLink")],1)])])])}),[],!1,null,null,null);a.default=e.exports}}]); \ No newline at end of file +(window.webpackJsonp=window.webpackJsonp||[]).push([[21],{355:function(t,a,s){t.exports=s.p+"assets/img/bdk_rn_complete_app.e382f61c.png"},356:function(t,a,s){t.exports=s.p+"assets/img/default_rn_app.9e60b4fb.png"},357:function(t,a,s){t.exports=s.p+"assets/img/folder_structure.d1c95bd6.png"},358:function(t,a,s){t.exports=s.p+"assets/img/bdk_rn_title.289f266d.png"},359:function(t,a,s){t.exports=s.p+"assets/img/bdk_rn_tutorial_screen_mnemonic.9963c418.png"},360:function(t,a,s){t.exports=s.p+"assets/img/bdk_rn_tutorial_screen_createwallet.916f2610.png"},361:function(t,a,s){t.exports=s.p+"assets/img/bdk_rn_get_balance.75af17bf.png"},362:function(t,a,s){t.exports=s.p+"assets/img/bdk_rn_get_address.4f570fb2.png"},363:function(t,a,s){t.exports=s.p+"assets/img/bdk_rn_get_restore.134b3681.png"},364:function(t,a,s){t.exports=s.p+"assets/img/bdk_rn_send.4e9dbc4a.png"},409:function(t,a,s){"use strict";s.r(a);var n=s(7),e=Object(n.a)({},(function(){var t=this,a=t._self._c;return a("ContentSlotsDistributor",{attrs:{"slot-key":t.$parent.slotKey}},[a("h2",{attrs:{id:"introduction"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#introduction"}},[t._v("#")]),t._v(" Introduction")]),t._v(" "),a("p",[a("code",[t._v("bdk-rn")]),t._v(" is the "),a("strong",[t._v("Bitcoin Dev kit")]),t._v("'s "),a("strong",[t._v("React Native")]),t._v(" library which enables building bitcoin applications for Android and iOS mobile platforms. Using "),a("code",[t._v("bdk-rn")]),t._v(" does not require knowledge of the underlying bitcoin or BDK API. Using "),a("code",[t._v("bdk-rn")]),t._v(" is similar to using any other RN module. Just do "),a("code",[t._v("yarn add bdk-rn")]),t._v(" and you are ready to code! This is the first tutorial on how to use "),a("code",[t._v("bdk-rn")]),t._v(", more coming soon, make sure to "),a("a",{attrs:{href:"https://twitter.com/BitcoinZavior?ref_src=twsrc%5Etfw",target:"_blank",rel:"noopener noreferrer"}},[t._v("follow"),a("OutboundLink")],1),t._v(" to be notified of new ones. In case you missed it, there is a recorded "),a("code",[t._v("bdk-rn")]),t._v(" focused Twitch Livestream available on the "),a("a",{attrs:{href:"https://www.youtube.com/watch?v=gMpWA875go4",target:"_blank",rel:"noopener noreferrer"}},[t._v("Bitcoin Developers"),a("OutboundLink")],1),t._v(" YouTube channel which covers most of this article, make sure to subscribe to Bitcoin Developers "),a("a",{attrs:{href:"https://www.youtube.com/channel/UCUq_ZdezVWKPvkWRicAYxLA/videos",target:"_blank",rel:"noopener noreferrer"}},[t._v("YouTube Channel"),a("OutboundLink")],1),t._v(" for more bitcoin development videos.")]),t._v(" "),a("p",[t._v("In this tutorial, we will explore "),a("code",[t._v("bdk-rn")]),t._v(" usage and the API it provides. This guide will walk through the development process and code for making a bitcoin application. The bitcoin application we create will be a non-custodial HD Wallet. The application will have the functionality to create a new wallet or restore from a known mnemonic seed phrase. This application will also be able to interact with the bitcoin network to sync UTXOs from new blocks and broadcast transactions.")]),t._v(" "),a("p",[t._v("The tutorial will focus on bitcoin and "),a("code",[t._v("bdk-rn")]),t._v(" concepts and API. So it will gloss over React Native aspects. The code for this tutorial is available on the "),a("a",{attrs:{href:"https://github.com/LtbLightning/BdkRnQuickStart",target:"_blank",rel:"noopener noreferrer"}},[t._v("LtbLightning GitHub"),a("OutboundLink")],1)]),t._v(" "),a("img",{staticStyle:{display:"block",margin:"0 auto",zoom:"50%"},attrs:{src:s(355),alt:"BDK RN Quick Start"}}),t._v(" "),a("h3",{attrs:{id:"prerequisites"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#prerequisites"}},[t._v("#")]),t._v(" Prerequisites")]),t._v(" "),a("p",[t._v("In order to use "),a("code",[t._v("bdk-rn")]),t._v(" in a React Native App, a React Native development environment is required. Please refer to resources out there on the internet if you need to set this up, here is one of many good resources to guide you on "),a("a",{attrs:{href:"https://reactnative.dev/docs/environment-setup",target:"_blank",rel:"noopener noreferrer"}},[t._v("environment setup"),a("OutboundLink")],1)]),t._v(" "),a("h3",{attrs:{id:"bitcoin-basics"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#bitcoin-basics"}},[t._v("#")]),t._v(" Bitcoin Basics")]),t._v(" "),a("p",[t._v("The bitcoin concepts used in this blog post are detailed and explained very well in external bitcoin resources. Here are some links for reference:")]),t._v(" "),a("p",[a("a",{attrs:{href:"https://github.com/bitcoinbook/bitcoinbook/blob/develop/ch04.asciidoc",target:"_blank",rel:"noopener noreferrer"}},[t._v("Mastering Bitcoin(HD Wallet chapter)"),a("OutboundLink")],1)]),t._v(" "),a("p",[a("a",{attrs:{href:"https://github.com/bitcoin/bitcoin/blob/master/doc/descriptors.md",target:"_blank",rel:"noopener noreferrer"}},[t._v("Bitcoin Output Descriptors from bitcoin GitHub"),a("OutboundLink")],1)]),t._v(" "),a("p",[t._v("Now let's jump into Bitcoin Dev Kit")]),t._v(" "),a("h2",{attrs:{id:"bitcoin-dev-kit-and-bdk-rn"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#bitcoin-dev-kit-and-bdk-rn"}},[t._v("#")]),t._v(" Bitcoin Dev Kit and bdk-rn")]),t._v(" "),a("p",[a("code",[t._v("bdk-rn")]),t._v(" is a React Native library of Bitcoin Dev Kit(BDK) for building React Native Apps.\nIt encapsulates all of the low-level APIs and methods for BDK and exposes them in a react native context. To use BDK in React Native(RN) apps only the "),a("code",[t._v("bdk-rn")]),t._v(" module is required. "),a("code",[t._v("Bdk-rn")]),t._v(" can be used like any other react native library and is available on "),a("a",{attrs:{href:"https://www.npmjs.com/package/bdk-rn",target:"_blank",rel:"noopener noreferrer"}},[t._v("public package managers(npm and yarn)"),a("OutboundLink")],1),t._v(".")]),t._v(" "),a("h2",{attrs:{id:"getting-started"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#getting-started"}},[t._v("#")]),t._v(" Getting Started")]),t._v(" "),a("p",[t._v("Although we won't delve deep into RN we will focus more on bitcoin and bdk-rn, however, some rudimentary RN setup is required, especially a basic RN app to add our code.")]),t._v(" "),a("p",[t._v("start by creating a new RN project.")]),t._v(" "),a("p",[a("code",[t._v("npx react-native init BdkRnQuickStart")])]),t._v(" "),a("p",[t._v("If this fails in an error on an M1/M2 Mac please use\n"),a("code",[t._v("arch -x86_64 pod install --repo-update")])]),t._v(" "),a("p",[t._v("Once done "),a("code",[t._v("cd")]),t._v(" into the new project directory and run the basic RN app that's created")]),t._v(" "),a("div",{staticClass:"language-shell extra-class"},[a("pre",{pre:!0,attrs:{class:"language-shell"}},[a("code",[a("span",{pre:!0,attrs:{class:"token builtin class-name"}},[t._v("cd")]),t._v(" BdkRnQuickStart\n"),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("yarn")]),t._v(" ios\n")])])]),a("p",[t._v("This should start building the app and launch the app in a simulator. So far we have created a basic RN project if this doesn't work then refer to the React Native development setup guide to troubleshoot.")]),t._v(" "),a("img",{staticStyle:{display:"block",margin:"0 auto",zoom:"25%"},attrs:{src:s(356)}}),t._v(" "),a("h2",{attrs:{id:"setting-up-styles-and-rn-app-structure"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#setting-up-styles-and-rn-app-structure"}},[t._v("#")]),t._v(" Setting up styles and RN app structure")]),t._v(" "),a("p",[t._v("Let's set up a very basic app structure and some RN scaffolding. Let's create an "),a("code",[t._v("src")]),t._v(" folder in the project root and inside it add new folders for "),a("code",[t._v("assets")]),t._v(", "),a("code",[t._v("elements")]),t._v(", "),a("code",[t._v("screens")]),t._v(" and "),a("code",[t._v("styles")])]),t._v(" "),a("p",[t._v("To make this quick you can download the styles and images used in the tutorial from the repository. The image assets, "),a("code",[t._v("Button.tsx")]),t._v(" and "),a("code",[t._v("styles.js")]),t._v(" can be taken from "),a("a",{attrs:{href:"https://github.com/LtbLightning/BdkRnQuickStart/tree/master/src",target:"_blank",rel:"noopener noreferrer"}},[t._v("here"),a("OutboundLink")],1),t._v(" and moved to the folders as shown. Alternatively, you can write your own styles and use your own images if you intend to style the app in a different way.")]),t._v(" "),a("p",[t._v("Create a "),a("code",[t._v("home.js")]),t._v(" file under "),a("code",[t._v("screens")]),t._v(" folder, this will be where we will be adding most of the code.")]),t._v(" "),a("p",[t._v("Once done the project structure should look like this:")]),t._v(" "),a("img",{staticStyle:{display:"block",margin:"0px auto",zoom:"67%"},attrs:{src:s(357)}}),t._v(" "),a("p",[t._v("Locate "),a("code",[t._v("App.js")]),t._v(" in the project root, this will have the default code added by "),a("code",[t._v("react-native init")]),t._v(", let's delete all contents of "),a("code",[t._v("App.js")]),t._v(" and replace it with code to import "),a("code",[t._v("home.js")]),t._v(" as our main screen.")]),t._v(" "),a("div",{staticClass:"language-javascript extra-class"},[a("pre",{pre:!0,attrs:{class:"language-javascript"}},[a("code",[a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// App.js ")]),t._v("\n\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("import")]),t._v(" React "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("from")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[t._v("'react'")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("import")]),t._v(" Home "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("from")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[t._v("'./src/screens/home'")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function-variable function"}},[t._v("App")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),t._v("Home "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("/")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("export")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("default")]),t._v(" App"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),a("p",[t._v("This will probably crash your app in the simulator but that's fine, it will be fixed in the next step.")]),t._v(" "),a("h2",{attrs:{id:"installing-bdk-rn"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#installing-bdk-rn"}},[t._v("#")]),t._v(" Installing "),a("code",[t._v("bdk-rn")])]),t._v(" "),a("p",[t._v("With the RN app project in place, we can now add "),a("code",[t._v("bdk-rn")]),t._v(" using either npm or yarn.")]),t._v(" "),a("p",[t._v("Using npm:")]),t._v(" "),a("div",{staticClass:"language-shell extra-class"},[a("pre",{pre:!0,attrs:{class:"language-shell"}},[a("code",[a("span",{pre:!0,attrs:{class:"token function"}},[t._v("npm")]),t._v(" i "),a("span",{pre:!0,attrs:{class:"token parameter variable"}},[t._v("--save")]),t._v(" bdk-rn\n")])])]),a("p",[t._v("Using yarn:")]),t._v(" "),a("div",{staticClass:"language-shell extra-class"},[a("pre",{pre:!0,attrs:{class:"language-shell"}},[a("code",[a("span",{pre:!0,attrs:{class:"token function"}},[t._v("yarn")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("add")]),t._v(" bdk-rn\n")])])]),a("p",[t._v("[iOS Only] Install pods:")]),t._v(" "),a("div",{staticClass:"language-shell extra-class"},[a("pre",{pre:!0,attrs:{class:"language-shell"}},[a("code",[t._v("npx pod-install\nor\n"),a("span",{pre:!0,attrs:{class:"token builtin class-name"}},[t._v("cd")]),t._v(" ios "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&&")]),t._v(" pod "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("install")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&&")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token builtin class-name"}},[t._v("cd")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("..")]),t._v("\n")])])]),a("p",[t._v("Verify that "),a("code",[t._v("bdk-rn")]),t._v(" has been added to "),a("code",[t._v("package.json")]),t._v(", once done "),a("code",[t._v("bdk-rn")]),t._v(" is installed and ready to be used in our "),a("strong",[t._v("BdkRnQuickStart")]),t._v(" App.")]),t._v(" "),a("h2",{attrs:{id:"importing-bdk-rn"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#importing-bdk-rn"}},[t._v("#")]),t._v(" Importing "),a("code",[t._v("bdk-rn")])]),t._v(" "),a("p",[t._v("Locate "),a("code",[t._v("home.js")]),t._v(" which we added in the setup section and import "),a("code",[t._v("bdk-rn")]),t._v(" and also create an RN functional component.")]),t._v(" "),a("div",{staticClass:"language-javascript extra-class"},[a("pre",{pre:!0,attrs:{class:"language-javascript"}},[a("code",[a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// screens/home.js")]),t._v("\n\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("import")]),t._v(" BdkRn "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("from")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[t._v("'bdk-rn'")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function-variable function"}},[t._v("Home")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("export")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("default")]),t._v(" Home"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),a("p",[t._v("Before we start using "),a("code",[t._v("bdk-rn")]),t._v(" let's add some additional RN component imports, as well as import styles, a button and image assets to create a basic layout to build our home screen.")]),t._v(" "),a("div",{staticClass:"language-jsx extra-class"},[a("pre",{pre:!0,attrs:{class:"language-jsx"}},[a("code",[a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// screens/home.js")]),t._v("\n\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("import")]),t._v(" BdkRn "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("from")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[t._v("'bdk-rn'")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("import")]),t._v(" React"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" Fragment"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" useState "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("from")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[t._v("'react'")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("import")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n ActivityIndicator"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n SafeAreaView"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n ScrollView"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n StatusBar"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n Text"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n TextInput"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n View"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n Image"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("from")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[t._v("'react-native'")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("import")]),t._v(" Button "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("from")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[t._v("'../elements/Button'")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("import")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" styles "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("from")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[t._v("'../styles/styles'")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" bitcoinLogo "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("require")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token string"}},[t._v("'../assets/bitcoin_logo.png'")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" bdkLogo "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("require")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token string"}},[t._v("'../assets/bdk_logo.png'")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function-variable function"}},[t._v("Home")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// BDK-RN method calls and state variables will be added here")]),t._v("\n\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("SafeAreaView")])]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),a("span",{pre:!0,attrs:{class:"token plain-text"}},[t._v("\n ")]),a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("StatusBar")])]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("/>")])]),a("span",{pre:!0,attrs:{class:"token plain-text"}},[t._v("\n ")]),a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("ScrollView")])]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("contentInsetAdjustmentBehavior")]),a("span",{pre:!0,attrs:{class:"token attr-value"}},[a("span",{pre:!0,attrs:{class:"token punctuation attr-equals"}},[t._v("=")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v('"')]),t._v("automatic"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v('"')])]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("contentContainerStyle")]),a("span",{pre:!0,attrs:{class:"token script language-javascript"}},[a("span",{pre:!0,attrs:{class:"token script-punctuation punctuation"}},[t._v("=")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("styles"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("container"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),a("span",{pre:!0,attrs:{class:"token plain-text"}},[t._v("\n ")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("/* Header */")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token plain-text"}},[t._v("\n ")]),a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("View")])]),t._v(" "),a("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("style")]),a("span",{pre:!0,attrs:{class:"token script language-javascript"}},[a("span",{pre:!0,attrs:{class:"token script-punctuation punctuation"}},[t._v("=")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("styles"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("headerSection"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),a("span",{pre:!0,attrs:{class:"token plain-text"}},[t._v("\n ")]),a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Image")])]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("style")]),a("span",{pre:!0,attrs:{class:"token script language-javascript"}},[a("span",{pre:!0,attrs:{class:"token script-punctuation punctuation"}},[t._v("=")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("resizeMode")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[t._v("'stretch'")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("height")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("36")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("width")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("36")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("source")]),a("span",{pre:!0,attrs:{class:"token script language-javascript"}},[a("span",{pre:!0,attrs:{class:"token script-punctuation punctuation"}},[t._v("=")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("bitcoinLogo"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("/>")])]),a("span",{pre:!0,attrs:{class:"token plain-text"}},[t._v("\n ")]),a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Text")])]),t._v(" "),a("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("style")]),a("span",{pre:!0,attrs:{class:"token script language-javascript"}},[a("span",{pre:!0,attrs:{class:"token script-punctuation punctuation"}},[t._v("=")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("styles"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("headerText"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),a("span",{pre:!0,attrs:{class:"token plain-text"}},[t._v("BDK-RN Tutorial")]),a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("")])]),a("span",{pre:!0,attrs:{class:"token plain-text"}},[t._v("\n ")]),a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Image")])]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("style")]),a("span",{pre:!0,attrs:{class:"token script language-javascript"}},[a("span",{pre:!0,attrs:{class:"token script-punctuation punctuation"}},[t._v("=")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("resizeMode")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[t._v("'center'")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("height")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("40")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("width")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("25")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("source")]),a("span",{pre:!0,attrs:{class:"token script language-javascript"}},[a("span",{pre:!0,attrs:{class:"token script-punctuation punctuation"}},[t._v("=")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("bdkLogo"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("/>")])]),a("span",{pre:!0,attrs:{class:"token plain-text"}},[t._v("\n ")]),a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("")])]),a("span",{pre:!0,attrs:{class:"token plain-text"}},[t._v("\n\n ")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("/* Balance */")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token plain-text"}},[t._v("\n\n ")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("/* method call result */")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token plain-text"}},[t._v("\n\n ")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("/* buttons for method calls */")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token plain-text"}},[t._v("\n\n ")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("/* input boxes and send transaction button */")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token plain-text"}},[t._v("\n\n ")]),a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("")])]),a("span",{pre:!0,attrs:{class:"token plain-text"}},[t._v("\n ")]),a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("")])]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("export")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("default")]),t._v(" Home"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),a("p",[t._v("We now have an app title section and a structure to hold the rest of our app components.")]),t._v(" "),a("img",{staticStyle:{display:"block",margin:"0 auto",zoom:"33%"},attrs:{src:s(358)}}),t._v(" "),a("h2",{attrs:{id:"calling-bdk-rn-methods"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#calling-bdk-rn-methods"}},[t._v("#")]),t._v(" Calling "),a("code",[t._v("bdk-rn")]),t._v(" methods")]),t._v(" "),a("p",[t._v("All "),a("code",[t._v("bdk-rn")]),t._v(" methods return a JSON response with data and error properties. All methods return a response as follows:")]),t._v(" "),a("div",{staticClass:"language-javascript extra-class"},[a("pre",{pre:!0,attrs:{class:"language-javascript"}},[a("code",[t._v("Promise"),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),t._v("Response"),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("error")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token boolean"}},[t._v("true")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("|")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token boolean"}},[t._v("false")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// success returns true else false.")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("data")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" string "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("|")]),t._v(" object "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("|")]),t._v(" any"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// output data for the method call.")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),a("p",[t._v("The first step in creating a non-custodial bitcoin app is creating a mnemonic seed phrase for the wallet.")]),t._v(" "),a("p",[a("code",[t._v("bdk-rn")]),t._v(" provides "),a("code",[t._v("generateMnemonic()")]),t._v(" method to create a default 12 word length mnemonic.")]),t._v(" "),a("div",{staticClass:"language-javascript extra-class"},[a("pre",{pre:!0,attrs:{class:"language-javascript"}},[a("code",[a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("import")]),t._v(" BdkRn "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("from")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[t._v("'bdk-rn'")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" response "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" BdkRn"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("generateMnemonic")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" mnemonic "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" response"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("data"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),a("p",[t._v("We can specify a longer length or we can also specify the bits of entropy we need by passing the length or entropy arguments.")]),t._v(" "),a("p",[t._v("To create a mnemonic with an entropy of 256 bits, which will be a 24-word length mnemonic sentence, we can use "),a("code",[t._v("{ entropy: 256 }")]),t._v(".\nRefer to the readme file on "),a("a",{attrs:{href:"https://github.com/LtbLightning/bdk-rn#generatemnemomic",target:"_blank",rel:"noopener noreferrer"}},[t._v("GitHub"),a("OutboundLink")],1),t._v(" for more details.")]),t._v(" "),a("div",{staticClass:"language-javascript extra-class"},[a("pre",{pre:!0,attrs:{class:"language-javascript"}},[a("code",[a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),a("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("data")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" mnemonic"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" BdkRn"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("generateMnemonic")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("entropy")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("256")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// here data is destructured and saved as 'mnemonic'")]),t._v("\n")])])]),a("p",[t._v("In order to use this in our RN app let's create a state variable to store the mnemonic and internal "),a("code",[t._v("generateMnemonic")]),t._v(" method which we can invoke when a button is clicked. We will also need a button which will invoke generateMnemonic when clicked. Adding the following code achieves all of this.")]),t._v(" "),a("div",{staticClass:"language-jsx extra-class"},[a("pre",{pre:!0,attrs:{class:"language-jsx"}},[a("code",[a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// screens/home.js")]),t._v("\n\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function-variable function"}},[t._v("Home")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// BDK-RN method calls and state variables will be added here")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// state variable to store and set mnemonic")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("mnemonic"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" setMnemonic"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("useState")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token string"}},[t._v("''")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// internal method to call bdk-rn to generate mnemonic")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function-variable function"}},[t._v("getMnemonic")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("async")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n\t\t"),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// call bdk-rn to generate mnemonic")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("data"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" BdkRn"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("generateMnemonic")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("length")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("12")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// save generated mnemonic to state variable")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("setMnemonic")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("data"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("SafeAreaView")])]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),a("span",{pre:!0,attrs:{class:"token plain-text"}},[t._v("\n ")]),a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("StatusBar")])]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("/>")])]),a("span",{pre:!0,attrs:{class:"token plain-text"}},[t._v("\n ")]),a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("ScrollView")])]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("contentInsetAdjustmentBehavior")]),a("span",{pre:!0,attrs:{class:"token attr-value"}},[a("span",{pre:!0,attrs:{class:"token punctuation attr-equals"}},[t._v("=")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v('"')]),t._v("automatic"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v('"')])]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("contentContainerStyle")]),a("span",{pre:!0,attrs:{class:"token script language-javascript"}},[a("span",{pre:!0,attrs:{class:"token script-punctuation punctuation"}},[t._v("=")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("styles"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("container"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),a("span",{pre:!0,attrs:{class:"token plain-text"}},[t._v("\n ")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("/* Header */")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token plain-text"}},[t._v("\n ")]),a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("View")])]),t._v(" "),a("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("style")]),a("span",{pre:!0,attrs:{class:"token script language-javascript"}},[a("span",{pre:!0,attrs:{class:"token script-punctuation punctuation"}},[t._v("=")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("styles"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("headerSection"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),a("span",{pre:!0,attrs:{class:"token plain-text"}},[t._v("\n ")]),a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Image")])]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("style")]),a("span",{pre:!0,attrs:{class:"token script language-javascript"}},[a("span",{pre:!0,attrs:{class:"token script-punctuation punctuation"}},[t._v("=")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("resizeMode")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[t._v("'stretch'")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("height")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("36")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("width")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("36")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("source")]),a("span",{pre:!0,attrs:{class:"token script language-javascript"}},[a("span",{pre:!0,attrs:{class:"token script-punctuation punctuation"}},[t._v("=")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("bitcoinLogo"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("/>")])]),a("span",{pre:!0,attrs:{class:"token plain-text"}},[t._v("\n ")]),a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Text")])]),t._v(" "),a("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("style")]),a("span",{pre:!0,attrs:{class:"token script language-javascript"}},[a("span",{pre:!0,attrs:{class:"token script-punctuation punctuation"}},[t._v("=")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("styles"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("headerText"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),a("span",{pre:!0,attrs:{class:"token plain-text"}},[t._v("BDK-RN Tutorial")]),a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("")])]),a("span",{pre:!0,attrs:{class:"token plain-text"}},[t._v("\n ")]),a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Image")])]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("style")]),a("span",{pre:!0,attrs:{class:"token script language-javascript"}},[a("span",{pre:!0,attrs:{class:"token script-punctuation punctuation"}},[t._v("=")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("resizeMode")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[t._v("'center'")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("height")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("40")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("width")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("25")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("source")]),a("span",{pre:!0,attrs:{class:"token script language-javascript"}},[a("span",{pre:!0,attrs:{class:"token script-punctuation punctuation"}},[t._v("=")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("bdkLogo"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("/>")])]),a("span",{pre:!0,attrs:{class:"token plain-text"}},[t._v("\n ")]),a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("")])]),a("span",{pre:!0,attrs:{class:"token plain-text"}},[t._v("\n\n ")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("/* Balance */")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token plain-text"}},[t._v("\n\n ")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("/* method call result */")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token plain-text"}},[t._v("\n\n ")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("/* buttons for method calls */")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token plain-text"}},[t._v("\n ")]),a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("View")])]),t._v(" "),a("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("style")]),a("span",{pre:!0,attrs:{class:"token script language-javascript"}},[a("span",{pre:!0,attrs:{class:"token script-punctuation punctuation"}},[t._v("=")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("styles"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("methodSection"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),a("span",{pre:!0,attrs:{class:"token plain-text"}},[t._v("\n ")]),a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Button")])]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("title")]),a("span",{pre:!0,attrs:{class:"token attr-value"}},[a("span",{pre:!0,attrs:{class:"token punctuation attr-equals"}},[t._v("=")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v('"')]),t._v("Generate Mnemonic"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v('"')])]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("style")]),a("span",{pre:!0,attrs:{class:"token script language-javascript"}},[a("span",{pre:!0,attrs:{class:"token script-punctuation punctuation"}},[t._v("=")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("styles"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("methodButton"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("onPress")]),a("span",{pre:!0,attrs:{class:"token script language-javascript"}},[a("span",{pre:!0,attrs:{class:"token script-punctuation punctuation"}},[t._v("=")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("getMnemonic"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("/>")])]),a("span",{pre:!0,attrs:{class:"token plain-text"}},[t._v("\n ")]),a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("")])]),a("span",{pre:!0,attrs:{class:"token plain-text"}},[t._v("\n\n ")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("/* input boxes and send transaction button */")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token plain-text"}},[t._v("\n ")]),a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("")])]),a("span",{pre:!0,attrs:{class:"token plain-text"}},[t._v("\n ")]),a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("")])]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),a("p",[t._v("Now we need to add a component to display the output of our method calls and this will also need a state variable to track our method call response. To achieve this add the following code.")]),t._v(" "),a("div",{staticClass:"language-javascript extra-class"},[a("pre",{pre:!0,attrs:{class:"language-javascript"}},[a("code",[a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// screens/home.js")]),t._v("\n\n"),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// add this as another state variable under mnemonic")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("displayText"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" setDisplayText"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("useState")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token string"}},[t._v("''")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// modify the generateMnenomic method to also set mnemonic as displayText")]),t._v("\n\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function-variable function"}},[t._v("getMnemonic")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("async")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("data"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" BdkRn"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("generateMnemonic")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("length")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("12")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("network")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[t._v("'testnet'")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("setMnemonic")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token constant"}},[t._v("JSON")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("stringify")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("data"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("setDisplayText")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token constant"}},[t._v("JSON")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("stringify")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("data"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),a("p",[t._v("and finally, let's add the component to display the output under "),a("code",[t._v("{/* method call result */}")])]),t._v(" "),a("div",{staticClass:"language-jsx extra-class"},[a("pre",{pre:!0,attrs:{class:"language-jsx"}},[a("code",[a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// screens/home.js")]),t._v("\n\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("/* method call result */")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\t"),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// display the component only if displayText has a value")]),t._v("\n\t"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("displayText "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&&")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("View")])]),t._v(" "),a("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("style")]),a("span",{pre:!0,attrs:{class:"token script language-javascript"}},[a("span",{pre:!0,attrs:{class:"token script-punctuation punctuation"}},[t._v("=")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("styles"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("responseSection"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),a("span",{pre:!0,attrs:{class:"token plain-text"}},[t._v("\n ")]),a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Text")])]),t._v(" "),a("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("style")]),a("span",{pre:!0,attrs:{class:"token script language-javascript"}},[a("span",{pre:!0,attrs:{class:"token script-punctuation punctuation"}},[t._v("=")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("styles"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("responseText"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),t._v(" "),a("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("selectable")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),a("span",{pre:!0,attrs:{class:"token plain-text"}},[t._v("\n Response:\n ")]),a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("")])]),a("span",{pre:!0,attrs:{class:"token plain-text"}},[t._v("\n ")]),a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Text")])]),t._v(" "),a("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("selectable")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("displayText"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("")])]),a("span",{pre:!0,attrs:{class:"token plain-text"}},[t._v("\n ")]),a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("")])]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),a("p",[t._v('We should now have a working" Generate Mnemonic" button which displays the new mnemonic')]),t._v(" "),a("img",{staticStyle:{display:"block",margin:"0 auto",zoom:"50%"},attrs:{src:s(359)}}),t._v(" "),a("p",[t._v("A quick recap, we added a button to trigger a call to a method. We created a button click event handler to call bdk-rn. Set the display state variable to display the output of the call in the display section. We will follow this pattern for the remaining calls to bdk-rn.")]),t._v(" "),a("h2",{attrs:{id:"creating-a-wallet"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#creating-a-wallet"}},[t._v("#")]),t._v(" Creating a wallet")]),t._v(" "),a("p",[t._v("Before moving on to creating a wallet, let's add a section at the top to display the balance of the wallet.")]),t._v(" "),a("p",[t._v("To display the balance we will need a state variable to store the balance and a display section to display it.")]),t._v(" "),a("p",[t._v("Under the "),a("code",[t._v("mnemonic")]),t._v(" and "),a("code",[t._v("displayText")]),t._v(" variables, let's add one for "),a("code",[t._v("balance")]),t._v(" as well")]),t._v(" "),a("div",{staticClass:"language-jsx extra-class"},[a("pre",{pre:!0,attrs:{class:"language-jsx"}},[a("code",[t._v("\t"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function-variable function"}},[t._v("Home")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n\t\t"),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// BDK-RN method calls and state variables will be added here")]),t._v("\n \t"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("mnemonic"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" setMnemonic"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("useState")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token string"}},[t._v("''")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n \t"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("displayText"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" setDisplayText"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("useState")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token string"}},[t._v("''")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n \t"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("balance"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" setBalance"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("useState")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),a("p",[t._v("And we will shortly need a "),a("code",[t._v("wallet")]),t._v(" and "),a("code",[t._v("syncResponse")]),t._v(" as well so add these too.")]),t._v(" "),a("div",{staticClass:"language-jsx extra-class"},[a("pre",{pre:!0,attrs:{class:"language-jsx"}},[a("code",[t._v("\t"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function-variable function"}},[t._v("Home")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n\t\t"),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// BDK-RN method calls and state variables will be added here")]),t._v("\n \t"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("mnemonic"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" setMnemonic"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("useState")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token string"}},[t._v("''")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n \t"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("displayText"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" setDisplayText"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("useState")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token string"}},[t._v("''")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n \t"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("balance"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" setBalance"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("useState")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("wallet"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" setWallet"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("useState")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n \t"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("syncResponse"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" setSyncResponse"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("useState")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),a("p",[t._v("Now we need some "),a("code",[t._v("jsx")]),t._v(" code to display the balance.")]),t._v(" "),a("p",[t._v("Just below "),a("code",[t._v("{/* Balance */}")]),t._v(" and above "),a("code",[t._v("{*/ method call result */}")]),t._v(" add the following UI components to display the balance. We only want to show the balance when it has a value so we will use a tertiary operator for a quick check.")]),t._v(" "),a("div",{staticClass:"language-jsx extra-class"},[a("pre",{pre:!0,attrs:{class:"language-jsx"}},[a("code",[t._v("\t\t\t\t"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("/* Balance */")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\t\t\t\t"),a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("View")])]),t._v(" "),a("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("style")]),a("span",{pre:!0,attrs:{class:"token script language-javascript"}},[a("span",{pre:!0,attrs:{class:"token script-punctuation punctuation"}},[t._v("=")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("styles"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("balanceSection"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),a("span",{pre:!0,attrs:{class:"token plain-text"}},[t._v("\n ")]),a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Text")])]),t._v(" "),a("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("style")]),a("span",{pre:!0,attrs:{class:"token script language-javascript"}},[a("span",{pre:!0,attrs:{class:"token script-punctuation punctuation"}},[t._v("=")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("styles"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("balanceText"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),t._v(" "),a("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("selectable")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),a("span",{pre:!0,attrs:{class:"token plain-text"}},[t._v("\n ")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),a("span",{pre:!0,attrs:{class:"token string"}},[t._v("'Balance: '")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token plain-text"}},[t._v("\n ")]),a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("")])]),a("span",{pre:!0,attrs:{class:"token plain-text"}},[t._v("\n ")]),a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Text")])]),t._v(" "),a("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("selectable")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("balance "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("?")]),t._v(" balance "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[t._v("'0'")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token plain-text"}},[t._v(" Sats")]),a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("")])]),a("span",{pre:!0,attrs:{class:"token plain-text"}},[t._v("\n ")]),a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("")])]),t._v("\n\t\t\t\t"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("/* method call result */")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),a("p",[t._v("We will next add code to create a wallet.")]),t._v(" "),a("p",[t._v("To create a wallet the simple approach is to call "),a("code",[t._v("createWallet()")]),t._v(" method with "),a("code",[t._v("mnemonic")]),t._v(" , "),a("code",[t._v("password")]),t._v(" and "),a("code",[t._v("network")]),t._v(".\nLet's add another click event handler below where we have the "),a("code",[t._v("getMnemonic()")]),t._v(" method\nWe want to see the response to this call so let's use "),a("code",[t._v("setDisplayText()")]),t._v(" to see the output")]),t._v(" "),a("div",{staticClass:"language-javascript extra-class"},[a("pre",{pre:!0,attrs:{class:"language-javascript"}},[a("code",[t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function-variable function"}},[t._v("createWallet")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("async")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" data "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" BdkRn"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("createWallet")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("mnemonic")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" mnemonic"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("password")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[t._v("'password'")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("network")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[t._v("'testnet'")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("setWallet")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("data"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("setDisplayText")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token constant"}},[t._v("JSON")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("stringify")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("data"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),a("p",[t._v("A new button will be required to trigger "),a("code",[t._v("createWallet")])]),t._v(" "),a("p",[t._v("Let's add a new button just above "),a("code",[t._v("{/* input boxes and send transaction button */}")])]),t._v(" "),a("div",{staticClass:"language-jsx extra-class"},[a("pre",{pre:!0,attrs:{class:"language-jsx"}},[a("code",[t._v("\t\t\t\t"),a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Button")])]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("title")]),a("span",{pre:!0,attrs:{class:"token attr-value"}},[a("span",{pre:!0,attrs:{class:"token punctuation attr-equals"}},[t._v("=")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v('"')]),t._v("Create Wallet"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v('"')])]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("style")]),a("span",{pre:!0,attrs:{class:"token script language-javascript"}},[a("span",{pre:!0,attrs:{class:"token script-punctuation punctuation"}},[t._v("=")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("styles"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("methodButton"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("onPress")]),a("span",{pre:!0,attrs:{class:"token script language-javascript"}},[a("span",{pre:!0,attrs:{class:"token script-punctuation punctuation"}},[t._v("=")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("createWallet"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("/>")])]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("")])]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("/* input boxes and send transaction button */")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),a("p",[t._v("The response returned by "),a("code",[t._v("createWallet")]),t._v(" is a new address for the created wallet.")]),t._v(" "),a("div",{staticClass:"language-javascript extra-class"},[a("pre",{pre:!0,attrs:{class:"language-javascript"}},[a("code",[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token string-property property"}},[t._v('"data"')]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token string-property property"}},[t._v('"address"')]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"tb1qxg8g8cdzgs09cttu3y7lc33udqc4wsesunjnhe"')]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token string-property property"}},[t._v('"error"')]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token boolean"}},[t._v("false")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),a("p",[t._v("The App should now be creating a wallet when we click "),a("strong",[t._v("Create Mnemonic")]),t._v(" followed by "),a("strong",[t._v("Create Wallet")]),t._v(".")]),t._v(" "),a("img",{staticStyle:{display:"block",margin:"0 auto",zoom:"50%"},attrs:{src:s(360)}}),t._v(" "),a("p",[t._v("The wallet created is a HD wallet and the address displayed is the 0 index address for the wallet. The path used by default is 84'/1'/0'/0/* for addresses and 84'/1'/0'/1/* for change.")]),t._v(" "),a("p",[t._v("As we specified "),a("code",[t._v("testnet")]),t._v(" and did not specify "),a("code",[t._v("blockChainName")]),t._v(" and "),a("code",[t._v("blockChainConfigUrl")]),t._v(" a default testnet server will be used as the bitcoin node, "),a("code",[t._v("ssl://electrum.blockstream.info")]),t._v(" is the default url used for testnet.")]),t._v(" "),a("p",[t._v("Using "),a("code",[t._v("mnemonic")]),t._v(" is a quick way to create a new wallet with "),a("code",[t._v("bdk-rn")]),t._v(". The "),a("code",[t._v("createWallet()")]),t._v(" method in "),a("code",[t._v("bdk-rn")]),t._v(" has many optional arguments to configure the wallet. In addition to mnemonic, a wallet can also be created with a descriptor. If a descriptor is passed as an argument the wallet will be created using the descriptor. When using a descriptor, arguments for network, password and mnemonic are not required. "),a("code",[t._v("bdk-rn")]),t._v(" has a "),a("code",[t._v("createDescriptor()")]),t._v(" method to create a descriptor. More about output descriptors "),a("a",{attrs:{href:"https://github.com/bitcoin/bitcoin/blob/master/doc/descriptors.md",target:"_blank",rel:"noopener noreferrer"}},[t._v("here"),a("OutboundLink")],1),t._v(". Refer to the "),a("a",{attrs:{href:"https://github.com/LtbLightning/bdk-rn#createdescriptor",target:"_blank",rel:"noopener noreferrer"}},[t._v("readme"),a("OutboundLink")],1),t._v(" for all options available when creating output descriptors with "),a("code",[t._v("bdk-rn")])]),t._v(" "),a("div",{staticClass:"language-javascript extra-class"},[a("pre",{pre:!0,attrs:{class:"language-javascript"}},[a("code",[a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// using a descriptor to create wallet ")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" response "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" BdkRn"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("createWallet")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("descriptor")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token string"}},[t._v("'tprv8ZgxMBicQKsPd3G66kPkZEuJZgUK9QXJRYCwnCtYLJjEZmw8xFjCxGoyx533AL83XFcSQeuVmVeJbZai5RTBxDp71Abd2FPSyQumRL79BKw'")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),a("p",[t._v("Other arguments for "),a("code",[t._v("createWallet()")]),t._v(" are:")]),t._v(" "),a("p",[a("strong",[t._v("blockChainName")]),t._v(": Blockchain backend to use, like "),a("a",{attrs:{href:"https://github.com/romanz/electrs",target:"_blank",rel:"noopener noreferrer"}},[a("code",[t._v("electrum")]),a("OutboundLink")],1),t._v(", "),a("a",{attrs:{href:"https://github.com/Blockstream/esplora",target:"_blank",rel:"noopener noreferrer"}},[a("code",[t._v("esplora")]),a("OutboundLink")],1),t._v(", "),a("code",[t._v("compact-filters")]),t._v(" ("),a("a",{attrs:{href:"https://github.com/bitcoin/bips/blob/master/bip-0157.mediawiki",target:"_blank",rel:"noopener noreferrer"}},[t._v("BIP157"),a("OutboundLink")],1),t._v(") and Bitcoin Core. "),a("code",[t._v("bdk-rn")]),t._v(" at the moment doesn't support compact-filters and Bitcoin Core, this will be added shortly in a future release.")]),t._v(" "),a("p",[a("strong",[t._v("blockChainConfigUrl")]),t._v(": This is the url of the specified bitcoin node this should match the chain and the type of blockchain specified as "),a("strong",[t._v("blockChainName")])]),t._v(" "),a("p",[t._v("Refer to "),a("a",{attrs:{href:"https://github.com/LtbLightning/bdk-rn#createwallet",target:"_blank",rel:"noopener noreferrer"}},[t._v("readme"),a("OutboundLink")],1),t._v(" for a complete list of options for "),a("code",[t._v("createWallet")])]),t._v(" "),a("h2",{attrs:{id:"utxos-and-balance"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#utxos-and-balance"}},[t._v("#")]),t._v(" UTXOs and balance")]),t._v(" "),a("p",[t._v("With the wallet created, we can now add methods to sync UTXOs compute balance.")]),t._v(" "),a("p",[a("code",[t._v("bdk-rn")]),t._v(" has a "),a("code",[t._v("syncWallet")]),t._v(" method to sync all UTXOs belonging to the wallet with the bitcoin network, the specified "),a("code",[t._v("blockChainName")]),t._v(" and "),a("code",[t._v("blockChainConfigUrl")]),t._v(" is used to sync. Once the wallet sync is complete balance is computed and "),a("code",[t._v("getBalance")]),t._v(" can fetch the balance.")]),t._v(" "),a("p",[t._v("Earlier we have aleady added state variables for"),a("code",[t._v("syncResponse")]),t._v("and "),a("code",[t._v("balance")]),t._v(". Now we will add buttons to call "),a("code",[t._v("syncWallet")]),t._v(" and "),a("code",[t._v("getBalance")]),t._v(". Just below the Create Wallet button lets add two buttons as follows:")]),t._v(" "),a("div",{staticClass:"language-jsx extra-class"},[a("pre",{pre:!0,attrs:{class:"language-jsx"}},[a("code",[t._v(" "),a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Button")])]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("title")]),a("span",{pre:!0,attrs:{class:"token attr-value"}},[a("span",{pre:!0,attrs:{class:"token punctuation attr-equals"}},[t._v("=")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v('"')]),t._v("Sync Wallet"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v('"')])]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("style")]),a("span",{pre:!0,attrs:{class:"token script language-javascript"}},[a("span",{pre:!0,attrs:{class:"token script-punctuation punctuation"}},[t._v("=")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("styles"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("methodButton"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("onPress")]),a("span",{pre:!0,attrs:{class:"token script language-javascript"}},[a("span",{pre:!0,attrs:{class:"token script-punctuation punctuation"}},[t._v("=")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("syncWallet"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("/>")])]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Button")])]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("title")]),a("span",{pre:!0,attrs:{class:"token attr-value"}},[a("span",{pre:!0,attrs:{class:"token punctuation attr-equals"}},[t._v("=")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v('"')]),t._v("Get Balance"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v('"')])]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("style")]),a("span",{pre:!0,attrs:{class:"token script language-javascript"}},[a("span",{pre:!0,attrs:{class:"token script-punctuation punctuation"}},[t._v("=")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("styles"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("methodButton"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("onPress")]),a("span",{pre:!0,attrs:{class:"token script language-javascript"}},[a("span",{pre:!0,attrs:{class:"token script-punctuation punctuation"}},[t._v("=")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("getBalance"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("/>")])]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("")])]),t._v("\n")])])]),a("p",[t._v("And two click handlers below createWallet:")]),t._v(" "),a("div",{staticClass:"language-javascript extra-class"},[a("pre",{pre:!0,attrs:{class:"language-javascript"}},[a("code",[t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function-variable function"}},[t._v("syncWallet")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("async")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" data "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" BdkRn"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("syncWallet")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("setSyncResponse")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("data"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("setDisplayText")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token constant"}},[t._v("JSON")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("stringify")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("data"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function-variable function"}},[t._v("getBalance")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("async")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" data "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" BdkRn"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("getBalance")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("setBalance")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("data"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("setDisplayText")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("data"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n")])])]),a("p",[t._v("We should now be able to create a wallet, sync UTXOs and get balance")]),t._v(" "),a("img",{staticStyle:{display:"block",margin:"0 auto",zoom:"50%"},attrs:{src:s(361)}}),t._v(" "),a("p",[t._v("We can use a public testnet faucet to send testnet coins to the wallet and check that the UTXO sync and balance fetch are working correctly. Before we do that add one more method to generate a new address we can then use this address to get testnet coins from a faucet.")]),t._v(" "),a("p",[t._v("Let's add a state variable for "),a("code",[t._v("address")]),t._v(", a button for "),a("strong",[t._v("Get Address")]),t._v(" and a click event handler to call "),a("code",[t._v("bdk-rn")]),t._v(" and create a new address. Let's do the following")]),t._v(" "),a("p",[t._v("Add "),a("code",[t._v("address")]),t._v(" and "),a("code",[t._v("setAddress")]),t._v(" state variables below balance and "),a("code",[t._v("setBalance")]),t._v(":")]),t._v(" "),a("div",{staticClass:"language-javascript extra-class"},[a("pre",{pre:!0,attrs:{class:"language-javascript"}},[a("code",[t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("address"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" setAddress"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("useState")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),a("p",[t._v("A new "),a("code",[t._v("getAddress")]),t._v(" click event handler below "),a("code",[t._v("getBalance")]),t._v(" click event handler:")]),t._v(" "),a("div",{staticClass:"language-javascript extra-class"},[a("pre",{pre:!0,attrs:{class:"language-javascript"}},[a("code",[t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function-variable function"}},[t._v("getAddress")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("async")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" data "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" BdkRn"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("getNewAddress")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("setAddress")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("data"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("setDisplayText")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("data"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),a("p",[t._v("And a Get Address button below the existing Get Balance button:")]),t._v(" "),a("div",{staticClass:"language-jsx extra-class"},[a("pre",{pre:!0,attrs:{class:"language-jsx"}},[a("code",[a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Button")])]),t._v("\n\t"),a("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("title")]),a("span",{pre:!0,attrs:{class:"token attr-value"}},[a("span",{pre:!0,attrs:{class:"token punctuation attr-equals"}},[t._v("=")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v('"')]),t._v("Get Address"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v('"')])]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("style")]),a("span",{pre:!0,attrs:{class:"token script language-javascript"}},[a("span",{pre:!0,attrs:{class:"token script-punctuation punctuation"}},[t._v("=")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("styles"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("methodButton"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("onPress")]),a("span",{pre:!0,attrs:{class:"token script language-javascript"}},[a("span",{pre:!0,attrs:{class:"token script-punctuation punctuation"}},[t._v("=")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("getAddress"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("/>")])]),t._v("\n")])])]),a("p",[t._v("We should now have the following, and Get Address will be able to display a new address.")]),t._v(" "),a("img",{staticStyle:{display:"block",margin:"0px auto",zoom:"50%"},attrs:{src:s(362)}}),t._v(" "),a("p",[t._v("Now that we are able to generate a receive address we can get some testnet bitcoin from one of the public "),a("a",{attrs:{href:"https://coinfaucet.eu/en/btc-testnet/",target:"_blank",rel:"noopener noreferrer"}},[t._v("testnet faucets"),a("OutboundLink")],1)]),t._v(" "),a("p",[t._v("After we send and after the transaction is confirmed we will need to sync the wallet before we can see the new balance from the received transaction.")]),t._v(" "),a("h2",{attrs:{id:"restoring-wallet"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#restoring-wallet"}},[t._v("#")]),t._v(" Restoring wallet")]),t._v(" "),a("p",[t._v("The "),a("code",[t._v("createWallet")]),t._v(" method creates a wallet using a "),a("code",[t._v("mnemonic")]),t._v(", in order to restore we can use the same method, we won't need to call "),a("code",[t._v("generateMnemonic")]),t._v(" as we will already have a "),a("code",[t._v("mnemonic")]),t._v(" to restore with.")]),t._v(" "),a("p",[t._v("Let's add an input box to enter our own "),a("code",[t._v("mnemonic")]),t._v(", we will use the "),a("code",[t._v("mnemonic")]),t._v(" entered in the input box to create a wallet.")]),t._v(" "),a("p",[t._v("Let's add an input box for "),a("code",[t._v("mnemonic")]),t._v(" below the Generate Mnemonic button.")]),t._v(" "),a("div",{staticClass:"language-jsx extra-class"},[a("pre",{pre:!0,attrs:{class:"language-jsx"}},[a("code",[a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("TextInput")])]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("style")]),a("span",{pre:!0,attrs:{class:"token script language-javascript"}},[a("span",{pre:!0,attrs:{class:"token script-punctuation punctuation"}},[t._v("=")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("styles"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("input"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("multiline")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("value")]),a("span",{pre:!0,attrs:{class:"token script language-javascript"}},[a("span",{pre:!0,attrs:{class:"token script-punctuation punctuation"}},[t._v("=")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("mnemonic"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("onChangeText")]),a("span",{pre:!0,attrs:{class:"token script language-javascript"}},[a("span",{pre:!0,attrs:{class:"token script-punctuation punctuation"}},[t._v("=")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("setMnemonic"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("textAlignVertical")]),a("span",{pre:!0,attrs:{class:"token attr-value"}},[a("span",{pre:!0,attrs:{class:"token punctuation attr-equals"}},[t._v("=")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v('"')]),t._v("top"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v('"')])]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("/>")])]),t._v("\n")])])]),a("p",[t._v("This code will also display the mnemonic state variable in the input box, if we click Generate Mnemonic the generated mnemonic will show up in the input box. We can overwrite it with our own mnemonic and doing so will also overwrite the mnemonic state variable. This way the mnemonic displayed will be the one used to create the wallet.")]),t._v(" "),a("p",[t._v("we are already using the mnemonic state variable in the "),a("code",[t._v("createWallet")]),t._v(" Method so no other changes are required.")]),t._v(" "),a("p",[t._v("We can now use our own mnemonic and use it to restore a wallet. This will come in handy if we have a wallet with testnet bitcoin as these are hard to come by.")]),t._v(" "),a("img",{staticStyle:{display:"block",margin:"0px auto",zoom:"50%"},attrs:{src:s(363)}}),t._v(" "),a("h2",{attrs:{id:"sending-bitcoin"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#sending-bitcoin"}},[t._v("#")]),t._v(" Sending bitcoin")]),t._v(" "),a("p",[t._v("We are now able to receive bitcoin, time to add functionality to send as well.")]),t._v(" "),a("p",[a("code",[t._v("bdk-rn")]),t._v(" has a number of transaction-related methods to enable varied use cases. A new send transaction can be created and broadcast using "),a("a",{attrs:{href:"https://github.com/LtbLightning/bdk-rn#quicksend",target:"_blank",rel:"noopener noreferrer"}},[t._v("quickSend()"),a("OutboundLink")],1),t._v(". If required an unsigned transaction can be created using "),a("a",{attrs:{href:"https://github.com/LtbLightning/bdk-rn#createtransaction",target:"_blank",rel:"noopener noreferrer"}},[t._v("createTransaction()"),a("OutboundLink")],1),t._v(" , this can be signed later with "),a("a",{attrs:{href:"https://github.com/LtbLightning/bdk-rn#signtransaction",target:"_blank",rel:"noopener noreferrer"}},[t._v("signTransactioin()"),a("OutboundLink")],1),t._v(" method and broadcast using "),a("a",{attrs:{href:"https://github.com/LtbLightning/bdk-rn#broadcasttransaction",target:"_blank",rel:"noopener noreferrer"}},[t._v("broadcastTransaction()"),a("OutboundLink")],1),t._v(". There are also methods to query transactions by pending or confirmed status and all transactions. Please refer to "),a("code",[t._v("bdk-rn")]),t._v(" "),a("a",{attrs:{href:"https://github.com/LtbLightning/bdk-rn/blob/main/README.md#gettransactions",target:"_blank",rel:"noopener noreferrer"}},[t._v("readme"),a("OutboundLink")],1),t._v(" for more details on all the methods.")]),t._v(" "),a("p",[t._v("We will need state variables for recipient address and amount as well as for transaction, these can be added below our existing variables for syncResponse and address")]),t._v(" "),a("div",{staticClass:"language-javascript extra-class"},[a("pre",{pre:!0,attrs:{class:"language-javascript"}},[a("code",[t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("syncResponse"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" setSyncResponse"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("useState")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("address"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" setAddress"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("useState")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("transaction"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" setTransaction"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("useState")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("recipient"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" setRecipient"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("useState")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token string"}},[t._v("''")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("amount"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" setAmount"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("useState")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),a("p",[t._v("A click event handler for send button, we will use the "),a("a",{attrs:{href:"https://github.com/LtbLightning/bdk-rn#quicksend",target:"_blank",rel:"noopener noreferrer"}},[a("code",[t._v("quickSend()")]),a("OutboundLink")],1),t._v(" method to send specified amount in sats to address.")]),t._v(" "),a("div",{staticClass:"language-javascript extra-class"},[a("pre",{pre:!0,attrs:{class:"language-javascript"}},[a("code",[t._v("\t"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function-variable function"}},[t._v("sendTx")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("async")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" data "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" BdkRn"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("quickSend")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("address")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" recipient"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("amount")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" amount"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("setTransaction")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("data"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("setDisplayText")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token constant"}},[t._v("JSON")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("stringify")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("data"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),a("p",[t._v("Add a new section for send transaction functionality. We will need an input box for the receiver address and an input box for the amount to send. We will also need a button to trigger the transaction.")]),t._v(" "),a("p",[t._v("Let's add the send transaction section and UI components below "),a("code",[t._v("{/* input boxes and send transaction button */}")])]),t._v(" "),a("div",{staticClass:"language-jsx extra-class"},[a("pre",{pre:!0,attrs:{class:"language-jsx"}},[a("code",[t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("/* input boxes and send transaction button */")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("View")])]),t._v(" "),a("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("style")]),a("span",{pre:!0,attrs:{class:"token script language-javascript"}},[a("span",{pre:!0,attrs:{class:"token script-punctuation punctuation"}},[t._v("=")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("styles"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("sendSection"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),a("span",{pre:!0,attrs:{class:"token plain-text"}},[t._v("\n ")]),a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Fragment")])]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),a("span",{pre:!0,attrs:{class:"token plain-text"}},[t._v("\n ")]),a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("TextInput")])]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("style")]),a("span",{pre:!0,attrs:{class:"token script language-javascript"}},[a("span",{pre:!0,attrs:{class:"token script-punctuation punctuation"}},[t._v("=")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("styles"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("input"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("placeholder")]),a("span",{pre:!0,attrs:{class:"token attr-value"}},[a("span",{pre:!0,attrs:{class:"token punctuation attr-equals"}},[t._v("=")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v('"')]),t._v("Recipient Address"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v('"')])]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("onChangeText")]),a("span",{pre:!0,attrs:{class:"token script language-javascript"}},[a("span",{pre:!0,attrs:{class:"token script-punctuation punctuation"}},[t._v("=")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("setRecipient"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("/>")])]),a("span",{pre:!0,attrs:{class:"token plain-text"}},[t._v("\n ")]),a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("TextInput")])]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("style")]),a("span",{pre:!0,attrs:{class:"token script language-javascript"}},[a("span",{pre:!0,attrs:{class:"token script-punctuation punctuation"}},[t._v("=")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("styles"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("input"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("placeholder")]),a("span",{pre:!0,attrs:{class:"token attr-value"}},[a("span",{pre:!0,attrs:{class:"token punctuation attr-equals"}},[t._v("=")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v('"')]),t._v("Amount (in sats)"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v('"')])]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("onChangeText")]),a("span",{pre:!0,attrs:{class:"token script language-javascript"}},[a("span",{pre:!0,attrs:{class:"token script-punctuation punctuation"}},[t._v("=")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),a("span",{pre:!0,attrs:{class:"token parameter"}},[t._v("e")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("setAmount")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("parseInt")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("e"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("/>")])]),a("span",{pre:!0,attrs:{class:"token plain-text"}},[t._v("\n ")]),a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Button")])]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("title")]),a("span",{pre:!0,attrs:{class:"token attr-value"}},[a("span",{pre:!0,attrs:{class:"token punctuation attr-equals"}},[t._v("=")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v('"')]),t._v("Send Transaction"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v('"')])]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("style")]),a("span",{pre:!0,attrs:{class:"token script language-javascript"}},[a("span",{pre:!0,attrs:{class:"token script-punctuation punctuation"}},[t._v("=")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("styles"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("methodButton"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("onPress")]),a("span",{pre:!0,attrs:{class:"token script language-javascript"}},[a("span",{pre:!0,attrs:{class:"token script-punctuation punctuation"}},[t._v("=")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("sendTx"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("/>")])]),a("span",{pre:!0,attrs:{class:"token plain-text"}},[t._v("\n ")]),a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("")])]),a("span",{pre:!0,attrs:{class:"token plain-text"}},[t._v("\n ")]),a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("")])]),t._v("\n")])])]),a("p",[t._v("We should now be able to send a transaction as long as there is sufficient balance.")]),t._v(" "),a("img",{staticStyle:{display:"block",margin:"0px auto",zoom:"50%"},attrs:{src:s(364)}}),t._v(" "),a("h2",{attrs:{id:"conclusion"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#conclusion"}},[t._v("#")]),t._v(" Conclusion")]),t._v(" "),a("p",[t._v("The App we created can be built and distributed for both iOS and Android thus sharing a code base and reducing development time. The development and coding focused on application-level code for use cases and we did not have to code intricate internal bitcoin protocol-level code or bitcoin node interactions, and transactions. UTXOs and sync-related functionalities were also not required. All this was managed by "),a("code",[t._v("bdk-rn")]),t._v(" allowing us to focus on the product, functionality and user journey. This is how "),a("code",[t._v("bdk")]),t._v(" and "),a("code",[t._v("bdk-rn")]),t._v(" intend to make Rapid Bitcoin Application Development possible by allowing product and application developers to focus on what they know best while "),a("code",[t._v("bdk")]),t._v(" handles bitcoin complexity.")]),t._v(" "),a("p",[a("code",[t._v("bdk-rn")]),t._v(" intends to expose functionality and APIs from "),a("code",[t._v("bdk")]),t._v(" which has a wide variety of API with granular details allowing for many interesting use cases to be implemented. "),a("code",[t._v("bdk-rn")]),t._v(" and "),a("code",[t._v("bdk")]),t._v(" are constantly updated and enhanced based on feedback from product teams and developers in the bitcoin community.")]),t._v(" "),a("p",[t._v("Stay tuned for more APIs and enhancements coming to "),a("code",[t._v("bdk-rn")]),t._v(" in the near future. Feature and API requests are most welcome. New blogs and tutorials will be published soon for a more in-depth exploration of bdk-rn.")]),t._v(" "),a("p",[t._v("In the meantime keep in touch with the project by following on "),a("a",{attrs:{href:"https://github.com/LtbLightning/bdk-rn",target:"_blank",rel:"noopener noreferrer"}},[t._v("GitHub"),a("OutboundLink")],1),t._v(" and "),a("a",{attrs:{href:"https://twitter.com/BitcoinZavior",target:"_blank",rel:"noopener noreferrer"}},[t._v("Twitter"),a("OutboundLink")],1)]),t._v(" "),a("h4",{attrs:{id:"references"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#references"}},[t._v("#")]),t._v(" References:")]),t._v(" "),a("ul",[a("li",[a("a",{attrs:{href:"https://github.com/bitcoindevkit",target:"_blank",rel:"noopener noreferrer"}},[t._v("bdk"),a("OutboundLink")],1)]),t._v(" "),a("li",[a("a",{attrs:{href:"https://github.com/LtbLightning/bdk-rn",target:"_blank",rel:"noopener noreferrer"}},[t._v("bdk-rn"),a("OutboundLink")],1)]),t._v(" "),a("li",[a("a",{attrs:{href:"https://www.youtube.com/watch?v=gMpWA875go4",target:"_blank",rel:"noopener noreferrer"}},[t._v("Bitcoin Developers YouTube"),a("OutboundLink")],1)]),t._v(" "),a("li",[a("a",{attrs:{href:"https://github.com/LtbLightning/BdkRnQuickStart",target:"_blank",rel:"noopener noreferrer"}},[t._v("BdkRnQuickStart App GitHub Repository"),a("OutboundLink")],1)]),t._v(" "),a("li",[a("a",{attrs:{href:"https://reactnative.dev/docs/environment-setup",target:"_blank",rel:"noopener noreferrer"}},[t._v("Setup React Native Development Environment"),a("OutboundLink")],1)]),t._v(" "),a("li",[a("a",{attrs:{href:"https://github.com/bitcoinbook/bitcoinbook/blob/develop/ch04.asciidoc",target:"_blank",rel:"noopener noreferrer"}},[t._v("Mastering Bitcoin(HD Wallet chapter)"),a("OutboundLink")],1)]),t._v(" "),a("li",[a("a",{attrs:{href:"https://github.com/bitcoin/bitcoin/blob/master/doc/descriptors.md",target:"_blank",rel:"noopener noreferrer"}},[t._v("Bitcoin Output Descriptors from bitcoin GitHub"),a("OutboundLink")],1)]),t._v(" "),a("li",[t._v("Testnet Faucet: "),a("a",{attrs:{href:"https://coinfaucet.eu/en/btc-testnet/",target:"_blank",rel:"noopener noreferrer"}},[t._v("https://coinfaucet.eu/en/btc-testnet/"),a("OutboundLink")],1),t._v(" or "),a("a",{attrs:{href:"https://bitcoinfaucet.uo1.net",target:"_blank",rel:"noopener noreferrer"}},[t._v("https://bitcoinfaucet.uo1.net"),a("OutboundLink")],1)])])])}),[],!1,null,null,null);a.default=e.exports}}]); \ No newline at end of file diff --git a/assets/js/31.00e676e0.js b/assets/js/31.dadf64cd.js similarity index 99% rename from assets/js/31.00e676e0.js rename to assets/js/31.dadf64cd.js index bc94982ce2..025736f127 100644 --- a/assets/js/31.00e676e0.js +++ b/assets/js/31.dadf64cd.js @@ -1 +1 @@ -(window.webpackJsonp=window.webpackJsonp||[]).push([[31],{352:function(t,e,a){t.exports=a.p+"assets/img/BDK-RN-Architecture.42fbc351.png"},353:function(t,e,a){t.exports=a.p+"assets/img/BDK-RN.370f20c3.png"},354:function(t,e,a){t.exports=a.p+"assets/img/android_folder.0ff999be.png"},406:function(t,e,a){"use strict";a.r(e);var n=a(7),s=Object(n.a)({},(function(){var t=this,e=t._self._c;return e("ContentSlotsDistributor",{attrs:{"slot-key":t.$parent.slotKey}},[e("p",[t._v("The "),e("strong",[t._v("BitcoinDevkit")]),t._v("'s "),e("strong",[t._v("React Native")]),t._v(" library ("),e("code",[t._v("bdk-rn")]),t._v(") makes it easy to develop bitcoin applications for both Android and iOS mobile platforms. Using "),e("code",[t._v("bdk-rn")]),t._v(", knowledge of the underlying bitcoin and BDK API is not required and using "),e("code",[t._v("bdk-rn")]),t._v(" is similar to using any other RN module. The goal is "),e("strong",[t._v("Rapid Bitcoin Application Development")]),t._v(" by doing the heavy lifting in advance and providing a reusable library for other developers to use. Developers simply install using "),e("code",[t._v("yarn add")]),t._v(" and start using it in a React Native Project. The native code, Rust lang implementation, configuration and other setup details are all taken care of by "),e("code",[t._v("bdk-rn")]),t._v(".")]),t._v(" "),e("p",[t._v("This article is "),e("strong",[t._v("NOT a guide on how to use bdk-rn")]),t._v(" to build a bitcoin application, rather this is an insight into how "),e("code",[t._v("bdk-rn")]),t._v(" was developed. For help on how to use "),e("code",[t._v("bdk-rn")]),t._v(" to develop a bitcoin wallet or application please refer to the user guide in the "),e("a",{attrs:{href:"https://github.com/LtbLightning/bdk-rn#usage",target:"_blank",rel:"noopener noreferrer"}},[t._v("readme"),e("OutboundLink")],1),t._v(" on Github. There will be "),e("code",[t._v("how to guides")]),t._v(" published shortly on getting started with "),e("code",[t._v("bdk-rn")]),t._v(".")]),t._v(" "),e("h2",{attrs:{id:"react-native-architecture"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#react-native-architecture"}},[t._v("#")]),t._v(" React Native Architecture")]),t._v(" "),e("p",[t._v("At a high level, RN consists of the UI front which is essentially JavaScript which interacts with the native iOS and Android platforms over a bridge. When communicating over the bridge values from JS are converted to native and vice versa.")]),t._v(" "),e("p",[t._v("The native part of RN consists of Android as well as iOS modules and components. The Android and iOS sections are full fledged native projects which interact with the JS side over the native bridge. A RN project has all the build configuraiton required to build both Android and iOS projects.")]),t._v(" "),e("p",[t._v("For the purpose of making "),e("code",[t._v("bdk-rn")]),t._v(", "),e("code",[t._v("bdk-kotlin")]),t._v(" is used as the native Android module and "),e("code",[t._v("bdk-swift")]),t._v(" as the native iOS module. These are configured and wrapped in a RN Project as part of the platform specific native modules within the RN Project. This RN Project is then built to be a reusable React Native module.")]),t._v(" "),e("figure",[e("img",{attrs:{src:a(352),alt:""}})]),t._v(" "),e("h2",{attrs:{id:"native-integration"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#native-integration"}},[t._v("#")]),t._v(" Native Integration")]),t._v(" "),e("p",[t._v("In order to communicate to native modules on Android and iOS, React Native provides React Context API for Java/Kotlin as well as Swift. React Context API are used to build the interface to the native bridge allowing communication from JS to native modules.")]),t._v(" "),e("p",[t._v("bdk-rn uses React Context API plus some native code to wrap and enhance bdk-kotlin and bdk-swift APIs. The native code calls and interacts with the Android and iOS native modules which interface with the underlying mobile platform.")]),t._v(" "),e("img",{staticStyle:{display:"block",margin:"0 auto",zoom:"20%"},attrs:{src:a(353)}}),t._v(" "),e("h2",{attrs:{id:"android-module"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#android-module"}},[t._v("#")]),t._v(" Android Module")]),t._v(" "),e("p",[t._v("We will go into the details of how the BDK Android Module is integrated, we wont cover iOS.")]),t._v(" "),e("p",[t._v("Starting off with a basic RN project. This project will be enhanced with bdk-kotlin and bdk-swift binaries and native code. For now lets go into the details for Android, iOS has similar steps to be done in Swift.")]),t._v(" "),e("p",[t._v("The Android native project is located under the root project folder.")]),t._v(" "),e("img",{staticStyle:{display:"block",margin:"0 auto",zoom:"120%"},attrs:{src:a(354)}}),t._v(" "),e("p",[t._v("Here we need to add a dependency in "),e("code",[t._v("build.gradle")]),t._v(" for bdk-kotlin's android native binary. This will enable bdk-kotlin to be downloaded and available as one of the native modules.")]),t._v(" "),e("div",{staticClass:"language-javascript extra-class"},[e("pre",{pre:!0,attrs:{class:"language-javascript"}},[e("code",[e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// File: build.gradle")]),t._v("\n\nrepositories "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("mavenCentral")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\ndependencies "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("//noinspection GradleDynamicVersion")]),t._v("\n implementation "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'com.facebook.react:react-native:+'")]),t._v("\n\n "),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// bitcoindevkit")]),t._v("\n implementation "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'org.bitcoindevkit:bdk-android:0.7.1'")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),e("p",[t._v("We will create an Android native module which will interact with "),e("code",[t._v("bdk-android")]),t._v(".\nThis is done by adding a new Kotlin file "),e("code",[t._v("BdkRnModule.kt")]),t._v(" inside "),e("code",[t._v("android/app/src/main/java/com/bdkrn/")]),t._v(" folder")]),t._v(" "),e("p",[t._v("This will be part of the native code for bdk-rn module.Here a new class will be created to encapsulate the interaction with bitcoindevkit's android native binary.")]),t._v(" "),e("div",{staticClass:"language-kotlin extra-class"},[e("pre",{pre:!0,attrs:{class:"language-kotlin"}},[e("code",[e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// File: BdkRnModule.kt")]),t._v("\n\n"),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("import")]),t._v(" android"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("annotation"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("SuppressLint\n"),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("import")]),t._v(" android"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("util"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("Log\n"),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("import")]),t._v(" com"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("facebook"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("react"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("bridge"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("Arguments\n"),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("import")]),t._v(" com"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("facebook"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("react"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("bridge"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("Promise "),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("as")]),t._v(" Result\n")])])]),e("p",[e("code",[t._v("org.bitcoindevkit")]),t._v(" will also need to be imported here")]),t._v(" "),e("div",{staticClass:"language-kotlin extra-class"},[e("pre",{pre:!0,attrs:{class:"language-kotlin"}},[e("code",[e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("import")]),t._v(" org"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("bitcoindevkit"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("Wallet "),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("as")]),t._v(" BdkWallet\n")])])]),e("p",[t._v("To use React Context API "),e("code",[t._v("com.facebook.react.bridge.*")]),t._v(" also needs to be imported")]),t._v(" "),e("div",{staticClass:"language-kotlin extra-class"},[e("pre",{pre:!0,attrs:{class:"language-kotlin"}},[e("code",[e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("import")]),t._v(" com"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("facebook"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("react"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("bridge"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v("\n")])])]),e("p",[t._v("A new class needs to be defined here which will implement the React Context API")]),t._v(" "),e("div",{staticClass:"language-kotlin extra-class"},[e("pre",{pre:!0,attrs:{class:"language-kotlin"}},[e("code",[e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// File: BdkRnModule.kt")]),t._v("\n\n"),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("BdkRnModule")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("reactContext"),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" ReactApplicationContext"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v("\n\t"),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("ReactContextBaseJavaModule")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("reactContext"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("override")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("fun")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("getName")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string-literal singleline"}},[e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"BdkRnModule"')])]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),e("p",[t._v("With the base imports and class defined, we can start writing methods.\nThis will demonstrate how bdk native module will be called and how values will be returned to JS over the native bridge")]),t._v(" "),e("p",[t._v("Lets create a method that can be called from JaveScript, to do so we use the "),e("code",[t._v("@ReactMethod")]),t._v(" directive which is part of the React Context API. This will expose the method so that it can be called from JavaScript.")]),t._v(" "),e("div",{staticClass:"language-kotlin extra-class"},[e("pre",{pre:!0,attrs:{class:"language-kotlin"}},[e("code",[e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// File: BdkRnModule.kt")]),t._v("\n\n"),e("span",{pre:!0,attrs:{class:"token annotation builtin"}},[t._v("@ReactMethod")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("fun")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("createWallet")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("result"),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" Promise"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n \n"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),e("p",[t._v("We need one more file to complete our native framework. A new Kotlin file, "),e("code",[t._v("BdkRnPackage.kt")]),t._v(" is required to package all our native code into a new android module, here we specify the name of the file we just crated as the module name("),e("code",[t._v("BdkRnModule")]),t._v("). This can be done by adding the following code:")]),t._v(" "),e("div",{staticClass:"language-kotlin extra-class"},[e("pre",{pre:!0,attrs:{class:"language-kotlin"}},[e("code",[e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// File: BdkRnPackage.kt")]),t._v("\n\n"),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("import")]),t._v(" com"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("facebook"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("react"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("ReactPackage\n"),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("import")]),t._v(" com"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("facebook"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("react"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("bridge"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("NativeModule\n"),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("import")]),t._v(" com"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("facebook"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("react"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("bridge"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("ReactApplicationContext\n"),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("import")]),t._v(" com"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("facebook"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("react"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("uimanager"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("ViewManager\n\n"),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),t._v(" BdkRnPackage "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" ReactPackage "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n\n "),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("override")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("fun")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("createNativeModules")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("reactContext"),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" ReactApplicationContext"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v("\n MutableList"),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),t._v("NativeModule"),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("mutableListOf")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("BdkRnModule")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("reactContext"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n")])])]),e("p",[t._v("Now lets add code for creating a wallet in BdkRnModule.kt")]),t._v(" "),e("p",[t._v("The methods used here are for bdk-kotlin and available in the bdk-kotlin documentation.")]),t._v(" "),e("p",[t._v("We first create a key info object")]),t._v(" "),e("div",{staticClass:"language-kotlin extra-class"},[e("pre",{pre:!0,attrs:{class:"language-kotlin"}},[e("code",[e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// File: BdkRnModule.kt")]),t._v("\n\n"),e("span",{pre:!0,attrs:{class:"token annotation builtin"}},[t._v("@ReactMethod")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("fun")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("createWallet")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("result"),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" Promise"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Create key info with a new mnemonic")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" keys"),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" ExtendedKeyInfo "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("generateExtendedKey")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n Network"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("TESTNET"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n WordCount"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("WORDS12"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token string-literal singleline"}},[e("span",{pre:!0,attrs:{class:"token string"}},[t._v('""')])]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n \n "),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// more code to follow...")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// create descriptor and change descriptor")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// create databaseConfig and blockchainconfig")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// create wallet")]),t._v("\n \n"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),e("p",[t._v("Then key info used to create a wallet descriptor and change descriptor:")]),t._v(" "),e("div",{staticClass:"language-kotlin extra-class"},[e("pre",{pre:!0,attrs:{class:"language-kotlin"}},[e("code",[e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" descriptor"),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" String "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string-literal singleline"}},[e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"wpkh("')])]),t._v(" "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("+")]),t._v(" keys"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("xprv "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("+")]),t._v(' "'),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("/")]),e("span",{pre:!0,attrs:{class:"token number"}},[t._v("84")]),t._v("'"),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("/")]),e("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),t._v("'"),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("/")]),e("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),t._v("'"),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("/")]),e("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("/*)\"\n\nval changeDescriptor: String = descriptor.replace(\"/84'/1'/0'/0/*\",\"/84'/1'/0'/1/*\")\n")])])])]),e("p",[t._v("To create a wallet with bdk we need to specify wallet descriptor, network, a database config, blockchain config. We intend to use bitcoin testnet and want to use default memory for data. For bitcoin node we will use a public electrum server. We will need to define these parameters to create a wallet.")]),t._v(" "),e("div",{staticClass:"language-kotlin extra-class"},[e("pre",{pre:!0,attrs:{class:"language-kotlin"}},[e("code",[e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" network "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" `Network"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("TESTNET`\n"),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" databaseConfig "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" DatabaseConfig"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("Memory\nblockchainConfig "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v("\n BlockchainConfig"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("Electrum")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("ElectrumConfig")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token string-literal singleline"}},[e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"ssl://electrum.blockstream.info:60002"')])]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("null")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" 5u"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("null")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" 10u"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n")])])]),e("p",[t._v("Once done we can use these parameters to create a BDK wallet using the native android BDK library:")]),t._v(" "),e("div",{staticClass:"language-kotlin extra-class"},[e("pre",{pre:!0,attrs:{class:"language-kotlin"}},[e("code",[e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("var")]),t._v(" wallet"),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" BdkWallet "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("BdkWallet")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n descriptor"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n changeDescriptor"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("setNetwork")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("network"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n databaseConfig"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n config\n"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n")])])]),e("p",[t._v("Once we have a wallet initialised, we can call methods on it to sync, generate a new address and to get balance")]),t._v(" "),e("div",{staticClass:"language-kotlin extra-class"},[e("pre",{pre:!0,attrs:{class:"language-kotlin"}},[e("code",[t._v("wallet"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("sync")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("ProgressLog"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" maxAddress"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n\nwallet"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("getNewAddress")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n\nwallet"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("getBalance")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("toLong")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n")])])]),e("p",[t._v("To return a value from the native android code to React Native’s Javascript side over the JS Native bridge we will use "),e("code",[t._v("com.facebook.react.bridge.Promise")]),t._v(". To return balance information to JS, the following code can be used")]),t._v(" "),e("div",{staticClass:"language-kotlin extra-class"},[e("pre",{pre:!0,attrs:{class:"language-kotlin"}},[e("code",[e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" balance"),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" String "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" wallet"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("getBalance")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("toLong")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\nresult"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("resolve")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("balance"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n")])])]),e("p",[t._v("At this point we have an Android native module and it can be invoked from JS by calling "),e("code",[t._v("createWallet")]),t._v(" and it will return the balance.")]),t._v(" "),e("p",[t._v("This project can be imported into any RN project to reuse the defined "),e("code",[t._v("createWallet")]),t._v(" method without the need to carry out the setup described above.")]),t._v(" "),e("div",{staticClass:"language-javascript extra-class"},[e("pre",{pre:!0,attrs:{class:"language-javascript"}},[e("code",[e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// any js file in React Native")]),t._v("\n\n"),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("import")]),t._v(" BdkRn "),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("from")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'bdk-rn'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// create a wallet and retrieve current balance")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" balance "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" BdkRn"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("createWallet")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\nconsole"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("log")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" balance "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n\n")])])]),e("p",[t._v("The actual "),e("code",[t._v("bdk-rn")]),t._v(" module has organised the native code into granular methods for different stages of creating a wallet and for different interactions and use cases for a bitcoin application, like generating, mnemonic, keys, creating wallet for different networks, creating descriptors, creating or restoring wallet, fetching balance, fetching transactions and many other methods. Please refer to the "),e("a",{attrs:{href:"https://github.com/LtbLightning/bdk-rn#usage",target:"_blank",rel:"noopener noreferrer"}},[t._v("user guide in the readme"),e("OutboundLink")],1),t._v(" on Github for the complete API. The set of APIs available will grow in the near future as more APIs are added. This article can also be used as a guide to add new methods to the existing bdk-rn project.")]),t._v(" "),e("p",[t._v("The objective of "),e("code",[t._v("bdk-rn")]),t._v(" is to enable React Native developers to quickly start developing applications without the need to package BDK as described above.")]),t._v(" "),e("p",[t._v("Be on the lookout for user guides and tutorials on how to build bitcoin applications using "),e("code",[t._v("bdk-rn")]),t._v(" and "),e("code",[t._v("bdk-flutter")]),t._v(".")]),t._v(" "),e("h2",{attrs:{id:"references"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#references"}},[t._v("#")]),t._v(" References")]),t._v(" "),e("p",[t._v("Creating native modules for Android and iOS: "),e("a",{attrs:{href:"https://reactnative.dev/docs/native-modules-intro",target:"_blank",rel:"noopener noreferrer"}},[t._v("https://reactnative.dev/docs/native-modules-intro"),e("OutboundLink")],1)]),t._v(" "),e("p",[t._v("React Native Architecture: "),e("a",{attrs:{href:"https://www.reactnative.guide/3-react-native-internals/3.1-react-native-internals.html",target:"_blank",rel:"noopener noreferrer"}},[t._v("https://www.reactnative.guide/3-react-native-internals/3.1-react-native-internals.html"),e("OutboundLink")],1)]),t._v(" "),e("p",[t._v("BDK-Android API: "),e("a",{attrs:{href:"https://bitcoindevkit.org/bdk-jvm/bdk-jvm/org.bitcoindevkit/index.html",target:"_blank",rel:"noopener noreferrer"}},[t._v("https://bitcoindevkit.org/bdk-jvm/bdk-jvm/org.bitcoindevkit/index.html"),e("OutboundLink")],1)]),t._v(" "),e("p",[t._v("BDK-RN: "),e("a",{attrs:{href:"https://github.com/LtbLightning/bdk-rn",target:"_blank",rel:"noopener noreferrer"}},[t._v("https://github.com/LtbLightning/bdk-rn"),e("OutboundLink")],1)]),t._v(" "),e("h2",{attrs:{id:"feedback"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#feedback"}},[t._v("#")]),t._v(" Feedback")]),t._v(" "),e("p",[t._v("The best way to give feedback on this would be to comment on the "),e("a",{attrs:{href:"https://github.com/bitcoindevkit/bitcoindevkit.org/pull/107",target:"_blank",rel:"noopener noreferrer"}},[t._v("pull request"),e("OutboundLink")],1),t._v(" for this blog post.\nThanks in advance.")])])}),[],!1,null,null,null);e.default=s.exports}}]); \ No newline at end of file +(window.webpackJsonp=window.webpackJsonp||[]).push([[31],{352:function(t,e,a){t.exports=a.p+"assets/img/BDK-RN-Architecture.42fbc351.png"},353:function(t,e,a){t.exports=a.p+"assets/img/BDK-RN.370f20c3.png"},354:function(t,e,a){t.exports=a.p+"assets/img/android_folder.0ff999be.png"},407:function(t,e,a){"use strict";a.r(e);var n=a(7),s=Object(n.a)({},(function(){var t=this,e=t._self._c;return e("ContentSlotsDistributor",{attrs:{"slot-key":t.$parent.slotKey}},[e("p",[t._v("The "),e("strong",[t._v("BitcoinDevkit")]),t._v("'s "),e("strong",[t._v("React Native")]),t._v(" library ("),e("code",[t._v("bdk-rn")]),t._v(") makes it easy to develop bitcoin applications for both Android and iOS mobile platforms. Using "),e("code",[t._v("bdk-rn")]),t._v(", knowledge of the underlying bitcoin and BDK API is not required and using "),e("code",[t._v("bdk-rn")]),t._v(" is similar to using any other RN module. The goal is "),e("strong",[t._v("Rapid Bitcoin Application Development")]),t._v(" by doing the heavy lifting in advance and providing a reusable library for other developers to use. Developers simply install using "),e("code",[t._v("yarn add")]),t._v(" and start using it in a React Native Project. The native code, Rust lang implementation, configuration and other setup details are all taken care of by "),e("code",[t._v("bdk-rn")]),t._v(".")]),t._v(" "),e("p",[t._v("This article is "),e("strong",[t._v("NOT a guide on how to use bdk-rn")]),t._v(" to build a bitcoin application, rather this is an insight into how "),e("code",[t._v("bdk-rn")]),t._v(" was developed. For help on how to use "),e("code",[t._v("bdk-rn")]),t._v(" to develop a bitcoin wallet or application please refer to the user guide in the "),e("a",{attrs:{href:"https://github.com/LtbLightning/bdk-rn#usage",target:"_blank",rel:"noopener noreferrer"}},[t._v("readme"),e("OutboundLink")],1),t._v(" on Github. There will be "),e("code",[t._v("how to guides")]),t._v(" published shortly on getting started with "),e("code",[t._v("bdk-rn")]),t._v(".")]),t._v(" "),e("h2",{attrs:{id:"react-native-architecture"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#react-native-architecture"}},[t._v("#")]),t._v(" React Native Architecture")]),t._v(" "),e("p",[t._v("At a high level, RN consists of the UI front which is essentially JavaScript which interacts with the native iOS and Android platforms over a bridge. When communicating over the bridge values from JS are converted to native and vice versa.")]),t._v(" "),e("p",[t._v("The native part of RN consists of Android as well as iOS modules and components. The Android and iOS sections are full fledged native projects which interact with the JS side over the native bridge. A RN project has all the build configuraiton required to build both Android and iOS projects.")]),t._v(" "),e("p",[t._v("For the purpose of making "),e("code",[t._v("bdk-rn")]),t._v(", "),e("code",[t._v("bdk-kotlin")]),t._v(" is used as the native Android module and "),e("code",[t._v("bdk-swift")]),t._v(" as the native iOS module. These are configured and wrapped in a RN Project as part of the platform specific native modules within the RN Project. This RN Project is then built to be a reusable React Native module.")]),t._v(" "),e("figure",[e("img",{attrs:{src:a(352),alt:""}})]),t._v(" "),e("h2",{attrs:{id:"native-integration"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#native-integration"}},[t._v("#")]),t._v(" Native Integration")]),t._v(" "),e("p",[t._v("In order to communicate to native modules on Android and iOS, React Native provides React Context API for Java/Kotlin as well as Swift. React Context API are used to build the interface to the native bridge allowing communication from JS to native modules.")]),t._v(" "),e("p",[t._v("bdk-rn uses React Context API plus some native code to wrap and enhance bdk-kotlin and bdk-swift APIs. The native code calls and interacts with the Android and iOS native modules which interface with the underlying mobile platform.")]),t._v(" "),e("img",{staticStyle:{display:"block",margin:"0 auto",zoom:"20%"},attrs:{src:a(353)}}),t._v(" "),e("h2",{attrs:{id:"android-module"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#android-module"}},[t._v("#")]),t._v(" Android Module")]),t._v(" "),e("p",[t._v("We will go into the details of how the BDK Android Module is integrated, we wont cover iOS.")]),t._v(" "),e("p",[t._v("Starting off with a basic RN project. This project will be enhanced with bdk-kotlin and bdk-swift binaries and native code. For now lets go into the details for Android, iOS has similar steps to be done in Swift.")]),t._v(" "),e("p",[t._v("The Android native project is located under the root project folder.")]),t._v(" "),e("img",{staticStyle:{display:"block",margin:"0 auto",zoom:"120%"},attrs:{src:a(354)}}),t._v(" "),e("p",[t._v("Here we need to add a dependency in "),e("code",[t._v("build.gradle")]),t._v(" for bdk-kotlin's android native binary. This will enable bdk-kotlin to be downloaded and available as one of the native modules.")]),t._v(" "),e("div",{staticClass:"language-javascript extra-class"},[e("pre",{pre:!0,attrs:{class:"language-javascript"}},[e("code",[e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// File: build.gradle")]),t._v("\n\nrepositories "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("mavenCentral")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\ndependencies "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("//noinspection GradleDynamicVersion")]),t._v("\n implementation "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'com.facebook.react:react-native:+'")]),t._v("\n\n "),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// bitcoindevkit")]),t._v("\n implementation "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'org.bitcoindevkit:bdk-android:0.7.1'")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),e("p",[t._v("We will create an Android native module which will interact with "),e("code",[t._v("bdk-android")]),t._v(".\nThis is done by adding a new Kotlin file "),e("code",[t._v("BdkRnModule.kt")]),t._v(" inside "),e("code",[t._v("android/app/src/main/java/com/bdkrn/")]),t._v(" folder")]),t._v(" "),e("p",[t._v("This will be part of the native code for bdk-rn module.Here a new class will be created to encapsulate the interaction with bitcoindevkit's android native binary.")]),t._v(" "),e("div",{staticClass:"language-kotlin extra-class"},[e("pre",{pre:!0,attrs:{class:"language-kotlin"}},[e("code",[e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// File: BdkRnModule.kt")]),t._v("\n\n"),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("import")]),t._v(" android"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("annotation"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("SuppressLint\n"),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("import")]),t._v(" android"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("util"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("Log\n"),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("import")]),t._v(" com"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("facebook"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("react"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("bridge"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("Arguments\n"),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("import")]),t._v(" com"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("facebook"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("react"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("bridge"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("Promise "),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("as")]),t._v(" Result\n")])])]),e("p",[e("code",[t._v("org.bitcoindevkit")]),t._v(" will also need to be imported here")]),t._v(" "),e("div",{staticClass:"language-kotlin extra-class"},[e("pre",{pre:!0,attrs:{class:"language-kotlin"}},[e("code",[e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("import")]),t._v(" org"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("bitcoindevkit"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("Wallet "),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("as")]),t._v(" BdkWallet\n")])])]),e("p",[t._v("To use React Context API "),e("code",[t._v("com.facebook.react.bridge.*")]),t._v(" also needs to be imported")]),t._v(" "),e("div",{staticClass:"language-kotlin extra-class"},[e("pre",{pre:!0,attrs:{class:"language-kotlin"}},[e("code",[e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("import")]),t._v(" com"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("facebook"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("react"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("bridge"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v("\n")])])]),e("p",[t._v("A new class needs to be defined here which will implement the React Context API")]),t._v(" "),e("div",{staticClass:"language-kotlin extra-class"},[e("pre",{pre:!0,attrs:{class:"language-kotlin"}},[e("code",[e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// File: BdkRnModule.kt")]),t._v("\n\n"),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("BdkRnModule")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("reactContext"),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" ReactApplicationContext"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v("\n\t"),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("ReactContextBaseJavaModule")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("reactContext"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("override")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("fun")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("getName")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string-literal singleline"}},[e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"BdkRnModule"')])]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),e("p",[t._v("With the base imports and class defined, we can start writing methods.\nThis will demonstrate how bdk native module will be called and how values will be returned to JS over the native bridge")]),t._v(" "),e("p",[t._v("Lets create a method that can be called from JaveScript, to do so we use the "),e("code",[t._v("@ReactMethod")]),t._v(" directive which is part of the React Context API. This will expose the method so that it can be called from JavaScript.")]),t._v(" "),e("div",{staticClass:"language-kotlin extra-class"},[e("pre",{pre:!0,attrs:{class:"language-kotlin"}},[e("code",[e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// File: BdkRnModule.kt")]),t._v("\n\n"),e("span",{pre:!0,attrs:{class:"token annotation builtin"}},[t._v("@ReactMethod")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("fun")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("createWallet")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("result"),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" Promise"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n \n"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),e("p",[t._v("We need one more file to complete our native framework. A new Kotlin file, "),e("code",[t._v("BdkRnPackage.kt")]),t._v(" is required to package all our native code into a new android module, here we specify the name of the file we just crated as the module name("),e("code",[t._v("BdkRnModule")]),t._v("). This can be done by adding the following code:")]),t._v(" "),e("div",{staticClass:"language-kotlin extra-class"},[e("pre",{pre:!0,attrs:{class:"language-kotlin"}},[e("code",[e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// File: BdkRnPackage.kt")]),t._v("\n\n"),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("import")]),t._v(" com"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("facebook"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("react"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("ReactPackage\n"),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("import")]),t._v(" com"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("facebook"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("react"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("bridge"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("NativeModule\n"),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("import")]),t._v(" com"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("facebook"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("react"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("bridge"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("ReactApplicationContext\n"),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("import")]),t._v(" com"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("facebook"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("react"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("uimanager"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("ViewManager\n\n"),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),t._v(" BdkRnPackage "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" ReactPackage "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n\n "),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("override")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("fun")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("createNativeModules")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("reactContext"),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" ReactApplicationContext"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v("\n MutableList"),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),t._v("NativeModule"),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("mutableListOf")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("BdkRnModule")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("reactContext"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n")])])]),e("p",[t._v("Now lets add code for creating a wallet in BdkRnModule.kt")]),t._v(" "),e("p",[t._v("The methods used here are for bdk-kotlin and available in the bdk-kotlin documentation.")]),t._v(" "),e("p",[t._v("We first create a key info object")]),t._v(" "),e("div",{staticClass:"language-kotlin extra-class"},[e("pre",{pre:!0,attrs:{class:"language-kotlin"}},[e("code",[e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// File: BdkRnModule.kt")]),t._v("\n\n"),e("span",{pre:!0,attrs:{class:"token annotation builtin"}},[t._v("@ReactMethod")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("fun")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("createWallet")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("result"),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" Promise"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Create key info with a new mnemonic")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" keys"),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" ExtendedKeyInfo "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("generateExtendedKey")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n Network"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("TESTNET"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n WordCount"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("WORDS12"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token string-literal singleline"}},[e("span",{pre:!0,attrs:{class:"token string"}},[t._v('""')])]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n \n "),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// more code to follow...")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// create descriptor and change descriptor")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// create databaseConfig and blockchainconfig")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// create wallet")]),t._v("\n \n"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),e("p",[t._v("Then key info used to create a wallet descriptor and change descriptor:")]),t._v(" "),e("div",{staticClass:"language-kotlin extra-class"},[e("pre",{pre:!0,attrs:{class:"language-kotlin"}},[e("code",[e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" descriptor"),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" String "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string-literal singleline"}},[e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"wpkh("')])]),t._v(" "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("+")]),t._v(" keys"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("xprv "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("+")]),t._v(' "'),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("/")]),e("span",{pre:!0,attrs:{class:"token number"}},[t._v("84")]),t._v("'"),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("/")]),e("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),t._v("'"),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("/")]),e("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),t._v("'"),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("/")]),e("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("/*)\"\n\nval changeDescriptor: String = descriptor.replace(\"/84'/1'/0'/0/*\",\"/84'/1'/0'/1/*\")\n")])])])]),e("p",[t._v("To create a wallet with bdk we need to specify wallet descriptor, network, a database config, blockchain config. We intend to use bitcoin testnet and want to use default memory for data. For bitcoin node we will use a public electrum server. We will need to define these parameters to create a wallet.")]),t._v(" "),e("div",{staticClass:"language-kotlin extra-class"},[e("pre",{pre:!0,attrs:{class:"language-kotlin"}},[e("code",[e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" network "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" `Network"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("TESTNET`\n"),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" databaseConfig "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" DatabaseConfig"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("Memory\nblockchainConfig "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v("\n BlockchainConfig"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("Electrum")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("ElectrumConfig")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token string-literal singleline"}},[e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"ssl://electrum.blockstream.info:60002"')])]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("null")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" 5u"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("null")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" 10u"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n")])])]),e("p",[t._v("Once done we can use these parameters to create a BDK wallet using the native android BDK library:")]),t._v(" "),e("div",{staticClass:"language-kotlin extra-class"},[e("pre",{pre:!0,attrs:{class:"language-kotlin"}},[e("code",[e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("var")]),t._v(" wallet"),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" BdkWallet "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("BdkWallet")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n descriptor"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n changeDescriptor"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("setNetwork")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("network"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n databaseConfig"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n config\n"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n")])])]),e("p",[t._v("Once we have a wallet initialised, we can call methods on it to sync, generate a new address and to get balance")]),t._v(" "),e("div",{staticClass:"language-kotlin extra-class"},[e("pre",{pre:!0,attrs:{class:"language-kotlin"}},[e("code",[t._v("wallet"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("sync")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("ProgressLog"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" maxAddress"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n\nwallet"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("getNewAddress")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n\nwallet"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("getBalance")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("toLong")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n")])])]),e("p",[t._v("To return a value from the native android code to React Native’s Javascript side over the JS Native bridge we will use "),e("code",[t._v("com.facebook.react.bridge.Promise")]),t._v(". To return balance information to JS, the following code can be used")]),t._v(" "),e("div",{staticClass:"language-kotlin extra-class"},[e("pre",{pre:!0,attrs:{class:"language-kotlin"}},[e("code",[e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" balance"),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" String "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" wallet"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("getBalance")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("toLong")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\nresult"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("resolve")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("balance"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n")])])]),e("p",[t._v("At this point we have an Android native module and it can be invoked from JS by calling "),e("code",[t._v("createWallet")]),t._v(" and it will return the balance.")]),t._v(" "),e("p",[t._v("This project can be imported into any RN project to reuse the defined "),e("code",[t._v("createWallet")]),t._v(" method without the need to carry out the setup described above.")]),t._v(" "),e("div",{staticClass:"language-javascript extra-class"},[e("pre",{pre:!0,attrs:{class:"language-javascript"}},[e("code",[e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// any js file in React Native")]),t._v("\n\n"),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("import")]),t._v(" BdkRn "),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("from")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'bdk-rn'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// create a wallet and retrieve current balance")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" balance "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" BdkRn"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("createWallet")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\nconsole"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("log")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" balance "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n\n")])])]),e("p",[t._v("The actual "),e("code",[t._v("bdk-rn")]),t._v(" module has organised the native code into granular methods for different stages of creating a wallet and for different interactions and use cases for a bitcoin application, like generating, mnemonic, keys, creating wallet for different networks, creating descriptors, creating or restoring wallet, fetching balance, fetching transactions and many other methods. Please refer to the "),e("a",{attrs:{href:"https://github.com/LtbLightning/bdk-rn#usage",target:"_blank",rel:"noopener noreferrer"}},[t._v("user guide in the readme"),e("OutboundLink")],1),t._v(" on Github for the complete API. The set of APIs available will grow in the near future as more APIs are added. This article can also be used as a guide to add new methods to the existing bdk-rn project.")]),t._v(" "),e("p",[t._v("The objective of "),e("code",[t._v("bdk-rn")]),t._v(" is to enable React Native developers to quickly start developing applications without the need to package BDK as described above.")]),t._v(" "),e("p",[t._v("Be on the lookout for user guides and tutorials on how to build bitcoin applications using "),e("code",[t._v("bdk-rn")]),t._v(" and "),e("code",[t._v("bdk-flutter")]),t._v(".")]),t._v(" "),e("h2",{attrs:{id:"references"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#references"}},[t._v("#")]),t._v(" References")]),t._v(" "),e("p",[t._v("Creating native modules for Android and iOS: "),e("a",{attrs:{href:"https://reactnative.dev/docs/native-modules-intro",target:"_blank",rel:"noopener noreferrer"}},[t._v("https://reactnative.dev/docs/native-modules-intro"),e("OutboundLink")],1)]),t._v(" "),e("p",[t._v("React Native Architecture: "),e("a",{attrs:{href:"https://www.reactnative.guide/3-react-native-internals/3.1-react-native-internals.html",target:"_blank",rel:"noopener noreferrer"}},[t._v("https://www.reactnative.guide/3-react-native-internals/3.1-react-native-internals.html"),e("OutboundLink")],1)]),t._v(" "),e("p",[t._v("BDK-Android API: "),e("a",{attrs:{href:"https://bitcoindevkit.org/bdk-jvm/bdk-jvm/org.bitcoindevkit/index.html",target:"_blank",rel:"noopener noreferrer"}},[t._v("https://bitcoindevkit.org/bdk-jvm/bdk-jvm/org.bitcoindevkit/index.html"),e("OutboundLink")],1)]),t._v(" "),e("p",[t._v("BDK-RN: "),e("a",{attrs:{href:"https://github.com/LtbLightning/bdk-rn",target:"_blank",rel:"noopener noreferrer"}},[t._v("https://github.com/LtbLightning/bdk-rn"),e("OutboundLink")],1)]),t._v(" "),e("h2",{attrs:{id:"feedback"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#feedback"}},[t._v("#")]),t._v(" Feedback")]),t._v(" "),e("p",[t._v("The best way to give feedback on this would be to comment on the "),e("a",{attrs:{href:"https://github.com/bitcoindevkit/bitcoindevkit.org/pull/107",target:"_blank",rel:"noopener noreferrer"}},[t._v("pull request"),e("OutboundLink")],1),t._v(" for this blog post.\nThanks in advance.")])])}),[],!1,null,null,null);e.default=s.exports}}]); \ No newline at end of file diff --git a/assets/js/37.a5bff0bd.js b/assets/js/37.4c491801.js similarity index 92% rename from assets/js/37.a5bff0bd.js rename to assets/js/37.4c491801.js index e8e98b54d2..e719b7f2b2 100644 --- a/assets/js/37.a5bff0bd.js +++ b/assets/js/37.4c491801.js @@ -1 +1 @@ -(window.webpackJsonp=window.webpackJsonp||[]).push([[37],{320:function(t,a,s){},379:function(t,a,s){"use strict";s(320)},439:function(t,a,s){"use strict";s.r(a);s(379);var i=s(7),r=Object(i.a)({},(function(){var t=this,a=t._self._c;return a("ContentSlotsDistributor",{attrs:{"slot-key":t.$parent.slotKey}},[a("h1",{attrs:{id:"desktop"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#desktop"}},[t._v("#")]),t._v(" Desktop")]),t._v(" "),a("div",{staticClass:"project"},[a("div",{staticClass:"project-logo"},[a("a",{attrs:{href:"https://www.caravanmultisig.com/",target:"_blank"}},[a("img",{attrs:{src:"/img/case-studies-logos/caravan-130.png"}})])]),t._v(" "),a("div",{staticClass:"tagline"},[a("h3",[a("a",{attrs:{href:"https://www.caravanmultisig.com/#/",target:"_blank"}},[t._v("Caravan")])]),t._v(" "),a("p",[t._v("Caravan is a multi-sig coordinator application, and an Unchained-sponsored open source project.")])])]),t._v(" "),a("div",{staticClass:"project"},[a("div",{staticClass:"project-logo"},[a("a",{attrs:{href:"https://www.anchorwatch.com/",target:"_blank"}},[a("img",{attrs:{src:"/img/case-studies-logos/anchorwatch-130.png"}})])]),t._v(" "),a("div",{staticClass:"tagline"},[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:"project"},[a("div",{staticClass:"project-logo"},[a("a",{attrs:{href:"https://wizardsardine.com/liana/",target:"_blank"}},[a("img",{attrs:{src:"/img/case-studies-logos/liana-130.png"}})])]),t._v(" "),a("div",{staticClass:"tagline"},[a("h3",[a("a",{attrs:{href:"https://wizardsardine.com/liana/",target:"_blank"}},[t._v("Liana")])]),t._v(" "),a("p",[t._v("Never lose your coins. Liana is a simple Bitcoin wallet with built-in loss protection and inheritance.")])])]),t._v(" "),a("div",{staticClass:"project"},[a("div",{staticClass:"project-logo"},[a("a",{attrs:{href:"https://github.com/utreexo/utreexod",target:"_blank"}},[a("img",{attrs:{src:"/img/case-studies-logos/utreexod-130.png"}})])]),t._v(" "),a("div",{staticClass:"tagline"},[a("h3",[a("a",{attrs:{href:"https://github.com/utreexo/utreexod",target:"_blank"}},[t._v("utreexod")])]),t._v(" "),a("p",[t._v("A fully validating Bitcoin node with Utreexo support.")])])])])}),[],!1,null,null,null);a.default=r.exports}}]); \ No newline at end of file +(window.webpackJsonp=window.webpackJsonp||[]).push([[37],{319:function(t,a,s){},378:function(t,a,s){"use strict";s(319)},438:function(t,a,s){"use strict";s.r(a);s(378);var i=s(7),r=Object(i.a)({},(function(){var t=this,a=t._self._c;return a("ContentSlotsDistributor",{attrs:{"slot-key":t.$parent.slotKey}},[a("h1",{attrs:{id:"desktop"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#desktop"}},[t._v("#")]),t._v(" Desktop")]),t._v(" "),a("div",{staticClass:"project"},[a("div",{staticClass:"project-logo"},[a("a",{attrs:{href:"https://www.caravanmultisig.com/",target:"_blank"}},[a("img",{attrs:{src:"/img/case-studies-logos/caravan-130.png"}})])]),t._v(" "),a("div",{staticClass:"tagline"},[a("h3",[a("a",{attrs:{href:"https://www.caravanmultisig.com/#/",target:"_blank"}},[t._v("Caravan")])]),t._v(" "),a("p",[t._v("Caravan is a multi-sig coordinator application, and an Unchained-sponsored open source project.")])])]),t._v(" "),a("div",{staticClass:"project"},[a("div",{staticClass:"project-logo"},[a("a",{attrs:{href:"https://www.anchorwatch.com/",target:"_blank"}},[a("img",{attrs:{src:"/img/case-studies-logos/anchorwatch-130.png"}})])]),t._v(" "),a("div",{staticClass:"tagline"},[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:"project"},[a("div",{staticClass:"project-logo"},[a("a",{attrs:{href:"https://wizardsardine.com/liana/",target:"_blank"}},[a("img",{attrs:{src:"/img/case-studies-logos/liana-130.png"}})])]),t._v(" "),a("div",{staticClass:"tagline"},[a("h3",[a("a",{attrs:{href:"https://wizardsardine.com/liana/",target:"_blank"}},[t._v("Liana")])]),t._v(" "),a("p",[t._v("Never lose your coins. Liana is a simple Bitcoin wallet with built-in loss protection and inheritance.")])])]),t._v(" "),a("div",{staticClass:"project"},[a("div",{staticClass:"project-logo"},[a("a",{attrs:{href:"https://github.com/utreexo/utreexod",target:"_blank"}},[a("img",{attrs:{src:"/img/case-studies-logos/utreexod-130.png"}})])]),t._v(" "),a("div",{staticClass:"tagline"},[a("h3",[a("a",{attrs:{href:"https://github.com/utreexo/utreexod",target:"_blank"}},[t._v("utreexod")])]),t._v(" "),a("p",[t._v("A fully validating Bitcoin node with Utreexo support.")])])])])}),[],!1,null,null,null);a.default=r.exports}}]); \ No newline at end of file diff --git a/assets/js/38.2ace5b2d.js b/assets/js/38.109014d3.js similarity index 87% rename from assets/js/38.2ace5b2d.js rename to assets/js/38.109014d3.js index f03a48b233..34f3a6deee 100644 --- a/assets/js/38.2ace5b2d.js +++ b/assets/js/38.109014d3.js @@ -1 +1 @@ -(window.webpackJsonp=window.webpackJsonp||[]).push([[38],{319:function(t,a,s){},378:function(t,a,s){"use strict";s(319)},438:function(t,a,s){"use strict";s.r(a);s(378);var e=s(7),i=Object(e.a)({},(function(){var t=this,a=t._self._c;return a("ContentSlotsDistributor",{attrs:{"slot-key":t.$parent.slotKey}},[a("h1",{attrs:{id:"exchange"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#exchange"}},[t._v("#")]),t._v(" Exchange")]),t._v(" "),a("div",{staticClass:"project"},[a("div",{staticClass:"project-logo"},[a("a",{attrs:{href:"https://www.bullbitcoin.com/",target:"_blank"}},[a("img",{attrs:{src:"/img/case-studies-logos/bull-bitcoin-130.png"}})])]),t._v(" "),a("div",{staticClass:"tagline"},[a("h3",[a("a",{attrs:{href:"https://www.bullbitcoin.com/",target:"_blank"}},[t._v("Bull Bitcoin")])]),t._v(" "),a("p",[t._v("A self-custodial Bitcoin Wallet and Exchange app that lets users buy, sell, spend and get paid with Bitcoin. Bitcoins are automatically sent from the exchange to the user's wallet.")])])]),t._v(" "),a("div",{staticClass:"project"},[a("div",{staticClass:"project-logo"},[a("a",{attrs:{href:"https://10101.finance/",target:"_blank"}},[a("img",{attrs:{src:"/img/case-studies-logos/10101-130.png"}})])]),t._v(" "),a("div",{staticClass:"tagline"},[a("h3",[a("a",{attrs:{href:"https://10101.finance/",target:"_blank"}},[t._v("10101")])]),t._v(" "),a("p",[t._v("Decentralised finance. For real. BTC trading without counterparty risk in one easy and fast app.")])])])])}),[],!1,null,null,null);a.default=i.exports}}]); \ No newline at end of file +(window.webpackJsonp=window.webpackJsonp||[]).push([[38],{320:function(t,a,s){},379:function(t,a,s){"use strict";s(320)},439:function(t,a,s){"use strict";s.r(a);s(379);var e=s(7),i=Object(e.a)({},(function(){var t=this,a=t._self._c;return a("ContentSlotsDistributor",{attrs:{"slot-key":t.$parent.slotKey}},[a("h1",{attrs:{id:"exchange"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#exchange"}},[t._v("#")]),t._v(" Exchange")]),t._v(" "),a("div",{staticClass:"project"},[a("div",{staticClass:"project-logo"},[a("a",{attrs:{href:"https://www.bullbitcoin.com/",target:"_blank"}},[a("img",{attrs:{src:"/img/case-studies-logos/bull-bitcoin-130.png"}})])]),t._v(" "),a("div",{staticClass:"tagline"},[a("h3",[a("a",{attrs:{href:"https://www.bullbitcoin.com/",target:"_blank"}},[t._v("Bull Bitcoin")])]),t._v(" "),a("p",[t._v("A self-custodial Bitcoin Wallet and Exchange app that lets users buy, sell, spend and get paid with Bitcoin. Bitcoins are automatically sent from the exchange to the user's wallet.")])])]),t._v(" "),a("div",{staticClass:"project"},[a("div",{staticClass:"project-logo"},[a("a",{attrs:{href:"https://10101.finance/",target:"_blank"}},[a("img",{attrs:{src:"/img/case-studies-logos/10101-130.png"}})])]),t._v(" "),a("div",{staticClass:"tagline"},[a("h3",[a("a",{attrs:{href:"https://10101.finance/",target:"_blank"}},[t._v("10101")])]),t._v(" "),a("p",[t._v("Decentralised finance. For real. BTC trading without counterparty risk in one easy and fast app.")])])])])}),[],!1,null,null,null);a.default=i.exports}}]); \ No newline at end of file diff --git a/assets/js/39.9b478629.js b/assets/js/39.811be492.js similarity index 88% rename from assets/js/39.9b478629.js rename to assets/js/39.811be492.js index f4c45a2759..f24c07d469 100644 --- a/assets/js/39.9b478629.js +++ b/assets/js/39.811be492.js @@ -1 +1 @@ -(window.webpackJsonp=window.webpackJsonp||[]).push([[39],{321:function(t,a,s){},380:function(t,a,s){"use strict";s(321)},440:function(t,a,s){"use strict";s.r(a);s(380);var e=s(7),i=Object(e.a)({},(function(){var t=this,a=t._self._c;return a("ContentSlotsDistributor",{attrs:{"slot-key":t.$parent.slotKey}},[a("h1",{attrs:{id:"hardware"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#hardware"}},[t._v("#")]),t._v(" Hardware")]),t._v(" "),a("div",{staticClass:"project"},[a("div",{staticClass:"project-logo"},[a("a",{attrs:{href:"https://bitkey.build/",target:"_blank"}},[a("img",{staticStyle:{"max-height":"130px"},attrs:{src:"/img/case-studies-logos/block-logo.gif"}})])]),t._v(" "),a("div",{staticClass:"tagline"},[a("h2",[a("a",{attrs:{href:"https://bitkey.build/",target:"_blank"}},[t._v("Bitkey")])]),t._v(" "),a("p",[t._v("\n Bitkey is the safe, easy way to own and manage bitcoin. It’s a mobile app, hardware device, and a set of recovery tools, for simple, secure self-custody.\n ")])])]),t._v(" "),a("div",{staticClass:"project"},[a("div",{staticClass:"project-logo"},[a("a",{attrs:{href:"https://foundationdevices.com/",target:"_blank"}},[a("img",{attrs:{src:"/img/case-studies-logos/foundation-130.png"}})])]),t._v(" "),a("div",{staticClass:"tagline"},[a("h3",[a("a",{attrs:{href:"https://foundationdevices.com/",target:"_blank"}},[t._v("Envoy By Foundation")])]),t._v(" "),a("p",[t._v("A Bitcoin wallet with powerful account management and privacy features. Use alongside your Passport hardware wallet to take true ownership of your Bitcoin.")])])])])}),[],!1,null,null,null);a.default=i.exports}}]); \ No newline at end of file +(window.webpackJsonp=window.webpackJsonp||[]).push([[39],{323:function(t,a,s){},382:function(t,a,s){"use strict";s(323)},442:function(t,a,s){"use strict";s.r(a);s(382);var e=s(7),i=Object(e.a)({},(function(){var t=this,a=t._self._c;return a("ContentSlotsDistributor",{attrs:{"slot-key":t.$parent.slotKey}},[a("h1",{attrs:{id:"hardware"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#hardware"}},[t._v("#")]),t._v(" Hardware")]),t._v(" "),a("div",{staticClass:"project"},[a("div",{staticClass:"project-logo"},[a("a",{attrs:{href:"https://bitkey.build/",target:"_blank"}},[a("img",{staticStyle:{"max-height":"130px"},attrs:{src:"/img/case-studies-logos/block-logo.gif"}})])]),t._v(" "),a("div",{staticClass:"tagline"},[a("h2",[a("a",{attrs:{href:"https://bitkey.build/",target:"_blank"}},[t._v("Bitkey")])]),t._v(" "),a("p",[t._v("\n Bitkey is the safe, easy way to own and manage bitcoin. It’s a mobile app, hardware device, and a set of recovery tools, for simple, secure self-custody.\n ")])])]),t._v(" "),a("div",{staticClass:"project"},[a("div",{staticClass:"project-logo"},[a("a",{attrs:{href:"https://foundationdevices.com/",target:"_blank"}},[a("img",{attrs:{src:"/img/case-studies-logos/foundation-130.png"}})])]),t._v(" "),a("div",{staticClass:"tagline"},[a("h3",[a("a",{attrs:{href:"https://foundationdevices.com/",target:"_blank"}},[t._v("Envoy By Foundation")])]),t._v(" "),a("p",[t._v("A Bitcoin wallet with powerful account management and privacy features. Use alongside your Passport hardware wallet to take true ownership of your Bitcoin.")])])])])}),[],!1,null,null,null);a.default=i.exports}}]); \ No newline at end of file diff --git a/assets/js/40.3dbbc631.js b/assets/js/40.73d2a9e6.js similarity index 86% rename from assets/js/40.3dbbc631.js rename to assets/js/40.73d2a9e6.js index 3994d3438e..1f657fa6ea 100644 --- a/assets/js/40.3dbbc631.js +++ b/assets/js/40.73d2a9e6.js @@ -1 +1 @@ -(window.webpackJsonp=window.webpackJsonp||[]).push([[40],{322:function(t,s,a){},381:function(t,s,a){"use strict";a(322)},441:function(t,s,a){"use strict";a.r(s);a(381);var i=a(7),r=Object(i.a)({},(function(){var t=this,s=t._self._c;return s("ContentSlotsDistributor",{attrs:{"slot-key":t.$parent.slotKey}},[s("h1",{attrs:{id:"infrastructure"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#infrastructure"}},[t._v("#")]),t._v(" Infrastructure")]),t._v(" "),s("div",{staticClass:"project"},[s("div",{staticClass:"project-logo"},[s("a",{attrs:{href:"https://github.com/BlockchainCommons/spotbit",target:"_blank"}},[s("img",{attrs:{src:"/img/case-studies-logos/spotbit-130.png"}})])]),t._v(" "),s("div",{staticClass:"tagline"},[s("h3",[s("a",{attrs:{href:"https://github.com/BlockchainCommons/spotbit",target:"_blank"}},[t._v("Spotbit")])]),t._v(" "),s("p",[t._v("Spotbit is a portable API for Bitcoin price data and candles.")])])]),t._v(" "),s("div",{staticClass:"project"},[s("div",{staticClass:"project-logo"},[s("a",{attrs:{href:"https://galoy.io/",target:"_blank"}},[s("img",{attrs:{src:"/img/case-studies-logos/galoy-130.png"}})])]),t._v(" "),s("div",{staticClass:"tagline"},[s("h3",[s("a",{attrs:{href:"https://galoy.io/",target:"_blank"}},[t._v("Galoy")])]),t._v(" "),s("p",[t._v("Bitcoin-native banking infrastructure for organizations.")])])])])}),[],!1,null,null,null);s.default=r.exports}}]); \ No newline at end of file +(window.webpackJsonp=window.webpackJsonp||[]).push([[40],{321:function(t,s,a){},380:function(t,s,a){"use strict";a(321)},440:function(t,s,a){"use strict";a.r(s);a(380);var i=a(7),r=Object(i.a)({},(function(){var t=this,s=t._self._c;return s("ContentSlotsDistributor",{attrs:{"slot-key":t.$parent.slotKey}},[s("h1",{attrs:{id:"infrastructure"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#infrastructure"}},[t._v("#")]),t._v(" Infrastructure")]),t._v(" "),s("div",{staticClass:"project"},[s("div",{staticClass:"project-logo"},[s("a",{attrs:{href:"https://github.com/BlockchainCommons/spotbit",target:"_blank"}},[s("img",{attrs:{src:"/img/case-studies-logos/spotbit-130.png"}})])]),t._v(" "),s("div",{staticClass:"tagline"},[s("h3",[s("a",{attrs:{href:"https://github.com/BlockchainCommons/spotbit",target:"_blank"}},[t._v("Spotbit")])]),t._v(" "),s("p",[t._v("Spotbit is a portable API for Bitcoin price data and candles.")])])]),t._v(" "),s("div",{staticClass:"project"},[s("div",{staticClass:"project-logo"},[s("a",{attrs:{href:"https://galoy.io/",target:"_blank"}},[s("img",{attrs:{src:"/img/case-studies-logos/galoy-130.png"}})])]),t._v(" "),s("div",{staticClass:"tagline"},[s("h3",[s("a",{attrs:{href:"https://galoy.io/",target:"_blank"}},[t._v("Galoy")])]),t._v(" "),s("p",[t._v("Bitcoin-native banking infrastructure for organizations.")])])])])}),[],!1,null,null,null);s.default=r.exports}}]); \ No newline at end of file diff --git a/assets/js/41.802e975e.js b/assets/js/41.dd41fb56.js similarity index 97% rename from assets/js/41.802e975e.js rename to assets/js/41.dd41fb56.js index 910da5500f..7bd4f15fb6 100644 --- a/assets/js/41.802e975e.js +++ b/assets/js/41.dd41fb56.js @@ -1 +1 @@ -(window.webpackJsonp=window.webpackJsonp||[]).push([[41],{323:function(t,a,s){},382:function(t,a,s){"use strict";s(323)},442:function(t,a,s){"use strict";s.r(a);s(382);var e=s(7),i=Object(e.a)({},(function(){var t=this,a=t._self._c;return a("ContentSlotsDistributor",{attrs:{"slot-key":t.$parent.slotKey}},[a("h1",{attrs:{id:"mobile"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#mobile"}},[t._v("#")]),t._v(" Mobile")]),t._v(" "),a("div",{staticClass:"project"},[a("div",{staticClass:"project-logo"},[a("a",{attrs:{href:"https://bitkey.build/",target:"_blank"}},[a("img",{staticStyle:{"max-height":"130px"},attrs:{src:"/img/case-studies-logos/block-logo.gif"}})])]),t._v(" "),a("div",{staticClass:"tagline"},[a("h2",[a("a",{attrs:{href:"https://bitkey.build/",target:"_blank"}},[t._v("Bitkey")])]),t._v(" "),a("p",[t._v("\n Bitkey is the safe, easy way to own and manage bitcoin. It’s a mobile app, hardware device, and a set of recovery tools, for simple, secure self-custody.\n ")])])]),t._v(" "),a("div",{staticClass:"project"},[a("div",{staticClass:"project-logo"},[a("a",{attrs:{href:"",target:"_blank"}},[a("img",{attrs:{src:"/img/case-studies-logos/peach-130.png"}})])]),t._v(" "),a("div",{staticClass:"tagline"},[a("h2",[a("a",{attrs:{href:"https://peachbitcoin.com/",target:"_blank"}},[t._v("Peach Bitcoin")])]),t._v(" "),a("p",[t._v("Connecting Bitcoin buyers and sellers directly together. Buy or sell bitcoin peer-to-peer anywhere, at anytime.")])])]),t._v(" "),a("div",{staticClass:"project"},[a("div",{staticClass:"project-logo"},[a("a",{attrs:{href:"https://www.mutinywallet.com/",target:"_blank"}},[a("img",{attrs:{src:"/img/case-studies-logos/mutiny-130.png"}})])]),t._v(" "),a("div",{staticClass:"tagline"},[a("h3",[a("a",{attrs:{href:"https://www.mutinywallet.com/",target:"_blank"}},[t._v("Mutiny Wallet")])]),t._v(" "),a("p",[t._v("Mutiny is a self-custodial lightning wallet that runs in the browser.")])])]),t._v(" "),a("div",{staticClass:"project"},[a("div",{staticClass:"project-logo"},[a("a",{attrs:{href:"https://foundationdevices.com/",target:"_blank"}},[a("img",{attrs:{src:"/img/case-studies-logos/foundation-130.png"}})])]),t._v(" "),a("div",{staticClass:"tagline"},[a("h3",[a("a",{attrs:{href:"https://foundationdevices.com/",target:"_blank"}},[t._v("Envoy By Foundation")])]),t._v(" "),a("p",[t._v("A Bitcoin wallet with powerful account management and privacy features. Use alongside your Passport hardware wallet to take true ownership of your Bitcoin.")])])]),t._v(" "),a("div",{staticClass:"project"},[a("div",{staticClass:"project-logo"},[a("a",{attrs:{href:"https://www.bullbitcoin.com/",target:"_blank"}},[a("img",{attrs:{src:"/img/case-studies-logos/bull-bitcoin-130.png"}})])]),t._v(" "),a("div",{staticClass:"tagline"},[a("h3",[a("a",{attrs:{href:"https://www.bullbitcoin.com/",target:"_blank"}},[t._v("Bull Bitcoin")])]),t._v(" "),a("p",[t._v("A self-custodial Bitcoin Wallet and Exchange app that lets users buy, sell, spend and get paid with Bitcoin. Bitcoins are automatically sent from the exchange to the user's wallet.")])])]),t._v(" "),a("div",{staticClass:"project"},[a("div",{staticClass:"project-logo"},[a("a",{attrs:{href:"https://www.lava.xyz/",target:"_blank"}},[a("img",{attrs:{src:"/img/case-studies-logos/lava-130.png"}})])]),t._v(" "),a("div",{staticClass:"tagline"},[a("h3",[a("a",{attrs:{href:"https://www.lava.xyz/",target:"_blank"}},[t._v("Lava")])]),t._v(" "),a("p",[t._v("The Future of Finance Available Today. Functional, safe and simple.")])])]),t._v(" "),a("div",{staticClass:"project"},[a("div",{staticClass:"project-logo"},[a("a",{attrs:{href:"https://github.com/lightningdevkit/ldk-node",target:"_blank"}},[a("img",{attrs:{src:"/img/case-studies-logos/ldk-node-130.png"}})])]),t._v(" "),a("div",{staticClass:"tagline"},[a("h3",[a("a",{attrs:{href:"https://github.com/lightningdevkit/ldk-node",target:"_blank"}},[t._v("LDK Node")])]),t._v(" "),a("p",[t._v("A ready-to-go Lightning node library built using LDK and BDK.")])])]),t._v(" "),a("div",{staticClass:"project"},[a("div",{staticClass:"project-logo"},[a("a",{attrs:{href:"https://play.google.com/store/apps/details?id=com.goldenraven.padawanwallet",target:"_blank"}},[a("img",{attrs:{src:"/img/case-studies-logos/padawan-130.png"}})])]),t._v(" "),a("div",{staticClass:"tagline"},[a("h3",[a("a",{attrs:{href:"https://play.google.com/store/apps/details?id=com.goldenraven.padawanwallet",target:"_blank"}},[t._v("Padawan Wallet")])]),t._v(" "),a("p",[t._v("Padawan is a testnet-only bitcoin wallet packed with tutorials to learn how to use bitcoin on mobile.")])])]),t._v(" "),a("div",{staticClass:"project"},[a("div",{staticClass:"project-logo"},[a("a",{attrs:{href:"https://www.smartvaults.io/",target:"_blank"}},[a("img",{staticStyle:{"max-height":"130px"},attrs:{src:"/img/case-studies-logos/smart-vaults-130.png"}})])]),t._v(" "),a("div",{staticClass:"tagline"},[a("h3",[a("a",{attrs:{href:"https://www.smartvaults.io/",target:"_blank"}},[t._v("Smart Vaults")])]),t._v(" "),a("p",[t._v("Determine who, how, and when your Bitcoin can be accessed.")])])]),t._v(" "),a("div",{staticClass:"project"},[a("div",{staticClass:"project-logo"},[a("a",{attrs:{href:"https://play.google.com/store/apps/details?id=com.iriswallet.testnet",target:"_blank"}},[a("img",{attrs:{src:"/img/case-studies-logos/iris-130.png"}})])]),t._v(" "),a("div",{staticClass:"tagline"},[a("h3",[a("a",{attrs:{href:"https://play.google.com/store/apps/details?id=com.iriswallet.testnet",target:"_blank"}},[t._v("Iris Wallet")])]),t._v(" "),a("p",[t._v("Open-source wallet for Bitcoin and RGB assets.")])])]),t._v(" "),a("div",{staticClass:"project"},[a("div",{staticClass:"project-logo"},[a("a",{attrs:{href:"https://github.com/BlockchainCommons/spotbit",target:"_blank"}},[a("img",{attrs:{src:"/img/case-studies-logos/spotbit-130.png"}})])]),t._v(" "),a("div",{staticClass:"tagline"},[a("h3",[a("a",{attrs:{href:"https://github.com/BlockchainCommons/spotbit",target:"_blank"}},[t._v("Spotbit")])]),t._v(" "),a("p",[t._v("Spotbit is a portable API for Bitcoin price data and candles.")])])]),t._v(" "),a("div",{staticClass:"project"},[a("div",{staticClass:"project-logo"},[a("a",{attrs:{href:"https://lipa.swiss/en",target:"_blank"}},[a("img",{attrs:{src:"/img/case-studies-logos/lipa-130.png"}})])]),t._v(" "),a("div",{staticClass:"tagline"},[a("h3",[a("a",{attrs:{href:"https://lipa.swiss/en",target:"_blank"}},[t._v("Lipa")])]),t._v(" "),a("p",[t._v("The Swiss app for cashless payments with Bitcoin.")])])]),t._v(" "),a("div",{staticClass:"project"},[a("div",{staticClass:"project-logo"},[a("a",{attrs:{href:"https://lexe.app/",target:"_blank"}},[a("img",{attrs:{src:"/img/case-studies-logos/lexe-130.png"}})])]),t._v(" "),a("div",{staticClass:"tagline"},[a("h3",[a("a",{attrs:{href:"https://lexe.app/",target:"_blank"}},[t._v("Lexe Wallet")])]),t._v(" "),a("p",[t._v("Lexe is a self-custodial Bitcoin and Lightning wallet that can receive payments 24/7.")])])]),t._v(" "),a("div",{staticClass:"project"},[a("div",{staticClass:"project-logo"},[a("a",{attrs:{href:"https://10101.finance/",target:"_blank"}},[a("img",{attrs:{src:"/img/case-studies-logos/10101-130.png"}})])]),t._v(" "),a("div",{staticClass:"tagline"},[a("h3",[a("a",{attrs:{href:"https://10101.finance/",target:"_blank"}},[t._v("10101")])]),t._v(" "),a("p",[t._v("Decentralised finance. For real. BTC trading without counterparty risk in one easy and fast app.")])])]),t._v(" "),a("div",{staticClass:"project"},[a("div",{staticClass:"project-logo"},[a("a",{attrs:{href:"https://wizardsardine.com/liana/",target:"_blank"}},[a("img",{attrs:{src:"/img/case-studies-logos/liana-130.png"}})])]),t._v(" "),a("div",{staticClass:"tagline"},[a("h3",[a("a",{attrs:{href:"https://wizardsardine.com/liana/",target:"_blank"}},[t._v("Liana")])]),t._v(" "),a("p",[t._v("Never lose your coins. Liana is a simple Bitcoin wallet with built-in loss protection and inheritance.")])])]),t._v(" "),a("div",{staticClass:"project"},[a("div",{staticClass:"project-logo"},[a("a",{attrs:{href:"https://github.com/utreexo/utreexod",target:"_blank"}},[a("img",{attrs:{src:"/img/case-studies-logos/utreexod-130.png"}})])]),t._v(" "),a("div",{staticClass:"tagline"},[a("h3",[a("a",{attrs:{href:"https://github.com/utreexo/utreexod",target:"_blank"}},[t._v("utreexod")])]),t._v(" "),a("p",[t._v("A fully validating Bitcoin node with Utreexo support.")])])])])}),[],!1,null,null,null);a.default=i.exports}}]); \ No newline at end of file +(window.webpackJsonp=window.webpackJsonp||[]).push([[41],{322:function(t,a,s){},381:function(t,a,s){"use strict";s(322)},441:function(t,a,s){"use strict";s.r(a);s(381);var e=s(7),i=Object(e.a)({},(function(){var t=this,a=t._self._c;return a("ContentSlotsDistributor",{attrs:{"slot-key":t.$parent.slotKey}},[a("h1",{attrs:{id:"mobile"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#mobile"}},[t._v("#")]),t._v(" Mobile")]),t._v(" "),a("div",{staticClass:"project"},[a("div",{staticClass:"project-logo"},[a("a",{attrs:{href:"https://bitkey.build/",target:"_blank"}},[a("img",{staticStyle:{"max-height":"130px"},attrs:{src:"/img/case-studies-logos/block-logo.gif"}})])]),t._v(" "),a("div",{staticClass:"tagline"},[a("h2",[a("a",{attrs:{href:"https://bitkey.build/",target:"_blank"}},[t._v("Bitkey")])]),t._v(" "),a("p",[t._v("\n Bitkey is the safe, easy way to own and manage bitcoin. It’s a mobile app, hardware device, and a set of recovery tools, for simple, secure self-custody.\n ")])])]),t._v(" "),a("div",{staticClass:"project"},[a("div",{staticClass:"project-logo"},[a("a",{attrs:{href:"",target:"_blank"}},[a("img",{attrs:{src:"/img/case-studies-logos/peach-130.png"}})])]),t._v(" "),a("div",{staticClass:"tagline"},[a("h2",[a("a",{attrs:{href:"https://peachbitcoin.com/",target:"_blank"}},[t._v("Peach Bitcoin")])]),t._v(" "),a("p",[t._v("Connecting Bitcoin buyers and sellers directly together. Buy or sell bitcoin peer-to-peer anywhere, at anytime.")])])]),t._v(" "),a("div",{staticClass:"project"},[a("div",{staticClass:"project-logo"},[a("a",{attrs:{href:"https://www.mutinywallet.com/",target:"_blank"}},[a("img",{attrs:{src:"/img/case-studies-logos/mutiny-130.png"}})])]),t._v(" "),a("div",{staticClass:"tagline"},[a("h3",[a("a",{attrs:{href:"https://www.mutinywallet.com/",target:"_blank"}},[t._v("Mutiny Wallet")])]),t._v(" "),a("p",[t._v("Mutiny is a self-custodial lightning wallet that runs in the browser.")])])]),t._v(" "),a("div",{staticClass:"project"},[a("div",{staticClass:"project-logo"},[a("a",{attrs:{href:"https://foundationdevices.com/",target:"_blank"}},[a("img",{attrs:{src:"/img/case-studies-logos/foundation-130.png"}})])]),t._v(" "),a("div",{staticClass:"tagline"},[a("h3",[a("a",{attrs:{href:"https://foundationdevices.com/",target:"_blank"}},[t._v("Envoy By Foundation")])]),t._v(" "),a("p",[t._v("A Bitcoin wallet with powerful account management and privacy features. Use alongside your Passport hardware wallet to take true ownership of your Bitcoin.")])])]),t._v(" "),a("div",{staticClass:"project"},[a("div",{staticClass:"project-logo"},[a("a",{attrs:{href:"https://www.bullbitcoin.com/",target:"_blank"}},[a("img",{attrs:{src:"/img/case-studies-logos/bull-bitcoin-130.png"}})])]),t._v(" "),a("div",{staticClass:"tagline"},[a("h3",[a("a",{attrs:{href:"https://www.bullbitcoin.com/",target:"_blank"}},[t._v("Bull Bitcoin")])]),t._v(" "),a("p",[t._v("A self-custodial Bitcoin Wallet and Exchange app that lets users buy, sell, spend and get paid with Bitcoin. Bitcoins are automatically sent from the exchange to the user's wallet.")])])]),t._v(" "),a("div",{staticClass:"project"},[a("div",{staticClass:"project-logo"},[a("a",{attrs:{href:"https://www.lava.xyz/",target:"_blank"}},[a("img",{attrs:{src:"/img/case-studies-logos/lava-130.png"}})])]),t._v(" "),a("div",{staticClass:"tagline"},[a("h3",[a("a",{attrs:{href:"https://www.lava.xyz/",target:"_blank"}},[t._v("Lava")])]),t._v(" "),a("p",[t._v("The Future of Finance Available Today. Functional, safe and simple.")])])]),t._v(" "),a("div",{staticClass:"project"},[a("div",{staticClass:"project-logo"},[a("a",{attrs:{href:"https://github.com/lightningdevkit/ldk-node",target:"_blank"}},[a("img",{attrs:{src:"/img/case-studies-logos/ldk-node-130.png"}})])]),t._v(" "),a("div",{staticClass:"tagline"},[a("h3",[a("a",{attrs:{href:"https://github.com/lightningdevkit/ldk-node",target:"_blank"}},[t._v("LDK Node")])]),t._v(" "),a("p",[t._v("A ready-to-go Lightning node library built using LDK and BDK.")])])]),t._v(" "),a("div",{staticClass:"project"},[a("div",{staticClass:"project-logo"},[a("a",{attrs:{href:"https://play.google.com/store/apps/details?id=com.goldenraven.padawanwallet",target:"_blank"}},[a("img",{attrs:{src:"/img/case-studies-logos/padawan-130.png"}})])]),t._v(" "),a("div",{staticClass:"tagline"},[a("h3",[a("a",{attrs:{href:"https://play.google.com/store/apps/details?id=com.goldenraven.padawanwallet",target:"_blank"}},[t._v("Padawan Wallet")])]),t._v(" "),a("p",[t._v("Padawan is a testnet-only bitcoin wallet packed with tutorials to learn how to use bitcoin on mobile.")])])]),t._v(" "),a("div",{staticClass:"project"},[a("div",{staticClass:"project-logo"},[a("a",{attrs:{href:"https://www.smartvaults.io/",target:"_blank"}},[a("img",{staticStyle:{"max-height":"130px"},attrs:{src:"/img/case-studies-logos/smart-vaults-130.png"}})])]),t._v(" "),a("div",{staticClass:"tagline"},[a("h3",[a("a",{attrs:{href:"https://www.smartvaults.io/",target:"_blank"}},[t._v("Smart Vaults")])]),t._v(" "),a("p",[t._v("Determine who, how, and when your Bitcoin can be accessed.")])])]),t._v(" "),a("div",{staticClass:"project"},[a("div",{staticClass:"project-logo"},[a("a",{attrs:{href:"https://play.google.com/store/apps/details?id=com.iriswallet.testnet",target:"_blank"}},[a("img",{attrs:{src:"/img/case-studies-logos/iris-130.png"}})])]),t._v(" "),a("div",{staticClass:"tagline"},[a("h3",[a("a",{attrs:{href:"https://play.google.com/store/apps/details?id=com.iriswallet.testnet",target:"_blank"}},[t._v("Iris Wallet")])]),t._v(" "),a("p",[t._v("Open-source wallet for Bitcoin and RGB assets.")])])]),t._v(" "),a("div",{staticClass:"project"},[a("div",{staticClass:"project-logo"},[a("a",{attrs:{href:"https://github.com/BlockchainCommons/spotbit",target:"_blank"}},[a("img",{attrs:{src:"/img/case-studies-logos/spotbit-130.png"}})])]),t._v(" "),a("div",{staticClass:"tagline"},[a("h3",[a("a",{attrs:{href:"https://github.com/BlockchainCommons/spotbit",target:"_blank"}},[t._v("Spotbit")])]),t._v(" "),a("p",[t._v("Spotbit is a portable API for Bitcoin price data and candles.")])])]),t._v(" "),a("div",{staticClass:"project"},[a("div",{staticClass:"project-logo"},[a("a",{attrs:{href:"https://lipa.swiss/en",target:"_blank"}},[a("img",{attrs:{src:"/img/case-studies-logos/lipa-130.png"}})])]),t._v(" "),a("div",{staticClass:"tagline"},[a("h3",[a("a",{attrs:{href:"https://lipa.swiss/en",target:"_blank"}},[t._v("Lipa")])]),t._v(" "),a("p",[t._v("The Swiss app for cashless payments with Bitcoin.")])])]),t._v(" "),a("div",{staticClass:"project"},[a("div",{staticClass:"project-logo"},[a("a",{attrs:{href:"https://lexe.app/",target:"_blank"}},[a("img",{attrs:{src:"/img/case-studies-logos/lexe-130.png"}})])]),t._v(" "),a("div",{staticClass:"tagline"},[a("h3",[a("a",{attrs:{href:"https://lexe.app/",target:"_blank"}},[t._v("Lexe Wallet")])]),t._v(" "),a("p",[t._v("Lexe is a self-custodial Bitcoin and Lightning wallet that can receive payments 24/7.")])])]),t._v(" "),a("div",{staticClass:"project"},[a("div",{staticClass:"project-logo"},[a("a",{attrs:{href:"https://10101.finance/",target:"_blank"}},[a("img",{attrs:{src:"/img/case-studies-logos/10101-130.png"}})])]),t._v(" "),a("div",{staticClass:"tagline"},[a("h3",[a("a",{attrs:{href:"https://10101.finance/",target:"_blank"}},[t._v("10101")])]),t._v(" "),a("p",[t._v("Decentralised finance. For real. BTC trading without counterparty risk in one easy and fast app.")])])]),t._v(" "),a("div",{staticClass:"project"},[a("div",{staticClass:"project-logo"},[a("a",{attrs:{href:"https://wizardsardine.com/liana/",target:"_blank"}},[a("img",{attrs:{src:"/img/case-studies-logos/liana-130.png"}})])]),t._v(" "),a("div",{staticClass:"tagline"},[a("h3",[a("a",{attrs:{href:"https://wizardsardine.com/liana/",target:"_blank"}},[t._v("Liana")])]),t._v(" "),a("p",[t._v("Never lose your coins. Liana is a simple Bitcoin wallet with built-in loss protection and inheritance.")])])]),t._v(" "),a("div",{staticClass:"project"},[a("div",{staticClass:"project-logo"},[a("a",{attrs:{href:"https://github.com/utreexo/utreexod",target:"_blank"}},[a("img",{attrs:{src:"/img/case-studies-logos/utreexod-130.png"}})])]),t._v(" "),a("div",{staticClass:"tagline"},[a("h3",[a("a",{attrs:{href:"https://github.com/utreexo/utreexod",target:"_blank"}},[t._v("utreexod")])]),t._v(" "),a("p",[t._v("A fully validating Bitcoin node with Utreexo support.")])])])])}),[],!1,null,null,null);a.default=i.exports}}]); \ No newline at end of file diff --git a/assets/js/42.86af1298.js b/assets/js/42.98efa542.js similarity index 96% rename from assets/js/42.86af1298.js rename to assets/js/42.98efa542.js index 72e59f6657..ba3db357c7 100644 --- a/assets/js/42.86af1298.js +++ b/assets/js/42.98efa542.js @@ -1 +1 @@ -(window.webpackJsonp=window.webpackJsonp||[]).push([[42],{324:function(t,a,s){},383:function(t,a,s){"use strict";s(324)},443:function(t,a,s){"use strict";s.r(a);s(383);var e=s(7),i=Object(e.a)({},(function(){var t=this,a=t._self._c;return a("ContentSlotsDistributor",{attrs:{"slot-key":t.$parent.slotKey}},[a("h1",{attrs:{id:"web"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#web"}},[t._v("#")]),t._v(" Web")]),t._v(" "),a("div",{staticClass:"project"},[a("div",{staticClass:"project-logo"},[a("a",{attrs:{href:"https://mempool.space/",target:"_blank"}},[a("img",{attrs:{src:"/img/case-studies-logos/mempool-130.png"}})])]),t._v(" "),a("div",{staticClass:"tagline"},[a("h3",[a("a",{attrs:{href:"https://mempool.space/",target:"_blank"}},[t._v("mempool.space")])]),t._v(" "),a("p",[t._v("Explore the full Bitcoin ecosystem.")])])]),t._v(" "),a("div",{staticClass:"project"},[a("div",{staticClass:"project-logo"},[a("a",{attrs:{href:"https://www.caravanmultisig.com/",target:"_blank"}},[a("img",{attrs:{src:"/img/case-studies-logos/caravan-130.png"}})])]),t._v(" "),a("div",{staticClass:"tagline"},[a("h3",[a("a",{attrs:{href:"https://www.caravanmultisig.com/#/",target:"_blank"}},[t._v("Caravan")])]),t._v(" "),a("p",[t._v("Caravan is a multi-sig coordinator application, and an Unchained-sponsored open source project.")])])]),t._v(" "),a("div",{staticClass:"project"},[a("div",{staticClass:"project-logo"},[a("a",{attrs:{href:"https://bitmask.app/",target:"_blank"}},[a("img",{attrs:{src:"/img/case-studies-logos/bitmask-130.png"}})])]),t._v(" "),a("div",{staticClass:"tagline"},[a("h3",[a("a",{attrs:{href:"https://bitmask.app/",target:"_blank"}},[t._v("BitMask Wallet")])]),t._v(" "),a("p",[t._v("Your Gateway to DeepWeb3 on Bitcoin. A browser extension for decentralized applications on Bitcoin.")])])])])}),[],!1,null,null,null);a.default=i.exports}}]); \ No newline at end of file +(window.webpackJsonp=window.webpackJsonp||[]).push([[42],{324:function(t,a,s){},383:function(t,a,s){"use strict";s(324)},444:function(t,a,s){"use strict";s.r(a);s(383);var e=s(7),i=Object(e.a)({},(function(){var t=this,a=t._self._c;return a("ContentSlotsDistributor",{attrs:{"slot-key":t.$parent.slotKey}},[a("h1",{attrs:{id:"web"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#web"}},[t._v("#")]),t._v(" Web")]),t._v(" "),a("div",{staticClass:"project"},[a("div",{staticClass:"project-logo"},[a("a",{attrs:{href:"https://mempool.space/",target:"_blank"}},[a("img",{attrs:{src:"/img/case-studies-logos/mempool-130.png"}})])]),t._v(" "),a("div",{staticClass:"tagline"},[a("h3",[a("a",{attrs:{href:"https://mempool.space/",target:"_blank"}},[t._v("mempool.space")])]),t._v(" "),a("p",[t._v("Explore the full Bitcoin ecosystem.")])])]),t._v(" "),a("div",{staticClass:"project"},[a("div",{staticClass:"project-logo"},[a("a",{attrs:{href:"https://www.caravanmultisig.com/",target:"_blank"}},[a("img",{attrs:{src:"/img/case-studies-logos/caravan-130.png"}})])]),t._v(" "),a("div",{staticClass:"tagline"},[a("h3",[a("a",{attrs:{href:"https://www.caravanmultisig.com/#/",target:"_blank"}},[t._v("Caravan")])]),t._v(" "),a("p",[t._v("Caravan is a multi-sig coordinator application, and an Unchained-sponsored open source project.")])])]),t._v(" "),a("div",{staticClass:"project"},[a("div",{staticClass:"project-logo"},[a("a",{attrs:{href:"https://bitmask.app/",target:"_blank"}},[a("img",{attrs:{src:"/img/case-studies-logos/bitmask-130.png"}})])]),t._v(" "),a("div",{staticClass:"tagline"},[a("h3",[a("a",{attrs:{href:"https://bitmask.app/",target:"_blank"}},[t._v("BitMask Wallet")])]),t._v(" "),a("p",[t._v("Your Gateway to DeepWeb3 on Bitcoin. A browser extension for decentralized applications on Bitcoin.")])])])])}),[],!1,null,null,null);a.default=i.exports}}]); \ No newline at end of file diff --git a/assets/js/46.8a620891.js b/assets/js/46.5ba99f9c.js similarity index 99% rename from assets/js/46.8a620891.js rename to assets/js/46.5ba99f9c.js index ec54614572..861107ab36 100644 --- a/assets/js/46.8a620891.js +++ b/assets/js/46.5ba99f9c.js @@ -1 +1 @@ -(window.webpackJsonp=window.webpackJsonp||[]).push([[46],{400:function(e,t,r){"use strict";r.r(t);var n=r(7),o=Object(n.a)({},(function(){var e=this,t=e._self._c;return t("ContentSlotsDistributor",{attrs:{"slot-key":e.$parent.slotKey}},[t("h3",{attrs:{id:"this-post"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#this-post"}},[e._v("#")]),e._v(" This Post")]),e._v(" "),t("p",[e._v("The "),t("a",{attrs:{href:"https://spiral.xyz",target:"_blank",rel:"noopener noreferrer"}},[e._v("Spiral"),t("OutboundLink")],1),e._v(" team has graciously supported BDK financially (and spiritually) for the past four years and since early 2022 the BDK team has let folks know what we've been up to via the "),t("a",{attrs:{href:"https://spiral.xyz/blog/",target:"_blank",rel:"noopener noreferrer"}},[e._v("Spiral blog"),t("OutboundLink")],1),e._v(". As of last summer we are grateful to also have received a generous "),t("a",{attrs:{href:"https://opensats.org/blog/bitcoin-and-nostr-grants-august-2023",target:"_blank",rel:"noopener noreferrer"}},[e._v("OpenSats grant"),t("OutboundLink")],1),e._v(" supporting our project. To keep our current and future financial supporters, open source contributors, and downstream users updated on our progress, starting this year we will be publishing a quarterly BDK project updates here on our blog.")]),e._v(" "),t("h3",{attrs:{id:"end-of-year-review"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#end-of-year-review"}},[e._v("#")]),e._v(" End of Year Review")]),e._v(" "),t("p",[e._v("The BDK project is made up of a core suite of "),t("a",{attrs:{href:"https://www.rust-lang.org/",target:"_blank",rel:"noopener noreferrer"}},[e._v("rust"),t("OutboundLink")],1),e._v(" libraries ("),t("a",{attrs:{href:"https://github.com/bitcoindevkit/bdk?tab=readme-ov-file#architecture",target:"_blank",rel:"noopener noreferrer"}},[e._v("bdk-*"),t("OutboundLink")],1),e._v(") that work together to provide everything an application developer needs to incorporate on-chain bitcoin wallet functionality into their project. Wrapped around the BDK core libraries is our "),t("a",{attrs:{href:"https://github.com/bitcoindevkit/bdk-ffi",target:"_blank",rel:"noopener noreferrer"}},[e._v("bdk-ffi"),t("OutboundLink")],1),e._v(" bindings libraries that let Kotlin (desktop/android), Swift (desktop/iOS), and Python developers use BDK seamlessly in their projects. And wrapped around all of this software is documentation and examples. For over a year the BDK team has been working on a major "),t("a",{attrs:{href:"https://bitcoindevkit.org/blog/tags/architecture/",target:"_blank",rel:"noopener noreferrer"}},[e._v("re-architecture"),t("OutboundLink")],1),e._v(" of the BDK libraries to improve blockchain syncing, embedded device support ("),t("a",{attrs:{href:"https://docs.rust-embedded.org/book/intro/no-std.html",target:"_blank",rel:"noopener noreferrer"}},[e._v("no-std"),t("OutboundLink")],1),e._v("), update key dependencies ("),t("a",{attrs:{href:"https://github.com/rust-bitcoin/rust-bitcoin",target:"_blank",rel:"noopener noreferrer"}},[e._v("rust-bitcoin"),t("OutboundLink")],1),e._v(", "),t("a",{attrs:{href:"https://github.com/rust-bitcoin/rust-miniscript",target:"_blank",rel:"noopener noreferrer"}},[e._v("rust-miniscript"),t("OutboundLink")],1),e._v(") and finally to provide a stable 1.0 API that our users can rely on for their production applications.")]),e._v(" "),t("p",[e._v("The team is currently working on the 1.0.0-alpha release train. The purposed of these alpha releases is to give early adopters (including our own "),t("code",[e._v("bdk-ffi")]),e._v(" contributors) a chance to try-out new BDK features and updated APIs and provide feedback. Once we have a stable, feature complete 1.0.0 BDK that our alpha users love we'll begin publishing 1.0.0-beta releases. With our beta releases we will finish updating tutorials and examples and performance testing, and ask all BDK users to start migrating and testing their applications with BDK 1.0.0. When our key contributors and users are satisfied that we have shaken out any final 1.0.0-beta issues we'll publish our BDK 1.0.0 release. Once 1.0.0 is out subsequent releases will use "),t("a",{attrs:{href:"https://semver.org/",target:"_blank",rel:"noopener noreferrer"}},[e._v("semantic versioning"),t("OutboundLink")],1),e._v(".")]),e._v(" "),t("p",[e._v("For those keeping score, we'd originally planned to have the BDK 1.0.0 release out last year, but (spoiler) that didn't happen. As I'm sure our kind readers understand making safe, feature rich, easy to use bitcoin software isn't easy, reviewing it is even harder, and we, like every project in the space are short-handed. But with every release, as we build the software we also on-board new contributors and build the team that will deliver BDK 1.0.0, 1.1.0, 2.0.0, and beyond.")]),e._v(" "),t("h3",{attrs:{id:"core-bdk"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#core-bdk"}},[e._v("#")]),e._v(" Core BDK")]),e._v(" "),t("p",[e._v("For Q4 2023 we "),t("a",{attrs:{href:"https://github.com/bitcoindevkit/bdk/pulls?page=1&q=is%3Apr+merged%3A2023-10-01..2023-12-31",target:"_blank",rel:"noopener noreferrer"}},[e._v("merged 33 PRs"),t("OutboundLink")],1),e._v(", "),t("a",{attrs:{href:"https://github.com/bitcoindevkit/bdk/issues?q=is%3Aissue+closed%3A2023-10-01..2023-12-31",target:"_blank",rel:"noopener noreferrer"}},[e._v("closed 32 issues"),t("OutboundLink")],1),e._v(", and completed two 1.0.0-alpha releases, "),t("a",{attrs:{href:"https://github.com/bitcoindevkit/bdk/releases/tag/v1.0.0-alpha.2",target:"_blank",rel:"noopener noreferrer"}},[e._v("1.0.0-alpha.2"),t("OutboundLink")],1),e._v(" and "),t("a",{attrs:{href:"https://github.com/bitcoindevkit/bdk/releases/tag/v1.0.0-alpha.3",target:"_blank",rel:"noopener noreferrer"}},[e._v("1.0.0-alpha.3"),t("OutboundLink")],1),e._v(". The primary deliverable of these releases was to further stabilize the "),t("code",[e._v("bdk_chain")]),e._v(" crate which provides the central logic for tracking and updating wallet keychains and scripts to be tracked and manages all of the related blockchain and transaction data. Additional PRs started this quarter lay the groundwork for the next phase of development focused on improving how we sync data via blockchain clients and save that data to persistent storage. We also made one maintenance release "),t("a",{attrs:{href:"https://github.com/bitcoindevkit/bdk/releases/tag/v0.29.0",target:"_blank",rel:"noopener noreferrer"}},[e._v("0.29.0"),t("OutboundLink")],1),e._v(" that upgraded our "),t("code",[e._v("rust-bitcoin")]),e._v(" dependency to release to 0.30.")]),e._v(" "),t("h3",{attrs:{id:"bdk-ffi"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#bdk-ffi"}},[e._v("#")]),e._v(" BDK-FFI")]),e._v(" "),t("p",[e._v("In Q4 the BDK-FFI bindings for Kotlin, Swift, and Python saw "),t("a",{attrs:{href:"https://github.com/bitcoindevkit/bdk-ffi/pulls?page=1&q=is%3Apr+merged%3A2023-10-01..2023-12-31",target:"_blank",rel:"noopener noreferrer"}},[e._v("23 PRs merged"),t("OutboundLink")],1),e._v(" and "),t("a",{attrs:{href:"https://github.com/bitcoindevkit/bdk-ffi/issues?q=is%3Aissue+closed%3A2023-10-01..2023-12-31",target:"_blank",rel:"noopener noreferrer"}},[e._v("15 issues closed"),t("OutboundLink")],1),e._v(". One maintenance release was completed, "),t("a",{attrs:{href:"https://github.com/bitcoindevkit/bdk-ffi/releases/tag/v0.31.0",target:"_blank",rel:"noopener noreferrer"}},[e._v("v0.31.0"),t("OutboundLink")],1),e._v(", which updated the language bindings dependency to the latest rust "),t("code",[e._v("bdk")]),e._v(" maintenance release 0.29.0 and in doing so updated the BDK FFI "),t("code",[e._v("rust-bitcoin")]),e._v(" dependency to version 0.30. This quarter the team took on the major task of creating the first language bindings based on the "),t("code",[e._v("bdk")]),e._v(" 1.0.0-alpha API. The resulting "),t("code",[e._v("bdk-ffi")]),e._v(" "),t("a",{attrs:{href:"https://github.com/bitcoindevkit/bdk-ffi/releases/tag/v1.0.0-alpha.2a",target:"_blank",rel:"noopener noreferrer"}},[e._v("v1.0.0-alpha2a"),t("OutboundLink")],1),e._v(" release is only able to expose part of the full "),t("code",[e._v("bdk")]),e._v(" 1.0.0 API but prepares the project for full support in future releases. As part of this work the current Kotlin API docs were removed, but fear not they will return in future alpha releases and be better than ever with not only API docs for Kotlin but also Swift and Python.")]),e._v(" "),t("h3",{attrs:{id:"bdk-contributors-spotlight"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#bdk-contributors-spotlight"}},[e._v("#")]),e._v(" BDK contributors spotlight")]),e._v(" "),t("p",[e._v("In this section we share what some of our hardworking contributors are doing to educate people about BDK, help on board new projects, and generally promote bitcoin and open source development around the world.")]),e._v(" "),t("p",[t("strong",[t("a",{attrs:{href:"https://github.com/danielabrozzoni/",target:"_blank",rel:"noopener noreferrer"}},[e._v("Daniela Brozzoni"),t("OutboundLink")],1)])]),e._v(" "),t("p",[e._v("November 3: Gave a "),t("a",{attrs:{href:"https://bolt.fun",target:"_blank",rel:"noopener noreferrer"}},[e._v("bolt.fun"),t("OutboundLink")],1),e._v(" talk on open source development, "),t("a",{attrs:{href:"https://www.youtube.com/watch?v=P75nCR1owws",target:"_blank",rel:"noopener noreferrer"}},[e._v("YouTube"),t("OutboundLink")],1),e._v(".")]),e._v(" "),t("p",[e._v("October 25-26: Joined a "),t("a",{attrs:{href:"https://planb.lugano.ch/contributing-to-free-and-open-source-projects/",target:"_blank",rel:"noopener noreferrer"}},[e._v('"Contributing to free and open source projects" panel'),t("OutboundLink")],1),e._v(" at "),t("a",{attrs:{href:"https://planb.lugano.ch/",target:"_blank",rel:"noopener noreferrer"}},[e._v("Plan B"),t("OutboundLink")],1),e._v(" lugano.")]),e._v(" "),t("p",[t("strong",[t("a",{attrs:{href:"https://github.com/evanlinjin/",target:"_blank",rel:"noopener noreferrer"}},[e._v("Evan Linjin"),t("OutboundLink")],1)])]),e._v(" "),t("p",[e._v("November 15: Worked with "),t("a",{attrs:{href:"https://wizardsardine.com/",target:"_blank",rel:"noopener noreferrer"}},[e._v("wizardsardine"),t("OutboundLink")],1),e._v(" team to "),t("a",{attrs:{href:"https://twitter.com/darosior/status/1724842410839093562",target:"_blank",rel:"noopener noreferrer"}},[e._v("extract and integrate BDK coin-selection into the Liana wallet"),t("OutboundLink")],1),e._v(".")]),e._v(" "),t("p",[e._v("December 3: Spoke at the "),t("a",{attrs:{href:"https://twitter.com/TaiwanBitdevs/status/1726537941688967238",target:"_blank",rel:"noopener noreferrer"}},[e._v("Bitcoin Tech Summit Taipei"),t("OutboundLink")],1),e._v(".")]),e._v(" "),t("p",[e._v("December 13: Gave a talk about Bitcoin and BDK at "),t("a",{attrs:{href:"https://twitter.com/JCBA_org/status/1735100779172856170",target:"_blank",rel:"noopener noreferrer"}},[e._v("Taipei Blockchain Week"),t("OutboundLink")],1),e._v(".")]),e._v(" "),t("p",[t("strong",[t("a",{attrs:{href:"https://github.com/thunderbiscuit/",target:"_blank",rel:"noopener noreferrer"}},[e._v("Thunderbiscuit"),t("OutboundLink")],1)])]),e._v(" "),t("p",[e._v("November 8: Created the educational "),t("a",{attrs:{href:"https://opcodeexplained.com/",target:"_blank",rel:"noopener noreferrer"}},[e._v("Opcode Explained"),t("OutboundLink")],1),e._v(" website to help... explain bitcoin opcodes!")]),e._v(" "),t("p",[e._v("November 15: Joined the panel on the "),t("a",{attrs:{href:"https://bitcoin.review/podcast/episode-55/",target:"_blank",rel:"noopener noreferrer"}},[e._v("Bitcoin Review Podcast Episode 55"),t("OutboundLink")],1),e._v(" to talked about his "),t("a",{attrs:{href:"https://github.com/thunderbiscuit/padawan-wallet",target:"_blank",rel:"noopener noreferrer"}},[e._v("padawan-wallet"),t("OutboundLink")],1),e._v(" project.")]),e._v(" "),t("p",[t("strong",[t("a",{attrs:{href:"https://github.com/reez/",target:"_blank",rel:"noopener noreferrer"}},[e._v("Matthew Ramsden"),t("OutboundLink")],1)])]),e._v(" "),t("p",[e._v("October 11: Spoke at the "),t("a",{attrs:{href:"https://www.meetup.com/bitcoinpark/events/291768716/",target:"_blank",rel:"noopener noreferrer"}},[e._v("Bitcoin Park OpenHouse"),t("OutboundLink")],1),e._v(" on the topic "),t("a",{attrs:{href:"https://podcasts.apple.com/us/podcast/open-house-exploring-the-lightning-network-ldk/id1646515985?i=1000631904227",target:"_blank",rel:"noopener noreferrer"}},[e._v('"Exploring the Lightning Network"'),t("OutboundLink")],1),e._v(".")]),e._v(" "),t("p",[e._v("November 8: Created a video for the "),t("a",{attrs:{href:"https://www.youtube.com/@bitcoindevelopers",target:"_blank",rel:"noopener noreferrer"}},[e._v("Bitcoin Developers"),t("OutboundLink")],1),e._v(" channel on YouTube titled "),t("a",{attrs:{href:"https://www.youtube.com/watch?v=rcU3LU6iZCs",target:"_blank",rel:"noopener noreferrer"}},[e._v('"Lightning Development with Swift: Make Your First Lightning App with LDK Node Swift"'),t("OutboundLink")],1),e._v(".")]),e._v(" "),t("p",[t("strong",[e._v("Other current and future contributors...")])]),e._v(" "),t("p",[e._v("If you are a contributor to BDK and doing something fun that's BDK and/or bitcoin related let us know! Tag "),t("a",{attrs:{href:"https://twitter.com/bitcoindevkit/",target:"_blank",rel:"noopener noreferrer"}},[e._v("@bitcoindevkit"),t("OutboundLink")],1),e._v(" on X, "),t("a",{attrs:{href:"https://primal.net/profile/npub1ke470rdgnxg4gjs9cw3tv0dp690wl68f5xak5smflpsksedadd7qtf8jfm",target:"_blank",rel:"noopener noreferrer"}},[e._v("notmandatory"),t("OutboundLink")],1),e._v(" on nostr, or send us an email: blog at bitcoindevkit dot org.")])])}),[],!1,null,null,null);t.default=o.exports}}]); \ No newline at end of file +(window.webpackJsonp=window.webpackJsonp||[]).push([[46],{402:function(e,t,r){"use strict";r.r(t);var n=r(7),o=Object(n.a)({},(function(){var e=this,t=e._self._c;return t("ContentSlotsDistributor",{attrs:{"slot-key":e.$parent.slotKey}},[t("h3",{attrs:{id:"this-post"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#this-post"}},[e._v("#")]),e._v(" This Post")]),e._v(" "),t("p",[e._v("The "),t("a",{attrs:{href:"https://spiral.xyz",target:"_blank",rel:"noopener noreferrer"}},[e._v("Spiral"),t("OutboundLink")],1),e._v(" team has graciously supported BDK financially (and spiritually) for the past four years and since early 2022 the BDK team has let folks know what we've been up to via the "),t("a",{attrs:{href:"https://spiral.xyz/blog/",target:"_blank",rel:"noopener noreferrer"}},[e._v("Spiral blog"),t("OutboundLink")],1),e._v(". As of last summer we are grateful to also have received a generous "),t("a",{attrs:{href:"https://opensats.org/blog/bitcoin-and-nostr-grants-august-2023",target:"_blank",rel:"noopener noreferrer"}},[e._v("OpenSats grant"),t("OutboundLink")],1),e._v(" supporting our project. To keep our current and future financial supporters, open source contributors, and downstream users updated on our progress, starting this year we will be publishing a quarterly BDK project updates here on our blog.")]),e._v(" "),t("h3",{attrs:{id:"end-of-year-review"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#end-of-year-review"}},[e._v("#")]),e._v(" End of Year Review")]),e._v(" "),t("p",[e._v("The BDK project is made up of a core suite of "),t("a",{attrs:{href:"https://www.rust-lang.org/",target:"_blank",rel:"noopener noreferrer"}},[e._v("rust"),t("OutboundLink")],1),e._v(" libraries ("),t("a",{attrs:{href:"https://github.com/bitcoindevkit/bdk?tab=readme-ov-file#architecture",target:"_blank",rel:"noopener noreferrer"}},[e._v("bdk-*"),t("OutboundLink")],1),e._v(") that work together to provide everything an application developer needs to incorporate on-chain bitcoin wallet functionality into their project. Wrapped around the BDK core libraries is our "),t("a",{attrs:{href:"https://github.com/bitcoindevkit/bdk-ffi",target:"_blank",rel:"noopener noreferrer"}},[e._v("bdk-ffi"),t("OutboundLink")],1),e._v(" bindings libraries that let Kotlin (desktop/android), Swift (desktop/iOS), and Python developers use BDK seamlessly in their projects. And wrapped around all of this software is documentation and examples. For over a year the BDK team has been working on a major "),t("a",{attrs:{href:"https://bitcoindevkit.org/blog/tags/architecture/",target:"_blank",rel:"noopener noreferrer"}},[e._v("re-architecture"),t("OutboundLink")],1),e._v(" of the BDK libraries to improve blockchain syncing, embedded device support ("),t("a",{attrs:{href:"https://docs.rust-embedded.org/book/intro/no-std.html",target:"_blank",rel:"noopener noreferrer"}},[e._v("no-std"),t("OutboundLink")],1),e._v("), update key dependencies ("),t("a",{attrs:{href:"https://github.com/rust-bitcoin/rust-bitcoin",target:"_blank",rel:"noopener noreferrer"}},[e._v("rust-bitcoin"),t("OutboundLink")],1),e._v(", "),t("a",{attrs:{href:"https://github.com/rust-bitcoin/rust-miniscript",target:"_blank",rel:"noopener noreferrer"}},[e._v("rust-miniscript"),t("OutboundLink")],1),e._v(") and finally to provide a stable 1.0 API that our users can rely on for their production applications.")]),e._v(" "),t("p",[e._v("The team is currently working on the 1.0.0-alpha release train. The purposed of these alpha releases is to give early adopters (including our own "),t("code",[e._v("bdk-ffi")]),e._v(" contributors) a chance to try-out new BDK features and updated APIs and provide feedback. Once we have a stable, feature complete 1.0.0 BDK that our alpha users love we'll begin publishing 1.0.0-beta releases. With our beta releases we will finish updating tutorials and examples and performance testing, and ask all BDK users to start migrating and testing their applications with BDK 1.0.0. When our key contributors and users are satisfied that we have shaken out any final 1.0.0-beta issues we'll publish our BDK 1.0.0 release. Once 1.0.0 is out subsequent releases will use "),t("a",{attrs:{href:"https://semver.org/",target:"_blank",rel:"noopener noreferrer"}},[e._v("semantic versioning"),t("OutboundLink")],1),e._v(".")]),e._v(" "),t("p",[e._v("For those keeping score, we'd originally planned to have the BDK 1.0.0 release out last year, but (spoiler) that didn't happen. As I'm sure our kind readers understand making safe, feature rich, easy to use bitcoin software isn't easy, reviewing it is even harder, and we, like every project in the space are short-handed. But with every release, as we build the software we also on-board new contributors and build the team that will deliver BDK 1.0.0, 1.1.0, 2.0.0, and beyond.")]),e._v(" "),t("h3",{attrs:{id:"core-bdk"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#core-bdk"}},[e._v("#")]),e._v(" Core BDK")]),e._v(" "),t("p",[e._v("For Q4 2023 we "),t("a",{attrs:{href:"https://github.com/bitcoindevkit/bdk/pulls?page=1&q=is%3Apr+merged%3A2023-10-01..2023-12-31",target:"_blank",rel:"noopener noreferrer"}},[e._v("merged 33 PRs"),t("OutboundLink")],1),e._v(", "),t("a",{attrs:{href:"https://github.com/bitcoindevkit/bdk/issues?q=is%3Aissue+closed%3A2023-10-01..2023-12-31",target:"_blank",rel:"noopener noreferrer"}},[e._v("closed 32 issues"),t("OutboundLink")],1),e._v(", and completed two 1.0.0-alpha releases, "),t("a",{attrs:{href:"https://github.com/bitcoindevkit/bdk/releases/tag/v1.0.0-alpha.2",target:"_blank",rel:"noopener noreferrer"}},[e._v("1.0.0-alpha.2"),t("OutboundLink")],1),e._v(" and "),t("a",{attrs:{href:"https://github.com/bitcoindevkit/bdk/releases/tag/v1.0.0-alpha.3",target:"_blank",rel:"noopener noreferrer"}},[e._v("1.0.0-alpha.3"),t("OutboundLink")],1),e._v(". The primary deliverable of these releases was to further stabilize the "),t("code",[e._v("bdk_chain")]),e._v(" crate which provides the central logic for tracking and updating wallet keychains and scripts to be tracked and manages all of the related blockchain and transaction data. Additional PRs started this quarter lay the groundwork for the next phase of development focused on improving how we sync data via blockchain clients and save that data to persistent storage. We also made one maintenance release "),t("a",{attrs:{href:"https://github.com/bitcoindevkit/bdk/releases/tag/v0.29.0",target:"_blank",rel:"noopener noreferrer"}},[e._v("0.29.0"),t("OutboundLink")],1),e._v(" that upgraded our "),t("code",[e._v("rust-bitcoin")]),e._v(" dependency to release to 0.30.")]),e._v(" "),t("h3",{attrs:{id:"bdk-ffi"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#bdk-ffi"}},[e._v("#")]),e._v(" BDK-FFI")]),e._v(" "),t("p",[e._v("In Q4 the BDK-FFI bindings for Kotlin, Swift, and Python saw "),t("a",{attrs:{href:"https://github.com/bitcoindevkit/bdk-ffi/pulls?page=1&q=is%3Apr+merged%3A2023-10-01..2023-12-31",target:"_blank",rel:"noopener noreferrer"}},[e._v("23 PRs merged"),t("OutboundLink")],1),e._v(" and "),t("a",{attrs:{href:"https://github.com/bitcoindevkit/bdk-ffi/issues?q=is%3Aissue+closed%3A2023-10-01..2023-12-31",target:"_blank",rel:"noopener noreferrer"}},[e._v("15 issues closed"),t("OutboundLink")],1),e._v(". One maintenance release was completed, "),t("a",{attrs:{href:"https://github.com/bitcoindevkit/bdk-ffi/releases/tag/v0.31.0",target:"_blank",rel:"noopener noreferrer"}},[e._v("v0.31.0"),t("OutboundLink")],1),e._v(", which updated the language bindings dependency to the latest rust "),t("code",[e._v("bdk")]),e._v(" maintenance release 0.29.0 and in doing so updated the BDK FFI "),t("code",[e._v("rust-bitcoin")]),e._v(" dependency to version 0.30. This quarter the team took on the major task of creating the first language bindings based on the "),t("code",[e._v("bdk")]),e._v(" 1.0.0-alpha API. The resulting "),t("code",[e._v("bdk-ffi")]),e._v(" "),t("a",{attrs:{href:"https://github.com/bitcoindevkit/bdk-ffi/releases/tag/v1.0.0-alpha.2a",target:"_blank",rel:"noopener noreferrer"}},[e._v("v1.0.0-alpha2a"),t("OutboundLink")],1),e._v(" release is only able to expose part of the full "),t("code",[e._v("bdk")]),e._v(" 1.0.0 API but prepares the project for full support in future releases. As part of this work the current Kotlin API docs were removed, but fear not they will return in future alpha releases and be better than ever with not only API docs for Kotlin but also Swift and Python.")]),e._v(" "),t("h3",{attrs:{id:"bdk-contributors-spotlight"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#bdk-contributors-spotlight"}},[e._v("#")]),e._v(" BDK contributors spotlight")]),e._v(" "),t("p",[e._v("In this section we share what some of our hardworking contributors are doing to educate people about BDK, help on board new projects, and generally promote bitcoin and open source development around the world.")]),e._v(" "),t("p",[t("strong",[t("a",{attrs:{href:"https://github.com/danielabrozzoni/",target:"_blank",rel:"noopener noreferrer"}},[e._v("Daniela Brozzoni"),t("OutboundLink")],1)])]),e._v(" "),t("p",[e._v("November 3: Gave a "),t("a",{attrs:{href:"https://bolt.fun",target:"_blank",rel:"noopener noreferrer"}},[e._v("bolt.fun"),t("OutboundLink")],1),e._v(" talk on open source development, "),t("a",{attrs:{href:"https://www.youtube.com/watch?v=P75nCR1owws",target:"_blank",rel:"noopener noreferrer"}},[e._v("YouTube"),t("OutboundLink")],1),e._v(".")]),e._v(" "),t("p",[e._v("October 25-26: Joined a "),t("a",{attrs:{href:"https://planb.lugano.ch/contributing-to-free-and-open-source-projects/",target:"_blank",rel:"noopener noreferrer"}},[e._v('"Contributing to free and open source projects" panel'),t("OutboundLink")],1),e._v(" at "),t("a",{attrs:{href:"https://planb.lugano.ch/",target:"_blank",rel:"noopener noreferrer"}},[e._v("Plan B"),t("OutboundLink")],1),e._v(" lugano.")]),e._v(" "),t("p",[t("strong",[t("a",{attrs:{href:"https://github.com/evanlinjin/",target:"_blank",rel:"noopener noreferrer"}},[e._v("Evan Linjin"),t("OutboundLink")],1)])]),e._v(" "),t("p",[e._v("November 15: Worked with "),t("a",{attrs:{href:"https://wizardsardine.com/",target:"_blank",rel:"noopener noreferrer"}},[e._v("wizardsardine"),t("OutboundLink")],1),e._v(" team to "),t("a",{attrs:{href:"https://twitter.com/darosior/status/1724842410839093562",target:"_blank",rel:"noopener noreferrer"}},[e._v("extract and integrate BDK coin-selection into the Liana wallet"),t("OutboundLink")],1),e._v(".")]),e._v(" "),t("p",[e._v("December 3: Spoke at the "),t("a",{attrs:{href:"https://twitter.com/TaiwanBitdevs/status/1726537941688967238",target:"_blank",rel:"noopener noreferrer"}},[e._v("Bitcoin Tech Summit Taipei"),t("OutboundLink")],1),e._v(".")]),e._v(" "),t("p",[e._v("December 13: Gave a talk about Bitcoin and BDK at "),t("a",{attrs:{href:"https://twitter.com/JCBA_org/status/1735100779172856170",target:"_blank",rel:"noopener noreferrer"}},[e._v("Taipei Blockchain Week"),t("OutboundLink")],1),e._v(".")]),e._v(" "),t("p",[t("strong",[t("a",{attrs:{href:"https://github.com/thunderbiscuit/",target:"_blank",rel:"noopener noreferrer"}},[e._v("Thunderbiscuit"),t("OutboundLink")],1)])]),e._v(" "),t("p",[e._v("November 8: Created the educational "),t("a",{attrs:{href:"https://opcodeexplained.com/",target:"_blank",rel:"noopener noreferrer"}},[e._v("Opcode Explained"),t("OutboundLink")],1),e._v(" website to help... explain bitcoin opcodes!")]),e._v(" "),t("p",[e._v("November 15: Joined the panel on the "),t("a",{attrs:{href:"https://bitcoin.review/podcast/episode-55/",target:"_blank",rel:"noopener noreferrer"}},[e._v("Bitcoin Review Podcast Episode 55"),t("OutboundLink")],1),e._v(" to talked about his "),t("a",{attrs:{href:"https://github.com/thunderbiscuit/padawan-wallet",target:"_blank",rel:"noopener noreferrer"}},[e._v("padawan-wallet"),t("OutboundLink")],1),e._v(" project.")]),e._v(" "),t("p",[t("strong",[t("a",{attrs:{href:"https://github.com/reez/",target:"_blank",rel:"noopener noreferrer"}},[e._v("Matthew Ramsden"),t("OutboundLink")],1)])]),e._v(" "),t("p",[e._v("October 11: Spoke at the "),t("a",{attrs:{href:"https://www.meetup.com/bitcoinpark/events/291768716/",target:"_blank",rel:"noopener noreferrer"}},[e._v("Bitcoin Park OpenHouse"),t("OutboundLink")],1),e._v(" on the topic "),t("a",{attrs:{href:"https://podcasts.apple.com/us/podcast/open-house-exploring-the-lightning-network-ldk/id1646515985?i=1000631904227",target:"_blank",rel:"noopener noreferrer"}},[e._v('"Exploring the Lightning Network"'),t("OutboundLink")],1),e._v(".")]),e._v(" "),t("p",[e._v("November 8: Created a video for the "),t("a",{attrs:{href:"https://www.youtube.com/@bitcoindevelopers",target:"_blank",rel:"noopener noreferrer"}},[e._v("Bitcoin Developers"),t("OutboundLink")],1),e._v(" channel on YouTube titled "),t("a",{attrs:{href:"https://www.youtube.com/watch?v=rcU3LU6iZCs",target:"_blank",rel:"noopener noreferrer"}},[e._v('"Lightning Development with Swift: Make Your First Lightning App with LDK Node Swift"'),t("OutboundLink")],1),e._v(".")]),e._v(" "),t("p",[t("strong",[e._v("Other current and future contributors...")])]),e._v(" "),t("p",[e._v("If you are a contributor to BDK and doing something fun that's BDK and/or bitcoin related let us know! Tag "),t("a",{attrs:{href:"https://twitter.com/bitcoindevkit/",target:"_blank",rel:"noopener noreferrer"}},[e._v("@bitcoindevkit"),t("OutboundLink")],1),e._v(" on X, "),t("a",{attrs:{href:"https://primal.net/profile/npub1ke470rdgnxg4gjs9cw3tv0dp690wl68f5xak5smflpsksedadd7qtf8jfm",target:"_blank",rel:"noopener noreferrer"}},[e._v("notmandatory"),t("OutboundLink")],1),e._v(" on nostr, or send us an email: blog at bitcoindevkit dot org.")])])}),[],!1,null,null,null);t.default=o.exports}}]); \ No newline at end of file diff --git a/assets/js/47.5dee4bad.js b/assets/js/47.70dc63ea.js similarity index 98% rename from assets/js/47.5dee4bad.js rename to assets/js/47.70dc63ea.js index 757156a73a..c289322578 100644 --- a/assets/js/47.5dee4bad.js +++ b/assets/js/47.70dc63ea.js @@ -1 +1 @@ -(window.webpackJsonp=window.webpackJsonp||[]).push([[47],{401:function(e,t,r){"use strict";r.r(t);var a=r(7),n=Object(a.a)({},(function(){var e=this,t=e._self._c;return t("ContentSlotsDistributor",{attrs:{"slot-key":e.$parent.slotKey}},[t("br"),e._v(" "),t("h3",{attrs:{id:"core-bdk"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#core-bdk"}},[e._v("#")]),e._v(" Core BDK")]),e._v(" "),t("p",[e._v("The majority of BDK rust library work this quarter was towards finishing new and improved electrum, esplora and Bitcoin Core RPC (block-by-block) syncing APIs. Bug fixes and improvements were also completed for the transaction builder and other wallet APIs. Six bi-weekly 1.0.0-alpha releases were made ("),t("a",{attrs:{href:"https://github.com/bitcoindevkit/bdk/releases/tag/v1.0.0-alpha.3",target:"_blank",rel:"noopener noreferrer"}},[e._v("alpha.3"),t("OutboundLink")],1),e._v(", "),t("a",{attrs:{href:"https://github.com/bitcoindevkit/bdk/releases/tag/v1.0.0-alpha.4",target:"_blank",rel:"noopener noreferrer"}},[e._v("alpha.4"),t("OutboundLink")],1),e._v(", "),t("a",{attrs:{href:"https://github.com/bitcoindevkit/bdk/releases/tag/v1.0.0-alpha.5",target:"_blank",rel:"noopener noreferrer"}},[e._v("alpha.5"),t("OutboundLink")],1),e._v(", "),t("a",{attrs:{href:"https://github.com/bitcoindevkit/bdk/releases/tag/v1.0.0-alpha.6",target:"_blank",rel:"noopener noreferrer"}},[e._v("alpha.6"),t("OutboundLink")],1),e._v(", "),t("a",{attrs:{href:"https://github.com/bitcoindevkit/bdk/releases/tag/v1.0.0-alpha.7",target:"_blank",rel:"noopener noreferrer"}},[e._v("alpha.7"),t("OutboundLink")],1),e._v(", "),t("a",{attrs:{href:"https://github.com/bitcoindevkit/bdk/releases/tag/v1.0.0-alpha.8",target:"_blank",rel:"noopener noreferrer"}},[e._v("alpha.8"),t("OutboundLink")],1),e._v("). For the quarter "),t("a",{attrs:{href:"https://github.com/bitcoindevkit/bdk/pulls?q=is%3Apr+merged%3A2024-01-01..2024-03-31+",target:"_blank",rel:"noopener noreferrer"}},[e._v("54 PRs"),t("OutboundLink")],1),e._v(" were merged and "),t("a",{attrs:{href:"https://github.com/bitcoindevkit/bdk/issues?q=is%3Aissue+closed%3A2024-01-01..2024-03-31+",target:"_blank",rel:"noopener noreferrer"}},[e._v("55 issues"),t("OutboundLink")],1),e._v(" were closed.")]),e._v(" "),t("h3",{attrs:{id:"bdk-ffi"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#bdk-ffi"}},[e._v("#")]),e._v(" BDK-FFI")]),e._v(" "),t("p",[e._v("For the language binding libraries (Kotlin, Swift, Python) the focus was on small bug fixes for the pre-1.0 releases ("),t("a",{attrs:{href:"https://github.com/bitcoindevkit/bdk-ffi/releases/tag/v0.31.0",target:"_blank",rel:"noopener noreferrer"}},[e._v("0.30.0"),t("OutboundLink")],1),e._v(" and "),t("a",{attrs:{href:"https://github.com/bitcoindevkit/bdk-ffi/releases/tag/v0.31.1",target:"_blank",rel:"noopener noreferrer"}},[e._v("0.30.1"),t("OutboundLink")],1),e._v(") and creating the first 1.0.0-alpha bindings release ("),t("a",{attrs:{href:"https://github.com/bitcoindevkit/bdk-ffi/releases/tag/v1.0.0-alpha.7",target:"_blank",rel:"noopener noreferrer"}},[e._v("1.0.0-alpha.7"),t("OutboundLink")],1),e._v("). For the quarter "),t("a",{attrs:{href:"https://github.com/bitcoindevkit/bdk-ffi/pulls?q=is%3Apr+merged%3A2024-01-01..2024-03-31+",target:"_blank",rel:"noopener noreferrer"}},[e._v("23 PRs"),t("OutboundLink")],1),e._v(" were merged and "),t("a",{attrs:{href:"https://github.com/bitcoindevkit/bdk-ffi/issues?q=is%3Aissue+closed%3A2024-01-01..2024-03-31+",target:"_blank",rel:"noopener noreferrer"}},[e._v("8 issues"),t("OutboundLink")],1),e._v(" closed.")]),e._v(" "),t("h3",{attrs:{id:"plans-for-next-quarter"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#plans-for-next-quarter"}},[e._v("#")]),e._v(" Plans for Next Quarter")]),e._v(" "),t("p",[e._v("The focus for Q2 development is completing our first 1.0.0 beta release and improving user docs and testing for it. The team will also work on updating all language bindings (Kotlin/Swift/Python) to use new rust lib 1.0.0 beta APIs.")]),e._v(" "),t("h3",{attrs:{id:"bdk-contributors-spotlight"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#bdk-contributors-spotlight"}},[e._v("#")]),e._v(" BDK contributors spotlight")]),e._v(" "),t("p",[e._v("In this section we share what some of our hardworking contributors are doing to educate people about BDK, help on board new projects, and generally promote bitcoin and open source development around the world.")]),e._v(" "),t("p",[t("strong",[t("a",{attrs:{href:"https://github.com/evanlinjin/",target:"_blank",rel:"noopener noreferrer"}},[e._v("Evan Linjin"),t("OutboundLink")],1)])]),e._v(" "),t("p",[e._v("February 22: Gave a talk on "),t("a",{attrs:{href:"https://btcplusplus.dev/conf/ba24/talks",target:"_blank",rel:"noopener noreferrer"}},[e._v("BDK 1.0 at BTC++"),t("OutboundLink")],1),e._v(" in Buena Aires, Argentina.")]),e._v(" "),t("p",[t("strong",[e._v("Other current and future contributors...")])]),e._v(" "),t("p",[e._v("If you are a contributor to BDK and doing something fun that's BDK and/or bitcoin related let us know! Tag "),t("a",{attrs:{href:"https://twitter.com/bitcoindevkit/",target:"_blank",rel:"noopener noreferrer"}},[e._v("@bitcoindevkit"),t("OutboundLink")],1),e._v(" on X, "),t("a",{attrs:{href:"https://primal.net/profile/npub1ke470rdgnxg4gjs9cw3tv0dp690wl68f5xak5smflpsksedadd7qtf8jfm",target:"_blank",rel:"noopener noreferrer"}},[e._v("notmandatory"),t("OutboundLink")],1),e._v(" on nostr, or send us an email: blog at bitcoindevkit dot org.")])])}),[],!1,null,null,null);t.default=n.exports}}]); \ No newline at end of file +(window.webpackJsonp=window.webpackJsonp||[]).push([[47],{400:function(e,t,r){"use strict";r.r(t);var a=r(7),n=Object(a.a)({},(function(){var e=this,t=e._self._c;return t("ContentSlotsDistributor",{attrs:{"slot-key":e.$parent.slotKey}},[t("br"),e._v(" "),t("h3",{attrs:{id:"core-bdk"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#core-bdk"}},[e._v("#")]),e._v(" Core BDK")]),e._v(" "),t("p",[e._v("The majority of BDK rust library work this quarter was towards finishing new and improved electrum, esplora and Bitcoin Core RPC (block-by-block) syncing APIs. Bug fixes and improvements were also completed for the transaction builder and other wallet APIs. Six bi-weekly 1.0.0-alpha releases were made ("),t("a",{attrs:{href:"https://github.com/bitcoindevkit/bdk/releases/tag/v1.0.0-alpha.3",target:"_blank",rel:"noopener noreferrer"}},[e._v("alpha.3"),t("OutboundLink")],1),e._v(", "),t("a",{attrs:{href:"https://github.com/bitcoindevkit/bdk/releases/tag/v1.0.0-alpha.4",target:"_blank",rel:"noopener noreferrer"}},[e._v("alpha.4"),t("OutboundLink")],1),e._v(", "),t("a",{attrs:{href:"https://github.com/bitcoindevkit/bdk/releases/tag/v1.0.0-alpha.5",target:"_blank",rel:"noopener noreferrer"}},[e._v("alpha.5"),t("OutboundLink")],1),e._v(", "),t("a",{attrs:{href:"https://github.com/bitcoindevkit/bdk/releases/tag/v1.0.0-alpha.6",target:"_blank",rel:"noopener noreferrer"}},[e._v("alpha.6"),t("OutboundLink")],1),e._v(", "),t("a",{attrs:{href:"https://github.com/bitcoindevkit/bdk/releases/tag/v1.0.0-alpha.7",target:"_blank",rel:"noopener noreferrer"}},[e._v("alpha.7"),t("OutboundLink")],1),e._v(", "),t("a",{attrs:{href:"https://github.com/bitcoindevkit/bdk/releases/tag/v1.0.0-alpha.8",target:"_blank",rel:"noopener noreferrer"}},[e._v("alpha.8"),t("OutboundLink")],1),e._v("). For the quarter "),t("a",{attrs:{href:"https://github.com/bitcoindevkit/bdk/pulls?q=is%3Apr+merged%3A2024-01-01..2024-03-31+",target:"_blank",rel:"noopener noreferrer"}},[e._v("54 PRs"),t("OutboundLink")],1),e._v(" were merged and "),t("a",{attrs:{href:"https://github.com/bitcoindevkit/bdk/issues?q=is%3Aissue+closed%3A2024-01-01..2024-03-31+",target:"_blank",rel:"noopener noreferrer"}},[e._v("55 issues"),t("OutboundLink")],1),e._v(" were closed.")]),e._v(" "),t("h3",{attrs:{id:"bdk-ffi"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#bdk-ffi"}},[e._v("#")]),e._v(" BDK-FFI")]),e._v(" "),t("p",[e._v("For the language binding libraries (Kotlin, Swift, Python) the focus was on small bug fixes for the pre-1.0 releases ("),t("a",{attrs:{href:"https://github.com/bitcoindevkit/bdk-ffi/releases/tag/v0.31.0",target:"_blank",rel:"noopener noreferrer"}},[e._v("0.30.0"),t("OutboundLink")],1),e._v(" and "),t("a",{attrs:{href:"https://github.com/bitcoindevkit/bdk-ffi/releases/tag/v0.31.1",target:"_blank",rel:"noopener noreferrer"}},[e._v("0.30.1"),t("OutboundLink")],1),e._v(") and creating the first 1.0.0-alpha bindings release ("),t("a",{attrs:{href:"https://github.com/bitcoindevkit/bdk-ffi/releases/tag/v1.0.0-alpha.7",target:"_blank",rel:"noopener noreferrer"}},[e._v("1.0.0-alpha.7"),t("OutboundLink")],1),e._v("). For the quarter "),t("a",{attrs:{href:"https://github.com/bitcoindevkit/bdk-ffi/pulls?q=is%3Apr+merged%3A2024-01-01..2024-03-31+",target:"_blank",rel:"noopener noreferrer"}},[e._v("23 PRs"),t("OutboundLink")],1),e._v(" were merged and "),t("a",{attrs:{href:"https://github.com/bitcoindevkit/bdk-ffi/issues?q=is%3Aissue+closed%3A2024-01-01..2024-03-31+",target:"_blank",rel:"noopener noreferrer"}},[e._v("8 issues"),t("OutboundLink")],1),e._v(" closed.")]),e._v(" "),t("h3",{attrs:{id:"plans-for-next-quarter"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#plans-for-next-quarter"}},[e._v("#")]),e._v(" Plans for Next Quarter")]),e._v(" "),t("p",[e._v("The focus for Q2 development is completing our first 1.0.0 beta release and improving user docs and testing for it. The team will also work on updating all language bindings (Kotlin/Swift/Python) to use new rust lib 1.0.0 beta APIs.")]),e._v(" "),t("h3",{attrs:{id:"bdk-contributors-spotlight"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#bdk-contributors-spotlight"}},[e._v("#")]),e._v(" BDK contributors spotlight")]),e._v(" "),t("p",[e._v("In this section we share what some of our hardworking contributors are doing to educate people about BDK, help on board new projects, and generally promote bitcoin and open source development around the world.")]),e._v(" "),t("p",[t("strong",[t("a",{attrs:{href:"https://github.com/evanlinjin/",target:"_blank",rel:"noopener noreferrer"}},[e._v("Evan Linjin"),t("OutboundLink")],1)])]),e._v(" "),t("p",[e._v("February 22: Gave a talk on "),t("a",{attrs:{href:"https://btcplusplus.dev/conf/ba24/talks",target:"_blank",rel:"noopener noreferrer"}},[e._v("BDK 1.0 at BTC++"),t("OutboundLink")],1),e._v(" in Buena Aires, Argentina.")]),e._v(" "),t("p",[t("strong",[e._v("Other current and future contributors...")])]),e._v(" "),t("p",[e._v("If you are a contributor to BDK and doing something fun that's BDK and/or bitcoin related let us know! Tag "),t("a",{attrs:{href:"https://twitter.com/bitcoindevkit/",target:"_blank",rel:"noopener noreferrer"}},[e._v("@bitcoindevkit"),t("OutboundLink")],1),e._v(" on X, "),t("a",{attrs:{href:"https://primal.net/profile/npub1ke470rdgnxg4gjs9cw3tv0dp690wl68f5xak5smflpsksedadd7qtf8jfm",target:"_blank",rel:"noopener noreferrer"}},[e._v("notmandatory"),t("OutboundLink")],1),e._v(" on nostr, or send us an email: blog at bitcoindevkit dot org.")])])}),[],!1,null,null,null);t.default=n.exports}}]); \ No newline at end of file diff --git a/assets/js/48.d82a543b.js b/assets/js/48.abab73ce.js similarity index 99% rename from assets/js/48.d82a543b.js rename to assets/js/48.abab73ce.js index 33f726960b..d25e6b614f 100644 --- a/assets/js/48.d82a543b.js +++ b/assets/js/48.abab73ce.js @@ -1 +1 @@ -(window.webpackJsonp=window.webpackJsonp||[]).push([[48],{402: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([[48],{404: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/49.0ab13c0b.js b/assets/js/49.cbffab28.js similarity index 99% rename from assets/js/49.0ab13c0b.js rename to assets/js/49.cbffab28.js index 3bf3ae7025..76cffda9fd 100644 --- a/assets/js/49.0ab13c0b.js +++ b/assets/js/49.cbffab28.js @@ -1 +1 @@ -(window.webpackJsonp=window.webpackJsonp||[]).push([[49],{404: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([[49],{401: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/51.6bd775ae.js b/assets/js/51.503dcbd1.js similarity index 99% rename from assets/js/51.6bd775ae.js rename to assets/js/51.503dcbd1.js index dbcb6c29c3..e07a348e10 100644 --- a/assets/js/51.6bd775ae.js +++ b/assets/js/51.503dcbd1.js @@ -1 +1 @@ -(window.webpackJsonp=window.webpackJsonp||[]).push([[51],{408:function(t,s,a){"use strict";a.r(s);var n=a(7),e=Object(n.a)({},(function(){var t=this,s=t._self._c;return s("ContentSlotsDistributor",{attrs:{"slot-key":t.$parent.slotKey}},[s("h2",{attrs:{id:"introduction"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#introduction"}},[t._v("#")]),t._v(" Introduction")]),t._v(" "),s("p",[t._v("It’s easy to underestimate the importance of privacy tech for Bitcoin,\nespecially when connecting to third party services. They can learn your\nIP address and associate the transactions you sent over it. You can only\nhope that this information will not be leaked anytime in the future with\nunpredictable consequences. In order to use Bitcoin privately, you need\nto encrypt and anonymize the data you send over the Internet.")]),t._v(" "),s("p",[t._v("Tor is one of the must-have privacy preserving tools for the Internet in\ngeneral, and for Bitcoin in particular. Tor network consists of nodes that\nuse clever cryptographic methods to encrypt user data and transfer them as\nanonymously as possible.")]),t._v(" "),s("p",[t._v("In this article we show how to integrate Tor with your BDK application.")]),t._v(" "),s("h2",{attrs:{id:"prerequisite"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#prerequisite"}},[t._v("#")]),t._v(" Prerequisite")]),t._v(" "),s("p",[t._v("First, you would need to have a Tor daemon up and running.")]),t._v(" "),s("p",[t._v("On Mac OS X you can install with Homebrew.")]),t._v(" "),s("div",{staticClass:"language-bash extra-class"},[s("pre",{pre:!0,attrs:{class:"language-bash"}},[s("code",[t._v("brew "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("install")]),t._v(" tor\nbrew services start tor\n")])])]),s("p",[t._v("On Ubuntu or other Debian-based distributions.")]),t._v(" "),s("div",{staticClass:"language-bash extra-class"},[s("pre",{pre:!0,attrs:{class:"language-bash"}},[s("code",[s("span",{pre:!0,attrs:{class:"token function"}},[t._v("sudo")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("apt")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("install")]),t._v(" tor\n")])])]),s("p",[t._v("In some cases you'll need to wait a minute or two for the bootstrapping to finish.\nIn general, Tor is not the fastest network, so if any of the examples below fail\ndue to timeout, simply restart it.")]),t._v(" "),s("p",[t._v("At the very end of the article we’ll show how to integrate Tor directly to\nyour application.")]),t._v(" "),s("p",[t._v("By default, Tor creates a "),s("a",{attrs:{href:"https://en.wikipedia.org/wiki/SOCKS",target:"_blank",rel:"noopener noreferrer"}},[t._v("SOCKS5"),s("OutboundLink")],1),t._v(" proxy\nendpoint and listens on port 9050. Your application should connect to the\nproxy on "),s("code",[t._v("localhost:9050")]),t._v(" and use it for its network activities.")]),t._v(" "),s("h2",{attrs:{id:"setting-up"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#setting-up"}},[t._v("#")]),t._v(" Setting Up")]),t._v(" "),s("p",[t._v("Create a new cargo project.")]),t._v(" "),s("div",{staticClass:"language-bash extra-class"},[s("pre",{pre:!0,attrs:{class:"language-bash"}},[s("code",[s("span",{pre:!0,attrs:{class:"token function"}},[t._v("mkdir")]),t._v(" ~/tutorial\n"),s("span",{pre:!0,attrs:{class:"token builtin class-name"}},[t._v("cd")]),t._v(" tutorial\n"),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("cargo")]),t._v(" new bdk-tor\n"),s("span",{pre:!0,attrs:{class:"token builtin class-name"}},[t._v("cd")]),t._v(" bdk-tor\n")])])]),s("p",[t._v("Open "),s("code",[t._v("src/main.rs")]),t._v(" file remove all its contents and add these lines.")]),t._v(" "),s("div",{staticClass:"language-rust extra-class"},[s("pre",{pre:!0,attrs:{class:"language-rust"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("use")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("std"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")])]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("str")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("FromStr")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("use")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("bdk"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),t._v("bitcoin"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),t._v("util"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")])]),t._v("bip32"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("use")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("bdk"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),t._v("bitcoin"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),t._v("util"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),t._v("bip32"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")])]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("ExtendedPrivKey")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("use")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("bdk"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),t._v("bitcoin"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")])]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Network")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("use")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("bdk"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),t._v("database"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")])]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("MemoryDatabase")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("use")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("bdk"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),t._v("template"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")])]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Bip84")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("use")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("bdk"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("KeychainKind")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("SyncOptions")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Wallet")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// add additional imports here")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("fn")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function-definition function"}},[t._v("main")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" network "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Network")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Testnet")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" xpriv "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"tprv8ZgxMBicQKsPcx5nBGsR63Pe8KnRUqmbJNENAfGftF3yuXoMMoVJJcYeUw5eVkm9WBPjWYt6HMWYJNesB5HaNVBaFc1M6dRjWSYnmewUMYy"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" xpriv "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("bip32"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")])]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("ExtendedPrivKey")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("from_str")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("xpriv"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("unwrap")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" blockchain "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("create_blockchain")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" wallet "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("create_wallet")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),t._v("network"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),t._v("xpriv"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token macro property"}},[t._v("println!")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Syncing the wallet..."')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n wallet"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("sync")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),t._v("blockchain"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("SyncOptions")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("default")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("unwrap")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token macro property"}},[t._v("println!")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"The wallet synced. Height: {}"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n blockchain"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("get_height")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("unwrap")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("fn")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function-definition function"}},[t._v("create_wallet")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("network"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Network")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" xpriv"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("ExtendedPrivKey")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("->")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Wallet")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("MemoryDatabase")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Wallet")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("new")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Bip84")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v("xpriv"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("KeychainKind")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("External")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Some")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Bip84")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v("xpriv"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("KeychainKind")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Internal")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v("network"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("MemoryDatabase")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("default")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("unwrap")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),s("p",[t._v("In this code we create a testnet wallet with "),s("code",[t._v("create_wallet()")]),t._v(" function and\ntry to sync it with a specific blockchain client implementation. We create a\nblockchain client using "),s("code",[t._v("create_blockchain()")]),t._v(" function. We’ll implement it\nlater for each type of blockchain client supported by BDK.")]),t._v(" "),s("h2",{attrs:{id:"electrumblockchain"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#electrumblockchain"}},[t._v("#")]),t._v(" ElectrumBlockchain")]),t._v(" "),s("p",[t._v("The Electrum client is enabled by default so the "),s("code",[t._v("Cargo.toml")]),t._v(" dependencies\nsection will look like this.")]),t._v(" "),s("div",{staticClass:"language-toml extra-class"},[s("pre",{pre:!0,attrs:{class:"language-toml"}},[s("code",[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token table class-name"}},[t._v("dependencies")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token key property"}},[t._v("bdk")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token key property"}},[t._v("version")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"^0.26"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),s("p",[t._v("And the imports look like this.")]),t._v(" "),s("div",{staticClass:"language-rust extra-class"},[s("pre",{pre:!0,attrs:{class:"language-rust"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("use")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("bdk"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),t._v("blockchain"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("ElectrumBlockchain")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("GetHeight")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("use")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("bdk"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),t._v("electrum_client"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Client")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("ConfigBuilder")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Socks5Config")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("p",[t._v("Here is the implementation of "),s("code",[t._v("create_blockchain()")]),t._v(" function for the\nElectrum client.")]),t._v(" "),s("div",{staticClass:"language-rust extra-class"},[s("pre",{pre:!0,attrs:{class:"language-rust"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("fn")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function-definition function"}},[t._v("create_blockchain")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("->")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("ElectrumBlockchain")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" url "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"ssl://electrum.blockstream.info:60002"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" socks_addr "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"127.0.0.1:9050"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token macro property"}},[t._v("println!")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Connecting to {} via {}"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),t._v("url"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),t._v("socks_addr"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" config "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("ConfigBuilder")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("new")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("socks5")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Some")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Socks5Config")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n addr"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" socks_addr"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("to_string")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n credentials"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("None")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("unwrap")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("build")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" client "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Client")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("from_config")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("url"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" config"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("unwrap")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("ElectrumBlockchain")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("from")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("client"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),s("p",[t._v("In this example we create an instance of "),s("code",[t._v("Socks5Config")]),t._v(" which defines the\nTor proxy parameters for "),s("code",[t._v("ElectrumBlockchain")]),t._v(".")]),t._v(" "),s("h2",{attrs:{id:"blocking-esplorablockchain"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#blocking-esplorablockchain"}},[t._v("#")]),t._v(" Blocking EsploraBlockchain")]),t._v(" "),s("p",[t._v("The blocking version of "),s("code",[t._v("EsploraBlockchain")]),t._v(" uses "),s("code",[t._v("ureq")]),t._v(" crate to send HTTP\nrequests to Eslora backends. By default, its SOCKS5 feature is disabled,\nso we need to enable it in "),s("code",[t._v("Cargo.toml")]),t._v(".")]),t._v(" "),s("div",{staticClass:"language-toml extra-class"},[s("pre",{pre:!0,attrs:{class:"language-toml"}},[s("code",[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token table class-name"}},[t._v("dependencies")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token key property"}},[t._v("bdk")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token key property"}},[t._v("version")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"^0.26"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token key property"}},[t._v("default-features")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token boolean"}},[t._v("false")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token key property"}},[t._v("features")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"use-esplora-blocking"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),s("p",[t._v("The imports are")]),t._v(" "),s("div",{staticClass:"language-rust extra-class"},[s("pre",{pre:!0,attrs:{class:"language-rust"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("use")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("bdk"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),t._v("blockchain"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("EsploraBlockchain")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("GetHeight")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("use")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("bdk"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),t._v("blockchain"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),t._v("esplora"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")])]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("EsploraBlockchainConfig")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("use")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("bdk"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),t._v("blockchain"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")])]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("ConfigurableBlockchain")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("p",[t._v("And "),s("code",[t._v("create_blockchain()")]),t._v(" implementation is")]),t._v(" "),s("div",{staticClass:"language-rust extra-class"},[s("pre",{pre:!0,attrs:{class:"language-rust"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("fn")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function-definition function"}},[t._v("create_blockchain")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("->")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("EsploraBlockchain")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" url "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"http://mempoolhqx4isw62xs7abwphsq7ldayuidyx2v2oethdhhj6mlo2r6ad.onion/testnet/api"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" socks_url "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"socks5://127.0.0.1:9050"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token macro property"}},[t._v("println!")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Connecting to {} via {}"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),t._v("url"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),t._v("socks_url"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" config "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("EsploraBlockchainConfig")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n base_url"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" url"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("into")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n proxy"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Some")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("socks_url"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("into")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n concurrency"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("None")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n stop_gap"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("20")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n timeout"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Some")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("120")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("EsploraBlockchain")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("from_config")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),t._v("config"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("unwrap")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),s("p",[t._v("Here we use "),s("code",[t._v("proxy()")]),t._v(" method of the config builder to set the Tor proxy\naddress. Please note, that unlike the previous examples, the Esplora client\nbuilder requires not just a proxy address, but a URL\n“socks5://127.0.0.1:9050”.")]),t._v(" "),s("h2",{attrs:{id:"asynchronous-esplorablockchain"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#asynchronous-esplorablockchain"}},[t._v("#")]),t._v(" Asynchronous EsploraBlockchain")]),t._v(" "),s("p",[t._v("There’s no need in enabling SOCKS5 for the asynchronous Esplora client,\nso we are good to go without additional dependencies.")]),t._v(" "),s("div",{staticClass:"language-toml extra-class"},[s("pre",{pre:!0,attrs:{class:"language-toml"}},[s("code",[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token table class-name"}},[t._v("dependencies")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token key property"}},[t._v("bdk")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token key property"}},[t._v("version")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"^0.26"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token key property"}},[t._v("default-features")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token boolean"}},[t._v("false")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token key property"}},[t._v("features")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"use-esplora-async"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),s("p",[t._v("The imports are the same as in previous example.")]),t._v(" "),s("div",{staticClass:"language-rust extra-class"},[s("pre",{pre:!0,attrs:{class:"language-rust"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("use")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("bdk"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),t._v("blockchain"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("EsploraBlockchain")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("GetHeight")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("use")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("bdk"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),t._v("blockchain"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),t._v("esplora"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")])]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("EsploraBlockchainConfig")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("use")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("bdk"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),t._v("blockchain"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")])]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("ConfigurableBlockchain")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("p",[s("code",[t._v("create_blockchain()")]),t._v(" is almost identical.")]),t._v(" "),s("div",{staticClass:"language-rust extra-class"},[s("pre",{pre:!0,attrs:{class:"language-rust"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("fn")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function-definition function"}},[t._v("create_blockchain")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("->")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("EsploraBlockchain")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" url "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"http://mempoolhqx4isw62xs7abwphsq7ldayuidyx2v2oethdhhj6mlo2r6ad.onion/testnet/api"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" socks_url "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"socks5h://127.0.0.1:9050"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token macro property"}},[t._v("println!")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Connecting to {} via {}"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),t._v("url"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),t._v("socks_url"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" config "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("EsploraBlockchainConfig")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n base_url"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" url"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("into")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n proxy"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Some")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("socks_url"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("into")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n concurrency"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("None")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n stop_gap"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("20")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n timeout"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Some")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("120")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("EsploraBlockchain")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("from_config")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),t._v("config"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("unwrap")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),s("p",[t._v("There are two notable differences though. First, we call "),s("code",[t._v("build_async()")]),t._v(" to\ncreate an asynchronous Esplora client. Second the SOCKS5 URL scheme is\n“socks5h”. It’s not a typo. The async client supports two SOCKS5 schemes\n“socks5” and “socks5h”. The difference between them is that the former\nmakes the client to resolve domain names, and the latter does not, so the\nclient passes them to the proxy as is. A regular DNS resolver cannot\nresolve Tor onion addresses, so we should use “socks5h” here.")]),t._v(" "),s("h2",{attrs:{id:"compactfiltersblockchain"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#compactfiltersblockchain"}},[t._v("#")]),t._v(" CompactFiltersBlockchain")]),t._v(" "),s("p",[t._v("Add these lines to the dependencies section of "),s("code",[t._v("Cargo.toml")]),t._v(" file to enable\nBIP-157/BIP-158 compact filter support.")]),t._v(" "),s("p",[t._v("It can take a while to sync a wallet using compact filters over Tor, so be\npatient.")]),t._v(" "),s("div",{staticClass:"language-toml extra-class"},[s("pre",{pre:!0,attrs:{class:"language-toml"}},[s("code",[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token table class-name"}},[t._v("dependencies")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token key property"}},[t._v("bdk")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token key property"}},[t._v("version")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"^0.26"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token key property"}},[t._v("default-features")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token boolean"}},[t._v("false")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token key property"}},[t._v("features")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"compact_filters"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),s("p",[t._v("Now add the required imports into "),s("code",[t._v("src/main.rs")]),t._v(".")]),t._v(" "),s("div",{staticClass:"language-rust extra-class"},[s("pre",{pre:!0,attrs:{class:"language-rust"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("use")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("std"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),t._v("sync"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")])]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Arc")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("use")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("bdk"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),t._v("blockchain"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),t._v("compact_filters"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Mempool")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Peer")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("use")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("bdk"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),t._v("blockchain"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("CompactFiltersBlockchain")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("GetHeight")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("p",[s("code",[t._v("create_blockchain()")]),t._v(" function will look like this.")]),t._v(" "),s("div",{staticClass:"language-rust extra-class"},[s("pre",{pre:!0,attrs:{class:"language-rust"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("fn")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function-definition function"}},[t._v("create_blockchain")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("->")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("CompactFiltersBlockchain")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" peer_addr "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"neutrino.testnet3.suredbits.com:18333"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" socks_addr "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"127.0.0.1:9050"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" mempool "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Arc")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("new")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Mempool")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("default")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n \n "),s("span",{pre:!0,attrs:{class:"token macro property"}},[t._v("println!")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Connecting to {} via {}"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" peer_addr"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" socks_addr"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n \n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" peer "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Peer")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("connect_proxy")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("peer_addr"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" socks_addr"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("None")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" mempool"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Network")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Testnet")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("unwrap")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("CompactFiltersBlockchain")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("new")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token macro property"}},[t._v("vec!")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("peer"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"./wallet-filters"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Some")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("500_000")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("unwrap")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),s("p",[t._v("Here we use "),s("code",[t._v("Peer::connect_proxy()")]),t._v(" which accepts the address to the SOCKS5\nproxy and performs all the heavy lifting for us.")]),t._v(" "),s("h2",{attrs:{id:"integrated-tor-daemon"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#integrated-tor-daemon"}},[t._v("#")]),t._v(" Integrated Tor daemon")]),t._v(" "),s("p",[t._v("As an application developer you don’t have to rely on your users to install\nand start Tor to use your application. Using "),s("code",[t._v("libtor")]),t._v(" crate you can bundle\nTor daemon with your app.")]),t._v(" "),s("p",[s("code",[t._v("libtor")]),t._v(" builds a Tor binary from the source files. Since Tor is written in C\nyou'll need a C compiler and build tools.")]),t._v(" "),s("p",[t._v("Install these packages on Mac OS X:")]),t._v(" "),s("div",{staticClass:"language-bash extra-class"},[s("pre",{pre:!0,attrs:{class:"language-bash"}},[s("code",[t._v("xcode-select "),s("span",{pre:!0,attrs:{class:"token parameter variable"}},[t._v("--install")]),t._v("\nbrew "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("install")]),t._v(" autoconf\nbrew "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("install")]),t._v(" automake\nbrew "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("install")]),t._v(" libtool\nbrew "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("install")]),t._v(" openssl\nbrew "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("install")]),t._v(" pkg-config\n"),s("span",{pre:!0,attrs:{class:"token builtin class-name"}},[t._v("export")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token assign-left variable"}},[t._v("LDFLAGS")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"-L/opt/homebrew/opt/openssl/lib"')]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token builtin class-name"}},[t._v("export")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token assign-left variable"}},[t._v("CPPFLAGS")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"-I/opt/homebrew/opt/openssl/include"')]),t._v("\n")])])]),s("p",[t._v("Or these packages on Ubuntu or another Debian-based Linux distribution:")]),t._v(" "),s("div",{staticClass:"language-bash extra-class"},[s("pre",{pre:!0,attrs:{class:"language-bash"}},[s("code",[s("span",{pre:!0,attrs:{class:"token function"}},[t._v("sudo")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("apt")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("install")]),t._v(" autoconf automake clang "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("file")]),t._v(" libtool openssl pkg-config\n")])])]),s("p",[t._v("Then add these dependencies to the "),s("code",[t._v("Cargo.toml")]),t._v(" file.")]),t._v(" "),s("div",{staticClass:"language-toml extra-class"},[s("pre",{pre:!0,attrs:{class:"language-toml"}},[s("code",[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token table class-name"}},[t._v("dependencies")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token key property"}},[t._v("bdk")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token key property"}},[t._v("version")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"^0.26"')]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token key property"}},[t._v("libtor")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"47.8.0+0.4.7.x"')]),t._v("\n")])])]),s("p",[t._v("This is an example of how we can use "),s("code",[t._v("libtor")]),t._v(" to start a Tor daemon.")]),t._v(" "),s("div",{staticClass:"language-rust extra-class"},[s("pre",{pre:!0,attrs:{class:"language-rust"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("use")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("std"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),t._v("fs"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")])]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("File")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("use")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("std"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),t._v("io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),t._v("prelude"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")])]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("use")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("std"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")])]),t._v("thread"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("use")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("std"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),t._v("time"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")])]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Duration")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("use")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("libtor"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")])]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("LogDestination")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("use")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("libtor"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")])]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("LogLevel")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("use")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("libtor"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("HiddenServiceVersion")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Tor")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("TorAddress")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("TorFlag")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("use")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("std"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")])]),t._v("env"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("pub")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("fn")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function-definition function"}},[t._v("start_tor")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("->")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("String")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" socks_port "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("19050")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" data_dir "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token macro property"}},[t._v("format!")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"{}/{}"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("env"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")])]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("temp_dir")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("display")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"bdk-tor"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" log_file_name "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token macro property"}},[t._v("format!")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"{}/{}"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),t._v("data_dir"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"log"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token macro property"}},[t._v("println!")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Staring Tor in {}"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),t._v("data_dir"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("truncate_log")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),t._v("log_file_name"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Tor")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("new")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("flag")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("TorFlag")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("DataDirectory")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("data_dir"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("into")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("flag")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("TorFlag")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("LogTo")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("LogLevel")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Notice")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("LogDestination")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("File")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("log_file_name"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("as_str")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("into")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("flag")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("TorFlag")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("SocksPort")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("socks_port"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("flag")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("TorFlag")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Custom")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"ExitPolicy reject *:*"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("into")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("flag")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("TorFlag")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Custom")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"BridgeRelay 0"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("into")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("start_background")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("mut")]),t._v(" started "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token boolean"}},[t._v("false")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("mut")]),t._v(" tries "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("while")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("!")]),t._v("started "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n tries "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("+=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),t._v(" tries "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("120")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token macro property"}},[t._v("panic!")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"It took too long to start Tor. See {} for details"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),t._v("log_file_name\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("thread"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")])]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("sleep")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Duration")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("from_millis")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1000")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n started "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("find_string_in_log")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),t._v("log_file_name"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Bootstrapped 100%"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("into")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token macro property"}},[t._v("println!")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Tor started"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token macro property"}},[t._v("format!")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"127.0.0.1:{}"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" socks_port"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),s("p",[t._v("First, we create a Tor object, and then we call "),s("code",[t._v("start_background()")]),t._v(" method\nto start it in the background. After that, we continuously try to find\n“Bootstrapped 100%” string in the log file. Once we find it, Tor is\nready to proxy our connections. We use port 19050 because, the user can\nhave their own instance of Tor running already.")]),t._v(" "),s("p",[t._v("Next you can modify "),s("code",[t._v("create_blockchain()")]),t._v(" like this")]),t._v(" "),s("div",{staticClass:"language-rust extra-class"},[s("pre",{pre:!0,attrs:{class:"language-rust"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("fn")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function-definition function"}},[t._v("create_blockchain")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("->")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("ElectrumBlockchain")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" url "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"ssl://electrum.blockstream.info:60002"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" socks_addr "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("start_tor")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n \n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("...")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),s("p",[t._v("In this example we start Tor first, then use the address returned by\n"),s("code",[t._v("start_tor()")]),t._v(" function as proxy address.")]),t._v(" "),s("p",[t._v("We omitted "),s("code",[t._v("find_string_in_log()")]),t._v(" and "),s("code",[t._v("truncate_log()")]),t._v(" for brevity. You\ncan find their implementations in "),s("a",{attrs:{href:"https://github.com/bitcoindevkit/bdk/blob/master/examples/esplora_backend_with_tor.rs",target:"_blank",rel:"noopener noreferrer"}},[t._v("esplora_backend_with_tor.rs"),s("OutboundLink")],1)])])}),[],!1,null,null,null);s.default=e.exports}}]); \ No newline at end of file +(window.webpackJsonp=window.webpackJsonp||[]).push([[51],{406:function(t,s,a){"use strict";a.r(s);var n=a(7),e=Object(n.a)({},(function(){var t=this,s=t._self._c;return s("ContentSlotsDistributor",{attrs:{"slot-key":t.$parent.slotKey}},[s("h2",{attrs:{id:"introduction"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#introduction"}},[t._v("#")]),t._v(" Introduction")]),t._v(" "),s("p",[t._v("It’s easy to underestimate the importance of privacy tech for Bitcoin,\nespecially when connecting to third party services. They can learn your\nIP address and associate the transactions you sent over it. You can only\nhope that this information will not be leaked anytime in the future with\nunpredictable consequences. In order to use Bitcoin privately, you need\nto encrypt and anonymize the data you send over the Internet.")]),t._v(" "),s("p",[t._v("Tor is one of the must-have privacy preserving tools for the Internet in\ngeneral, and for Bitcoin in particular. Tor network consists of nodes that\nuse clever cryptographic methods to encrypt user data and transfer them as\nanonymously as possible.")]),t._v(" "),s("p",[t._v("In this article we show how to integrate Tor with your BDK application.")]),t._v(" "),s("h2",{attrs:{id:"prerequisite"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#prerequisite"}},[t._v("#")]),t._v(" Prerequisite")]),t._v(" "),s("p",[t._v("First, you would need to have a Tor daemon up and running.")]),t._v(" "),s("p",[t._v("On Mac OS X you can install with Homebrew.")]),t._v(" "),s("div",{staticClass:"language-bash extra-class"},[s("pre",{pre:!0,attrs:{class:"language-bash"}},[s("code",[t._v("brew "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("install")]),t._v(" tor\nbrew services start tor\n")])])]),s("p",[t._v("On Ubuntu or other Debian-based distributions.")]),t._v(" "),s("div",{staticClass:"language-bash extra-class"},[s("pre",{pre:!0,attrs:{class:"language-bash"}},[s("code",[s("span",{pre:!0,attrs:{class:"token function"}},[t._v("sudo")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("apt")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("install")]),t._v(" tor\n")])])]),s("p",[t._v("In some cases you'll need to wait a minute or two for the bootstrapping to finish.\nIn general, Tor is not the fastest network, so if any of the examples below fail\ndue to timeout, simply restart it.")]),t._v(" "),s("p",[t._v("At the very end of the article we’ll show how to integrate Tor directly to\nyour application.")]),t._v(" "),s("p",[t._v("By default, Tor creates a "),s("a",{attrs:{href:"https://en.wikipedia.org/wiki/SOCKS",target:"_blank",rel:"noopener noreferrer"}},[t._v("SOCKS5"),s("OutboundLink")],1),t._v(" proxy\nendpoint and listens on port 9050. Your application should connect to the\nproxy on "),s("code",[t._v("localhost:9050")]),t._v(" and use it for its network activities.")]),t._v(" "),s("h2",{attrs:{id:"setting-up"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#setting-up"}},[t._v("#")]),t._v(" Setting Up")]),t._v(" "),s("p",[t._v("Create a new cargo project.")]),t._v(" "),s("div",{staticClass:"language-bash extra-class"},[s("pre",{pre:!0,attrs:{class:"language-bash"}},[s("code",[s("span",{pre:!0,attrs:{class:"token function"}},[t._v("mkdir")]),t._v(" ~/tutorial\n"),s("span",{pre:!0,attrs:{class:"token builtin class-name"}},[t._v("cd")]),t._v(" tutorial\n"),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("cargo")]),t._v(" new bdk-tor\n"),s("span",{pre:!0,attrs:{class:"token builtin class-name"}},[t._v("cd")]),t._v(" bdk-tor\n")])])]),s("p",[t._v("Open "),s("code",[t._v("src/main.rs")]),t._v(" file remove all its contents and add these lines.")]),t._v(" "),s("div",{staticClass:"language-rust extra-class"},[s("pre",{pre:!0,attrs:{class:"language-rust"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("use")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("std"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")])]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("str")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("FromStr")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("use")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("bdk"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),t._v("bitcoin"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),t._v("util"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")])]),t._v("bip32"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("use")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("bdk"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),t._v("bitcoin"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),t._v("util"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),t._v("bip32"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")])]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("ExtendedPrivKey")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("use")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("bdk"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),t._v("bitcoin"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")])]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Network")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("use")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("bdk"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),t._v("database"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")])]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("MemoryDatabase")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("use")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("bdk"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),t._v("template"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")])]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Bip84")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("use")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("bdk"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("KeychainKind")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("SyncOptions")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Wallet")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// add additional imports here")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("fn")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function-definition function"}},[t._v("main")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" network "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Network")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Testnet")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" xpriv "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"tprv8ZgxMBicQKsPcx5nBGsR63Pe8KnRUqmbJNENAfGftF3yuXoMMoVJJcYeUw5eVkm9WBPjWYt6HMWYJNesB5HaNVBaFc1M6dRjWSYnmewUMYy"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" xpriv "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("bip32"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")])]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("ExtendedPrivKey")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("from_str")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("xpriv"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("unwrap")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" blockchain "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("create_blockchain")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" wallet "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("create_wallet")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),t._v("network"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),t._v("xpriv"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token macro property"}},[t._v("println!")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Syncing the wallet..."')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n wallet"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("sync")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),t._v("blockchain"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("SyncOptions")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("default")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("unwrap")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token macro property"}},[t._v("println!")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"The wallet synced. Height: {}"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n blockchain"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("get_height")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("unwrap")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("fn")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function-definition function"}},[t._v("create_wallet")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("network"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Network")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" xpriv"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("ExtendedPrivKey")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("->")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Wallet")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("MemoryDatabase")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Wallet")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("new")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Bip84")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v("xpriv"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("KeychainKind")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("External")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Some")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Bip84")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v("xpriv"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("KeychainKind")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Internal")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v("network"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("MemoryDatabase")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("default")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("unwrap")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),s("p",[t._v("In this code we create a testnet wallet with "),s("code",[t._v("create_wallet()")]),t._v(" function and\ntry to sync it with a specific blockchain client implementation. We create a\nblockchain client using "),s("code",[t._v("create_blockchain()")]),t._v(" function. We’ll implement it\nlater for each type of blockchain client supported by BDK.")]),t._v(" "),s("h2",{attrs:{id:"electrumblockchain"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#electrumblockchain"}},[t._v("#")]),t._v(" ElectrumBlockchain")]),t._v(" "),s("p",[t._v("The Electrum client is enabled by default so the "),s("code",[t._v("Cargo.toml")]),t._v(" dependencies\nsection will look like this.")]),t._v(" "),s("div",{staticClass:"language-toml extra-class"},[s("pre",{pre:!0,attrs:{class:"language-toml"}},[s("code",[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token table class-name"}},[t._v("dependencies")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token key property"}},[t._v("bdk")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token key property"}},[t._v("version")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"^0.26"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),s("p",[t._v("And the imports look like this.")]),t._v(" "),s("div",{staticClass:"language-rust extra-class"},[s("pre",{pre:!0,attrs:{class:"language-rust"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("use")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("bdk"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),t._v("blockchain"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("ElectrumBlockchain")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("GetHeight")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("use")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("bdk"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),t._v("electrum_client"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Client")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("ConfigBuilder")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Socks5Config")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("p",[t._v("Here is the implementation of "),s("code",[t._v("create_blockchain()")]),t._v(" function for the\nElectrum client.")]),t._v(" "),s("div",{staticClass:"language-rust extra-class"},[s("pre",{pre:!0,attrs:{class:"language-rust"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("fn")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function-definition function"}},[t._v("create_blockchain")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("->")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("ElectrumBlockchain")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" url "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"ssl://electrum.blockstream.info:60002"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" socks_addr "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"127.0.0.1:9050"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token macro property"}},[t._v("println!")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Connecting to {} via {}"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),t._v("url"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),t._v("socks_addr"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" config "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("ConfigBuilder")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("new")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("socks5")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Some")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Socks5Config")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n addr"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" socks_addr"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("to_string")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n credentials"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("None")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("unwrap")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("build")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" client "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Client")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("from_config")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("url"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" config"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("unwrap")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("ElectrumBlockchain")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("from")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("client"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),s("p",[t._v("In this example we create an instance of "),s("code",[t._v("Socks5Config")]),t._v(" which defines the\nTor proxy parameters for "),s("code",[t._v("ElectrumBlockchain")]),t._v(".")]),t._v(" "),s("h2",{attrs:{id:"blocking-esplorablockchain"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#blocking-esplorablockchain"}},[t._v("#")]),t._v(" Blocking EsploraBlockchain")]),t._v(" "),s("p",[t._v("The blocking version of "),s("code",[t._v("EsploraBlockchain")]),t._v(" uses "),s("code",[t._v("ureq")]),t._v(" crate to send HTTP\nrequests to Eslora backends. By default, its SOCKS5 feature is disabled,\nso we need to enable it in "),s("code",[t._v("Cargo.toml")]),t._v(".")]),t._v(" "),s("div",{staticClass:"language-toml extra-class"},[s("pre",{pre:!0,attrs:{class:"language-toml"}},[s("code",[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token table class-name"}},[t._v("dependencies")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token key property"}},[t._v("bdk")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token key property"}},[t._v("version")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"^0.26"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token key property"}},[t._v("default-features")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token boolean"}},[t._v("false")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token key property"}},[t._v("features")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"use-esplora-blocking"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),s("p",[t._v("The imports are")]),t._v(" "),s("div",{staticClass:"language-rust extra-class"},[s("pre",{pre:!0,attrs:{class:"language-rust"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("use")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("bdk"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),t._v("blockchain"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("EsploraBlockchain")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("GetHeight")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("use")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("bdk"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),t._v("blockchain"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),t._v("esplora"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")])]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("EsploraBlockchainConfig")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("use")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("bdk"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),t._v("blockchain"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")])]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("ConfigurableBlockchain")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("p",[t._v("And "),s("code",[t._v("create_blockchain()")]),t._v(" implementation is")]),t._v(" "),s("div",{staticClass:"language-rust extra-class"},[s("pre",{pre:!0,attrs:{class:"language-rust"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("fn")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function-definition function"}},[t._v("create_blockchain")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("->")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("EsploraBlockchain")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" url "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"http://mempoolhqx4isw62xs7abwphsq7ldayuidyx2v2oethdhhj6mlo2r6ad.onion/testnet/api"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" socks_url "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"socks5://127.0.0.1:9050"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token macro property"}},[t._v("println!")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Connecting to {} via {}"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),t._v("url"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),t._v("socks_url"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" config "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("EsploraBlockchainConfig")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n base_url"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" url"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("into")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n proxy"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Some")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("socks_url"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("into")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n concurrency"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("None")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n stop_gap"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("20")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n timeout"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Some")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("120")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("EsploraBlockchain")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("from_config")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),t._v("config"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("unwrap")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),s("p",[t._v("Here we use "),s("code",[t._v("proxy()")]),t._v(" method of the config builder to set the Tor proxy\naddress. Please note, that unlike the previous examples, the Esplora client\nbuilder requires not just a proxy address, but a URL\n“socks5://127.0.0.1:9050”.")]),t._v(" "),s("h2",{attrs:{id:"asynchronous-esplorablockchain"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#asynchronous-esplorablockchain"}},[t._v("#")]),t._v(" Asynchronous EsploraBlockchain")]),t._v(" "),s("p",[t._v("There’s no need in enabling SOCKS5 for the asynchronous Esplora client,\nso we are good to go without additional dependencies.")]),t._v(" "),s("div",{staticClass:"language-toml extra-class"},[s("pre",{pre:!0,attrs:{class:"language-toml"}},[s("code",[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token table class-name"}},[t._v("dependencies")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token key property"}},[t._v("bdk")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token key property"}},[t._v("version")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"^0.26"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token key property"}},[t._v("default-features")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token boolean"}},[t._v("false")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token key property"}},[t._v("features")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"use-esplora-async"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),s("p",[t._v("The imports are the same as in previous example.")]),t._v(" "),s("div",{staticClass:"language-rust extra-class"},[s("pre",{pre:!0,attrs:{class:"language-rust"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("use")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("bdk"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),t._v("blockchain"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("EsploraBlockchain")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("GetHeight")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("use")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("bdk"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),t._v("blockchain"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),t._v("esplora"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")])]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("EsploraBlockchainConfig")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("use")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("bdk"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),t._v("blockchain"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")])]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("ConfigurableBlockchain")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("p",[s("code",[t._v("create_blockchain()")]),t._v(" is almost identical.")]),t._v(" "),s("div",{staticClass:"language-rust extra-class"},[s("pre",{pre:!0,attrs:{class:"language-rust"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("fn")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function-definition function"}},[t._v("create_blockchain")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("->")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("EsploraBlockchain")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" url "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"http://mempoolhqx4isw62xs7abwphsq7ldayuidyx2v2oethdhhj6mlo2r6ad.onion/testnet/api"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" socks_url "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"socks5h://127.0.0.1:9050"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token macro property"}},[t._v("println!")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Connecting to {} via {}"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),t._v("url"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),t._v("socks_url"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" config "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("EsploraBlockchainConfig")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n base_url"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" url"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("into")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n proxy"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Some")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("socks_url"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("into")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n concurrency"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("None")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n stop_gap"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("20")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n timeout"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Some")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("120")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("EsploraBlockchain")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("from_config")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),t._v("config"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("unwrap")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),s("p",[t._v("There are two notable differences though. First, we call "),s("code",[t._v("build_async()")]),t._v(" to\ncreate an asynchronous Esplora client. Second the SOCKS5 URL scheme is\n“socks5h”. It’s not a typo. The async client supports two SOCKS5 schemes\n“socks5” and “socks5h”. The difference between them is that the former\nmakes the client to resolve domain names, and the latter does not, so the\nclient passes them to the proxy as is. A regular DNS resolver cannot\nresolve Tor onion addresses, so we should use “socks5h” here.")]),t._v(" "),s("h2",{attrs:{id:"compactfiltersblockchain"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#compactfiltersblockchain"}},[t._v("#")]),t._v(" CompactFiltersBlockchain")]),t._v(" "),s("p",[t._v("Add these lines to the dependencies section of "),s("code",[t._v("Cargo.toml")]),t._v(" file to enable\nBIP-157/BIP-158 compact filter support.")]),t._v(" "),s("p",[t._v("It can take a while to sync a wallet using compact filters over Tor, so be\npatient.")]),t._v(" "),s("div",{staticClass:"language-toml extra-class"},[s("pre",{pre:!0,attrs:{class:"language-toml"}},[s("code",[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token table class-name"}},[t._v("dependencies")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token key property"}},[t._v("bdk")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token key property"}},[t._v("version")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"^0.26"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token key property"}},[t._v("default-features")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token boolean"}},[t._v("false")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token key property"}},[t._v("features")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"compact_filters"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),s("p",[t._v("Now add the required imports into "),s("code",[t._v("src/main.rs")]),t._v(".")]),t._v(" "),s("div",{staticClass:"language-rust extra-class"},[s("pre",{pre:!0,attrs:{class:"language-rust"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("use")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("std"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),t._v("sync"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")])]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Arc")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("use")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("bdk"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),t._v("blockchain"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),t._v("compact_filters"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Mempool")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Peer")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("use")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("bdk"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),t._v("blockchain"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("CompactFiltersBlockchain")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("GetHeight")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("p",[s("code",[t._v("create_blockchain()")]),t._v(" function will look like this.")]),t._v(" "),s("div",{staticClass:"language-rust extra-class"},[s("pre",{pre:!0,attrs:{class:"language-rust"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("fn")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function-definition function"}},[t._v("create_blockchain")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("->")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("CompactFiltersBlockchain")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" peer_addr "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"neutrino.testnet3.suredbits.com:18333"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" socks_addr "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"127.0.0.1:9050"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" mempool "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Arc")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("new")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Mempool")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("default")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n \n "),s("span",{pre:!0,attrs:{class:"token macro property"}},[t._v("println!")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Connecting to {} via {}"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" peer_addr"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" socks_addr"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n \n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" peer "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Peer")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("connect_proxy")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("peer_addr"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" socks_addr"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("None")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" mempool"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Network")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Testnet")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("unwrap")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("CompactFiltersBlockchain")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("new")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token macro property"}},[t._v("vec!")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("peer"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"./wallet-filters"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Some")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("500_000")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("unwrap")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),s("p",[t._v("Here we use "),s("code",[t._v("Peer::connect_proxy()")]),t._v(" which accepts the address to the SOCKS5\nproxy and performs all the heavy lifting for us.")]),t._v(" "),s("h2",{attrs:{id:"integrated-tor-daemon"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#integrated-tor-daemon"}},[t._v("#")]),t._v(" Integrated Tor daemon")]),t._v(" "),s("p",[t._v("As an application developer you don’t have to rely on your users to install\nand start Tor to use your application. Using "),s("code",[t._v("libtor")]),t._v(" crate you can bundle\nTor daemon with your app.")]),t._v(" "),s("p",[s("code",[t._v("libtor")]),t._v(" builds a Tor binary from the source files. Since Tor is written in C\nyou'll need a C compiler and build tools.")]),t._v(" "),s("p",[t._v("Install these packages on Mac OS X:")]),t._v(" "),s("div",{staticClass:"language-bash extra-class"},[s("pre",{pre:!0,attrs:{class:"language-bash"}},[s("code",[t._v("xcode-select "),s("span",{pre:!0,attrs:{class:"token parameter variable"}},[t._v("--install")]),t._v("\nbrew "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("install")]),t._v(" autoconf\nbrew "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("install")]),t._v(" automake\nbrew "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("install")]),t._v(" libtool\nbrew "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("install")]),t._v(" openssl\nbrew "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("install")]),t._v(" pkg-config\n"),s("span",{pre:!0,attrs:{class:"token builtin class-name"}},[t._v("export")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token assign-left variable"}},[t._v("LDFLAGS")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"-L/opt/homebrew/opt/openssl/lib"')]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token builtin class-name"}},[t._v("export")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token assign-left variable"}},[t._v("CPPFLAGS")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"-I/opt/homebrew/opt/openssl/include"')]),t._v("\n")])])]),s("p",[t._v("Or these packages on Ubuntu or another Debian-based Linux distribution:")]),t._v(" "),s("div",{staticClass:"language-bash extra-class"},[s("pre",{pre:!0,attrs:{class:"language-bash"}},[s("code",[s("span",{pre:!0,attrs:{class:"token function"}},[t._v("sudo")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("apt")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("install")]),t._v(" autoconf automake clang "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("file")]),t._v(" libtool openssl pkg-config\n")])])]),s("p",[t._v("Then add these dependencies to the "),s("code",[t._v("Cargo.toml")]),t._v(" file.")]),t._v(" "),s("div",{staticClass:"language-toml extra-class"},[s("pre",{pre:!0,attrs:{class:"language-toml"}},[s("code",[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token table class-name"}},[t._v("dependencies")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token key property"}},[t._v("bdk")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token key property"}},[t._v("version")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"^0.26"')]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token key property"}},[t._v("libtor")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"47.8.0+0.4.7.x"')]),t._v("\n")])])]),s("p",[t._v("This is an example of how we can use "),s("code",[t._v("libtor")]),t._v(" to start a Tor daemon.")]),t._v(" "),s("div",{staticClass:"language-rust extra-class"},[s("pre",{pre:!0,attrs:{class:"language-rust"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("use")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("std"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),t._v("fs"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")])]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("File")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("use")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("std"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),t._v("io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),t._v("prelude"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")])]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("use")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("std"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")])]),t._v("thread"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("use")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("std"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),t._v("time"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")])]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Duration")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("use")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("libtor"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")])]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("LogDestination")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("use")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("libtor"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")])]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("LogLevel")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("use")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("libtor"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("HiddenServiceVersion")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Tor")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("TorAddress")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("TorFlag")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("use")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("std"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")])]),t._v("env"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("pub")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("fn")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function-definition function"}},[t._v("start_tor")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("->")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("String")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" socks_port "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("19050")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" data_dir "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token macro property"}},[t._v("format!")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"{}/{}"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("env"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")])]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("temp_dir")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("display")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"bdk-tor"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" log_file_name "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token macro property"}},[t._v("format!")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"{}/{}"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),t._v("data_dir"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"log"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token macro property"}},[t._v("println!")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Staring Tor in {}"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),t._v("data_dir"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("truncate_log")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),t._v("log_file_name"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Tor")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("new")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("flag")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("TorFlag")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("DataDirectory")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("data_dir"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("into")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("flag")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("TorFlag")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("LogTo")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("LogLevel")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Notice")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("LogDestination")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("File")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("log_file_name"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("as_str")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("into")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("flag")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("TorFlag")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("SocksPort")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("socks_port"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("flag")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("TorFlag")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Custom")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"ExitPolicy reject *:*"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("into")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("flag")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("TorFlag")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Custom")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"BridgeRelay 0"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("into")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("start_background")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("mut")]),t._v(" started "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token boolean"}},[t._v("false")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("mut")]),t._v(" tries "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("while")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("!")]),t._v("started "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n tries "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("+=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),t._v(" tries "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("120")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token macro property"}},[t._v("panic!")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"It took too long to start Tor. See {} for details"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),t._v("log_file_name\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("thread"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")])]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("sleep")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Duration")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("from_millis")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1000")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n started "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("find_string_in_log")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),t._v("log_file_name"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Bootstrapped 100%"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("into")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token macro property"}},[t._v("println!")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Tor started"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token macro property"}},[t._v("format!")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"127.0.0.1:{}"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" socks_port"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),s("p",[t._v("First, we create a Tor object, and then we call "),s("code",[t._v("start_background()")]),t._v(" method\nto start it in the background. After that, we continuously try to find\n“Bootstrapped 100%” string in the log file. Once we find it, Tor is\nready to proxy our connections. We use port 19050 because, the user can\nhave their own instance of Tor running already.")]),t._v(" "),s("p",[t._v("Next you can modify "),s("code",[t._v("create_blockchain()")]),t._v(" like this")]),t._v(" "),s("div",{staticClass:"language-rust extra-class"},[s("pre",{pre:!0,attrs:{class:"language-rust"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("fn")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function-definition function"}},[t._v("create_blockchain")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("->")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("ElectrumBlockchain")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" url "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"ssl://electrum.blockstream.info:60002"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" socks_addr "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("start_tor")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n \n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("...")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),s("p",[t._v("In this example we start Tor first, then use the address returned by\n"),s("code",[t._v("start_tor()")]),t._v(" function as proxy address.")]),t._v(" "),s("p",[t._v("We omitted "),s("code",[t._v("find_string_in_log()")]),t._v(" and "),s("code",[t._v("truncate_log()")]),t._v(" for brevity. You\ncan find their implementations in "),s("a",{attrs:{href:"https://github.com/bitcoindevkit/bdk/blob/master/examples/esplora_backend_with_tor.rs",target:"_blank",rel:"noopener noreferrer"}},[t._v("esplora_backend_with_tor.rs"),s("OutboundLink")],1)])])}),[],!1,null,null,null);s.default=e.exports}}]); \ No newline at end of file diff --git a/assets/js/52.c345bff4.js b/assets/js/52.776c8d09.js similarity index 99% rename from assets/js/52.c345bff4.js rename to assets/js/52.776c8d09.js index 6bedfe0694..609663b715 100644 --- a/assets/js/52.c345bff4.js +++ b/assets/js/52.776c8d09.js @@ -1 +1 @@ -(window.webpackJsonp=window.webpackJsonp||[]).push([[52],{407:function(e,t,i){"use strict";i.r(t);var r=i(7),o=Object(r.a)({},(function(){var e=this,t=e._self._c;return t("ContentSlotsDistributor",{attrs:{"slot-key":e.$parent.slotKey}},[t("p",[t("strong",[e._v("tldr;")]),e._v(" "),t("em",[e._v("we can't produce and maintain bindings for all Rust crates we get requests for, but we are working to help others build their own bindings by (1) making our architecture composable and reusable, and (2) building strong examples and documentation on how to do it for other crates.")])]),e._v(" "),t("br"),e._v(" "),t("p",[e._v("Over the past 2 years, the Bitcoin Development Kit team has been successful at building and releasing language bindings for our Rust library. In particular, over the past 18 months we have locked in and solidified our approach for the iOS, Android, Kotlin, Java, and Python bindings by using a Rust library called "),t("a",{attrs:{href:"https://github.com/mozilla/uniffi-rs",target:"_blank",rel:"noopener noreferrer"}},[e._v("Uniffi"),t("OutboundLink")],1),e._v(".")]),e._v(" "),t("p",[e._v("Over the course of the year, we've had many requests to add to the bindings certain features that are not directly in the Rust BDK library. These request mainly break down into two groups:")]),e._v(" "),t("ol",[t("li",[e._v('Features that are part of crates "upstream" of BDK (rust-bitcoin, rust-miniscript)')]),e._v(" "),t("li",[e._v("Features that are not but that have Rust crates and would be useful on mobile (payjoin, coinjoin implementations, silent payments, BIP-47)")])]),e._v(" "),t("h2",{attrs:{id:"current-architecture"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#current-architecture"}},[e._v("#")]),e._v(" Current architecture")]),e._v(" "),t("p",[e._v("The current architecture for the BDK bindings is more or less wrapping the bdk, rust-bitcoin, and rust-miniscript crates and exposing an API that allows users to leverage them similarly to how they would BDK in Rust if they were using it in a Rust project.")]),e._v(" "),t("p",[e._v('While we started with a simplified version of the Rust BDK API, over time users asked for more and more functionality, and exposing some of the underlying rust-bitcoin constructs became important. This makes sense, and indeed users of the bitcoin development kit in Rust have access to all the related APIs by simply importing rust-bitcoin and rust-miniscript, hence our desire to accommodate these use cases as well. However, this is currently done all in one "bindings" library (i.e. if you import '),t("code",[e._v("bdk-android")]),e._v(" in a project, you'll have access to an API that is mostly bdk-based, but also contains a bit of rust-bitcoin and rust-miniscript).")]),e._v(" "),t("h2",{attrs:{id:"moving-forward-building-a-family-of-libraries"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#moving-forward-building-a-family-of-libraries"}},[e._v("#")]),e._v(" Moving forward: building a family of libraries")]),e._v(" "),t("p",[e._v("At the same time, other Rust-based libraries started using the uniffi approach (a good example is "),t("a",{attrs:{href:"https://github.com/lightningdevkit/ldk-node",target:"_blank",rel:"noopener noreferrer"}},[e._v("ldk-node"),t("OutboundLink")],1),e._v(") to expose bindings. When developing and using those libraries together, it quickly became clear that much of the work was duplicated; both libraries needed access to underlying rust-bitcoin types, but they both exposed their own versions of it.")]),e._v(" "),t("p",[e._v("Over the coming months, the team is looking at extracting the rust-bitcoin part of the BDK bindings library (bdk-ffi) and publishing that library on "),t("a",{attrs:{href:"https://crates.io/",target:"_blank",rel:"noopener noreferrer"}},[e._v("crates.io"),t("OutboundLink")],1),e._v(" so as to make it available to others who wish to build Rust bindings using uniffi.")]),e._v(" "),t("h2",{attrs:{id:"why-cant-we-just-build-one-big-bdk-library-with-everything-in-it"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#why-cant-we-just-build-one-big-bdk-library-with-everything-in-it"}},[e._v("#")]),e._v(" Why can't we just build one big BDK library with "),t("em",[e._v("everything")]),e._v(" in it?")]),e._v(" "),t("ol",[t("li",[e._v("The short answer to this is that it would simply not be maintainable. If we rely on many underlying Rust crates, we'd need to release patches every time one of the underlying libraries patches a bug. We'd also need to keep them all in sync (what API versions work with what), and we'd be relying on work from teams that may or may not have the capacity to keep their crates up to date.")]),e._v(" "),t("li",[e._v("Scope creep. Unless we define a narrow and structured scope for the library, we will forever be handling requests for features that may or may not be feasible to accommodate.")]),e._v(" "),t("li",[e._v("Library size. Because one of our primary focus for the bindings is mobile devices, we need to make sure we don't build a library that is too big. This is a more nuanced issue, but it relates to point (2), where too large a scope would eventually produce a library that is potentially not optimal for mobile devices because it attempts to do too much all in one package.")])]),e._v(" "),t("h2",{attrs:{id:"are-you-looking-to-build-rust-bindings-yourself"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#are-you-looking-to-build-rust-bindings-yourself"}},[e._v("#")]),e._v(" Are you looking to build Rust bindings yourself?")]),e._v(" "),t("p",[e._v("We got your back! The Bitcoin Development Kit team intends to help others in the Rust bitcoin ecosystem build bindings if they wish to. To that effect, we maintain 3 repositories that should help you get going with bindings in no time:")]),e._v(" "),t("ol",[t("li",[t("strong",[t("a",{attrs:{href:"https://github.com/thunderbiscuit/uniffi-bindings-template",target:"_blank",rel:"noopener noreferrer"}},[e._v("Uniffi library template"),t("OutboundLink")],1)]),e._v(". This is a repository you can fork and start adding code to produce bindings directly for iOS and Android. Included are our custom-made Gradle plugin and Swift release shell scripts, as well as information about the little build quirks you need to know about for smooth releases.")]),e._v(" "),t("li",[t("strong",[t("a",{attrs:{href:"https://github.com/thunderbiscuit/uniffi-examples",target:"_blank",rel:"noopener noreferrer"}},[e._v("Uniffi examples"),t("OutboundLink")],1)]),e._v(". This repository provides boiled-down examples of APIs exposed using uniffi, with an "),t("a",{attrs:{href:"https://thunderbiscuit.github.io/uniffi-examples/",target:"_blank",rel:"noopener noreferrer"}},[e._v("accompanying documentation website"),t("OutboundLink")],1),e._v(". Functions, enums, objects, callbacks, multi-libraries, a lot of information and examples to get you started.")]),e._v(" "),t("li",[t("strong",[t("a",{attrs:{href:"https://github.com/thunderbiscuit/bitcoin-frontier",target:"_blank",rel:"noopener noreferrer"}},[e._v("Sandbox library "),t("code",[e._v("bitcoin-frontier")]),t("OutboundLink")],1)]),e._v(". This repository is meant as a sandbox to start developing and testing your own bindings. Simply fork it and start adding code! It comes with a fully working Android app you can leverage to test out whatever bindings you're building.")])])])}),[],!1,null,null,null);t.default=o.exports}}]); \ No newline at end of file +(window.webpackJsonp=window.webpackJsonp||[]).push([[52],{408:function(e,t,i){"use strict";i.r(t);var r=i(7),o=Object(r.a)({},(function(){var e=this,t=e._self._c;return t("ContentSlotsDistributor",{attrs:{"slot-key":e.$parent.slotKey}},[t("p",[t("strong",[e._v("tldr;")]),e._v(" "),t("em",[e._v("we can't produce and maintain bindings for all Rust crates we get requests for, but we are working to help others build their own bindings by (1) making our architecture composable and reusable, and (2) building strong examples and documentation on how to do it for other crates.")])]),e._v(" "),t("br"),e._v(" "),t("p",[e._v("Over the past 2 years, the Bitcoin Development Kit team has been successful at building and releasing language bindings for our Rust library. In particular, over the past 18 months we have locked in and solidified our approach for the iOS, Android, Kotlin, Java, and Python bindings by using a Rust library called "),t("a",{attrs:{href:"https://github.com/mozilla/uniffi-rs",target:"_blank",rel:"noopener noreferrer"}},[e._v("Uniffi"),t("OutboundLink")],1),e._v(".")]),e._v(" "),t("p",[e._v("Over the course of the year, we've had many requests to add to the bindings certain features that are not directly in the Rust BDK library. These request mainly break down into two groups:")]),e._v(" "),t("ol",[t("li",[e._v('Features that are part of crates "upstream" of BDK (rust-bitcoin, rust-miniscript)')]),e._v(" "),t("li",[e._v("Features that are not but that have Rust crates and would be useful on mobile (payjoin, coinjoin implementations, silent payments, BIP-47)")])]),e._v(" "),t("h2",{attrs:{id:"current-architecture"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#current-architecture"}},[e._v("#")]),e._v(" Current architecture")]),e._v(" "),t("p",[e._v("The current architecture for the BDK bindings is more or less wrapping the bdk, rust-bitcoin, and rust-miniscript crates and exposing an API that allows users to leverage them similarly to how they would BDK in Rust if they were using it in a Rust project.")]),e._v(" "),t("p",[e._v('While we started with a simplified version of the Rust BDK API, over time users asked for more and more functionality, and exposing some of the underlying rust-bitcoin constructs became important. This makes sense, and indeed users of the bitcoin development kit in Rust have access to all the related APIs by simply importing rust-bitcoin and rust-miniscript, hence our desire to accommodate these use cases as well. However, this is currently done all in one "bindings" library (i.e. if you import '),t("code",[e._v("bdk-android")]),e._v(" in a project, you'll have access to an API that is mostly bdk-based, but also contains a bit of rust-bitcoin and rust-miniscript).")]),e._v(" "),t("h2",{attrs:{id:"moving-forward-building-a-family-of-libraries"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#moving-forward-building-a-family-of-libraries"}},[e._v("#")]),e._v(" Moving forward: building a family of libraries")]),e._v(" "),t("p",[e._v("At the same time, other Rust-based libraries started using the uniffi approach (a good example is "),t("a",{attrs:{href:"https://github.com/lightningdevkit/ldk-node",target:"_blank",rel:"noopener noreferrer"}},[e._v("ldk-node"),t("OutboundLink")],1),e._v(") to expose bindings. When developing and using those libraries together, it quickly became clear that much of the work was duplicated; both libraries needed access to underlying rust-bitcoin types, but they both exposed their own versions of it.")]),e._v(" "),t("p",[e._v("Over the coming months, the team is looking at extracting the rust-bitcoin part of the BDK bindings library (bdk-ffi) and publishing that library on "),t("a",{attrs:{href:"https://crates.io/",target:"_blank",rel:"noopener noreferrer"}},[e._v("crates.io"),t("OutboundLink")],1),e._v(" so as to make it available to others who wish to build Rust bindings using uniffi.")]),e._v(" "),t("h2",{attrs:{id:"why-cant-we-just-build-one-big-bdk-library-with-everything-in-it"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#why-cant-we-just-build-one-big-bdk-library-with-everything-in-it"}},[e._v("#")]),e._v(" Why can't we just build one big BDK library with "),t("em",[e._v("everything")]),e._v(" in it?")]),e._v(" "),t("ol",[t("li",[e._v("The short answer to this is that it would simply not be maintainable. If we rely on many underlying Rust crates, we'd need to release patches every time one of the underlying libraries patches a bug. We'd also need to keep them all in sync (what API versions work with what), and we'd be relying on work from teams that may or may not have the capacity to keep their crates up to date.")]),e._v(" "),t("li",[e._v("Scope creep. Unless we define a narrow and structured scope for the library, we will forever be handling requests for features that may or may not be feasible to accommodate.")]),e._v(" "),t("li",[e._v("Library size. Because one of our primary focus for the bindings is mobile devices, we need to make sure we don't build a library that is too big. This is a more nuanced issue, but it relates to point (2), where too large a scope would eventually produce a library that is potentially not optimal for mobile devices because it attempts to do too much all in one package.")])]),e._v(" "),t("h2",{attrs:{id:"are-you-looking-to-build-rust-bindings-yourself"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#are-you-looking-to-build-rust-bindings-yourself"}},[e._v("#")]),e._v(" Are you looking to build Rust bindings yourself?")]),e._v(" "),t("p",[e._v("We got your back! The Bitcoin Development Kit team intends to help others in the Rust bitcoin ecosystem build bindings if they wish to. To that effect, we maintain 3 repositories that should help you get going with bindings in no time:")]),e._v(" "),t("ol",[t("li",[t("strong",[t("a",{attrs:{href:"https://github.com/thunderbiscuit/uniffi-bindings-template",target:"_blank",rel:"noopener noreferrer"}},[e._v("Uniffi library template"),t("OutboundLink")],1)]),e._v(". This is a repository you can fork and start adding code to produce bindings directly for iOS and Android. Included are our custom-made Gradle plugin and Swift release shell scripts, as well as information about the little build quirks you need to know about for smooth releases.")]),e._v(" "),t("li",[t("strong",[t("a",{attrs:{href:"https://github.com/thunderbiscuit/uniffi-examples",target:"_blank",rel:"noopener noreferrer"}},[e._v("Uniffi examples"),t("OutboundLink")],1)]),e._v(". This repository provides boiled-down examples of APIs exposed using uniffi, with an "),t("a",{attrs:{href:"https://thunderbiscuit.github.io/uniffi-examples/",target:"_blank",rel:"noopener noreferrer"}},[e._v("accompanying documentation website"),t("OutboundLink")],1),e._v(". Functions, enums, objects, callbacks, multi-libraries, a lot of information and examples to get you started.")]),e._v(" "),t("li",[t("strong",[t("a",{attrs:{href:"https://github.com/thunderbiscuit/bitcoin-frontier",target:"_blank",rel:"noopener noreferrer"}},[e._v("Sandbox library "),t("code",[e._v("bitcoin-frontier")]),t("OutboundLink")],1)]),e._v(". This repository is meant as a sandbox to start developing and testing your own bindings. Simply fork it and start adding code! It comes with a fully working Android app you can leverage to test out whatever bindings you're building.")])])])}),[],!1,null,null,null);t.default=o.exports}}]); \ No newline at end of file diff --git a/assets/js/53.bf39d2fb.js b/assets/js/53.b417d2aa.js similarity index 99% rename from assets/js/53.bf39d2fb.js rename to assets/js/53.b417d2aa.js index 95e13d6efa..3f8be5b842 100644 --- a/assets/js/53.bf39d2fb.js +++ b/assets/js/53.b417d2aa.js @@ -1 +1 @@ -(window.webpackJsonp=window.webpackJsonp||[]).push([[53],{409: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([[53],{413: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/57.64bfd1b2.js b/assets/js/57.3bf4c76c.js similarity index 99% rename from assets/js/57.64bfd1b2.js rename to assets/js/57.3bf4c76c.js index 24a089371c..b729ca218d 100644 --- a/assets/js/57.64bfd1b2.js +++ b/assets/js/57.3bf4c76c.js @@ -1 +1 @@ -(window.webpackJsonp=window.webpackJsonp||[]).push([[57],{415:function(e,t,a){"use strict";a.r(t);var o=a(7),n=Object(o.a)({},(function(){var e=this,t=e._self._c;return t("ContentSlotsDistributor",{attrs:{"slot-key":e.$parent.slotKey}},[t("p",[e._v("This post is part 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([[57],{430: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/58.de4ccb60.js b/assets/js/58.8864ccb6.js similarity index 99% rename from assets/js/58.de4ccb60.js rename to assets/js/58.8864ccb6.js index 9b7103f1c2..aa9093ab6e 100644 --- a/assets/js/58.de4ccb60.js +++ b/assets/js/58.8864ccb6.js @@ -1 +1 @@ -(window.webpackJsonp=window.webpackJsonp||[]).push([[58],{416: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([[58],{418:function(e,t,a){"use strict";a.r(t);var n=a(7),s=Object(n.a)({},(function(){var e=this,t=e._self._c;return t("ContentSlotsDistributor",{attrs:{"slot-key":e.$parent.slotKey}},[t("p",[e._v("This post is part 3 of 3 of a series. ("),t("RouterLink",{attrs:{to:"/blog/2021/01/fee-estimation-for-light-clients-part-1/"}},[e._v("Part 1")]),e._v(", "),t("RouterLink",{attrs:{to:"/blog/2021/01/fee-estimation-for-light-clients-part-2/"}},[e._v("Part 2")]),e._v(")")],1),e._v(" "),t("ul",[t("li",[t("a",{attrs:{href:"#the-model"}},[e._v("The model")]),e._v(" "),t("ul",[t("li",[t("a",{attrs:{href:"#splitting"}},[e._v("Splitting")])]),e._v(" "),t("li",[t("a",{attrs:{href:"#preprocessing"}},[e._v("Preprocessing")])]),e._v(" "),t("li",[t("a",{attrs:{href:"#build"}},[e._v("Build")])]),e._v(" "),t("li",[t("a",{attrs:{href:"#finally--training"}},[e._v("Finally, training")])])])]),e._v(" "),t("li",[t("a",{attrs:{href:"#the-prediction-phase"}},[e._v("The prediction phase")])]),e._v(" "),t("li",[t("a",{attrs:{href:"#conclusion-and-future-development"}},[e._v("Conclusion and future development")])]),e._v(" "),t("li",[t("a",{attrs:{href:"#acknowledgements"}},[e._v("Acknowledgements")])])]),e._v(" "),t("h2",{attrs:{id:"the-model"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#the-model"}},[e._v("#")]),e._v(" The model")]),e._v(" "),t("p",[e._v("The code building and training the model with "),t("a",{attrs:{href:"https://www.tensorflow.org/",target:"_blank",rel:"noopener noreferrer"}},[e._v("tensorflow"),t("OutboundLink")],1),e._v(" is available in "),t("a",{attrs:{href:"https://colab.research.google.com/drive/1yamwh8nE4NhmGButep-pfUT-1uRKs49a?usp=sharing",target:"_blank",rel:"noopener noreferrer"}},[e._v("google colab notebook"),t("OutboundLink")],1),e._v(" (jupyter notebook); you can also download the file as plain python and run it locally. At least 1 hour is needed to train the full model, but it heavily depends on the hardware available.")]),e._v(" "),t("p",[t("img",{attrs:{src:"/img/fee-estimation-for-light-clients/20210125-091313-confirms_in-fee_rate.png",alt:"graph confirm_in blocks vs fee_rate"}})]),t("div",{attrs:{align:"center"}},[e._v("Do you want to choose the fee without a model? In the last 5 weeks a ~50 sat/vbyte transaction never took more than a day to confirm and a ~10 sat/vbyte never took more than a week")]),t("br"),t("p"),e._v(" "),t("p",[e._v("As a reference, in the code we have a calculation of the bitcoin core "),t("code",[e._v("estimatesmartfee")]),e._v(" MAE"),t("sup",{staticClass:"footnote-ref"},[t("a",{attrs:{href:"#fn1",id:"fnref1"}},[e._v("[1]")])]),e._v(" and drift"),t("sup",{staticClass:"footnote-ref"},[t("a",{attrs:{href:"#fn2",id:"fnref2"}},[e._v("[2]")])]),e._v(".\nMAE is computed as "),t("code",[e._v("avg(abs(fee_rate - core_econ))")]),e._v(" when "),t("code",[e._v("core_econ")]),e._v(" is available (about 1.2M observations, sometime the value is not available when considered too old).")]),e._v(" "),t("table",[t("thead",[t("tr",[t("th",[e._v("estimatesmartfee mode")]),e._v(" "),t("th",[e._v("MAE [satoshi/vbytes]")]),e._v(" "),t("th",[e._v("drift")])])]),e._v(" "),t("tbody",[t("tr",[t("td",[e._v("economic")]),e._v(" "),t("td",[e._v("28.77")]),e._v(" "),t("td",[e._v("20.79")])]),e._v(" "),t("tr",[t("td",[e._v("conservative")]),e._v(" "),t("td",[e._v("46.49")]),e._v(" "),t("td",[e._v("44.73")])])])]),e._v(" "),t("p",[e._v("As seen from the table, the error is quite high, but the positive drift suggests "),t("code",[e._v("estimatesmartfee")]),e._v(" prefers to overestimate to avoid transactions not confirming.")]),e._v(" "),t("p",[e._v('As we said in the introduction, network traffic is correlated with time and we have the timestamp of when the transaction has been first seen, however a ML model doesn\'t like plain numbers too much, but it behaves better with "number that repeats", like categories, so we are converting the timestamp in '),t("code",[e._v("day_of_week")]),e._v(" a number from 0 to 6, and "),t("code",[e._v("hours")]),e._v(" a number from 0 to 24.")]),e._v(" "),t("h4",{attrs:{id:"splitting"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#splitting"}},[e._v("#")]),e._v(" Splitting")]),e._v(" "),t("p",[e._v("The dataset is splitted in training and test data with a 80/20 proportion. As the name suggest the training part is used to train the model, the test is composed of other observations to test if the model is good with observations that has never seen (proving the model can generalize, not just memorizing the answer).")]),e._v(" "),t("p",[e._v("During the training the data is splitted again in 80/20 for training and validation respectively, validation is basically testing during training.")]),e._v(" "),t("p",[e._v("During splitting, the dataset is converted from a pandas data frame to tensorflow dataset, decreasing training times.")]),e._v(" "),t("h4",{attrs:{id:"preprocessing"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#preprocessing"}},[e._v("#")]),e._v(" Preprocessing")]),e._v(" "),t("p",[e._v("The preprocessing phase is part of the model however it contains transformations without parameters trained by the model.\nThis transformations are useful because model trains better if data are in some format, and having this phase inside the model helps to avoid to prepare the data before feeding the model at prediction phase.")]),e._v(" "),t("p",[e._v("Our model performs 2 kind of preprocessing:")]),e._v(" "),t("ul",[t("li",[t("p",[e._v("Normalization: model trains faster if numerical features have mean 0 and standard deviation equal to 1, so this layer is built by computing the "),t("code",[e._v("mean")]),e._v(" and "),t("code",[e._v("std")]),e._v(" from the series of a feature before training, and the model is feed with "),t("code",[e._v("(feature - mean)/std")]),e._v(". Our model normalize "),t("code",[e._v("confirms_in")]),e._v(" feature and all the buckets "),t("code",[e._v("a*")])])]),e._v(" "),t("li",[t("p",[e._v("one-hot vector: Numerical categories having a small number of different unique values like our "),t("code",[e._v("day_of_week")]),e._v(" and "),t("code",[e._v("hours")]),e._v(" could be trained better/faster by being converted in one hot vector. For example "),t("code",[e._v("day_of_week=6")]),e._v(" (Sunday) is converted in a vector "),t("code",[e._v("['0', '0', '0', '0', '0', '0', '1']")]),e._v(" while "),t("code",[e._v("day_of_week=5")]),e._v(" (Saturday) is converted in the vector "),t("code",[e._v("['0', '0', '0', '0', '0', '1', '0']")])])])]),e._v(" "),t("h4",{attrs:{id:"build"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#build"}},[e._v("#")]),e._v(" Build")]),e._v(" "),t("div",{staticClass:"language-python extra-class"},[t("pre",{pre:!0,attrs:{class:"language-python"}},[t("code",[e._v("all_features "),t("span",{pre:!0,attrs:{class:"token operator"}},[e._v("=")]),e._v(" tf"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(".")]),e._v("keras"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(".")]),e._v("layers"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(".")]),e._v("concatenate"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v("(")]),e._v("encoded_features"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(")")]),e._v("\nx "),t("span",{pre:!0,attrs:{class:"token operator"}},[e._v("=")]),e._v(" tf"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(".")]),e._v("keras"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(".")]),e._v("layers"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(".")]),e._v("Dense"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v("(")]),t("span",{pre:!0,attrs:{class:"token number"}},[e._v("64")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(",")]),e._v(" activation"),t("span",{pre:!0,attrs:{class:"token operator"}},[e._v("=")]),t("span",{pre:!0,attrs:{class:"token string"}},[e._v('"relu"')]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(")")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v("(")]),e._v("all_features"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(")")]),e._v("\nx "),t("span",{pre:!0,attrs:{class:"token operator"}},[e._v("=")]),e._v(" tf"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(".")]),e._v("keras"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(".")]),e._v("layers"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(".")]),e._v("Dense"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v("(")]),t("span",{pre:!0,attrs:{class:"token number"}},[e._v("64")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(",")]),e._v(" activation"),t("span",{pre:!0,attrs:{class:"token operator"}},[e._v("=")]),t("span",{pre:!0,attrs:{class:"token string"}},[e._v('"relu"')]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(")")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v("(")]),e._v("x"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(")")]),e._v("\noutput "),t("span",{pre:!0,attrs:{class:"token operator"}},[e._v("=")]),e._v(" tf"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(".")]),e._v("keras"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(".")]),e._v("layers"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(".")]),e._v("Dense"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v("(")]),t("span",{pre:!0,attrs:{class:"token number"}},[e._v("1")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(",")]),e._v(" activation"),t("span",{pre:!0,attrs:{class:"token operator"}},[e._v("=")]),e._v("clip"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(")")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v("(")]),e._v("x"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(")")]),e._v("\nmodel "),t("span",{pre:!0,attrs:{class:"token operator"}},[e._v("=")]),e._v(" tf"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(".")]),e._v("keras"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(".")]),e._v("Model"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v("(")]),e._v("all_inputs"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(",")]),e._v(" output"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(")")]),e._v("\noptimizer "),t("span",{pre:!0,attrs:{class:"token operator"}},[e._v("=")]),e._v(" tf"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(".")]),e._v("optimizers"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(".")]),e._v("Adam"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v("(")]),e._v("learning_rate"),t("span",{pre:!0,attrs:{class:"token operator"}},[e._v("=")]),t("span",{pre:!0,attrs:{class:"token number"}},[e._v("0.01")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(")")]),e._v("\nmodel"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(".")]),t("span",{pre:!0,attrs:{class:"token builtin"}},[e._v("compile")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v("(")]),e._v("loss"),t("span",{pre:!0,attrs:{class:"token operator"}},[e._v("=")]),t("span",{pre:!0,attrs:{class:"token string"}},[e._v("'mse'")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(",")]),e._v("\n optimizer"),t("span",{pre:!0,attrs:{class:"token operator"}},[e._v("=")]),e._v("optimizer"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(",")]),e._v("\n metrics"),t("span",{pre:!0,attrs:{class:"token operator"}},[e._v("=")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v("[")]),t("span",{pre:!0,attrs:{class:"token string"}},[e._v("'mae'")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(",")]),e._v(" "),t("span",{pre:!0,attrs:{class:"token string"}},[e._v("'mse'")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v("]")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(")")]),e._v("\n")])])]),t("figure",[t("img",{attrs:{src:"/img/fee-estimation-for-light-clients/20210125-091313-model.png",alt:"model graph"}})]),e._v(" "),t("p",[e._v("The model is fed with the "),t("code",[e._v("encoded_features")]),e._v(" coming from the processing phase, then there are 2 layers with 64 neurons each followed by one neuron giving the "),t("code",[e._v("fee_rate")]),e._v(" as output.")]),e._v(" "),t("p",[e._v("With this configurations the model has:")]),e._v(" "),t("ul",[t("li",[e._v("Total params: "),t("code",[e._v("7,412")])]),e._v(" "),t("li",[e._v("Trainable params: "),t("code",[e._v("7,361")])]),e._v(" "),t("li",[e._v("Non-trainable params: "),t("code",[e._v("51")])])]),e._v(" "),t("p",[e._v("Non-trainable params comes from the normalization layer and are computed in the pre-processing phase (it contains, for example, the mean of a series). Trainable parameters are values initialized randomly and changed during the training phase. The trainable parameters are "),t("code",[e._v("7,361")]),e._v(", this number comes from the following, every neuron has an associated bias and a weight for every element in the inputs, thus:")]),e._v(" "),t("div",{staticClass:"language-shell extra-class"},[t("pre",{pre:!0,attrs:{class:"language-shell"}},[t("code",[t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v("(")]),t("span",{pre:!0,attrs:{class:"token number"}},[e._v("48")]),e._v(" input_values_weights + "),t("span",{pre:!0,attrs:{class:"token number"}},[e._v("1")]),e._v(" bias"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(")")]),e._v(" * "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v("(")]),t("span",{pre:!0,attrs:{class:"token number"}},[e._v("64")]),e._v(" first_layer_neurons"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(")")]),e._v("\n+ "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v("(")]),t("span",{pre:!0,attrs:{class:"token number"}},[e._v("64")]),e._v(" input_values_weights + "),t("span",{pre:!0,attrs:{class:"token number"}},[e._v("1")]),e._v(" bias"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(")")]),e._v(" * "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v("(")]),t("span",{pre:!0,attrs:{class:"token number"}},[e._v("64")]),e._v(" second layer neurons"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(")")]),e._v("\n+ "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v("(")]),t("span",{pre:!0,attrs:{class:"token number"}},[e._v("64")]),e._v(" input values weights + "),t("span",{pre:!0,attrs:{class:"token number"}},[e._v("1")]),e._v(" bias"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(")")]),e._v("\n\n"),t("span",{pre:!0,attrs:{class:"token number"}},[e._v("49")]),e._v("*64+65*64+65 "),t("span",{pre:!0,attrs:{class:"token operator"}},[e._v("=")]),e._v(" "),t("span",{pre:!0,attrs:{class:"token number"}},[e._v("7361")]),e._v("\n")])])]),t("p",[e._v("Honestly, neural network parameters are mostly the one taken from this tensorflow "),t("a",{attrs:{href:"https://www.tensorflow.org/tutorials/keras/regression",target:"_blank",rel:"noopener noreferrer"}},[e._v("example"),t("OutboundLink")],1),e._v(", we even tried to "),t("a",{attrs:{href:"https://www.tensorflow.org/tutorials/keras/keras_tuner",target:"_blank",rel:"noopener noreferrer"}},[e._v("tune hyperparameters"),t("OutboundLink")],1),e._v(", however, we decided to follow this "),t("a",{attrs:{href:"https://www.tensorflow.org/tutorials/keras/overfit_and_underfit#demonstrate_overfitting",target:"_blank",rel:"noopener noreferrer"}},[e._v("advice"),t("OutboundLink")],1),e._v(": "),t("em",[e._v('"The simplest way to prevent overfitting is to start with a small model:"')]),e._v(". We hope this work will attract other data scientists to this bitcoin problem, improving the model. We also think that a longer time for the data collection is needed to capture various situations.")]),e._v(" "),t("p",[e._v("A significant part of a ML model are the activation functions, "),t("code",[e._v("relu")]),e._v(" (Rectified Linear Unit) is one of the most used lately, because it's simple and works well as we learned in this "),t("a",{attrs:{href:"https://youtu.be/aircAruvnKk?t=1035",target:"_blank",rel:"noopener noreferrer"}},[e._v("introducing neural network video"),t("OutboundLink")],1),e._v(". "),t("code",[e._v("relu")]),e._v(" it's equal to zero for negative values and equal to the input for positive values. Being non-linear allows the whole model to be non-linear.")]),e._v(" "),t("p",[e._v("For the last layer it is different: we want to enforce a minimum for the output, which is the minimum relay fee "),t("code",[e._v("1.0")]),t("sup",{staticClass:"footnote-ref"},[t("a",{attrs:{href:"#fn3",id:"fnref3"}},[e._v("[3]")])]),e._v(". One could not simply cut the output of the model after prediction because all the training would not consider this constraint. So we need to build a custom activation function that the model training will be able to use for the "),t("a",{attrs:{href:"https://en.wikipedia.org/wiki/Gradient_descent#:~:text=Gradient%20descent%20is%20a%20first,the%20direction%20of%20steepest%20descent.",target:"_blank",rel:"noopener noreferrer"}},[e._v("gradient descent"),t("OutboundLink")],1),e._v(" optimization step. Luckily this is very simple using tensorflow primitives:")]),e._v(" "),t("div",{staticClass:"language- extra-class"},[t("pre",{pre:!0,attrs:{class:"language-text"}},[t("code",[e._v("def clip(x):\n min = tf.constant(1.0)\n return tf.where(tf.less(x, min), min, x)\n")])])]),t("p",[e._v("Another important part is the optimizer, when we first read the aforementioned "),t("a",{attrs:{href:"https://www.tensorflow.org/tutorials/keras/regression",target:"_blank",rel:"noopener noreferrer"}},[e._v("example"),t("OutboundLink")],1),e._v(" the optimizer used was "),t("code",[e._v("RMSProp")]),e._v(" however the example updated lately and we noticed the optimizer changed in favor of "),t("code",[e._v("Adam")]),e._v(" which we read is the "),t("a",{attrs:{href:"https://towardsdatascience.com/adam-latest-trends-in-deep-learning-optimization-6be9a291375c",target:"_blank",rel:"noopener noreferrer"}},[e._v("latest trend"),t("OutboundLink")],1),e._v(" in data science. We changed the model to use "),t("code",[e._v("Adam")]),e._v(" and effectively the training is faster with "),t("code",[e._v("Adam")]),e._v(" and even slightly lower error is achieved.\nAnother important parameter is the learning rate, which we set to "),t("code",[e._v("0.01")]),e._v(" after manual trials; however there might be space for improvements such as using "),t("a",{attrs:{href:"https://www.tensorflow.org/api_docs/python/tf/compat/v1/train/exponential_decay",target:"_blank",rel:"noopener noreferrer"}},[e._v("exponential decay"),t("OutboundLink")],1),e._v(", starting with an high learning rate and decreasing it through training epochs.")]),e._v(" "),t("p",[e._v('The last part of the model configuration is the loss function: the objective of the training is to find the minimum of this function. Usually for regression problem (the ones having a number as output, not a category) the most used is the Mean squared error (MSE). MSE is measured as the average of squared difference between predictions and actual observations, giving larger penalties to large difference because of the square. An interesting property is that the bigger the error the faster the changes is good at the beginning of the training, while slowing down when the model predicts better is desirable to avoid "jumping out" the local minimum.')]),e._v(" "),t("h4",{attrs:{id:"finally-the-model-training"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#finally-the-model-training"}},[e._v("#")]),e._v(" Finally, the model training")]),e._v(" "),t("div",{staticClass:"language- extra-class"},[t("pre",{pre:!0,attrs:{class:"language-text"}},[t("code",[e._v("PATIENCE = 20\nMAX_EPOCHS = 200\n\ndef train():\n early_stop = keras.callbacks.EarlyStopping(monitor='val_loss', patience=PATIENCE)\n history = model.fit(train_ds, epochs=MAX_EPOCHS, validation_data=val_ds, verbose=1, callbacks=[early_stop])\n return history\n\nhistory = train()\n")])])]),t("p",[e._v("This steps is the core of the neural network, it takes a while, let's analyze the output:")]),e._v(" "),t("div",{staticClass:"language- extra-class"},[t("pre",{pre:!0,attrs:{class:"language-text"}},[t("code",[e._v("Epoch 1/200\n7559/7559 [==============================] - 34s 3ms/step - loss: 547.8023 - mae: 16.9547 - mse: 547.8023 - val_loss: 300.5965 - val_ma\ne: 11.9202 - val_mse: 300.5965\n...\nEpoch 158/200\n7559/7559 [==============================] - 31s 3ms/step - loss: 163.2548 - mae: 8.3126 - mse: 163.2548 - val_loss: 164.8296 - val_mae: 8.3402 - val_mse: 164.8296\n")])])]),t("p",[e._v("Training is done in epochs, under every epoch all the training data is iterated and model parameters updated to minimize the loss function.")]),e._v(" "),t("p",[e._v("The number "),t("code",[e._v("7559")]),e._v(" represent the number of steps. Theoretically the whole training data should be processed at once and parameters updated accordingly, however in practice this is infeasible for example for memory resource, thus the training happens in batch. In our case we have "),t("code",[e._v("1,934,999")]),e._v(" observations in the training set and our batch size is "),t("code",[e._v("256")]),e._v(", thus we have "),t("code",[e._v("1,437,841/256=7,558.58")]),e._v(" which by excess result in "),t("code",[e._v("7559")]),e._v(" steps.")]),e._v(" "),t("p",[e._v("The "),t("code",[e._v("~31s")]),e._v(" is the time it takes to process the epoch on a threadripper CPU but GPU or TPU could do better.")]),e._v(" "),t("p",[e._v("The value "),t("code",[e._v("loss")]),e._v(" is the MSE on the training data while "),t("code",[e._v("val_loss")]),e._v(" is the MSE value on the validation data. As far as we understand the separated validation data helps to detect the machine learning enemy, overfitting. Because in case of overfitting the value "),t("code",[e._v("loss")]),e._v(" continue to improve (almost indefinitely) while "),t("code",[e._v("val_loss")]),e._v(" start improving with the loss but a certain point diverge, indicating the network is memorizing the training data to improve "),t("code",[e._v("loss")]),e._v(" but in doing so losing generalizing capabilities.")]),e._v(" "),t("p",[e._v("Our model doesn't look to suffer overfitting cause "),t("code",[e._v("loss")]),e._v(" and "),t("code",[e._v("val_loss")]),e._v(" doesn't diverge during training")]),e._v(" "),t("figure",[t("img",{attrs:{src:"/img/fee-estimation-for-light-clients/20210125-091313-train-history.png",alt:"train history"}})]),e._v(" "),t("p",[e._v("While we told the training to do 200 epochs, the training stopped at 158 because we added an "),t("code",[e._v("early_stop")]),e._v(" call back with "),t("code",[e._v("20")]),e._v(" as "),t("code",[e._v("PATIENCE")]),e._v(", meaning that after 20 epoch and no improvement in "),t("code",[e._v("val_loss")]),e._v(" the training is halted, saving time and potentially avoiding overfitting.")]),e._v(" "),t("h2",{attrs:{id:"the-prediction-phase"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#the-prediction-phase"}},[e._v("#")]),e._v(" The prediction phase")]),e._v(" "),t("p",[e._v("A "),t("a",{attrs:{href:"https://github.com/RCasatta/estimate_ml_fee",target:"_blank",rel:"noopener noreferrer"}},[e._v("prediction test tool"),t("OutboundLink")],1),e._v(" is available on github. At the moment it uses a bitcoin core node to provide network data for simplicity, but it queries it only for the mempool and the last 6 blocks, so it's something that also a light-client could do"),t("sup",{staticClass:"footnote-ref"},[t("a",{attrs:{href:"#fn4",id:"fnref4"}},[e._v("[4]")])]),e._v(".")]),e._v(" "),t("p",[e._v("The following chart is probably the best visualization to evaluate the model, on the x axis there is the real fee rate while on the y axis there is the prediction, the more the points are centered on the bisection, the more the model is good.\nWe can see the model is doing quite well, the MAE is 8 which is way lower than "),t("code",[e._v("estimatesmartfee")]),e._v(". However, there are big errors some times, in particular for prediction for fast confirmation ("),t("code",[e._v("confirms_in=1 or confirms_in=2")]),e._v(") as shown by the orange points. Creating a model only for blocks target greater than 2 instead of simply remove some observations may be an option.")]),e._v(" "),t("figure",[t("img",{attrs:{src:"/img/fee-estimation-for-light-clients/20210125-091313-true-and-predictions.png",alt:"prediction results"}})]),e._v(" "),t("p",[e._v("The following chart is instead a distribution of the errors, which for good model should resemble the normal distribution centered in 0, and it loooks like the model is respecting that.")]),e._v(" "),t("figure",[t("img",{attrs:{src:"/img/fee-estimation-for-light-clients/20210125-091313-error-distribution.png",alt:"error distribution"}})]),e._v(" "),t("h2",{attrs:{id:"conclusion-and-future-development"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#conclusion-and-future-development"}},[e._v("#")]),e._v(" Conclusion and future development")]),e._v(" "),t("p",[e._v("The results have shown deep neural network are a tool capable of good bitcoin transaction fee estimations; this suggests that further ML research in this area might be promising.")]),e._v(" "),t("p",[e._v("This is just a starting point, there are many future improvements such as:")]),e._v(" "),t("ul",[t("li",[e._v("Build a separate model with full knowledge, thus for full, always-connected nodes could be interesting and improve network resource allocation with respect to current estimators.")]),e._v(" "),t("li",[e._v("Tensorflow is a huge dependency, and since it contains all the feature to build and train a model, most of the feature are not needed in the prediction phase. In fact tensorflow lite exists which is specifically created for embedded and mobile devices; the "),t("a",{attrs:{href:"https://github.com/RCasatta/estimate_ml_fee",target:"_blank",rel:"noopener noreferrer"}},[e._v("prediction test tool"),t("OutboundLink")],1),e._v(" and the final integration in "),t("a",{attrs:{href:"https://github.com/bitcoindevkit/bdk",target:"_blank",rel:"noopener noreferrer"}},[e._v("bdk"),t("OutboundLink")],1),e._v(" should use it.")]),e._v(" "),t("li",[e._v("Explore other fields to improve model predictions such as:\n"),t("ul",[t("li",[e._v("A bucket array of the transactions in the last 6 blocks with known fee rates. This should in particular help estimations with almost empty mempool.")]),e._v(" "),t("li",[e._v("Transaction weight")]),e._v(" "),t("li",[e._v("Time from last block")])])]),e._v(" "),t("li",[e._v("Some fields are very important and could benefit from pre-processing expansion, for instance applying "),t("a",{attrs:{href:"https://www.tensorflow.org/tutorials/structured_data/feature_columns#hashed_feature_columns",target:"_blank",rel:"noopener noreferrer"}},[e._v("hashed feature columns"),t("OutboundLink")],1),e._v(" to "),t("code",[e._v("confirms_in")]),e._v(".")]),e._v(" "),t("li",[e._v("Bitcoin logger could be improved by a merge command to unify raw logs files, reducing redundancy and consequently disk occupation.")]),e._v(" "),t("li",[e._v("The dataset could be created in multiple files to allow more parallelism and use less memory during training.")]),e._v(" "),t("li",[e._v("Saving the dataset in "),t("a",{attrs:{href:"https://www.tensorflow.org/tutorials/load_data/tfrecord",target:"_blank",rel:"noopener noreferrer"}},[e._v("TFRecord format"),t("OutboundLink")],1),e._v(" instead of CSV")]),e._v(" "),t("li",[e._v("At the moment we are training the model on a threadripper CPU, training the code on GPU or even TPU will be needed to decrease training time, especially because input data will grow.")]),e._v(" "),t("li",[e._v("The "),t("a",{attrs:{href:"https://github.com/RCasatta/estimate_ml_fee",target:"_blank",rel:"noopener noreferrer"}},[e._v("prediction test tool"),t("OutboundLink")],1),e._v(" should estimate only using the p2p bitcoin network, without requiring a node. This work would be propedeutic for "),t("a",{attrs:{href:"https://github.com/bitcoindevkit/bdk",target:"_blank",rel:"noopener noreferrer"}},[e._v("bdk"),t("OutboundLink")],1),e._v(" integration")]),e._v(" "),t("li",[e._v("At the moment mempool buckets are multiple inputs "),t("code",[e._v("a*")]),e._v(" as show in the model graph; since they are related, is it possible to merge them in one TensorArray?")]),e._v(" "),t("li",[e._v("Sometimes the model does not learn and "),t("a",{attrs:{href:"https://github.com/RCasatta/bitcoin_logger/blob/master/notes.md",target:"_blank",rel:"noopener noreferrer"}},[e._v("gets stuck"),t("OutboundLink")],1),e._v(". The reason is the "),t("code",[e._v("clip")]),e._v(" function applied in the last layer is constant for a value lower than 1. In this case, the derivative is 0 and the gradient descent doesn't know where to go. Instead of using the "),t("code",[e._v("clip")]),e._v(" function apply penalties to the loss function for values lower than 1.")]),e._v(" "),t("li",[e._v("There are issues regarding dead neurons (going to 0) or neurons with big weight, weight results should be monitored for this events, and also weight decay and L2 regularization should be explored.")]),e._v(" "),t("li",[e._v("Tune hyper-parameters technique should be re-tested.")]),e._v(" "),t("li",[e._v("Predictions should be monotonic decreasing for growing "),t("code",[e._v("confirms_in")]),e._v(" parameter; for obvious reason it doesn't make sense that an higher fee rate will result in a higher confirmation time. But since this is not enforced anywhere in the model, at the moment this could happen.")]),e._v(" "),t("li",[e._v("Since nodes with bloom filter disabled doesn't serve the mempool anymore, a model based only on last blocks should be evaluated.")])]),e._v(" "),t("h2",{attrs:{id:"acknowledgements"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#acknowledgements"}},[e._v("#")]),e._v(" Acknowledgements")]),e._v(" "),t("p",[e._v("Thanks to "),t("a",{attrs:{href:"https://squarecrypto.org/",target:"_blank",rel:"noopener noreferrer"}},[e._v("Square crypto"),t("OutboundLink")],1),e._v(" for sponsoring this work and thanks to the reviewers: "),t("a",{attrs:{href:"https://twitter.com/LeoComandini",target:"_blank",rel:"noopener noreferrer"}},[e._v("Leonardo Comandini"),t("OutboundLink")],1),e._v(", "),t("a",{attrs:{href:"https://twitter.com/domegabri",target:"_blank",rel:"noopener noreferrer"}},[e._v("Domenico Gabriele"),t("OutboundLink")],1),e._v(", "),t("a",{attrs:{href:"https://twitter.com/afilini",target:"_blank",rel:"noopener noreferrer"}},[e._v("Alekos Filini"),t("OutboundLink")],1),e._v(", "),t("a",{attrs:{href:"https://twitter.com/Ferdinando1970",target:"_blank",rel:"noopener noreferrer"}},[e._v("Ferdinando Ametrano"),t("OutboundLink")],1),e._v(".")]),e._v(" "),t("p",[e._v("And also this tweet that remembered me "),t("a",{attrs:{href:"https://twitter.com/RCasatta",target:"_blank",rel:"noopener noreferrer"}},[e._v("I"),t("OutboundLink")],1),e._v(" had this work in my TODO list")]),e._v(" "),t("blockquote",{staticClass:"twitter-tweet"},[t("p",{attrs:{lang:"en",dir:"ltr"}},[e._v("I don't understand Machine Learning(ML), but is it horrible to use ML to predict bitcoin fees? "),t("br"),t("br"),e._v('I have heard tales of this "Deep Learning" thing where you throw a bunch of data at it and it gives you good results with high accuracy.')]),e._v("— sanket1729 (@sanket1729) "),t("a",{attrs:{href:"https://twitter.com/sanket1729/status/1336624662365822977?ref_src=twsrc%5Etfw"}},[e._v("December 9, 2020")])]),e._v(" "),t("script",{attrs:{async:"",src:"https://platform.twitter.com/widgets.js",charset:"utf-8"}}),e._v(" "),t("p",[e._v("This is the final part of the series. In the previous "),t("RouterLink",{attrs:{to:"/blog/2021/01/fee-estimation-for-light-clients-part-1/"}},[e._v("Part 1")]),e._v(" we talked about the problem and in "),t("RouterLink",{attrs:{to:"/blog/2021/01/fee-estimation-for-light-clients-part-2/"}},[e._v("Part 2")]),e._v(" we talked about the dataset.")],1),e._v(" "),t("hr",{staticClass:"footnotes-sep"}),e._v(" "),t("section",{staticClass:"footnotes"},[t("ol",{staticClass:"footnotes-list"},[t("li",{staticClass:"footnote-item",attrs:{id:"fn1"}},[t("p",[e._v("MAE is Mean Absolute Error, which is the average of the series built by the absolute difference between the real value and the estimation. "),t("a",{staticClass:"footnote-backref",attrs:{href:"#fnref1"}},[e._v("↩︎")])])]),e._v(" "),t("li",{staticClass:"footnote-item",attrs:{id:"fn2"}},[t("p",[e._v("drift like MAE, but without the absolute value "),t("a",{staticClass:"footnote-backref",attrs:{href:"#fnref2"}},[e._v("↩︎")])])]),e._v(" "),t("li",{staticClass:"footnote-item",attrs:{id:"fn3"}},[t("p",[e._v("Most node won't relay transactions with fee lower than the min relay fee, which has a default of "),t("code",[e._v("1.0")]),e._v(" "),t("a",{staticClass:"footnote-backref",attrs:{href:"#fnref3"}},[e._v("↩︎")])])]),e._v(" "),t("li",{staticClass:"footnote-item",attrs:{id:"fn4"}},[t("p",[e._v("An important issue emerged after the article came out, a bitcoin core client with bloom filter disabled (default as of 0.21) doesn't serve the mempool via p2p. "),t("a",{staticClass:"footnote-backref",attrs:{href:"#fnref4"}},[e._v("↩︎")])])])])])])}),[],!1,null,null,null);t.default=s.exports}}]); \ No newline at end of file diff --git a/assets/js/59.7e9a8d23.js b/assets/js/59.0c9b7bcd.js similarity index 99% rename from assets/js/59.7e9a8d23.js rename to assets/js/59.0c9b7bcd.js index 4e9bb3d3ca..ae33232186 100644 --- a/assets/js/59.7e9a8d23.js +++ b/assets/js/59.0c9b7bcd.js @@ -1 +1 @@ -(window.webpackJsonp=window.webpackJsonp||[]).push([[59],{417:function(e,t,s){"use strict";s.r(t);var n=s(7),a=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 is the first of a two-parts blog series in which I will try to explain all the changes that I made to BDK (and some of its dependencies) to make our "),t("a",{attrs:{href:"https://twitter.com/afilini/status/1459763243556163584",target:"_blank",rel:"noopener noreferrer"}},[e._v("first Taproot transaction in mainnet"),t("OutboundLink")],1),e._v(", which also\nturned out to be "),t("a",{attrs:{href:"https://twitter.com/afilini/status/1459774394054725634",target:"_blank",rel:"noopener noreferrer"}},[e._v("the first ever use of the new "),t("code",[e._v("OP_CHECKSIGADD")]),e._v(" opcode"),t("OutboundLink")],1),e._v(".")]),e._v(" "),t("p",[e._v("Hopefully this will give an insight into what kind of changes need to be made to a wallet in order to support spending "),t("code",[e._v("P2TR")]),e._v(" outputs, both with key-spend and script-spend. BDK actually delegates\nmost of the hard work to "),t("a",{attrs:{href:"https://github.com/rust-bitcoin/rust-miniscript",target:"_blank",rel:"noopener noreferrer"}},[e._v("rust-miniscript"),t("OutboundLink")],1),e._v(", and luckily most of the Taproot code was already implemented by the time I started working on it. I only had to patch a few little bugs here and there, and it ended up\nworking flawlessly in the end.")]),e._v(" "),t("p",[e._v("In this first part I will focus on the changes made to our dependencies, "),t("a",{attrs:{href:"https://github.com/rust-bitcoin/rust-bitcoin",target:"_blank",rel:"noopener noreferrer"}},[e._v("rust-bitcoin"),t("OutboundLink")],1),e._v(" and "),t("a",{attrs:{href:"https://github.com/rust-bitcoin/rust-miniscript",target:"_blank",rel:"noopener noreferrer"}},[e._v("rust-miniscript"),t("OutboundLink")],1),e._v(". In the second part I will talk about BDK itself.")]),e._v(" "),t("h2",{attrs:{id:"backstory"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#backstory"}},[e._v("#")]),e._v(" Backstory")]),e._v(" "),t("p",[e._v("On the evening of Thursday, November 11th I was attending our weekly "),t("a",{attrs:{href:"https://www.satoshispritz.com/",target:"_blank",rel:"noopener noreferrer"}},[e._v("Satoshi Spritz"),t("OutboundLink")],1),e._v(" meetup in Milan. The activation of Taproot was right around the corner, and naturally that was the main discussion\ntopic that night. The activation was forecasted for the early afternoon of Sunday, November 14th, a little less than 72h later.")]),e._v(" "),t("p",[e._v("I began to wonder how hard it would be to patch BDK and add support for Taproot. I knew most of the work had already been done in our main dependencies, "),t("a",{attrs:{href:"https://github.com/rust-bitcoin/rust-bitcoin",target:"_blank",rel:"noopener noreferrer"}},[e._v("rust-bitcoin"),t("OutboundLink")],1),e._v(" and "),t("a",{attrs:{href:"https://github.com/rust-bitcoin/rust-miniscript",target:"_blank",rel:"noopener noreferrer"}},[e._v("rust-miniscript"),t("OutboundLink")],1),e._v(", and so I decided\nto challenge myself: could I make it in time for the activation?")]),e._v(" "),t("p",[e._v('The following day I started digging into the topic. It didn\'t help that up until that time I only had a rather "high level" idea of how Taproot worked, but luckily all the BIPs were very well written and\nstraightforward to understand.')]),e._v(" "),t("p",[e._v("By Friday night (or rather, early Saturday morning) "),t("a",{attrs:{href:"https://mempool.space/signet/tx/ba0ebb350717701ca4ea109aadfbaf3058f6cd73e5ece3927ddee653de06cf5a",target:"_blank",rel:"noopener noreferrer"}},[e._v("I had Taproot key-spend working"),t("OutboundLink")],1),e._v(", which made me pretty optimistic even though the activation date was actually moving closer, now being forecasted for\nSunday "),t("em",[e._v("morning")]),e._v(".")]),e._v(" "),t("p",[e._v("After a few hours of sleep I went back to work and by early Saturday afternoon "),t("a",{attrs:{href:"https://mempool.space/signet/tx/41d7d49f9f4edffa9ca88ad6fb887fbf1ae68f9f31def267fdb3a5949f766bf5",target:"_blank",rel:"noopener noreferrer"}},[e._v("I had Taproot script-spend working as well"),t("OutboundLink")],1),e._v(". This left me a few hours to coordinate with some friends and "),t("a",{attrs:{href:"https://mempool.space/address/1Taproote7gvQGKz5g982ecSbPvqJhMUf",target:"_blank",rel:"noopener noreferrer"}},[e._v("generate a vanity address"),t("OutboundLink")],1),e._v("\nto deposit funds into temporarily, as we didn't trust sending them to Taproot addresses before the activation (as they were anyone-can-spend according to the pre-activation rules).")]),e._v(" "),t("p",[e._v("After another pretty short night, I woke up a 5:30 AM on Sunday to monitor the activation. I broadcasted our transactions shortly after 6:00 AM as the activation block was being mined. Unfortunately, the first\nthree blocks that were enforcing Taproot rules "),t("a",{attrs:{href:"https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2021-November/019598.html",target:"_blank",rel:"noopener noreferrer"}},[e._v("didn't include any Taproot transaction"),t("OutboundLink")],1),e._v(", which indicates that the miners weren't actually running the new Bitcoin Core 22.0 nodes. The fourth block, mined by "),t("code",[e._v("Foundry USA")]),e._v(" "),t("a",{attrs:{href:"https://mempool.space/tx/2eb8dbaa346d4be4e82fe444c2f0be00654d8cfd8c4a9a61b11aeaab8c00b272",target:"_blank",rel:"noopener noreferrer"}},[e._v("included my transaction"),t("OutboundLink")],1),e._v(" and "),t("a",{attrs:{href:"https://twitter.com/achow101/status/1459760452775387136?s=20",target:"_blank",rel:"noopener noreferrer"}},[e._v("a few others"),t("OutboundLink")],1),e._v(".")]),e._v(" "),t("p",[e._v("In the end our transaction was the third Taproot script-spend in the block, but the first to use the new "),t("a",{attrs:{href:"https://github.com/bitcoin/bips/blob/master/bip-0342.mediawiki#script-execution",target:"_blank",rel:"noopener noreferrer"}},[t("code",[e._v("OP_CHECKSIGADD")]),t("OutboundLink")],1),e._v(" opcode, as the two preceding it were respectively "),t("a",{attrs:{href:"https://mempool.space/tx/37777defed8717c581b4c0509329550e344bdc14ac38f71fc050096887e535c8",target:"_blank",rel:"noopener noreferrer"}},[e._v("a single-sig"),t("OutboundLink")],1),e._v(" and "),t("a",{attrs:{href:"https://mempool.space/tx/905ecdf95a84804b192f4dc221cfed4d77959b81ed66013a7e41a6e61e7ed530",target:"_blank",rel:"noopener noreferrer"}},[e._v("a 2-of-2 multisig"),t("OutboundLink")],1),e._v("\nscript, made with with two "),t("code",[e._v("OP_CHECKSIG(VERIFY)")]),e._v("s.")]),e._v(" "),t("p",[e._v("Now, with the context out of the way, we can begin talking about the code!")]),e._v(" "),t("h2",{attrs:{id:"rust-bitcoin"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#rust-bitcoin"}},[e._v("#")]),e._v(" rust-bitcoin")]),e._v(" "),t("p",[e._v("The first dependency I had to update was "),t("a",{attrs:{href:"https://github.com/rust-bitcoin/rust-bitcoin",target:"_blank",rel:"noopener noreferrer"}},[e._v("rust-bitcoin"),t("OutboundLink")],1),e._v(". Most of the taproot stuff were already merged in "),t("code",[e._v("master")]),e._v(" (altough they hadn't been released yet). One notable missing part was the support for "),t("a",{attrs:{href:"https://github.com/bitcoin/bips/blob/master/bip-0371.mediawiki",target:"_blank",rel:"noopener noreferrer"}},[t("code",[e._v("BIP371")]),t("OutboundLink")],1),e._v(",\nwhich is an extension of "),t("a",{attrs:{href:"https://github.com/bitcoin/bips/blob/master/bip-0174.mediawiki",target:"_blank",rel:"noopener noreferrer"}},[t("code",[e._v("BIP174")]),t("OutboundLink")],1),e._v(", aka the "),t("code",[e._v("Partially Signed Bitcoin Transaction")]),e._v(" BIP. This new BIP defines a few new fields that are required to properly handle Taproot transactions.")]),e._v(" "),t("p",[e._v("Luckily most of the work had already been done by "),t("a",{attrs:{href:"https://twitter.com/sanket1729",target:"_blank",rel:"noopener noreferrer"}},[e._v("sanket1729"),t("OutboundLink")],1),e._v(", so I forked his branch and made only few very minor changes, just to expose a structure that I will have to use later which in his code wasn't public.")]),e._v(" "),t("p",[e._v("You can find all the commits mentioned here in "),t("a",{attrs:{href:"https://github.com/afilini/rust-bitcoin/tree/taproot-testing",target:"_blank",rel:"noopener noreferrer"}},[e._v("my rust-bitcoin "),t("code",[e._v("taproot-testing")]),e._v(" branch"),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("$ git diff 187234f f830df9\n")])])]),t("div",{staticClass:"language-diff extra-class"},[t("pre",{pre:!0,attrs:{class:"language-diff"}},[t("code",[e._v("diff --git a/src/lib.rs b/src/lib.rs\nindex 87d9c36..d5e5802 100644\n"),t("span",{pre:!0,attrs:{class:"token coord"}},[e._v("--- a/src/lib.rs")]),e._v("\n"),t("span",{pre:!0,attrs:{class:"token coord"}},[e._v("+++ b/src/lib.rs")]),e._v("\n"),t("span",{pre:!0,attrs:{class:"token coord"}},[e._v("@@ -54,7 +54,6 @@")]),e._v("\n"),t("span",{pre:!0,attrs:{class:"token unchanged"}},[t("span",{pre:!0,attrs:{class:"token prefix unchanged"}},[e._v(" ")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v("#![deny(unused_mut)]\n")]),t("span",{pre:!0,attrs:{class:"token prefix unchanged"}},[e._v(" ")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v("#![deny(dead_code)]\n")]),t("span",{pre:!0,attrs:{class:"token prefix unchanged"}},[e._v(" ")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v("#![deny(unused_imports)]\n")])]),t("span",{pre:!0,attrs:{class:"token deleted-sign deleted"}},[t("span",{pre:!0,attrs:{class:"token prefix deleted"}},[e._v("-")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v("#![deny(missing_docs)]\n")])]),t("span",{pre:!0,attrs:{class:"token unchanged"}},[t("span",{pre:!0,attrs:{class:"token prefix unchanged"}},[e._v(" ")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v("#![deny(unused_must_use)]\n")]),t("span",{pre:!0,attrs:{class:"token prefix unchanged"}},[e._v(" ")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v("#![deny(broken_intra_doc_links)]\n")])]),e._v("\ndiff --git a/src/util/taproot.rs b/src/util/taproot.rs\nindex 674eeee..3d56cbc 100644\n"),t("span",{pre:!0,attrs:{class:"token coord"}},[e._v("--- a/src/util/taproot.rs")]),e._v("\n"),t("span",{pre:!0,attrs:{class:"token coord"}},[e._v("+++ b/src/util/taproot.rs")]),e._v("\n@@ -440,7 +440,7 @@ impl TaprootBuilder {\n"),t("span",{pre:!0,attrs:{class:"token unchanged"}},[t("span",{pre:!0,attrs:{class:"token prefix unchanged"}},[e._v(" ")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v("// Internally used structure to represent the node information in taproot tree\n")]),t("span",{pre:!0,attrs:{class:"token prefix unchanged"}},[e._v(" ")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v("#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]\n")]),t("span",{pre:!0,attrs:{class:"token prefix unchanged"}},[e._v(" ")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v('#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]\n')])]),t("span",{pre:!0,attrs:{class:"token deleted-sign deleted"}},[t("span",{pre:!0,attrs:{class:"token prefix deleted"}},[e._v("-")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v("pub(crate) struct NodeInfo {\n")])]),t("span",{pre:!0,attrs:{class:"token inserted-sign inserted"}},[t("span",{pre:!0,attrs:{class:"token prefix inserted"}},[e._v("+")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v("pub struct NodeInfo {\n")])]),t("span",{pre:!0,attrs:{class:"token unchanged"}},[t("span",{pre:!0,attrs:{class:"token prefix unchanged"}},[e._v(" ")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" /// Merkle Hash for this node\n")]),t("span",{pre:!0,attrs:{class:"token prefix unchanged"}},[e._v(" ")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" pub(crate) hash: sha256::Hash,\n")]),t("span",{pre:!0,attrs:{class:"token prefix unchanged"}},[e._v(" ")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" /// information about leaves inside this node\n")])]),e._v("@@ -448,8 +448,12 @@ pub(crate) struct NodeInfo {\n"),t("span",{pre:!0,attrs:{class:"token unchanged"}},[t("span",{pre:!0,attrs:{class:"token prefix unchanged"}},[e._v(" ")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v("}\n")])]),e._v("\n"),t("span",{pre:!0,attrs:{class:"token unchanged"}},[t("span",{pre:!0,attrs:{class:"token prefix unchanged"}},[e._v(" ")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v("impl NodeInfo {\n")])]),t("span",{pre:!0,attrs:{class:"token inserted-sign inserted"}},[t("span",{pre:!0,attrs:{class:"token prefix inserted"}},[e._v("+")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" pub fn hash(&self) -> &sha256::Hash {\n")]),t("span",{pre:!0,attrs:{class:"token prefix inserted"}},[e._v("+")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" &self.hash\n")]),t("span",{pre:!0,attrs:{class:"token prefix inserted"}},[e._v("+")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" }\n")]),t("span",{pre:!0,attrs:{class:"token prefix inserted"}},[e._v("+")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v("\n")])]),t("span",{pre:!0,attrs:{class:"token unchanged"}},[t("span",{pre:!0,attrs:{class:"token prefix unchanged"}},[e._v(" ")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" // Create a new NodeInfo with omitted/hidden info\n")])]),t("span",{pre:!0,attrs:{class:"token deleted-sign deleted"}},[t("span",{pre:!0,attrs:{class:"token prefix deleted"}},[e._v("-")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" fn new_hidden(hash: sha256::Hash) -> Self {\n")])]),t("span",{pre:!0,attrs:{class:"token inserted-sign inserted"}},[t("span",{pre:!0,attrs:{class:"token prefix inserted"}},[e._v("+")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" pub fn new_hidden(hash: sha256::Hash) -> Self {\n")])]),t("span",{pre:!0,attrs:{class:"token unchanged"}},[t("span",{pre:!0,attrs:{class:"token prefix unchanged"}},[e._v(" ")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" Self {\n")]),t("span",{pre:!0,attrs:{class:"token prefix unchanged"}},[e._v(" ")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" hash: hash,\n")]),t("span",{pre:!0,attrs:{class:"token prefix unchanged"}},[e._v(" ")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" leaves: vec![],\n")])]),e._v("@@ -457,7 +461,7 @@ impl NodeInfo {\n"),t("span",{pre:!0,attrs:{class:"token unchanged"}},[t("span",{pre:!0,attrs:{class:"token prefix unchanged"}},[e._v(" ")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" }\n")])]),e._v("\n"),t("span",{pre:!0,attrs:{class:"token unchanged"}},[t("span",{pre:!0,attrs:{class:"token prefix unchanged"}},[e._v(" ")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" // Create a new leaf with NodeInfo\n")])]),t("span",{pre:!0,attrs:{class:"token deleted-sign deleted"}},[t("span",{pre:!0,attrs:{class:"token prefix deleted"}},[e._v("-")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" fn new_leaf_with_ver(script: Script, ver: LeafVersion) -> Self {\n")])]),t("span",{pre:!0,attrs:{class:"token inserted-sign inserted"}},[t("span",{pre:!0,attrs:{class:"token prefix inserted"}},[e._v("+")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" pub fn new_leaf_with_ver(script: Script, ver: LeafVersion) -> Self {\n")])]),t("span",{pre:!0,attrs:{class:"token unchanged"}},[t("span",{pre:!0,attrs:{class:"token prefix unchanged"}},[e._v(" ")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" let leaf = LeafInfo::new(script, ver);\n")]),t("span",{pre:!0,attrs:{class:"token prefix unchanged"}},[e._v(" ")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" Self {\n")]),t("span",{pre:!0,attrs:{class:"token prefix unchanged"}},[e._v(" ")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" hash: leaf.hash(),\n")])]),e._v("@@ -466,7 +470,7 @@ impl NodeInfo {\n"),t("span",{pre:!0,attrs:{class:"token unchanged"}},[t("span",{pre:!0,attrs:{class:"token prefix unchanged"}},[e._v(" ")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" }\n")])]),e._v("\n"),t("span",{pre:!0,attrs:{class:"token unchanged"}},[t("span",{pre:!0,attrs:{class:"token prefix unchanged"}},[e._v(" ")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" // Combine two NodeInfo's to create a new parent\n")])]),t("span",{pre:!0,attrs:{class:"token deleted-sign deleted"}},[t("span",{pre:!0,attrs:{class:"token prefix deleted"}},[e._v("-")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" fn combine(a: Self, b: Self) -> Result {\n")])]),t("span",{pre:!0,attrs:{class:"token inserted-sign inserted"}},[t("span",{pre:!0,attrs:{class:"token prefix inserted"}},[e._v("+")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" pub fn combine(a: Self, b: Self) -> Result {\n")])]),t("span",{pre:!0,attrs:{class:"token unchanged"}},[t("span",{pre:!0,attrs:{class:"token prefix unchanged"}},[e._v(" ")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" let mut all_leaves = Vec::with_capacity(a.leaves.len() + b.leaves.len());\n")]),t("span",{pre:!0,attrs:{class:"token prefix unchanged"}},[e._v(" ")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" for mut a_leaf in a.leaves {\n")]),t("span",{pre:!0,attrs:{class:"token prefix unchanged"}},[e._v(" ")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" a_leaf.merkle_branch.push(b.hash)?; // add hashing partner\n")])]),e._v("\n")])])]),t("p",[e._v("There isn't much to explain here: I disabled the "),t("code",[e._v("missing_docs")]),e._v(" lint so that the compiler wouldn't complain about the new public methods that aren't documented.\nThen, I added a getter for the "),t("code",[e._v("hash")]),e._v(" field of "),t("code",[e._v("NodeInfo")]),e._v(" and made the struct itself and a bunch of methods public.")]),e._v(" "),t("p",[e._v('We will use this structure later to recover the merkle root of a Taproot script tree, given one leaf and the other "hidden" branches.')]),e._v(" "),t("h2",{attrs:{id:"rust-miniscript"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#rust-miniscript"}},[e._v("#")]),e._v(" rust-miniscript")]),e._v(" "),t("p",[e._v("Moving on to "),t("a",{attrs:{href:"https://github.com/rust-bitcoin/rust-miniscript",target:"_blank",rel:"noopener noreferrer"}},[e._v("rust-miniscript"),t("OutboundLink")],1),e._v(': once again, most of the work required to support Taproot had already been done, but this time I was working with very "early" prototype-like code, so I was prepared to\nmake some changes to the code to get it to work how I wanted.')]),e._v(" "),t("p",[e._v("Instead of showing one big diff I will talk about the commits individually, which I think will help making more clear what I was doing.")]),e._v(" "),t("p",[e._v("Once again, you can find all the commits referenced here in "),t("a",{attrs:{href:"https://github.com/afilini/rust-miniscript/tree/taproot",target:"_blank",rel:"noopener noreferrer"}},[e._v("my rust-miniscript "),t("code",[e._v("taproot")]),e._v(" branch"),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("$ git show 34cf15b\n")])])]),t("div",{staticClass:"language-diff extra-class"},[t("pre",{pre:!0,attrs:{class:"language-diff"}},[t("code",[e._v("commit 34cf15b3aac1d8c2693af1b9749b888f3f29e510\nAuthor: Alekos Filini \nDate: Fri Nov 12 12:06:35 2021 +0100\n\n"),t("span",{pre:!0,attrs:{class:"token unchanged"}},[t("span",{pre:!0,attrs:{class:"token prefix unchanged"}},[e._v(" ")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" Fix TapTree iter depth\n")])]),e._v("\ndiff --git a/src/descriptor/tr.rs b/src/descriptor/tr.rs\nindex 79d3c05..314c7f4 100644\n"),t("span",{pre:!0,attrs:{class:"token coord"}},[e._v("--- a/src/descriptor/tr.rs")]),e._v("\n"),t("span",{pre:!0,attrs:{class:"token coord"}},[e._v("+++ b/src/descriptor/tr.rs")]),e._v("\n@@ -65,7 +65,7 @@ impl TapTree {\n"),t("span",{pre:!0,attrs:{class:"token unchanged"}},[t("span",{pre:!0,attrs:{class:"token prefix unchanged"}},[e._v(" ")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v("\n")]),t("span",{pre:!0,attrs:{class:"token prefix unchanged"}},[e._v(" ")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" /// Iterate over all miniscripts\n")]),t("span",{pre:!0,attrs:{class:"token prefix unchanged"}},[e._v(" ")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" pub fn iter(&self) -> TapTreeIter {\n")])]),t("span",{pre:!0,attrs:{class:"token deleted-sign deleted"}},[t("span",{pre:!0,attrs:{class:"token prefix deleted"}},[e._v("-")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" TapTreeIter { stack: vec![self] }\n")])]),t("span",{pre:!0,attrs:{class:"token inserted-sign inserted"}},[t("span",{pre:!0,attrs:{class:"token prefix inserted"}},[e._v("+")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" TapTreeIter { stack: vec![(0, self)] }\n")])]),t("span",{pre:!0,attrs:{class:"token unchanged"}},[t("span",{pre:!0,attrs:{class:"token prefix unchanged"}},[e._v(" ")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" }\n")]),t("span",{pre:!0,attrs:{class:"token prefix unchanged"}},[e._v(" ")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v("\n")]),t("span",{pre:!0,attrs:{class:"token prefix unchanged"}},[e._v(" ")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" // Helper function to translate keys\n")])]),e._v("@@ -262,7 +262,7 @@ pub struct TapTreeIter<'a, Pk: MiniscriptKey>\n"),t("span",{pre:!0,attrs:{class:"token unchanged"}},[t("span",{pre:!0,attrs:{class:"token prefix unchanged"}},[e._v(" ")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v("where\n")]),t("span",{pre:!0,attrs:{class:"token prefix unchanged"}},[e._v(" ")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" Pk: 'a,\n")]),t("span",{pre:!0,attrs:{class:"token prefix unchanged"}},[e._v(" ")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v("{\n")])]),t("span",{pre:!0,attrs:{class:"token deleted-sign deleted"}},[t("span",{pre:!0,attrs:{class:"token prefix deleted"}},[e._v("-")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" stack: Vec<&'a TapTree>,\n")])]),t("span",{pre:!0,attrs:{class:"token inserted-sign inserted"}},[t("span",{pre:!0,attrs:{class:"token prefix inserted"}},[e._v("+")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" stack: Vec<(usize, &'a TapTree)>,\n")])]),t("span",{pre:!0,attrs:{class:"token unchanged"}},[t("span",{pre:!0,attrs:{class:"token prefix unchanged"}},[e._v(" ")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v("}\n")]),t("span",{pre:!0,attrs:{class:"token prefix unchanged"}},[e._v(" ")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v("\n")]),t("span",{pre:!0,attrs:{class:"token prefix unchanged"}},[e._v(" ")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v("impl<'a, Pk> Iterator for TapTreeIter<'a, Pk>\n")])]),e._v("@@ -273,13 +273,13 @@ where\n"),t("span",{pre:!0,attrs:{class:"token unchanged"}},[t("span",{pre:!0,attrs:{class:"token prefix unchanged"}},[e._v(" ")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v("\n")]),t("span",{pre:!0,attrs:{class:"token prefix unchanged"}},[e._v(" ")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" fn next(&mut self) -> Option {\n")]),t("span",{pre:!0,attrs:{class:"token prefix unchanged"}},[e._v(" ")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" while !self.stack.is_empty() {\n")])]),t("span",{pre:!0,attrs:{class:"token deleted-sign deleted"}},[t("span",{pre:!0,attrs:{class:"token prefix deleted"}},[e._v("-")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(' let last = self.stack.pop().expect("Size checked above");\n')])]),t("span",{pre:!0,attrs:{class:"token inserted-sign inserted"}},[t("span",{pre:!0,attrs:{class:"token prefix inserted"}},[e._v("+")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(' let (depth, last) = self.stack.pop().expect("Size checked above");\n')])]),t("span",{pre:!0,attrs:{class:"token unchanged"}},[t("span",{pre:!0,attrs:{class:"token prefix unchanged"}},[e._v(" ")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" match &*last {\n")]),t("span",{pre:!0,attrs:{class:"token prefix unchanged"}},[e._v(" ")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" TapTree::Tree(l, r) => {\n")])]),t("span",{pre:!0,attrs:{class:"token deleted-sign deleted"}},[t("span",{pre:!0,attrs:{class:"token prefix deleted"}},[e._v("-")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" self.stack.push(&r);\n")]),t("span",{pre:!0,attrs:{class:"token prefix deleted"}},[e._v("-")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" self.stack.push(&l);\n")])]),t("span",{pre:!0,attrs:{class:"token inserted-sign inserted"}},[t("span",{pre:!0,attrs:{class:"token prefix inserted"}},[e._v("+")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" self.stack.push((depth + 1, &r));\n")]),t("span",{pre:!0,attrs:{class:"token prefix inserted"}},[e._v("+")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" self.stack.push((depth + 1, &l));\n")])]),t("span",{pre:!0,attrs:{class:"token unchanged"}},[t("span",{pre:!0,attrs:{class:"token prefix unchanged"}},[e._v(" ")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" }\n")])]),t("span",{pre:!0,attrs:{class:"token deleted-sign deleted"}},[t("span",{pre:!0,attrs:{class:"token prefix deleted"}},[e._v("-")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" TapTree::Leaf(ref ms) => return Some((self.stack.len(), ms)),\n")])]),t("span",{pre:!0,attrs:{class:"token inserted-sign inserted"}},[t("span",{pre:!0,attrs:{class:"token prefix inserted"}},[e._v("+")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" TapTree::Leaf(ref ms) => return Some((depth, ms)),\n")])]),t("span",{pre:!0,attrs:{class:"token unchanged"}},[t("span",{pre:!0,attrs:{class:"token prefix unchanged"}},[e._v(" ")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" }\n")]),t("span",{pre:!0,attrs:{class:"token prefix unchanged"}},[e._v(" ")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" }\n")]),t("span",{pre:!0,attrs:{class:"token prefix unchanged"}},[e._v(" ")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" None\n")])])])])]),t("p",[t("code",[e._v("TapTreeIterator")]),e._v(" is an iterator that goes through a "),t("code",[e._v("TapTree")]),e._v(" and yields a "),t("code",[e._v("(depth, node)")]),e._v(" pair. This is then fed to "),t("a",{attrs:{href:"https://github.com/afilini/rust-miniscript/blob/taproot/src/descriptor/tr.rs#L183-L189",target:"_blank",rel:"noopener noreferrer"}},[t("code",[e._v("TaprootBuilder")]),t("OutboundLink")],1),e._v(", which returns an error if trying to insert nodes\nin "),t("a",{attrs:{href:"https://github.com/afilini/rust-bitcoin/blob/taproot-testing/src/util/taproot.rs#L403-L405",target:"_blank",rel:"noopener noreferrer"}},[e._v("an order that is not DFS"),t("OutboundLink")],1),e._v(".")]),e._v(" "),t("p",[e._v("The way the depth was computed before made the builder always fail for non-trivial trees (i.e. more than 1 node).")]),e._v(" "),t("p",[e._v("Here I decided to play the safe card, and just keep track of the depth explicitly: I think there might be a way to compute the depth just knowing the "),t("code",[e._v("self.stack.len()")]),e._v(" (assuming the tree has a specific structure,\nwhich I'm not sure applies here), but anyway I didn't have much time to think about it and I just went for the \"dumb but idiot-proof\" way which ended up working fine.")]),e._v(" "),t("div",{staticClass:"language- extra-class"},[t("pre",{pre:!0,attrs:{class:"language-text"}},[t("code",[e._v("$ git show f4a3459\n")])])]),t("div",{staticClass:"language-diff extra-class"},[t("pre",{pre:!0,attrs:{class:"language-diff"}},[t("code",[e._v("commit f4a3459128e37ca0c2701b8b6da064d4952296ff\nAuthor: Alekos Filini \nDate: Sat Nov 13 14:15:52 2021 +0100\n\n"),t("span",{pre:!0,attrs:{class:"token unchanged"}},[t("span",{pre:!0,attrs:{class:"token prefix unchanged"}},[e._v(" ")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" Switch rust-bitcoin rev\n")])]),e._v("\ndiff --git a/Cargo.toml b/Cargo.toml\nindex 12825e8..8240024 100644\n"),t("span",{pre:!0,attrs:{class:"token coord"}},[e._v("--- a/Cargo.toml")]),e._v("\n"),t("span",{pre:!0,attrs:{class:"token coord"}},[e._v("+++ b/Cargo.toml")]),e._v('\n@@ -17,7 +17,7 @@ rand = ["bitcoin/rand"]\n\n'),t("span",{pre:!0,attrs:{class:"token unchanged"}},[t("span",{pre:!0,attrs:{class:"token prefix unchanged"}},[e._v(" ")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v("[dependencies]\n")]),t("span",{pre:!0,attrs:{class:"token prefix unchanged"}},[e._v(" ")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v('# bitcoin = "0.27"\n')])]),t("span",{pre:!0,attrs:{class:"token deleted-sign deleted"}},[t("span",{pre:!0,attrs:{class:"token prefix deleted"}},[e._v("-")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v('bitcoin = {git = "https://github.com/sanket1729/rust-bitcoin", branch = "taproot_psbt"}\n')])]),t("span",{pre:!0,attrs:{class:"token inserted-sign inserted"}},[t("span",{pre:!0,attrs:{class:"token prefix inserted"}},[e._v("+")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v('bitcoin = { git = "https://github.com/afilini/rust-bitcoin.git", branch = "taproot-testing" }\n')])]),e._v("\n"),t("span",{pre:!0,attrs:{class:"token unchanged"}},[t("span",{pre:!0,attrs:{class:"token prefix unchanged"}},[e._v(" ")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v("[dependencies.serde]\n")]),t("span",{pre:!0,attrs:{class:"token prefix unchanged"}},[e._v(" ")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v('version = "1.0"\n')])])])])]),t("p",[e._v("Trivial commit, switch to "),t("a",{attrs:{href:"https://github.com/afilini/rust-bitcoin/tree/taproot-testing",target:"_blank",rel:"noopener noreferrer"}},[e._v("my fork of rust-bitcoin"),t("OutboundLink")],1),e._v(" so that I can make changes if necessary.")]),e._v(" "),t("div",{staticClass:"language- extra-class"},[t("pre",{pre:!0,attrs:{class:"language-text"}},[t("code",[e._v("$ git show 0446b16\n")])])]),t("div",{staticClass:"language-diff extra-class"},[t("pre",{pre:!0,attrs:{class:"language-diff"}},[t("code",[e._v("commit 0446b1631cec9f7118d46f0f4c94ccd20de29f94\nAuthor: Alekos Filini \nDate: Sat Nov 13 14:25:18 2021 +0100\n\n"),t("span",{pre:!0,attrs:{class:"token unchanged"}},[t("span",{pre:!0,attrs:{class:"token prefix unchanged"}},[e._v(" ")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" Parse x-only keys\n")])]),e._v("\ndiff --git a/src/descriptor/key.rs b/src/descriptor/key.rs\nindex 4108d00..b7f90b5 100644\n"),t("span",{pre:!0,attrs:{class:"token coord"}},[e._v("--- a/src/descriptor/key.rs")]),e._v("\n"),t("span",{pre:!0,attrs:{class:"token coord"}},[e._v("+++ b/src/descriptor/key.rs")]),e._v("\n@@ -283,9 +283,9 @@ impl FromStr for DescriptorPublicKey {\n\n"),t("span",{pre:!0,attrs:{class:"token unchanged"}},[t("span",{pre:!0,attrs:{class:"token prefix unchanged"}},[e._v(" ")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" fn from_str(s: &str) -> Result {\n")]),t("span",{pre:!0,attrs:{class:"token prefix unchanged"}},[e._v(" ")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(' // A "raw" public key without any origin is the least we accept.\n')])]),t("span",{pre:!0,attrs:{class:"token deleted-sign deleted"}},[t("span",{pre:!0,attrs:{class:"token prefix deleted"}},[e._v("-")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" if s.len() < 66 {\n")])]),t("span",{pre:!0,attrs:{class:"token inserted-sign inserted"}},[t("span",{pre:!0,attrs:{class:"token prefix inserted"}},[e._v("+")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" if s.len() < 64 {\n")])]),t("span",{pre:!0,attrs:{class:"token unchanged"}},[t("span",{pre:!0,attrs:{class:"token prefix unchanged"}},[e._v(" ")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" return Err(DescriptorKeyParseError(\n")])]),t("span",{pre:!0,attrs:{class:"token deleted-sign deleted"}},[t("span",{pre:!0,attrs:{class:"token prefix deleted"}},[e._v("-")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(' "Key too short (<66 char), doesn\'t match any format",\n')])]),t("span",{pre:!0,attrs:{class:"token inserted-sign inserted"}},[t("span",{pre:!0,attrs:{class:"token prefix inserted"}},[e._v("+")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(' "Key too short (<64 char), doesn\'t match any format",\n')])]),t("span",{pre:!0,attrs:{class:"token unchanged"}},[t("span",{pre:!0,attrs:{class:"token prefix unchanged"}},[e._v(" ")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" ));\n")]),t("span",{pre:!0,attrs:{class:"token prefix unchanged"}},[e._v(" ")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" }\n")])]),e._v("\n@@ -301,6 +301,14 @@ impl FromStr for DescriptorPublicKey {\n"),t("span",{pre:!0,attrs:{class:"token unchanged"}},[t("span",{pre:!0,attrs:{class:"token prefix unchanged"}},[e._v(" ")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" derivation_path,\n")]),t("span",{pre:!0,attrs:{class:"token prefix unchanged"}},[e._v(" ")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" wildcard,\n")]),t("span",{pre:!0,attrs:{class:"token prefix unchanged"}},[e._v(" ")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" }))\n")])]),t("span",{pre:!0,attrs:{class:"token inserted-sign inserted"}},[t("span",{pre:!0,attrs:{class:"token prefix inserted"}},[e._v("+")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" } else if key_part.len() == 64 {\n")]),t("span",{pre:!0,attrs:{class:"token prefix inserted"}},[e._v("+")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" // x-only pubkey, prefix it with `02`\n")]),t("span",{pre:!0,attrs:{class:"token prefix inserted"}},[e._v("+")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(' let key = bitcoin::PublicKey::from_str(&format!("02{}", key_part))\n')]),t("span",{pre:!0,attrs:{class:"token prefix inserted"}},[e._v("+")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(' .map_err(|_| DescriptorKeyParseError("Error while parsing x-only public key"))?;\n')]),t("span",{pre:!0,attrs:{class:"token prefix inserted"}},[e._v("+")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" Ok(DescriptorPublicKey::SinglePub(DescriptorSinglePub {\n")]),t("span",{pre:!0,attrs:{class:"token prefix inserted"}},[e._v("+")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" key,\n")]),t("span",{pre:!0,attrs:{class:"token prefix inserted"}},[e._v("+")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" origin,\n")]),t("span",{pre:!0,attrs:{class:"token prefix inserted"}},[e._v("+")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" }))\n")])]),t("span",{pre:!0,attrs:{class:"token unchanged"}},[t("span",{pre:!0,attrs:{class:"token prefix unchanged"}},[e._v(" ")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" } else {\n")]),t("span",{pre:!0,attrs:{class:"token prefix unchanged"}},[e._v(" ")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" if key_part.len() >= 2\n")]),t("span",{pre:!0,attrs:{class:"token prefix unchanged"}},[e._v(" ")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(' && !(&key_part[0..2] == "02" || &key_part[0..2] == "03" || &key_part[0..2] == "04")\n')])]),e._v("diff --git a/src/lib.rs b/src/lib.rs\nindex e168b16..3a2335e 100644\n"),t("span",{pre:!0,attrs:{class:"token coord"}},[e._v("--- a/src/lib.rs")]),e._v("\n"),t("span",{pre:!0,attrs:{class:"token coord"}},[e._v("+++ b/src/lib.rs")]),e._v("\n"),t("span",{pre:!0,attrs:{class:"token coord"}},[e._v("@@ -95,8 +95,6 @@")]),e._v("\n"),t("span",{pre:!0,attrs:{class:"token unchanged"}},[t("span",{pre:!0,attrs:{class:"token prefix unchanged"}},[e._v(" ")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v("#![deny(non_snake_case)]\n")]),t("span",{pre:!0,attrs:{class:"token prefix unchanged"}},[e._v(" ")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v("#![deny(unused_mut)]\n")]),t("span",{pre:!0,attrs:{class:"token prefix unchanged"}},[e._v(" ")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v("#![deny(dead_code)]\n")])]),t("span",{pre:!0,attrs:{class:"token deleted-sign deleted"}},[t("span",{pre:!0,attrs:{class:"token prefix deleted"}},[e._v("-")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v("#![deny(unused_imports)]\n")]),t("span",{pre:!0,attrs:{class:"token prefix deleted"}},[e._v("-")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v("#![deny(missing_docs)]\n")])]),e._v("\n"),t("span",{pre:!0,attrs:{class:"token unchanged"}},[t("span",{pre:!0,attrs:{class:"token prefix unchanged"}},[e._v(" ")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v("pub extern crate bitcoin;\n")]),t("span",{pre:!0,attrs:{class:"token prefix unchanged"}},[e._v(" ")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v('#[cfg(feature = "serde")]\n')])])])])]),t("p",[e._v("This, I'm not really sure of: Taproot uses x-only public keys, which means that the first byte (which is usually a "),t("code",[e._v("03")]),e._v(" or a "),t("code",[e._v("02")]),e._v(") that indicates the parity of the EC point is completely dropped, and it's implicit\nthat the point is even (= "),t("code",[e._v("02")]),e._v("). Check out "),t("a",{attrs:{href:"https://github.com/bitcoin/bips/blob/master/bip-0340.mediawiki",target:"_blank",rel:"noopener noreferrer"}},[t("code",[e._v("BIP340")]),t("OutboundLink")],1),e._v(" for a much better explanation.")]),e._v(" "),t("p",[e._v("So here when I find a string that is only 64 characters long I will assume it's an x-only pubkey, and I will parse it as a normal "),t("code",[e._v("bitcoin::PublicKey")]),e._v(" by prefixing it with "),t("code",[e._v("02")]),e._v(".")]),e._v(" "),t("p",[e._v("I guess one alternative could have been to try and parse it as a "),t("code",[e._v("schnorr::PublicKey")]),e._v(' and then "convert" it to a '),t("code",[e._v("ecdsa::PublicKey")]),e._v(" which should be supported, but once again I just wanted to get it done quickly and\nthis worked fine.")]),e._v(" "),t("p",[e._v("I also disabled the "),t("code",[e._v("unused_imports")]),e._v(" and "),t("code",[e._v("missing_docs")]),e._v(" lint so that the compiler wouldn't whine too much.")]),e._v(" "),t("div",{staticClass:"language- extra-class"},[t("pre",{pre:!0,attrs:{class:"language-text"}},[t("code",[e._v("$ git show 87316ff\n")])])]),t("div",{staticClass:"language-diff extra-class"},[t("pre",{pre:!0,attrs:{class:"language-diff"}},[t("code",[e._v("commit 87316fffd06ab3bdf300fd1a958ddaa2789a6696\nAuthor: Alekos Filini \nDate: Sat Nov 13 14:26:01 2021 +0100\n\n"),t("span",{pre:!0,attrs:{class:"token unchanged"}},[t("span",{pre:!0,attrs:{class:"token prefix unchanged"}},[e._v(" ")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" Parse `tr()` descriptors\n")])]),e._v("\ndiff --git a/src/descriptor/mod.rs b/src/descriptor/mod.rs\nindex 06d98e1..4190786 100644\n"),t("span",{pre:!0,attrs:{class:"token coord"}},[e._v("--- a/src/descriptor/mod.rs")]),e._v("\n"),t("span",{pre:!0,attrs:{class:"token coord"}},[e._v("+++ b/src/descriptor/mod.rs")]),e._v("\n@@ -610,6 +610,7 @@ where\n"),t("span",{pre:!0,attrs:{class:"token unchanged"}},[t("span",{pre:!0,attrs:{class:"token prefix unchanged"}},[e._v(" ")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(' ("wpkh", 1) => Descriptor::Wpkh(Wpkh::from_tree(top)?),\n')]),t("span",{pre:!0,attrs:{class:"token prefix unchanged"}},[e._v(" ")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(' ("sh", 1) => Descriptor::Sh(Sh::from_tree(top)?),\n')]),t("span",{pre:!0,attrs:{class:"token prefix unchanged"}},[e._v(" ")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(' ("wsh", 1) => Descriptor::Wsh(Wsh::from_tree(top)?),\n')])]),t("span",{pre:!0,attrs:{class:"token inserted-sign inserted"}},[t("span",{pre:!0,attrs:{class:"token prefix inserted"}},[e._v("+")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(' ("tr", _) => Descriptor::Tr(Tr::from_tree(top)?),\n')])]),t("span",{pre:!0,attrs:{class:"token unchanged"}},[t("span",{pre:!0,attrs:{class:"token prefix unchanged"}},[e._v(" ")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" _ => Descriptor::Bare(Bare::from_tree(top)?),\n")]),t("span",{pre:!0,attrs:{class:"token prefix unchanged"}},[e._v(" ")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" })\n")]),t("span",{pre:!0,attrs:{class:"token prefix unchanged"}},[e._v(" ")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" }\n")])]),e._v("diff --git a/src/expression.rs b/src/expression.rs\nindex 1cef614..11a68d3 100644\n"),t("span",{pre:!0,attrs:{class:"token coord"}},[e._v("--- a/src/expression.rs")]),e._v("\n"),t("span",{pre:!0,attrs:{class:"token coord"}},[e._v("+++ b/src/expression.rs")]),e._v("\n@@ -100,7 +100,12 @@ impl<'a> Tree<'a> {\n\n"),t("span",{pre:!0,attrs:{class:"token unchanged"}},[t("span",{pre:!0,attrs:{class:"token prefix unchanged"}},[e._v(" ")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" sl = &sl[n + 1..];\n")]),t("span",{pre:!0,attrs:{class:"token prefix unchanged"}},[e._v(" ")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" loop {\n")])]),t("span",{pre:!0,attrs:{class:"token deleted-sign deleted"}},[t("span",{pre:!0,attrs:{class:"token prefix deleted"}},[e._v("-")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" let (arg, new_sl) = Tree::from_slice_helper_round(sl, depth + 1)?;\n")])]),t("span",{pre:!0,attrs:{class:"token inserted-sign inserted"}},[t("span",{pre:!0,attrs:{class:"token prefix inserted"}},[e._v("+")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" let (arg, new_sl) = if sl.contains('{') {\n")]),t("span",{pre:!0,attrs:{class:"token prefix inserted"}},[e._v("+")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" Tree::from_slice_helper_curly(sl, depth + 1)?\n")]),t("span",{pre:!0,attrs:{class:"token prefix inserted"}},[e._v("+")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" } else {\n")]),t("span",{pre:!0,attrs:{class:"token prefix inserted"}},[e._v("+")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" Tree::from_slice_helper_round(sl, depth + 1)?\n")]),t("span",{pre:!0,attrs:{class:"token prefix inserted"}},[e._v("+")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" };\n")]),t("span",{pre:!0,attrs:{class:"token prefix inserted"}},[e._v("+")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v("\n")])]),t("span",{pre:!0,attrs:{class:"token unchanged"}},[t("span",{pre:!0,attrs:{class:"token prefix unchanged"}},[e._v(" ")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" ret.args.push(arg);\n")])]),e._v("\n"),t("span",{pre:!0,attrs:{class:"token unchanged"}},[t("span",{pre:!0,attrs:{class:"token prefix unchanged"}},[e._v(" ")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" if new_sl.is_empty() {\n")])])])])]),t("p",[e._v("When trying to parse a descriptor (essentially turning a recursive string of "),t("code",[e._v("operator(args)")]),e._v(" into an abstract tree in memory) use a "),t("em",[e._v("curly-bracket-aware")]),e._v(" parser if there is one in the string.")]),e._v(" "),t("p",[e._v("The code to then build a "),t("code",[e._v("Tr")]),e._v(" struct given an "),t("code",[e._v("expression::Tree")]),e._v(" (and the "),t("code",[e._v("from_slice_helper_curly")]),e._v(" function) were already implemented, so it was just a matter of correctly\nbuilding the abstract tree by parsing curly brackets in descriptors.")]),e._v(" "),t("div",{staticClass:"language- extra-class"},[t("pre",{pre:!0,attrs:{class:"language-text"}},[t("code",[e._v("$ git show 3055cab\n")])])]),t("div",{staticClass:"language-diff extra-class"},[t("pre",{pre:!0,attrs:{class:"language-diff"}},[t("code",[e._v("commit 3055cabef8bd51eda344ce501b03c533fd367b4f\nAuthor: Alekos Filini \nDate: Sat Nov 13 14:26:30 2021 +0100\n\n"),t("span",{pre:!0,attrs:{class:"token unchanged"}},[t("span",{pre:!0,attrs:{class:"token prefix unchanged"}},[e._v(" ")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" Fix control block creation when satisfying `Tr`\n")])]),e._v("\ndiff --git a/src/descriptor/tr.rs b/src/descriptor/tr.rs\nindex 314c7f4..8487d56 100644\n"),t("span",{pre:!0,attrs:{class:"token coord"}},[e._v("--- a/src/descriptor/tr.rs")]),e._v("\n"),t("span",{pre:!0,attrs:{class:"token coord"}},[e._v("+++ b/src/descriptor/tr.rs")]),e._v("\n@@ -571,17 +571,14 @@ impl DescriptorTrait for Tr {\n"),t("span",{pre:!0,attrs:{class:"token unchanged"}},[t("span",{pre:!0,attrs:{class:"token prefix unchanged"}},[e._v(" ")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" } else {\n")]),t("span",{pre:!0,attrs:{class:"token prefix unchanged"}},[e._v(" ")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" let ver = LeafVersion::default();\n")]),t("span",{pre:!0,attrs:{class:"token prefix unchanged"}},[e._v(" ")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" let leaf_script = (ms.encode(), ver);\n")])]),t("span",{pre:!0,attrs:{class:"token deleted-sign deleted"}},[t("span",{pre:!0,attrs:{class:"token prefix deleted"}},[e._v("-")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" let control_block_set = spend_info\n")]),t("span",{pre:!0,attrs:{class:"token prefix deleted"}},[e._v("-")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" .as_script_map()\n")]),t("span",{pre:!0,attrs:{class:"token prefix deleted"}},[e._v("-")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" .get(&leaf_script)\n")]),t("span",{pre:!0,attrs:{class:"token prefix deleted"}},[e._v("-")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(' .expect("Control block must exist in script map for every known leaf");\n')])]),t("span",{pre:!0,attrs:{class:"token inserted-sign inserted"}},[t("span",{pre:!0,attrs:{class:"token prefix inserted"}},[e._v("+")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" // let control_block_set = spend_info\n")]),t("span",{pre:!0,attrs:{class:"token prefix inserted"}},[e._v("+")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" // .as_script_map()\n")]),t("span",{pre:!0,attrs:{class:"token prefix inserted"}},[e._v("+")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" // .get(&leaf_script)\n")]),t("span",{pre:!0,attrs:{class:"token prefix inserted"}},[e._v("+")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(' // .expect("Control block must exist in script map for every known leaf");\n')]),t("span",{pre:!0,attrs:{class:"token prefix inserted"}},[e._v("+")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(' let control_block = spend_info.control_block(&leaf_script).expect("Control block must exist in script map for every known leaf");\n')])]),t("span",{pre:!0,attrs:{class:"token unchanged"}},[t("span",{pre:!0,attrs:{class:"token prefix unchanged"}},[e._v(" ")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" wit.push(leaf_script.0.into_bytes()); // Push the leaf script\n")]),t("span",{pre:!0,attrs:{class:"token prefix unchanged"}},[e._v(" ")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" // There can be multiple control blocks for a (script, ver) pair\n")]),t("span",{pre:!0,attrs:{class:"token prefix unchanged"}},[e._v(" ")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" // Find the smallest one amongst those\n")])]),t("span",{pre:!0,attrs:{class:"token deleted-sign deleted"}},[t("span",{pre:!0,attrs:{class:"token prefix deleted"}},[e._v("-")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" let control_block = control_block_set\n")]),t("span",{pre:!0,attrs:{class:"token prefix deleted"}},[e._v("-")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" .iter()\n")]),t("span",{pre:!0,attrs:{class:"token prefix deleted"}},[e._v("-")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" .min_by(|x, y| x.as_inner().len().cmp(&y.as_inner().len()))\n")]),t("span",{pre:!0,attrs:{class:"token prefix deleted"}},[e._v("-")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(' .expect("Atleast one control must exist for a known leaf");\n')])]),t("span",{pre:!0,attrs:{class:"token unchanged"}},[t("span",{pre:!0,attrs:{class:"token prefix unchanged"}},[e._v(" ")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" wit.push(control_block.serialize());\n")]),t("span",{pre:!0,attrs:{class:"token prefix unchanged"}},[e._v(" ")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" // Finally, save the minimum\n")]),t("span",{pre:!0,attrs:{class:"token prefix unchanged"}},[e._v(" ")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" min_wit = Some(wit);\n")])]),e._v("\n")])])]),t("p",[e._v("This is where things get more interesting: this section of code builds the witness to satisfy a Taproot descriptor. In case of a script-spend, we need to prove that the script we are using had been committed\ninto the public key of our "),t("code",[e._v("P2TR")]),e._v(' input. We do this by adding a "control block", that contains data about the parity of the key, the leaf version used, and the merkle path from the leaf we are using to spend\nup to the merkle root, which is committed into the public key. Once again, this is explained very well in '),t("a",{attrs:{href:"https://github.com/bitcoin/bips/blob/master/bip-0341.mediawiki",target:"_blank",rel:"noopener noreferrer"}},[t("code",[e._v("BIP341")]),t("OutboundLink")],1),e._v(".")]),e._v(" "),t("p",[e._v("Before my patch the code was only getting the set of merkle paths that could lead from the root to the leaves that contain a given script. For context, the signature of "),t("code",[e._v("TaprootSpendInfo::as_script_map(&self)")]),e._v(" is:")]),e._v(" "),t("div",{staticClass:"language-rust extra-class"},[t("pre",{pre:!0,attrs:{class:"language-rust"}},[t("code",[t("span",{pre:!0,attrs:{class:"token comment"}},[e._v("/// Access the internal script map")]),e._v("\n"),t("span",{pre:!0,attrs:{class:"token keyword"}},[e._v("pub")]),e._v(" "),t("span",{pre:!0,attrs:{class:"token keyword"}},[e._v("fn")]),e._v(" "),t("span",{pre:!0,attrs:{class:"token function-definition function"}},[e._v("as_script_map")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v("(")]),t("span",{pre:!0,attrs:{class:"token operator"}},[e._v("&")]),t("span",{pre:!0,attrs:{class:"token keyword"}},[e._v("self")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(")")]),e._v(" "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v("->")]),e._v(" "),t("span",{pre:!0,attrs:{class:"token operator"}},[e._v("&")]),t("span",{pre:!0,attrs:{class:"token class-name"}},[e._v("BTreeMap")]),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 class-name"}},[e._v("Script")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(",")]),e._v(" "),t("span",{pre:!0,attrs:{class:"token class-name"}},[e._v("LeafVersion")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(")")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(",")]),e._v(" "),t("span",{pre:!0,attrs:{class:"token class-name"}},[e._v("BTreeSet")]),t("span",{pre:!0,attrs:{class:"token operator"}},[e._v("<")]),t("span",{pre:!0,attrs:{class:"token class-name"}},[e._v("TaprootMerkleBranch")]),t("span",{pre:!0,attrs:{class:"token operator"}},[e._v(">>")]),e._v(" "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v("{")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v("}")]),e._v("\n")])])]),t("p",[e._v('Then the code would look for the "shortest" path to that specific script, as it would save size in the final transaction (leaves that are more "deep" in the tree than others naturally have more hidden branches\nin their path to the root, and thus require a longer control block to reveal them all).')]),e._v(" "),t("p",[e._v("The issue here is that the "),t("code",[e._v("control_block")]),e._v(" variable is then serialized directly into the witness. But this is not a control block, it's just a set of merkle paths! A control block only has "),t("em",[e._v("one")]),e._v(" merkle path, and\nincludes the leaf version and the key parity bit.")]),e._v(" "),t("p",[e._v("Conveniently, the "),t("code",[e._v("TaprootSpendInfo")]),e._v(' struct also has this other method (I\'m including the implementation as well, because it shows that internally it does the same "trick" to find the shortest path):')]),e._v(" "),t("div",{staticClass:"language-rust extra-class"},[t("pre",{pre:!0,attrs:{class:"language-rust"}},[t("code",[t("span",{pre:!0,attrs:{class:"token comment"}},[e._v("/// Obtain a [`ControlBlock`] for particular script with the given version.")]),e._v("\n"),t("span",{pre:!0,attrs:{class:"token comment"}},[e._v("/// Returns [`None`] if the script is not contained in the [`TaprootSpendInfo`]")]),e._v("\n"),t("span",{pre:!0,attrs:{class:"token comment"}},[e._v("/// If there are multiple ControlBlocks possible, this returns the shortest one.")]),e._v("\n"),t("span",{pre:!0,attrs:{class:"token keyword"}},[e._v("pub")]),e._v(" "),t("span",{pre:!0,attrs:{class:"token keyword"}},[e._v("fn")]),e._v(" "),t("span",{pre:!0,attrs:{class:"token function-definition function"}},[e._v("control_block")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v("(")]),t("span",{pre:!0,attrs:{class:"token operator"}},[e._v("&")]),t("span",{pre:!0,attrs:{class:"token keyword"}},[e._v("self")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(",")]),e._v(" script_ver"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(":")]),e._v(" "),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 class-name"}},[e._v("Script")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(",")]),e._v(" "),t("span",{pre:!0,attrs:{class:"token class-name"}},[e._v("LeafVersion")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(")")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(")")]),e._v(" "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v("->")]),e._v(" "),t("span",{pre:!0,attrs:{class:"token class-name"}},[e._v("Option")]),t("span",{pre:!0,attrs:{class:"token operator"}},[e._v("<")]),t("span",{pre:!0,attrs:{class:"token class-name"}},[e._v("ControlBlock")]),t("span",{pre:!0,attrs:{class:"token operator"}},[e._v(">")]),e._v(" "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v("{")]),e._v("\n "),t("span",{pre:!0,attrs:{class:"token keyword"}},[e._v("let")]),e._v(" merkle_branch_set "),t("span",{pre:!0,attrs:{class:"token operator"}},[e._v("=")]),e._v(" "),t("span",{pre:!0,attrs:{class:"token keyword"}},[e._v("self")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(".")]),e._v("script_map"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(".")]),t("span",{pre:!0,attrs:{class:"token function"}},[e._v("get")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v("(")]),e._v("script_ver"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(")")]),t("span",{pre:!0,attrs:{class:"token operator"}},[e._v("?")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(";")]),e._v("\n "),t("span",{pre:!0,attrs:{class:"token comment"}},[e._v("// Choose the smallest one amongst the multiple script maps")]),e._v("\n "),t("span",{pre:!0,attrs:{class:"token keyword"}},[e._v("let")]),e._v(" smallest "),t("span",{pre:!0,attrs:{class:"token operator"}},[e._v("=")]),e._v(" merkle_branch_set\n "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(".")]),t("span",{pre:!0,attrs:{class:"token function"}},[e._v("iter")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v("(")]),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 function"}},[e._v("min_by")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v("(")]),t("span",{pre:!0,attrs:{class:"token closure-params"}},[t("span",{pre:!0,attrs:{class:"token closure-punctuation punctuation"}},[e._v("|")]),e._v("x"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(",")]),e._v(" y"),t("span",{pre:!0,attrs:{class:"token closure-punctuation punctuation"}},[e._v("|")])]),e._v(" x"),t("span",{pre:!0,attrs:{class:"token number"}},[e._v(".0")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(".")]),t("span",{pre:!0,attrs:{class:"token function"}},[e._v("len")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v("(")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(")")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(".")]),t("span",{pre:!0,attrs:{class:"token function"}},[e._v("cmp")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v("(")]),t("span",{pre:!0,attrs:{class:"token operator"}},[e._v("&")]),e._v("y"),t("span",{pre:!0,attrs:{class:"token number"}},[e._v(".0")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(".")]),t("span",{pre:!0,attrs:{class:"token function"}},[e._v("len")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v("(")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(")")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(")")]),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 function"}},[e._v("expect")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v("(")]),t("span",{pre:!0,attrs:{class:"token string"}},[e._v('"Non-empty iterator"')]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(")")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(";")]),e._v("\n "),t("span",{pre:!0,attrs:{class:"token class-name"}},[e._v("Some")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v("(")]),t("span",{pre:!0,attrs:{class:"token class-name"}},[e._v("ControlBlock")]),e._v(" "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v("{")]),e._v("\n internal_key"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(":")]),e._v(" "),t("span",{pre:!0,attrs:{class:"token keyword"}},[e._v("self")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(".")]),e._v("internal_key"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(",")]),e._v("\n output_key_parity"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(":")]),e._v(" "),t("span",{pre:!0,attrs:{class:"token keyword"}},[e._v("self")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(".")]),e._v("output_key_parity"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(",")]),e._v("\n leaf_version"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(":")]),e._v(" "),t("span",{pre:!0,attrs:{class:"token class-name"}},[e._v("LeafVersion")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v("::")]),t("span",{pre:!0,attrs:{class:"token function"}},[e._v("default")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v("(")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(")")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(",")]),e._v("\n merkle_branch"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(":")]),e._v(" smallest"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(".")]),t("span",{pre:!0,attrs:{class:"token function"}},[e._v("clone")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v("(")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(")")]),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 punctuation"}},[e._v(")")]),e._v("\n"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v("}")]),e._v("\n")])])]),t("p",[e._v("So to fix this code we just have to use that method instead, and we can get it done in one single line!")]),e._v(" "),t("p",[e._v('Instead of removing the old code at the time I only commented it out, because I initially thought I would still have to look for the shortest script myself, and I figured the "sorting" code would come in handy\nlater on.')]),e._v(" "),t("p",[e._v("Also, if you are an acute observer, you might have noticed that there's a bug in this last snippet of code. Feel free to think about it a little bit, then check out the "),t("a",{attrs:{href:"https://github.com/rust-bitcoin/rust-bitcoin/pull/703",target:"_blank",rel:"noopener noreferrer"}},[e._v("PR"),t("OutboundLink")],1),e._v(" I made\nif you wanna know the answer!")]),e._v(" "),t("div",{staticClass:"language- extra-class"},[t("pre",{pre:!0,attrs:{class:"language-text"}},[t("code",[e._v("git show 35378ad\n")])])]),t("div",{staticClass:"language-diff extra-class"},[t("pre",{pre:!0,attrs:{class:"language-diff"}},[t("code",[e._v("commit 35378ad01a6f2b8161a3f36448b24d031f8aeaec\nAuthor: Alekos Filini \nDate: Sat Nov 13 14:27:14 2021 +0100\n\n"),t("span",{pre:!0,attrs:{class:"token unchanged"}},[t("span",{pre:!0,attrs:{class:"token prefix unchanged"}},[e._v(" ")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" Consider key-spend max satisfaction weight\n")])]),e._v("\ndiff --git a/src/descriptor/tr.rs b/src/descriptor/tr.rs\nindex 8487d56..fabf860 100644\n"),t("span",{pre:!0,attrs:{class:"token coord"}},[e._v("--- a/src/descriptor/tr.rs")]),e._v("\n"),t("span",{pre:!0,attrs:{class:"token coord"}},[e._v("+++ b/src/descriptor/tr.rs")]),e._v("\n@@ -593,7 +593,7 @@ impl DescriptorTrait for Tr {\n"),t("span",{pre:!0,attrs:{class:"token unchanged"}},[t("span",{pre:!0,attrs:{class:"token prefix unchanged"}},[e._v(" ")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" }\n")])]),e._v("\n"),t("span",{pre:!0,attrs:{class:"token unchanged"}},[t("span",{pre:!0,attrs:{class:"token prefix unchanged"}},[e._v(" ")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" fn max_satisfaction_weight(&self) -> Result {\n")])]),t("span",{pre:!0,attrs:{class:"token deleted-sign deleted"}},[t("span",{pre:!0,attrs:{class:"token prefix deleted"}},[e._v("-")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" let mut max_wieght = None;\n")])]),t("span",{pre:!0,attrs:{class:"token inserted-sign inserted"}},[t("span",{pre:!0,attrs:{class:"token prefix inserted"}},[e._v("+")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" let mut max_wieght = Some(65);\n")])]),t("span",{pre:!0,attrs:{class:"token unchanged"}},[t("span",{pre:!0,attrs:{class:"token prefix unchanged"}},[e._v(" ")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" for (depth, ms) in self.iter_scripts() {\n")]),t("span",{pre:!0,attrs:{class:"token prefix unchanged"}},[e._v(" ")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" let script_size = ms.script_size();\n")]),t("span",{pre:!0,attrs:{class:"token prefix unchanged"}},[e._v(" ")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" let max_sat_elems = match ms.max_satisfaction_witness_elements() {\n")])])])])]),t("p",[e._v("This is a little bug in the code that tries to compute what the maximum satisfaction weight would be for a descriptor. For instance, we use this in BDK to compute how many extra sats of fees we need to pay\nin order to target a given fee rate, assuming the descriptor is satisfied with the worst (larger and most expensive) path.")]),e._v(" "),t("p",[e._v("For Taproot descriptors, it's just a matter of iterating over the leaves in the tree and pick the most expensive one... or is it? This doesn't take into account that Taproot outputs can also be spent with\nkey-spend, which means just pushing a signature to the witness. This signature is 64 bytes long when using the new "),t("a",{attrs:{href:"https://github.com/bitcoin/bips/blob/master/bip-0341.mediawiki",target:"_blank",rel:"noopener noreferrer"}},[t("code",[e._v("SIGHASH_DEFAULT")]),t("OutboundLink")],1),e._v(" sighash, or 65 otherwise. Since we are thinking about the maximum satisfaction\nweight, or the worst case possible, we naturally pick the latter.")]),e._v(" "),t("p",[e._v("Note that theoretically you could build a Taproot address \"without\" an available key-path spend (by using an unspendable Schnorr public key), but the code here in rust-miniscript doesn't take that into\naccount, as there's no way that I'm aware of to specificy in a "),t("code",[e._v("tr()")]),e._v(" descriptor that the key is unspendable. So, while theoretically here we should first check whether the key-spend path is available before\naccounting for its weight, in practice this is always true in miniscript so we just use that as our starting worst case and update it later if necessary while iterating the tree leaves.")]),e._v(" "),t("div",{staticClass:"language- extra-class"},[t("pre",{pre:!0,attrs:{class:"language-text"}},[t("code",[e._v("$ git show b4878f8\n")])])]),t("div",{staticClass:"language-diff extra-class"},[t("pre",{pre:!0,attrs:{class:"language-diff"}},[t("code",[e._v("commit b4878f816e9ede11d5ed947c06e03aa988e3e26f\nAuthor: Alekos Filini \nDate: Sat Nov 13 14:27:53 2021 +0100\n\n"),t("span",{pre:!0,attrs:{class:"token unchanged"}},[t("span",{pre:!0,attrs:{class:"token prefix unchanged"}},[e._v(" ")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" Look for taproot stuff in psbts\n")])]),e._v("\ndiff --git a/src/psbt/mod.rs b/src/psbt/mod.rs\nindex 9a8b17d..42c6ce8 100644\n"),t("span",{pre:!0,attrs:{class:"token coord"}},[e._v("--- a/src/psbt/mod.rs")]),e._v("\n"),t("span",{pre:!0,attrs:{class:"token coord"}},[e._v("+++ b/src/psbt/mod.rs")]),e._v("\n@@ -25,13 +25,14 @@ use bitcoin;\n"),t("span",{pre:!0,attrs:{class:"token unchanged"}},[t("span",{pre:!0,attrs:{class:"token prefix unchanged"}},[e._v(" ")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v("use bitcoin::hashes::{hash160, ripemd160, sha256, sha256d};\n")]),t("span",{pre:!0,attrs:{class:"token prefix unchanged"}},[e._v(" ")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v("use bitcoin::secp256k1::{self, Secp256k1};\n")]),t("span",{pre:!0,attrs:{class:"token prefix unchanged"}},[e._v(" ")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v("use bitcoin::util::psbt::PartiallySignedTransaction as Psbt;\n")])]),t("span",{pre:!0,attrs:{class:"token inserted-sign inserted"}},[t("span",{pre:!0,attrs:{class:"token prefix inserted"}},[e._v("+")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v("use bitcoin::util::taproot::TapLeafHash;\n")])]),t("span",{pre:!0,attrs:{class:"token unchanged"}},[t("span",{pre:!0,attrs:{class:"token prefix unchanged"}},[e._v(" ")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v("use bitcoin::Script;\n")])]),e._v("\n"),t("span",{pre:!0,attrs:{class:"token unchanged"}},[t("span",{pre:!0,attrs:{class:"token prefix unchanged"}},[e._v(" ")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v("use interpreter;\n")]),t("span",{pre:!0,attrs:{class:"token prefix unchanged"}},[e._v(" ")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v("use miniscript::limits::SEQUENCE_LOCKTIME_DISABLE_FLAG;\n")]),t("span",{pre:!0,attrs:{class:"token prefix unchanged"}},[e._v(" ")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v("use miniscript::satisfy::{After, Older};\n")]),t("span",{pre:!0,attrs:{class:"token prefix unchanged"}},[e._v(" ")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v("use Satisfier;\n")])]),t("span",{pre:!0,attrs:{class:"token deleted-sign deleted"}},[t("span",{pre:!0,attrs:{class:"token prefix deleted"}},[e._v("-")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v("use {BitcoinECSig, Preimage32};\n")])]),t("span",{pre:!0,attrs:{class:"token inserted-sign inserted"}},[t("span",{pre:!0,attrs:{class:"token prefix inserted"}},[e._v("+")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v("use {BitcoinECSig, BitcoinSchnorrSig, Preimage32};\n")])]),t("span",{pre:!0,attrs:{class:"token unchanged"}},[t("span",{pre:!0,attrs:{class:"token prefix unchanged"}},[e._v(" ")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v("use {MiniscriptKey, ToPublicKey};\n")])]),e._v("\n"),t("span",{pre:!0,attrs:{class:"token unchanged"}},[t("span",{pre:!0,attrs:{class:"token prefix unchanged"}},[e._v(" ")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v("mod finalizer;\n")])]),e._v("@@ -231,6 +232,24 @@ impl<'psbt> PsbtInputSatisfier<'psbt> {\n"),t("span",{pre:!0,attrs:{class:"token unchanged"}},[t("span",{pre:!0,attrs:{class:"token prefix unchanged"}},[e._v(" ")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v("}\n")])]),e._v("\n"),t("span",{pre:!0,attrs:{class:"token unchanged"}},[t("span",{pre:!0,attrs:{class:"token prefix unchanged"}},[e._v(" ")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v("impl<'psbt, Pk: MiniscriptKey + ToPublicKey> Satisfier for PsbtInputSatisfier<'psbt> {\n")])]),t("span",{pre:!0,attrs:{class:"token inserted-sign inserted"}},[t("span",{pre:!0,attrs:{class:"token prefix inserted"}},[e._v("+")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" fn lookup_tap_key_spend_sig(&self) -> Option {\n")]),t("span",{pre:!0,attrs:{class:"token prefix inserted"}},[e._v("+")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" if let Some((sig, hash_ty)) = self.psbt.inputs[self.index].tap_key_sig {\n")]),t("span",{pre:!0,attrs:{class:"token prefix inserted"}},[e._v("+")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" Some(BitcoinSchnorrSig { sig, hash_ty })\n")]),t("span",{pre:!0,attrs:{class:"token prefix inserted"}},[e._v("+")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" } else {\n")]),t("span",{pre:!0,attrs:{class:"token prefix inserted"}},[e._v("+")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" None\n")]),t("span",{pre:!0,attrs:{class:"token prefix inserted"}},[e._v("+")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" }\n")]),t("span",{pre:!0,attrs:{class:"token prefix inserted"}},[e._v("+")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" }\n")]),t("span",{pre:!0,attrs:{class:"token prefix inserted"}},[e._v("+")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v("\n")]),t("span",{pre:!0,attrs:{class:"token prefix inserted"}},[e._v("+")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" fn lookup_tap_leaf_script_sig(&self, pk: &Pk, lh: &TapLeafHash) -> Option {\n")]),t("span",{pre:!0,attrs:{class:"token prefix inserted"}},[e._v("+")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" let pk = pk.to_x_only_pubkey();\n")]),t("span",{pre:!0,attrs:{class:"token prefix inserted"}},[e._v("+")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v("\n")]),t("span",{pre:!0,attrs:{class:"token prefix inserted"}},[e._v("+")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" if let Some((sig, hash_ty)) = self.psbt.inputs[self.index].tap_script_sigs.get(&(pk, *lh)) {\n")]),t("span",{pre:!0,attrs:{class:"token prefix inserted"}},[e._v("+")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" Some(BitcoinSchnorrSig { sig: *sig, hash_ty: *hash_ty })\n")]),t("span",{pre:!0,attrs:{class:"token prefix inserted"}},[e._v("+")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" } else {\n")]),t("span",{pre:!0,attrs:{class:"token prefix inserted"}},[e._v("+")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" None\n")]),t("span",{pre:!0,attrs:{class:"token prefix inserted"}},[e._v("+")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" }\n")]),t("span",{pre:!0,attrs:{class:"token prefix inserted"}},[e._v("+")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" }\n")]),t("span",{pre:!0,attrs:{class:"token prefix inserted"}},[e._v("+")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v("\n")])]),t("span",{pre:!0,attrs:{class:"token unchanged"}},[t("span",{pre:!0,attrs:{class:"token prefix unchanged"}},[e._v(" ")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" fn lookup_ec_sig(&self, pk: &Pk) -> Option {\n")]),t("span",{pre:!0,attrs:{class:"token prefix unchanged"}},[e._v(" ")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" if let Some(rawsig) = self.psbt.inputs[self.index]\n")]),t("span",{pre:!0,attrs:{class:"token prefix unchanged"}},[e._v(" ")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" .partial_sigs\n")])])])])]),t("p",[e._v("This commit implements the Taproot-specific "),t("code",[e._v("Satisfier")]),e._v(" methods on "),t("code",[e._v("PsbtInputSatisfier")]),e._v(". The code to produce a valid witness (i.e. "),t("em",[e._v("satisfy")]),e._v(") a descriptor by looking for Taproot key-spend or script-spend signatures\nis already implemented, so it's just a matter of actually returning those, if they are present in a PSBT.")]),e._v(" "),t("div",{staticClass:"language- extra-class"},[t("pre",{pre:!0,attrs:{class:"language-text"}},[t("code",[e._v("$ git show 80da0ba\n")])])]),t("div",{staticClass:"language-diff extra-class"},[t("pre",{pre:!0,attrs:{class:"language-diff"}},[t("code",[e._v("commit 80da0ba9b742b2dee23e7302e2f95a6e96b1d6ed\nAuthor: Alekos Filini \nDate: Sat Nov 13 16:54:27 2021 +0100\n\n"),t("span",{pre:!0,attrs:{class:"token unchanged"}},[t("span",{pre:!0,attrs:{class:"token prefix unchanged"}},[e._v(" ")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" Iter keys in `MultiA`\n")])]),e._v("\ndiff --git a/src/miniscript/iter.rs b/src/miniscript/iter.rs\nindex 36c4b69..a54a371 100644\n"),t("span",{pre:!0,attrs:{class:"token coord"}},[e._v("--- a/src/miniscript/iter.rs")]),e._v("\n"),t("span",{pre:!0,attrs:{class:"token coord"}},[e._v("+++ b/src/miniscript/iter.rs")]),e._v("\n@@ -121,7 +121,7 @@ impl Miniscript {\n"),t("span",{pre:!0,attrs:{class:"token unchanged"}},[t("span",{pre:!0,attrs:{class:"token prefix unchanged"}},[e._v(" ")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" pub fn get_leaf_pk(&self) -> Vec {\n")]),t("span",{pre:!0,attrs:{class:"token prefix unchanged"}},[e._v(" ")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" match self.node {\n")]),t("span",{pre:!0,attrs:{class:"token prefix unchanged"}},[e._v(" ")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" Terminal::PkK(ref key) => vec![key.clone()],\n")])]),t("span",{pre:!0,attrs:{class:"token deleted-sign deleted"}},[t("span",{pre:!0,attrs:{class:"token prefix deleted"}},[e._v("-")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" Terminal::Multi(_, ref keys) => keys.clone(),\n")])]),t("span",{pre:!0,attrs:{class:"token inserted-sign inserted"}},[t("span",{pre:!0,attrs:{class:"token prefix inserted"}},[e._v("+")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" Terminal::Multi(_, ref keys) | Terminal::MultiA(_, ref keys) => keys.clone(),\n")])]),t("span",{pre:!0,attrs:{class:"token unchanged"}},[t("span",{pre:!0,attrs:{class:"token prefix unchanged"}},[e._v(" ")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" _ => vec![],\n")]),t("span",{pre:!0,attrs:{class:"token prefix unchanged"}},[e._v(" ")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" }\n")]),t("span",{pre:!0,attrs:{class:"token prefix unchanged"}},[e._v(" ")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" }\n")])]),e._v("@@ -139,7 +139,7 @@ impl Miniscript {\n"),t("span",{pre:!0,attrs:{class:"token unchanged"}},[t("span",{pre:!0,attrs:{class:"token prefix unchanged"}},[e._v(" ")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" match self.node {\n")]),t("span",{pre:!0,attrs:{class:"token prefix unchanged"}},[e._v(" ")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" Terminal::PkH(ref hash) => vec![hash.clone()],\n")]),t("span",{pre:!0,attrs:{class:"token prefix unchanged"}},[e._v(" ")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" Terminal::PkK(ref key) => vec![key.to_pubkeyhash()],\n")])]),t("span",{pre:!0,attrs:{class:"token deleted-sign deleted"}},[t("span",{pre:!0,attrs:{class:"token prefix deleted"}},[e._v("-")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" Terminal::Multi(_, ref keys) => keys.iter().map(Pk::to_pubkeyhash).collect(),\n")])]),t("span",{pre:!0,attrs:{class:"token inserted-sign inserted"}},[t("span",{pre:!0,attrs:{class:"token prefix inserted"}},[e._v("+")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" Terminal::Multi(_, ref keys) | Terminal::MultiA(_, ref keys) => keys.iter().map(Pk::to_pubkeyhash).collect(),\n")])]),t("span",{pre:!0,attrs:{class:"token unchanged"}},[t("span",{pre:!0,attrs:{class:"token prefix unchanged"}},[e._v(" ")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" _ => vec![],\n")]),t("span",{pre:!0,attrs:{class:"token prefix unchanged"}},[e._v(" ")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" }\n")]),t("span",{pre:!0,attrs:{class:"token prefix unchanged"}},[e._v(" ")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" }\n")])]),e._v("@@ -155,7 +155,7 @@ impl Miniscript {\n"),t("span",{pre:!0,attrs:{class:"token unchanged"}},[t("span",{pre:!0,attrs:{class:"token prefix unchanged"}},[e._v(" ")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" match self.node {\n")]),t("span",{pre:!0,attrs:{class:"token prefix unchanged"}},[e._v(" ")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" Terminal::PkH(ref hash) => vec![PkPkh::HashedPubkey(hash.clone())],\n")]),t("span",{pre:!0,attrs:{class:"token prefix unchanged"}},[e._v(" ")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" Terminal::PkK(ref key) => vec![PkPkh::PlainPubkey(key.clone())],\n")])]),t("span",{pre:!0,attrs:{class:"token deleted-sign deleted"}},[t("span",{pre:!0,attrs:{class:"token prefix deleted"}},[e._v("-")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" Terminal::Multi(_, ref keys) => keys\n")])]),t("span",{pre:!0,attrs:{class:"token inserted-sign inserted"}},[t("span",{pre:!0,attrs:{class:"token prefix inserted"}},[e._v("+")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" Terminal::Multi(_, ref keys) | Terminal::MultiA(_, ref keys) => keys\n")])]),t("span",{pre:!0,attrs:{class:"token unchanged"}},[t("span",{pre:!0,attrs:{class:"token prefix unchanged"}},[e._v(" ")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" .into_iter()\n")]),t("span",{pre:!0,attrs:{class:"token prefix unchanged"}},[e._v(" ")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" .map(|key| PkPkh::PlainPubkey(key.clone()))\n")]),t("span",{pre:!0,attrs:{class:"token prefix unchanged"}},[e._v(" ")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" .collect(),\n")])]),e._v("@@ -170,7 +170,7 @@ impl Miniscript {\n"),t("span",{pre:!0,attrs:{class:"token unchanged"}},[t("span",{pre:!0,attrs:{class:"token prefix unchanged"}},[e._v(" ")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" pub fn get_nth_pk(&self, n: usize) -> Option {\n")]),t("span",{pre:!0,attrs:{class:"token prefix unchanged"}},[e._v(" ")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" match (&self.node, n) {\n")]),t("span",{pre:!0,attrs:{class:"token prefix unchanged"}},[e._v(" ")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" (&Terminal::PkK(ref key), 0) => Some(key.clone()),\n")])]),t("span",{pre:!0,attrs:{class:"token deleted-sign deleted"}},[t("span",{pre:!0,attrs:{class:"token prefix deleted"}},[e._v("-")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" (&Terminal::Multi(_, ref keys), _) => keys.get(n).cloned(),\n")])]),t("span",{pre:!0,attrs:{class:"token inserted-sign inserted"}},[t("span",{pre:!0,attrs:{class:"token prefix inserted"}},[e._v("+")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" (&Terminal::Multi(_, ref keys), _) | (&Terminal::MultiA(_, ref keys), _) => keys.get(n).cloned(),\n")])]),t("span",{pre:!0,attrs:{class:"token unchanged"}},[t("span",{pre:!0,attrs:{class:"token prefix unchanged"}},[e._v(" ")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" _ => None,\n")]),t("span",{pre:!0,attrs:{class:"token prefix unchanged"}},[e._v(" ")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" }\n")]),t("span",{pre:!0,attrs:{class:"token prefix unchanged"}},[e._v(" ")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" }\n")])]),e._v("@@ -186,7 +186,7 @@ impl Miniscript {\n"),t("span",{pre:!0,attrs:{class:"token unchanged"}},[t("span",{pre:!0,attrs:{class:"token prefix unchanged"}},[e._v(" ")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" match (&self.node, n) {\n")]),t("span",{pre:!0,attrs:{class:"token prefix unchanged"}},[e._v(" ")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" (&Terminal::PkH(ref hash), 0) => Some(hash.clone()),\n")]),t("span",{pre:!0,attrs:{class:"token prefix unchanged"}},[e._v(" ")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" (&Terminal::PkK(ref key), 0) => Some(key.to_pubkeyhash()),\n")])]),t("span",{pre:!0,attrs:{class:"token deleted-sign deleted"}},[t("span",{pre:!0,attrs:{class:"token prefix deleted"}},[e._v("-")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" (&Terminal::Multi(_, ref keys), _) => keys.get(n).map(Pk::to_pubkeyhash),\n")])]),t("span",{pre:!0,attrs:{class:"token inserted-sign inserted"}},[t("span",{pre:!0,attrs:{class:"token prefix inserted"}},[e._v("+")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" (&Terminal::Multi(_, ref keys), _) | (&Terminal::MultiA(_, ref keys), _) => keys.get(n).map(Pk::to_pubkeyhash),\n")])]),t("span",{pre:!0,attrs:{class:"token unchanged"}},[t("span",{pre:!0,attrs:{class:"token prefix unchanged"}},[e._v(" ")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" _ => None,\n")]),t("span",{pre:!0,attrs:{class:"token prefix unchanged"}},[e._v(" ")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" }\n")]),t("span",{pre:!0,attrs:{class:"token prefix unchanged"}},[e._v(" ")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" }\n")])]),e._v("@@ -199,7 +199,7 @@ impl Miniscript {\n"),t("span",{pre:!0,attrs:{class:"token unchanged"}},[t("span",{pre:!0,attrs:{class:"token prefix unchanged"}},[e._v(" ")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" match (&self.node, n) {\n")]),t("span",{pre:!0,attrs:{class:"token prefix unchanged"}},[e._v(" ")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" (&Terminal::PkH(ref hash), 0) => Some(PkPkh::HashedPubkey(hash.clone())),\n")]),t("span",{pre:!0,attrs:{class:"token prefix unchanged"}},[e._v(" ")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" (&Terminal::PkK(ref key), 0) => Some(PkPkh::PlainPubkey(key.clone())),\n")])]),t("span",{pre:!0,attrs:{class:"token deleted-sign deleted"}},[t("span",{pre:!0,attrs:{class:"token prefix deleted"}},[e._v("-")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" (&Terminal::Multi(_, ref keys), _) => {\n")])]),t("span",{pre:!0,attrs:{class:"token inserted-sign inserted"}},[t("span",{pre:!0,attrs:{class:"token prefix inserted"}},[e._v("+")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" (&Terminal::Multi(_, ref keys), _) | (&Terminal::MultiA(_, ref keys), _) => {\n")])]),t("span",{pre:!0,attrs:{class:"token unchanged"}},[t("span",{pre:!0,attrs:{class:"token prefix unchanged"}},[e._v(" ")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" keys.get(n).map(|key| PkPkh::PlainPubkey(key.clone()))\n")]),t("span",{pre:!0,attrs:{class:"token prefix unchanged"}},[e._v(" ")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" }\n")]),t("span",{pre:!0,attrs:{class:"token prefix unchanged"}},[e._v(" ")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" _ => None,\n")])])])])]),t("p",[e._v("Taproot descriptors add a new miniscript operator called "),t("code",[e._v("multi_a()")]),e._v(" which behaves like "),t("code",[e._v("multi()")]),e._v(" in non-Taproot descriptors, but uses the new "),t("a",{attrs:{href:"https://github.com/bitcoin/bips/blob/master/bip-0342.mediawiki#script-execution",target:"_blank",rel:"noopener noreferrer"}},[t("code",[e._v("OP_CHECKSIGADD")]),t("OutboundLink")],1),e._v(" opcode when serialized in a script.")]),e._v(" "),t("p",[e._v("When this was added, somebody forgot to update the various methods that iterate over the public keys of a descriptor to correctly return the keys contained in "),t("code",[e._v("multi_a()")]),e._v(" - essentially, it was falling back in\nthe default case used by the operators that don't contain any key, but this one does!")]),e._v(" "),t("div",{staticClass:"language- extra-class"},[t("pre",{pre:!0,attrs:{class:"language-text"}},[t("code",[e._v("$ git show 8b108c5\n")])])]),t("div",{staticClass:"language-diff extra-class"},[t("pre",{pre:!0,attrs:{class:"language-diff"}},[t("code",[e._v("commit 8b108c5c0bf50b66b7220746525742b71f6cd4b4\nAuthor: Alekos Filini \nDate: Sat Nov 13 17:26:53 2021 +0100\n\n"),t("span",{pre:!0,attrs:{class:"token unchanged"}},[t("span",{pre:!0,attrs:{class:"token prefix unchanged"}},[e._v(" ")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" Fix witness generation for `MultiA`\n")])]),e._v("\ndiff --git a/src/miniscript/satisfy.rs b/src/miniscript/satisfy.rs\nindex 655436e..ab43707 100644\n"),t("span",{pre:!0,attrs:{class:"token coord"}},[e._v("--- a/src/miniscript/satisfy.rs")]),e._v("\n"),t("span",{pre:!0,attrs:{class:"token coord"}},[e._v("+++ b/src/miniscript/satisfy.rs")]),e._v("\n@@ -1264,7 +1264,7 @@ impl Satisfaction {\n"),t("span",{pre:!0,attrs:{class:"token unchanged"}},[t("span",{pre:!0,attrs:{class:"token prefix unchanged"}},[e._v(" ")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" // Collect all available signatures\n")]),t("span",{pre:!0,attrs:{class:"token prefix unchanged"}},[e._v(" ")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" let mut sig_count = 0;\n")]),t("span",{pre:!0,attrs:{class:"token prefix unchanged"}},[e._v(" ")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" let mut sigs = vec![vec![vec![]]; keys.len()];\n")])]),t("span",{pre:!0,attrs:{class:"token deleted-sign deleted"}},[t("span",{pre:!0,attrs:{class:"token prefix deleted"}},[e._v("-")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" for (i, pk) in keys.iter().enumerate() {\n")])]),t("span",{pre:!0,attrs:{class:"token inserted-sign inserted"}},[t("span",{pre:!0,attrs:{class:"token prefix inserted"}},[e._v("+")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" for (i, pk) in keys.iter().rev().enumerate() {\n")])]),t("span",{pre:!0,attrs:{class:"token unchanged"}},[t("span",{pre:!0,attrs:{class:"token prefix unchanged"}},[e._v(" ")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" match Witness::signature::<_, _, Ctx>(stfr, pk, leaf_hash) {\n")]),t("span",{pre:!0,attrs:{class:"token prefix unchanged"}},[e._v(" ")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" Witness::Stack(sig) => {\n")]),t("span",{pre:!0,attrs:{class:"token prefix unchanged"}},[e._v(" ")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" sigs[i] = sig;\n")])])])])]),t("p",[e._v("And finally, the last little fix: the "),t("code",[e._v("multi_a()")]),e._v(" operator is satisfied by pushing to the witness either a signature (if you have one available for that specific public key) or an empty vector. The problem is,\nthey have to be in the right order to match the order of public keys in your Taproot script.")]),e._v(" "),t("p",[e._v("rust-miniscript was pushing them in reverse order, so script validation was always failing for multisigs that had more than 1 key. Adding a "),t("code",[e._v(".rev()")]),e._v(" to the iterator fixed the issue.")]),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("And that was it! We now have a fully working "),t("a",{attrs:{href:"https://github.com/rust-bitcoin/rust-bitcoin",target:"_blank",rel:"noopener noreferrer"}},[e._v("rust-bitcoin"),t("OutboundLink")],1),e._v(" and "),t("a",{attrs:{href:"https://github.com/rust-bitcoin/rust-miniscript",target:"_blank",rel:"noopener noreferrer"}},[e._v("rust-miniscript"),t("OutboundLink")],1),e._v(" ready for Taproot.")]),e._v(" "),t("p",[e._v("In "),t("a",{attrs:{href:"/blog/2021/12/first-bdk-taproot-tx-look-at-the-code-part-2"}},[e._v("Part 2")]),e._v(" I will go over the code changes in BDK, but I think it's now time for you and I to take a break 😃")])])}),[],!1,null,null,null);t.default=a.exports}}]); \ No newline at end of file +(window.webpackJsonp=window.webpackJsonp||[]).push([[59],{415:function(e,t,s){"use strict";s.r(t);var n=s(7),a=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 is the first of a two-parts blog series in which I will try to explain all the changes that I made to BDK (and some of its dependencies) to make our "),t("a",{attrs:{href:"https://twitter.com/afilini/status/1459763243556163584",target:"_blank",rel:"noopener noreferrer"}},[e._v("first Taproot transaction in mainnet"),t("OutboundLink")],1),e._v(", which also\nturned out to be "),t("a",{attrs:{href:"https://twitter.com/afilini/status/1459774394054725634",target:"_blank",rel:"noopener noreferrer"}},[e._v("the first ever use of the new "),t("code",[e._v("OP_CHECKSIGADD")]),e._v(" opcode"),t("OutboundLink")],1),e._v(".")]),e._v(" "),t("p",[e._v("Hopefully this will give an insight into what kind of changes need to be made to a wallet in order to support spending "),t("code",[e._v("P2TR")]),e._v(" outputs, both with key-spend and script-spend. BDK actually delegates\nmost of the hard work to "),t("a",{attrs:{href:"https://github.com/rust-bitcoin/rust-miniscript",target:"_blank",rel:"noopener noreferrer"}},[e._v("rust-miniscript"),t("OutboundLink")],1),e._v(", and luckily most of the Taproot code was already implemented by the time I started working on it. I only had to patch a few little bugs here and there, and it ended up\nworking flawlessly in the end.")]),e._v(" "),t("p",[e._v("In this first part I will focus on the changes made to our dependencies, "),t("a",{attrs:{href:"https://github.com/rust-bitcoin/rust-bitcoin",target:"_blank",rel:"noopener noreferrer"}},[e._v("rust-bitcoin"),t("OutboundLink")],1),e._v(" and "),t("a",{attrs:{href:"https://github.com/rust-bitcoin/rust-miniscript",target:"_blank",rel:"noopener noreferrer"}},[e._v("rust-miniscript"),t("OutboundLink")],1),e._v(". In the second part I will talk about BDK itself.")]),e._v(" "),t("h2",{attrs:{id:"backstory"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#backstory"}},[e._v("#")]),e._v(" Backstory")]),e._v(" "),t("p",[e._v("On the evening of Thursday, November 11th I was attending our weekly "),t("a",{attrs:{href:"https://www.satoshispritz.com/",target:"_blank",rel:"noopener noreferrer"}},[e._v("Satoshi Spritz"),t("OutboundLink")],1),e._v(" meetup in Milan. The activation of Taproot was right around the corner, and naturally that was the main discussion\ntopic that night. The activation was forecasted for the early afternoon of Sunday, November 14th, a little less than 72h later.")]),e._v(" "),t("p",[e._v("I began to wonder how hard it would be to patch BDK and add support for Taproot. I knew most of the work had already been done in our main dependencies, "),t("a",{attrs:{href:"https://github.com/rust-bitcoin/rust-bitcoin",target:"_blank",rel:"noopener noreferrer"}},[e._v("rust-bitcoin"),t("OutboundLink")],1),e._v(" and "),t("a",{attrs:{href:"https://github.com/rust-bitcoin/rust-miniscript",target:"_blank",rel:"noopener noreferrer"}},[e._v("rust-miniscript"),t("OutboundLink")],1),e._v(", and so I decided\nto challenge myself: could I make it in time for the activation?")]),e._v(" "),t("p",[e._v('The following day I started digging into the topic. It didn\'t help that up until that time I only had a rather "high level" idea of how Taproot worked, but luckily all the BIPs were very well written and\nstraightforward to understand.')]),e._v(" "),t("p",[e._v("By Friday night (or rather, early Saturday morning) "),t("a",{attrs:{href:"https://mempool.space/signet/tx/ba0ebb350717701ca4ea109aadfbaf3058f6cd73e5ece3927ddee653de06cf5a",target:"_blank",rel:"noopener noreferrer"}},[e._v("I had Taproot key-spend working"),t("OutboundLink")],1),e._v(", which made me pretty optimistic even though the activation date was actually moving closer, now being forecasted for\nSunday "),t("em",[e._v("morning")]),e._v(".")]),e._v(" "),t("p",[e._v("After a few hours of sleep I went back to work and by early Saturday afternoon "),t("a",{attrs:{href:"https://mempool.space/signet/tx/41d7d49f9f4edffa9ca88ad6fb887fbf1ae68f9f31def267fdb3a5949f766bf5",target:"_blank",rel:"noopener noreferrer"}},[e._v("I had Taproot script-spend working as well"),t("OutboundLink")],1),e._v(". This left me a few hours to coordinate with some friends and "),t("a",{attrs:{href:"https://mempool.space/address/1Taproote7gvQGKz5g982ecSbPvqJhMUf",target:"_blank",rel:"noopener noreferrer"}},[e._v("generate a vanity address"),t("OutboundLink")],1),e._v("\nto deposit funds into temporarily, as we didn't trust sending them to Taproot addresses before the activation (as they were anyone-can-spend according to the pre-activation rules).")]),e._v(" "),t("p",[e._v("After another pretty short night, I woke up a 5:30 AM on Sunday to monitor the activation. I broadcasted our transactions shortly after 6:00 AM as the activation block was being mined. Unfortunately, the first\nthree blocks that were enforcing Taproot rules "),t("a",{attrs:{href:"https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2021-November/019598.html",target:"_blank",rel:"noopener noreferrer"}},[e._v("didn't include any Taproot transaction"),t("OutboundLink")],1),e._v(", which indicates that the miners weren't actually running the new Bitcoin Core 22.0 nodes. The fourth block, mined by "),t("code",[e._v("Foundry USA")]),e._v(" "),t("a",{attrs:{href:"https://mempool.space/tx/2eb8dbaa346d4be4e82fe444c2f0be00654d8cfd8c4a9a61b11aeaab8c00b272",target:"_blank",rel:"noopener noreferrer"}},[e._v("included my transaction"),t("OutboundLink")],1),e._v(" and "),t("a",{attrs:{href:"https://twitter.com/achow101/status/1459760452775387136?s=20",target:"_blank",rel:"noopener noreferrer"}},[e._v("a few others"),t("OutboundLink")],1),e._v(".")]),e._v(" "),t("p",[e._v("In the end our transaction was the third Taproot script-spend in the block, but the first to use the new "),t("a",{attrs:{href:"https://github.com/bitcoin/bips/blob/master/bip-0342.mediawiki#script-execution",target:"_blank",rel:"noopener noreferrer"}},[t("code",[e._v("OP_CHECKSIGADD")]),t("OutboundLink")],1),e._v(" opcode, as the two preceding it were respectively "),t("a",{attrs:{href:"https://mempool.space/tx/37777defed8717c581b4c0509329550e344bdc14ac38f71fc050096887e535c8",target:"_blank",rel:"noopener noreferrer"}},[e._v("a single-sig"),t("OutboundLink")],1),e._v(" and "),t("a",{attrs:{href:"https://mempool.space/tx/905ecdf95a84804b192f4dc221cfed4d77959b81ed66013a7e41a6e61e7ed530",target:"_blank",rel:"noopener noreferrer"}},[e._v("a 2-of-2 multisig"),t("OutboundLink")],1),e._v("\nscript, made with with two "),t("code",[e._v("OP_CHECKSIG(VERIFY)")]),e._v("s.")]),e._v(" "),t("p",[e._v("Now, with the context out of the way, we can begin talking about the code!")]),e._v(" "),t("h2",{attrs:{id:"rust-bitcoin"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#rust-bitcoin"}},[e._v("#")]),e._v(" rust-bitcoin")]),e._v(" "),t("p",[e._v("The first dependency I had to update was "),t("a",{attrs:{href:"https://github.com/rust-bitcoin/rust-bitcoin",target:"_blank",rel:"noopener noreferrer"}},[e._v("rust-bitcoin"),t("OutboundLink")],1),e._v(". Most of the taproot stuff were already merged in "),t("code",[e._v("master")]),e._v(" (altough they hadn't been released yet). One notable missing part was the support for "),t("a",{attrs:{href:"https://github.com/bitcoin/bips/blob/master/bip-0371.mediawiki",target:"_blank",rel:"noopener noreferrer"}},[t("code",[e._v("BIP371")]),t("OutboundLink")],1),e._v(",\nwhich is an extension of "),t("a",{attrs:{href:"https://github.com/bitcoin/bips/blob/master/bip-0174.mediawiki",target:"_blank",rel:"noopener noreferrer"}},[t("code",[e._v("BIP174")]),t("OutboundLink")],1),e._v(", aka the "),t("code",[e._v("Partially Signed Bitcoin Transaction")]),e._v(" BIP. This new BIP defines a few new fields that are required to properly handle Taproot transactions.")]),e._v(" "),t("p",[e._v("Luckily most of the work had already been done by "),t("a",{attrs:{href:"https://twitter.com/sanket1729",target:"_blank",rel:"noopener noreferrer"}},[e._v("sanket1729"),t("OutboundLink")],1),e._v(", so I forked his branch and made only few very minor changes, just to expose a structure that I will have to use later which in his code wasn't public.")]),e._v(" "),t("p",[e._v("You can find all the commits mentioned here in "),t("a",{attrs:{href:"https://github.com/afilini/rust-bitcoin/tree/taproot-testing",target:"_blank",rel:"noopener noreferrer"}},[e._v("my rust-bitcoin "),t("code",[e._v("taproot-testing")]),e._v(" branch"),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("$ git diff 187234f f830df9\n")])])]),t("div",{staticClass:"language-diff extra-class"},[t("pre",{pre:!0,attrs:{class:"language-diff"}},[t("code",[e._v("diff --git a/src/lib.rs b/src/lib.rs\nindex 87d9c36..d5e5802 100644\n"),t("span",{pre:!0,attrs:{class:"token coord"}},[e._v("--- a/src/lib.rs")]),e._v("\n"),t("span",{pre:!0,attrs:{class:"token coord"}},[e._v("+++ b/src/lib.rs")]),e._v("\n"),t("span",{pre:!0,attrs:{class:"token coord"}},[e._v("@@ -54,7 +54,6 @@")]),e._v("\n"),t("span",{pre:!0,attrs:{class:"token unchanged"}},[t("span",{pre:!0,attrs:{class:"token prefix unchanged"}},[e._v(" ")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v("#![deny(unused_mut)]\n")]),t("span",{pre:!0,attrs:{class:"token prefix unchanged"}},[e._v(" ")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v("#![deny(dead_code)]\n")]),t("span",{pre:!0,attrs:{class:"token prefix unchanged"}},[e._v(" ")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v("#![deny(unused_imports)]\n")])]),t("span",{pre:!0,attrs:{class:"token deleted-sign deleted"}},[t("span",{pre:!0,attrs:{class:"token prefix deleted"}},[e._v("-")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v("#![deny(missing_docs)]\n")])]),t("span",{pre:!0,attrs:{class:"token unchanged"}},[t("span",{pre:!0,attrs:{class:"token prefix unchanged"}},[e._v(" ")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v("#![deny(unused_must_use)]\n")]),t("span",{pre:!0,attrs:{class:"token prefix unchanged"}},[e._v(" ")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v("#![deny(broken_intra_doc_links)]\n")])]),e._v("\ndiff --git a/src/util/taproot.rs b/src/util/taproot.rs\nindex 674eeee..3d56cbc 100644\n"),t("span",{pre:!0,attrs:{class:"token coord"}},[e._v("--- a/src/util/taproot.rs")]),e._v("\n"),t("span",{pre:!0,attrs:{class:"token coord"}},[e._v("+++ b/src/util/taproot.rs")]),e._v("\n@@ -440,7 +440,7 @@ impl TaprootBuilder {\n"),t("span",{pre:!0,attrs:{class:"token unchanged"}},[t("span",{pre:!0,attrs:{class:"token prefix unchanged"}},[e._v(" ")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v("// Internally used structure to represent the node information in taproot tree\n")]),t("span",{pre:!0,attrs:{class:"token prefix unchanged"}},[e._v(" ")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v("#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]\n")]),t("span",{pre:!0,attrs:{class:"token prefix unchanged"}},[e._v(" ")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v('#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]\n')])]),t("span",{pre:!0,attrs:{class:"token deleted-sign deleted"}},[t("span",{pre:!0,attrs:{class:"token prefix deleted"}},[e._v("-")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v("pub(crate) struct NodeInfo {\n")])]),t("span",{pre:!0,attrs:{class:"token inserted-sign inserted"}},[t("span",{pre:!0,attrs:{class:"token prefix inserted"}},[e._v("+")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v("pub struct NodeInfo {\n")])]),t("span",{pre:!0,attrs:{class:"token unchanged"}},[t("span",{pre:!0,attrs:{class:"token prefix unchanged"}},[e._v(" ")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" /// Merkle Hash for this node\n")]),t("span",{pre:!0,attrs:{class:"token prefix unchanged"}},[e._v(" ")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" pub(crate) hash: sha256::Hash,\n")]),t("span",{pre:!0,attrs:{class:"token prefix unchanged"}},[e._v(" ")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" /// information about leaves inside this node\n")])]),e._v("@@ -448,8 +448,12 @@ pub(crate) struct NodeInfo {\n"),t("span",{pre:!0,attrs:{class:"token unchanged"}},[t("span",{pre:!0,attrs:{class:"token prefix unchanged"}},[e._v(" ")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v("}\n")])]),e._v("\n"),t("span",{pre:!0,attrs:{class:"token unchanged"}},[t("span",{pre:!0,attrs:{class:"token prefix unchanged"}},[e._v(" ")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v("impl NodeInfo {\n")])]),t("span",{pre:!0,attrs:{class:"token inserted-sign inserted"}},[t("span",{pre:!0,attrs:{class:"token prefix inserted"}},[e._v("+")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" pub fn hash(&self) -> &sha256::Hash {\n")]),t("span",{pre:!0,attrs:{class:"token prefix inserted"}},[e._v("+")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" &self.hash\n")]),t("span",{pre:!0,attrs:{class:"token prefix inserted"}},[e._v("+")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" }\n")]),t("span",{pre:!0,attrs:{class:"token prefix inserted"}},[e._v("+")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v("\n")])]),t("span",{pre:!0,attrs:{class:"token unchanged"}},[t("span",{pre:!0,attrs:{class:"token prefix unchanged"}},[e._v(" ")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" // Create a new NodeInfo with omitted/hidden info\n")])]),t("span",{pre:!0,attrs:{class:"token deleted-sign deleted"}},[t("span",{pre:!0,attrs:{class:"token prefix deleted"}},[e._v("-")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" fn new_hidden(hash: sha256::Hash) -> Self {\n")])]),t("span",{pre:!0,attrs:{class:"token inserted-sign inserted"}},[t("span",{pre:!0,attrs:{class:"token prefix inserted"}},[e._v("+")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" pub fn new_hidden(hash: sha256::Hash) -> Self {\n")])]),t("span",{pre:!0,attrs:{class:"token unchanged"}},[t("span",{pre:!0,attrs:{class:"token prefix unchanged"}},[e._v(" ")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" Self {\n")]),t("span",{pre:!0,attrs:{class:"token prefix unchanged"}},[e._v(" ")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" hash: hash,\n")]),t("span",{pre:!0,attrs:{class:"token prefix unchanged"}},[e._v(" ")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" leaves: vec![],\n")])]),e._v("@@ -457,7 +461,7 @@ impl NodeInfo {\n"),t("span",{pre:!0,attrs:{class:"token unchanged"}},[t("span",{pre:!0,attrs:{class:"token prefix unchanged"}},[e._v(" ")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" }\n")])]),e._v("\n"),t("span",{pre:!0,attrs:{class:"token unchanged"}},[t("span",{pre:!0,attrs:{class:"token prefix unchanged"}},[e._v(" ")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" // Create a new leaf with NodeInfo\n")])]),t("span",{pre:!0,attrs:{class:"token deleted-sign deleted"}},[t("span",{pre:!0,attrs:{class:"token prefix deleted"}},[e._v("-")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" fn new_leaf_with_ver(script: Script, ver: LeafVersion) -> Self {\n")])]),t("span",{pre:!0,attrs:{class:"token inserted-sign inserted"}},[t("span",{pre:!0,attrs:{class:"token prefix inserted"}},[e._v("+")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" pub fn new_leaf_with_ver(script: Script, ver: LeafVersion) -> Self {\n")])]),t("span",{pre:!0,attrs:{class:"token unchanged"}},[t("span",{pre:!0,attrs:{class:"token prefix unchanged"}},[e._v(" ")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" let leaf = LeafInfo::new(script, ver);\n")]),t("span",{pre:!0,attrs:{class:"token prefix unchanged"}},[e._v(" ")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" Self {\n")]),t("span",{pre:!0,attrs:{class:"token prefix unchanged"}},[e._v(" ")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" hash: leaf.hash(),\n")])]),e._v("@@ -466,7 +470,7 @@ impl NodeInfo {\n"),t("span",{pre:!0,attrs:{class:"token unchanged"}},[t("span",{pre:!0,attrs:{class:"token prefix unchanged"}},[e._v(" ")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" }\n")])]),e._v("\n"),t("span",{pre:!0,attrs:{class:"token unchanged"}},[t("span",{pre:!0,attrs:{class:"token prefix unchanged"}},[e._v(" ")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" // Combine two NodeInfo's to create a new parent\n")])]),t("span",{pre:!0,attrs:{class:"token deleted-sign deleted"}},[t("span",{pre:!0,attrs:{class:"token prefix deleted"}},[e._v("-")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" fn combine(a: Self, b: Self) -> Result {\n")])]),t("span",{pre:!0,attrs:{class:"token inserted-sign inserted"}},[t("span",{pre:!0,attrs:{class:"token prefix inserted"}},[e._v("+")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" pub fn combine(a: Self, b: Self) -> Result {\n")])]),t("span",{pre:!0,attrs:{class:"token unchanged"}},[t("span",{pre:!0,attrs:{class:"token prefix unchanged"}},[e._v(" ")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" let mut all_leaves = Vec::with_capacity(a.leaves.len() + b.leaves.len());\n")]),t("span",{pre:!0,attrs:{class:"token prefix unchanged"}},[e._v(" ")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" for mut a_leaf in a.leaves {\n")]),t("span",{pre:!0,attrs:{class:"token prefix unchanged"}},[e._v(" ")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" a_leaf.merkle_branch.push(b.hash)?; // add hashing partner\n")])]),e._v("\n")])])]),t("p",[e._v("There isn't much to explain here: I disabled the "),t("code",[e._v("missing_docs")]),e._v(" lint so that the compiler wouldn't complain about the new public methods that aren't documented.\nThen, I added a getter for the "),t("code",[e._v("hash")]),e._v(" field of "),t("code",[e._v("NodeInfo")]),e._v(" and made the struct itself and a bunch of methods public.")]),e._v(" "),t("p",[e._v('We will use this structure later to recover the merkle root of a Taproot script tree, given one leaf and the other "hidden" branches.')]),e._v(" "),t("h2",{attrs:{id:"rust-miniscript"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#rust-miniscript"}},[e._v("#")]),e._v(" rust-miniscript")]),e._v(" "),t("p",[e._v("Moving on to "),t("a",{attrs:{href:"https://github.com/rust-bitcoin/rust-miniscript",target:"_blank",rel:"noopener noreferrer"}},[e._v("rust-miniscript"),t("OutboundLink")],1),e._v(': once again, most of the work required to support Taproot had already been done, but this time I was working with very "early" prototype-like code, so I was prepared to\nmake some changes to the code to get it to work how I wanted.')]),e._v(" "),t("p",[e._v("Instead of showing one big diff I will talk about the commits individually, which I think will help making more clear what I was doing.")]),e._v(" "),t("p",[e._v("Once again, you can find all the commits referenced here in "),t("a",{attrs:{href:"https://github.com/afilini/rust-miniscript/tree/taproot",target:"_blank",rel:"noopener noreferrer"}},[e._v("my rust-miniscript "),t("code",[e._v("taproot")]),e._v(" branch"),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("$ git show 34cf15b\n")])])]),t("div",{staticClass:"language-diff extra-class"},[t("pre",{pre:!0,attrs:{class:"language-diff"}},[t("code",[e._v("commit 34cf15b3aac1d8c2693af1b9749b888f3f29e510\nAuthor: Alekos Filini \nDate: Fri Nov 12 12:06:35 2021 +0100\n\n"),t("span",{pre:!0,attrs:{class:"token unchanged"}},[t("span",{pre:!0,attrs:{class:"token prefix unchanged"}},[e._v(" ")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" Fix TapTree iter depth\n")])]),e._v("\ndiff --git a/src/descriptor/tr.rs b/src/descriptor/tr.rs\nindex 79d3c05..314c7f4 100644\n"),t("span",{pre:!0,attrs:{class:"token coord"}},[e._v("--- a/src/descriptor/tr.rs")]),e._v("\n"),t("span",{pre:!0,attrs:{class:"token coord"}},[e._v("+++ b/src/descriptor/tr.rs")]),e._v("\n@@ -65,7 +65,7 @@ impl TapTree {\n"),t("span",{pre:!0,attrs:{class:"token unchanged"}},[t("span",{pre:!0,attrs:{class:"token prefix unchanged"}},[e._v(" ")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v("\n")]),t("span",{pre:!0,attrs:{class:"token prefix unchanged"}},[e._v(" ")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" /// Iterate over all miniscripts\n")]),t("span",{pre:!0,attrs:{class:"token prefix unchanged"}},[e._v(" ")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" pub fn iter(&self) -> TapTreeIter {\n")])]),t("span",{pre:!0,attrs:{class:"token deleted-sign deleted"}},[t("span",{pre:!0,attrs:{class:"token prefix deleted"}},[e._v("-")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" TapTreeIter { stack: vec![self] }\n")])]),t("span",{pre:!0,attrs:{class:"token inserted-sign inserted"}},[t("span",{pre:!0,attrs:{class:"token prefix inserted"}},[e._v("+")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" TapTreeIter { stack: vec![(0, self)] }\n")])]),t("span",{pre:!0,attrs:{class:"token unchanged"}},[t("span",{pre:!0,attrs:{class:"token prefix unchanged"}},[e._v(" ")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" }\n")]),t("span",{pre:!0,attrs:{class:"token prefix unchanged"}},[e._v(" ")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v("\n")]),t("span",{pre:!0,attrs:{class:"token prefix unchanged"}},[e._v(" ")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" // Helper function to translate keys\n")])]),e._v("@@ -262,7 +262,7 @@ pub struct TapTreeIter<'a, Pk: MiniscriptKey>\n"),t("span",{pre:!0,attrs:{class:"token unchanged"}},[t("span",{pre:!0,attrs:{class:"token prefix unchanged"}},[e._v(" ")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v("where\n")]),t("span",{pre:!0,attrs:{class:"token prefix unchanged"}},[e._v(" ")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" Pk: 'a,\n")]),t("span",{pre:!0,attrs:{class:"token prefix unchanged"}},[e._v(" ")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v("{\n")])]),t("span",{pre:!0,attrs:{class:"token deleted-sign deleted"}},[t("span",{pre:!0,attrs:{class:"token prefix deleted"}},[e._v("-")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" stack: Vec<&'a TapTree>,\n")])]),t("span",{pre:!0,attrs:{class:"token inserted-sign inserted"}},[t("span",{pre:!0,attrs:{class:"token prefix inserted"}},[e._v("+")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" stack: Vec<(usize, &'a TapTree)>,\n")])]),t("span",{pre:!0,attrs:{class:"token unchanged"}},[t("span",{pre:!0,attrs:{class:"token prefix unchanged"}},[e._v(" ")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v("}\n")]),t("span",{pre:!0,attrs:{class:"token prefix unchanged"}},[e._v(" ")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v("\n")]),t("span",{pre:!0,attrs:{class:"token prefix unchanged"}},[e._v(" ")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v("impl<'a, Pk> Iterator for TapTreeIter<'a, Pk>\n")])]),e._v("@@ -273,13 +273,13 @@ where\n"),t("span",{pre:!0,attrs:{class:"token unchanged"}},[t("span",{pre:!0,attrs:{class:"token prefix unchanged"}},[e._v(" ")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v("\n")]),t("span",{pre:!0,attrs:{class:"token prefix unchanged"}},[e._v(" ")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" fn next(&mut self) -> Option {\n")]),t("span",{pre:!0,attrs:{class:"token prefix unchanged"}},[e._v(" ")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" while !self.stack.is_empty() {\n")])]),t("span",{pre:!0,attrs:{class:"token deleted-sign deleted"}},[t("span",{pre:!0,attrs:{class:"token prefix deleted"}},[e._v("-")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(' let last = self.stack.pop().expect("Size checked above");\n')])]),t("span",{pre:!0,attrs:{class:"token inserted-sign inserted"}},[t("span",{pre:!0,attrs:{class:"token prefix inserted"}},[e._v("+")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(' let (depth, last) = self.stack.pop().expect("Size checked above");\n')])]),t("span",{pre:!0,attrs:{class:"token unchanged"}},[t("span",{pre:!0,attrs:{class:"token prefix unchanged"}},[e._v(" ")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" match &*last {\n")]),t("span",{pre:!0,attrs:{class:"token prefix unchanged"}},[e._v(" ")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" TapTree::Tree(l, r) => {\n")])]),t("span",{pre:!0,attrs:{class:"token deleted-sign deleted"}},[t("span",{pre:!0,attrs:{class:"token prefix deleted"}},[e._v("-")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" self.stack.push(&r);\n")]),t("span",{pre:!0,attrs:{class:"token prefix deleted"}},[e._v("-")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" self.stack.push(&l);\n")])]),t("span",{pre:!0,attrs:{class:"token inserted-sign inserted"}},[t("span",{pre:!0,attrs:{class:"token prefix inserted"}},[e._v("+")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" self.stack.push((depth + 1, &r));\n")]),t("span",{pre:!0,attrs:{class:"token prefix inserted"}},[e._v("+")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" self.stack.push((depth + 1, &l));\n")])]),t("span",{pre:!0,attrs:{class:"token unchanged"}},[t("span",{pre:!0,attrs:{class:"token prefix unchanged"}},[e._v(" ")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" }\n")])]),t("span",{pre:!0,attrs:{class:"token deleted-sign deleted"}},[t("span",{pre:!0,attrs:{class:"token prefix deleted"}},[e._v("-")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" TapTree::Leaf(ref ms) => return Some((self.stack.len(), ms)),\n")])]),t("span",{pre:!0,attrs:{class:"token inserted-sign inserted"}},[t("span",{pre:!0,attrs:{class:"token prefix inserted"}},[e._v("+")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" TapTree::Leaf(ref ms) => return Some((depth, ms)),\n")])]),t("span",{pre:!0,attrs:{class:"token unchanged"}},[t("span",{pre:!0,attrs:{class:"token prefix unchanged"}},[e._v(" ")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" }\n")]),t("span",{pre:!0,attrs:{class:"token prefix unchanged"}},[e._v(" ")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" }\n")]),t("span",{pre:!0,attrs:{class:"token prefix unchanged"}},[e._v(" ")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" None\n")])])])])]),t("p",[t("code",[e._v("TapTreeIterator")]),e._v(" is an iterator that goes through a "),t("code",[e._v("TapTree")]),e._v(" and yields a "),t("code",[e._v("(depth, node)")]),e._v(" pair. This is then fed to "),t("a",{attrs:{href:"https://github.com/afilini/rust-miniscript/blob/taproot/src/descriptor/tr.rs#L183-L189",target:"_blank",rel:"noopener noreferrer"}},[t("code",[e._v("TaprootBuilder")]),t("OutboundLink")],1),e._v(", which returns an error if trying to insert nodes\nin "),t("a",{attrs:{href:"https://github.com/afilini/rust-bitcoin/blob/taproot-testing/src/util/taproot.rs#L403-L405",target:"_blank",rel:"noopener noreferrer"}},[e._v("an order that is not DFS"),t("OutboundLink")],1),e._v(".")]),e._v(" "),t("p",[e._v("The way the depth was computed before made the builder always fail for non-trivial trees (i.e. more than 1 node).")]),e._v(" "),t("p",[e._v("Here I decided to play the safe card, and just keep track of the depth explicitly: I think there might be a way to compute the depth just knowing the "),t("code",[e._v("self.stack.len()")]),e._v(" (assuming the tree has a specific structure,\nwhich I'm not sure applies here), but anyway I didn't have much time to think about it and I just went for the \"dumb but idiot-proof\" way which ended up working fine.")]),e._v(" "),t("div",{staticClass:"language- extra-class"},[t("pre",{pre:!0,attrs:{class:"language-text"}},[t("code",[e._v("$ git show f4a3459\n")])])]),t("div",{staticClass:"language-diff extra-class"},[t("pre",{pre:!0,attrs:{class:"language-diff"}},[t("code",[e._v("commit f4a3459128e37ca0c2701b8b6da064d4952296ff\nAuthor: Alekos Filini \nDate: Sat Nov 13 14:15:52 2021 +0100\n\n"),t("span",{pre:!0,attrs:{class:"token unchanged"}},[t("span",{pre:!0,attrs:{class:"token prefix unchanged"}},[e._v(" ")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" Switch rust-bitcoin rev\n")])]),e._v("\ndiff --git a/Cargo.toml b/Cargo.toml\nindex 12825e8..8240024 100644\n"),t("span",{pre:!0,attrs:{class:"token coord"}},[e._v("--- a/Cargo.toml")]),e._v("\n"),t("span",{pre:!0,attrs:{class:"token coord"}},[e._v("+++ b/Cargo.toml")]),e._v('\n@@ -17,7 +17,7 @@ rand = ["bitcoin/rand"]\n\n'),t("span",{pre:!0,attrs:{class:"token unchanged"}},[t("span",{pre:!0,attrs:{class:"token prefix unchanged"}},[e._v(" ")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v("[dependencies]\n")]),t("span",{pre:!0,attrs:{class:"token prefix unchanged"}},[e._v(" ")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v('# bitcoin = "0.27"\n')])]),t("span",{pre:!0,attrs:{class:"token deleted-sign deleted"}},[t("span",{pre:!0,attrs:{class:"token prefix deleted"}},[e._v("-")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v('bitcoin = {git = "https://github.com/sanket1729/rust-bitcoin", branch = "taproot_psbt"}\n')])]),t("span",{pre:!0,attrs:{class:"token inserted-sign inserted"}},[t("span",{pre:!0,attrs:{class:"token prefix inserted"}},[e._v("+")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v('bitcoin = { git = "https://github.com/afilini/rust-bitcoin.git", branch = "taproot-testing" }\n')])]),e._v("\n"),t("span",{pre:!0,attrs:{class:"token unchanged"}},[t("span",{pre:!0,attrs:{class:"token prefix unchanged"}},[e._v(" ")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v("[dependencies.serde]\n")]),t("span",{pre:!0,attrs:{class:"token prefix unchanged"}},[e._v(" ")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v('version = "1.0"\n')])])])])]),t("p",[e._v("Trivial commit, switch to "),t("a",{attrs:{href:"https://github.com/afilini/rust-bitcoin/tree/taproot-testing",target:"_blank",rel:"noopener noreferrer"}},[e._v("my fork of rust-bitcoin"),t("OutboundLink")],1),e._v(" so that I can make changes if necessary.")]),e._v(" "),t("div",{staticClass:"language- extra-class"},[t("pre",{pre:!0,attrs:{class:"language-text"}},[t("code",[e._v("$ git show 0446b16\n")])])]),t("div",{staticClass:"language-diff extra-class"},[t("pre",{pre:!0,attrs:{class:"language-diff"}},[t("code",[e._v("commit 0446b1631cec9f7118d46f0f4c94ccd20de29f94\nAuthor: Alekos Filini \nDate: Sat Nov 13 14:25:18 2021 +0100\n\n"),t("span",{pre:!0,attrs:{class:"token unchanged"}},[t("span",{pre:!0,attrs:{class:"token prefix unchanged"}},[e._v(" ")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" Parse x-only keys\n")])]),e._v("\ndiff --git a/src/descriptor/key.rs b/src/descriptor/key.rs\nindex 4108d00..b7f90b5 100644\n"),t("span",{pre:!0,attrs:{class:"token coord"}},[e._v("--- a/src/descriptor/key.rs")]),e._v("\n"),t("span",{pre:!0,attrs:{class:"token coord"}},[e._v("+++ b/src/descriptor/key.rs")]),e._v("\n@@ -283,9 +283,9 @@ impl FromStr for DescriptorPublicKey {\n\n"),t("span",{pre:!0,attrs:{class:"token unchanged"}},[t("span",{pre:!0,attrs:{class:"token prefix unchanged"}},[e._v(" ")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" fn from_str(s: &str) -> Result {\n")]),t("span",{pre:!0,attrs:{class:"token prefix unchanged"}},[e._v(" ")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(' // A "raw" public key without any origin is the least we accept.\n')])]),t("span",{pre:!0,attrs:{class:"token deleted-sign deleted"}},[t("span",{pre:!0,attrs:{class:"token prefix deleted"}},[e._v("-")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" if s.len() < 66 {\n")])]),t("span",{pre:!0,attrs:{class:"token inserted-sign inserted"}},[t("span",{pre:!0,attrs:{class:"token prefix inserted"}},[e._v("+")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" if s.len() < 64 {\n")])]),t("span",{pre:!0,attrs:{class:"token unchanged"}},[t("span",{pre:!0,attrs:{class:"token prefix unchanged"}},[e._v(" ")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" return Err(DescriptorKeyParseError(\n")])]),t("span",{pre:!0,attrs:{class:"token deleted-sign deleted"}},[t("span",{pre:!0,attrs:{class:"token prefix deleted"}},[e._v("-")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(' "Key too short (<66 char), doesn\'t match any format",\n')])]),t("span",{pre:!0,attrs:{class:"token inserted-sign inserted"}},[t("span",{pre:!0,attrs:{class:"token prefix inserted"}},[e._v("+")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(' "Key too short (<64 char), doesn\'t match any format",\n')])]),t("span",{pre:!0,attrs:{class:"token unchanged"}},[t("span",{pre:!0,attrs:{class:"token prefix unchanged"}},[e._v(" ")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" ));\n")]),t("span",{pre:!0,attrs:{class:"token prefix unchanged"}},[e._v(" ")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" }\n")])]),e._v("\n@@ -301,6 +301,14 @@ impl FromStr for DescriptorPublicKey {\n"),t("span",{pre:!0,attrs:{class:"token unchanged"}},[t("span",{pre:!0,attrs:{class:"token prefix unchanged"}},[e._v(" ")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" derivation_path,\n")]),t("span",{pre:!0,attrs:{class:"token prefix unchanged"}},[e._v(" ")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" wildcard,\n")]),t("span",{pre:!0,attrs:{class:"token prefix unchanged"}},[e._v(" ")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" }))\n")])]),t("span",{pre:!0,attrs:{class:"token inserted-sign inserted"}},[t("span",{pre:!0,attrs:{class:"token prefix inserted"}},[e._v("+")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" } else if key_part.len() == 64 {\n")]),t("span",{pre:!0,attrs:{class:"token prefix inserted"}},[e._v("+")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" // x-only pubkey, prefix it with `02`\n")]),t("span",{pre:!0,attrs:{class:"token prefix inserted"}},[e._v("+")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(' let key = bitcoin::PublicKey::from_str(&format!("02{}", key_part))\n')]),t("span",{pre:!0,attrs:{class:"token prefix inserted"}},[e._v("+")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(' .map_err(|_| DescriptorKeyParseError("Error while parsing x-only public key"))?;\n')]),t("span",{pre:!0,attrs:{class:"token prefix inserted"}},[e._v("+")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" Ok(DescriptorPublicKey::SinglePub(DescriptorSinglePub {\n")]),t("span",{pre:!0,attrs:{class:"token prefix inserted"}},[e._v("+")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" key,\n")]),t("span",{pre:!0,attrs:{class:"token prefix inserted"}},[e._v("+")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" origin,\n")]),t("span",{pre:!0,attrs:{class:"token prefix inserted"}},[e._v("+")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" }))\n")])]),t("span",{pre:!0,attrs:{class:"token unchanged"}},[t("span",{pre:!0,attrs:{class:"token prefix unchanged"}},[e._v(" ")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" } else {\n")]),t("span",{pre:!0,attrs:{class:"token prefix unchanged"}},[e._v(" ")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" if key_part.len() >= 2\n")]),t("span",{pre:!0,attrs:{class:"token prefix unchanged"}},[e._v(" ")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(' && !(&key_part[0..2] == "02" || &key_part[0..2] == "03" || &key_part[0..2] == "04")\n')])]),e._v("diff --git a/src/lib.rs b/src/lib.rs\nindex e168b16..3a2335e 100644\n"),t("span",{pre:!0,attrs:{class:"token coord"}},[e._v("--- a/src/lib.rs")]),e._v("\n"),t("span",{pre:!0,attrs:{class:"token coord"}},[e._v("+++ b/src/lib.rs")]),e._v("\n"),t("span",{pre:!0,attrs:{class:"token coord"}},[e._v("@@ -95,8 +95,6 @@")]),e._v("\n"),t("span",{pre:!0,attrs:{class:"token unchanged"}},[t("span",{pre:!0,attrs:{class:"token prefix unchanged"}},[e._v(" ")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v("#![deny(non_snake_case)]\n")]),t("span",{pre:!0,attrs:{class:"token prefix unchanged"}},[e._v(" ")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v("#![deny(unused_mut)]\n")]),t("span",{pre:!0,attrs:{class:"token prefix unchanged"}},[e._v(" ")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v("#![deny(dead_code)]\n")])]),t("span",{pre:!0,attrs:{class:"token deleted-sign deleted"}},[t("span",{pre:!0,attrs:{class:"token prefix deleted"}},[e._v("-")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v("#![deny(unused_imports)]\n")]),t("span",{pre:!0,attrs:{class:"token prefix deleted"}},[e._v("-")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v("#![deny(missing_docs)]\n")])]),e._v("\n"),t("span",{pre:!0,attrs:{class:"token unchanged"}},[t("span",{pre:!0,attrs:{class:"token prefix unchanged"}},[e._v(" ")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v("pub extern crate bitcoin;\n")]),t("span",{pre:!0,attrs:{class:"token prefix unchanged"}},[e._v(" ")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v('#[cfg(feature = "serde")]\n')])])])])]),t("p",[e._v("This, I'm not really sure of: Taproot uses x-only public keys, which means that the first byte (which is usually a "),t("code",[e._v("03")]),e._v(" or a "),t("code",[e._v("02")]),e._v(") that indicates the parity of the EC point is completely dropped, and it's implicit\nthat the point is even (= "),t("code",[e._v("02")]),e._v("). Check out "),t("a",{attrs:{href:"https://github.com/bitcoin/bips/blob/master/bip-0340.mediawiki",target:"_blank",rel:"noopener noreferrer"}},[t("code",[e._v("BIP340")]),t("OutboundLink")],1),e._v(" for a much better explanation.")]),e._v(" "),t("p",[e._v("So here when I find a string that is only 64 characters long I will assume it's an x-only pubkey, and I will parse it as a normal "),t("code",[e._v("bitcoin::PublicKey")]),e._v(" by prefixing it with "),t("code",[e._v("02")]),e._v(".")]),e._v(" "),t("p",[e._v("I guess one alternative could have been to try and parse it as a "),t("code",[e._v("schnorr::PublicKey")]),e._v(' and then "convert" it to a '),t("code",[e._v("ecdsa::PublicKey")]),e._v(" which should be supported, but once again I just wanted to get it done quickly and\nthis worked fine.")]),e._v(" "),t("p",[e._v("I also disabled the "),t("code",[e._v("unused_imports")]),e._v(" and "),t("code",[e._v("missing_docs")]),e._v(" lint so that the compiler wouldn't whine too much.")]),e._v(" "),t("div",{staticClass:"language- extra-class"},[t("pre",{pre:!0,attrs:{class:"language-text"}},[t("code",[e._v("$ git show 87316ff\n")])])]),t("div",{staticClass:"language-diff extra-class"},[t("pre",{pre:!0,attrs:{class:"language-diff"}},[t("code",[e._v("commit 87316fffd06ab3bdf300fd1a958ddaa2789a6696\nAuthor: Alekos Filini \nDate: Sat Nov 13 14:26:01 2021 +0100\n\n"),t("span",{pre:!0,attrs:{class:"token unchanged"}},[t("span",{pre:!0,attrs:{class:"token prefix unchanged"}},[e._v(" ")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" Parse `tr()` descriptors\n")])]),e._v("\ndiff --git a/src/descriptor/mod.rs b/src/descriptor/mod.rs\nindex 06d98e1..4190786 100644\n"),t("span",{pre:!0,attrs:{class:"token coord"}},[e._v("--- a/src/descriptor/mod.rs")]),e._v("\n"),t("span",{pre:!0,attrs:{class:"token coord"}},[e._v("+++ b/src/descriptor/mod.rs")]),e._v("\n@@ -610,6 +610,7 @@ where\n"),t("span",{pre:!0,attrs:{class:"token unchanged"}},[t("span",{pre:!0,attrs:{class:"token prefix unchanged"}},[e._v(" ")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(' ("wpkh", 1) => Descriptor::Wpkh(Wpkh::from_tree(top)?),\n')]),t("span",{pre:!0,attrs:{class:"token prefix unchanged"}},[e._v(" ")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(' ("sh", 1) => Descriptor::Sh(Sh::from_tree(top)?),\n')]),t("span",{pre:!0,attrs:{class:"token prefix unchanged"}},[e._v(" ")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(' ("wsh", 1) => Descriptor::Wsh(Wsh::from_tree(top)?),\n')])]),t("span",{pre:!0,attrs:{class:"token inserted-sign inserted"}},[t("span",{pre:!0,attrs:{class:"token prefix inserted"}},[e._v("+")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(' ("tr", _) => Descriptor::Tr(Tr::from_tree(top)?),\n')])]),t("span",{pre:!0,attrs:{class:"token unchanged"}},[t("span",{pre:!0,attrs:{class:"token prefix unchanged"}},[e._v(" ")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" _ => Descriptor::Bare(Bare::from_tree(top)?),\n")]),t("span",{pre:!0,attrs:{class:"token prefix unchanged"}},[e._v(" ")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" })\n")]),t("span",{pre:!0,attrs:{class:"token prefix unchanged"}},[e._v(" ")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" }\n")])]),e._v("diff --git a/src/expression.rs b/src/expression.rs\nindex 1cef614..11a68d3 100644\n"),t("span",{pre:!0,attrs:{class:"token coord"}},[e._v("--- a/src/expression.rs")]),e._v("\n"),t("span",{pre:!0,attrs:{class:"token coord"}},[e._v("+++ b/src/expression.rs")]),e._v("\n@@ -100,7 +100,12 @@ impl<'a> Tree<'a> {\n\n"),t("span",{pre:!0,attrs:{class:"token unchanged"}},[t("span",{pre:!0,attrs:{class:"token prefix unchanged"}},[e._v(" ")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" sl = &sl[n + 1..];\n")]),t("span",{pre:!0,attrs:{class:"token prefix unchanged"}},[e._v(" ")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" loop {\n")])]),t("span",{pre:!0,attrs:{class:"token deleted-sign deleted"}},[t("span",{pre:!0,attrs:{class:"token prefix deleted"}},[e._v("-")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" let (arg, new_sl) = Tree::from_slice_helper_round(sl, depth + 1)?;\n")])]),t("span",{pre:!0,attrs:{class:"token inserted-sign inserted"}},[t("span",{pre:!0,attrs:{class:"token prefix inserted"}},[e._v("+")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" let (arg, new_sl) = if sl.contains('{') {\n")]),t("span",{pre:!0,attrs:{class:"token prefix inserted"}},[e._v("+")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" Tree::from_slice_helper_curly(sl, depth + 1)?\n")]),t("span",{pre:!0,attrs:{class:"token prefix inserted"}},[e._v("+")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" } else {\n")]),t("span",{pre:!0,attrs:{class:"token prefix inserted"}},[e._v("+")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" Tree::from_slice_helper_round(sl, depth + 1)?\n")]),t("span",{pre:!0,attrs:{class:"token prefix inserted"}},[e._v("+")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" };\n")]),t("span",{pre:!0,attrs:{class:"token prefix inserted"}},[e._v("+")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v("\n")])]),t("span",{pre:!0,attrs:{class:"token unchanged"}},[t("span",{pre:!0,attrs:{class:"token prefix unchanged"}},[e._v(" ")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" ret.args.push(arg);\n")])]),e._v("\n"),t("span",{pre:!0,attrs:{class:"token unchanged"}},[t("span",{pre:!0,attrs:{class:"token prefix unchanged"}},[e._v(" ")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" if new_sl.is_empty() {\n")])])])])]),t("p",[e._v("When trying to parse a descriptor (essentially turning a recursive string of "),t("code",[e._v("operator(args)")]),e._v(" into an abstract tree in memory) use a "),t("em",[e._v("curly-bracket-aware")]),e._v(" parser if there is one in the string.")]),e._v(" "),t("p",[e._v("The code to then build a "),t("code",[e._v("Tr")]),e._v(" struct given an "),t("code",[e._v("expression::Tree")]),e._v(" (and the "),t("code",[e._v("from_slice_helper_curly")]),e._v(" function) were already implemented, so it was just a matter of correctly\nbuilding the abstract tree by parsing curly brackets in descriptors.")]),e._v(" "),t("div",{staticClass:"language- extra-class"},[t("pre",{pre:!0,attrs:{class:"language-text"}},[t("code",[e._v("$ git show 3055cab\n")])])]),t("div",{staticClass:"language-diff extra-class"},[t("pre",{pre:!0,attrs:{class:"language-diff"}},[t("code",[e._v("commit 3055cabef8bd51eda344ce501b03c533fd367b4f\nAuthor: Alekos Filini \nDate: Sat Nov 13 14:26:30 2021 +0100\n\n"),t("span",{pre:!0,attrs:{class:"token unchanged"}},[t("span",{pre:!0,attrs:{class:"token prefix unchanged"}},[e._v(" ")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" Fix control block creation when satisfying `Tr`\n")])]),e._v("\ndiff --git a/src/descriptor/tr.rs b/src/descriptor/tr.rs\nindex 314c7f4..8487d56 100644\n"),t("span",{pre:!0,attrs:{class:"token coord"}},[e._v("--- a/src/descriptor/tr.rs")]),e._v("\n"),t("span",{pre:!0,attrs:{class:"token coord"}},[e._v("+++ b/src/descriptor/tr.rs")]),e._v("\n@@ -571,17 +571,14 @@ impl DescriptorTrait for Tr {\n"),t("span",{pre:!0,attrs:{class:"token unchanged"}},[t("span",{pre:!0,attrs:{class:"token prefix unchanged"}},[e._v(" ")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" } else {\n")]),t("span",{pre:!0,attrs:{class:"token prefix unchanged"}},[e._v(" ")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" let ver = LeafVersion::default();\n")]),t("span",{pre:!0,attrs:{class:"token prefix unchanged"}},[e._v(" ")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" let leaf_script = (ms.encode(), ver);\n")])]),t("span",{pre:!0,attrs:{class:"token deleted-sign deleted"}},[t("span",{pre:!0,attrs:{class:"token prefix deleted"}},[e._v("-")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" let control_block_set = spend_info\n")]),t("span",{pre:!0,attrs:{class:"token prefix deleted"}},[e._v("-")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" .as_script_map()\n")]),t("span",{pre:!0,attrs:{class:"token prefix deleted"}},[e._v("-")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" .get(&leaf_script)\n")]),t("span",{pre:!0,attrs:{class:"token prefix deleted"}},[e._v("-")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(' .expect("Control block must exist in script map for every known leaf");\n')])]),t("span",{pre:!0,attrs:{class:"token inserted-sign inserted"}},[t("span",{pre:!0,attrs:{class:"token prefix inserted"}},[e._v("+")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" // let control_block_set = spend_info\n")]),t("span",{pre:!0,attrs:{class:"token prefix inserted"}},[e._v("+")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" // .as_script_map()\n")]),t("span",{pre:!0,attrs:{class:"token prefix inserted"}},[e._v("+")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" // .get(&leaf_script)\n")]),t("span",{pre:!0,attrs:{class:"token prefix inserted"}},[e._v("+")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(' // .expect("Control block must exist in script map for every known leaf");\n')]),t("span",{pre:!0,attrs:{class:"token prefix inserted"}},[e._v("+")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(' let control_block = spend_info.control_block(&leaf_script).expect("Control block must exist in script map for every known leaf");\n')])]),t("span",{pre:!0,attrs:{class:"token unchanged"}},[t("span",{pre:!0,attrs:{class:"token prefix unchanged"}},[e._v(" ")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" wit.push(leaf_script.0.into_bytes()); // Push the leaf script\n")]),t("span",{pre:!0,attrs:{class:"token prefix unchanged"}},[e._v(" ")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" // There can be multiple control blocks for a (script, ver) pair\n")]),t("span",{pre:!0,attrs:{class:"token prefix unchanged"}},[e._v(" ")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" // Find the smallest one amongst those\n")])]),t("span",{pre:!0,attrs:{class:"token deleted-sign deleted"}},[t("span",{pre:!0,attrs:{class:"token prefix deleted"}},[e._v("-")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" let control_block = control_block_set\n")]),t("span",{pre:!0,attrs:{class:"token prefix deleted"}},[e._v("-")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" .iter()\n")]),t("span",{pre:!0,attrs:{class:"token prefix deleted"}},[e._v("-")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" .min_by(|x, y| x.as_inner().len().cmp(&y.as_inner().len()))\n")]),t("span",{pre:!0,attrs:{class:"token prefix deleted"}},[e._v("-")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(' .expect("Atleast one control must exist for a known leaf");\n')])]),t("span",{pre:!0,attrs:{class:"token unchanged"}},[t("span",{pre:!0,attrs:{class:"token prefix unchanged"}},[e._v(" ")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" wit.push(control_block.serialize());\n")]),t("span",{pre:!0,attrs:{class:"token prefix unchanged"}},[e._v(" ")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" // Finally, save the minimum\n")]),t("span",{pre:!0,attrs:{class:"token prefix unchanged"}},[e._v(" ")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" min_wit = Some(wit);\n")])]),e._v("\n")])])]),t("p",[e._v("This is where things get more interesting: this section of code builds the witness to satisfy a Taproot descriptor. In case of a script-spend, we need to prove that the script we are using had been committed\ninto the public key of our "),t("code",[e._v("P2TR")]),e._v(' input. We do this by adding a "control block", that contains data about the parity of the key, the leaf version used, and the merkle path from the leaf we are using to spend\nup to the merkle root, which is committed into the public key. Once again, this is explained very well in '),t("a",{attrs:{href:"https://github.com/bitcoin/bips/blob/master/bip-0341.mediawiki",target:"_blank",rel:"noopener noreferrer"}},[t("code",[e._v("BIP341")]),t("OutboundLink")],1),e._v(".")]),e._v(" "),t("p",[e._v("Before my patch the code was only getting the set of merkle paths that could lead from the root to the leaves that contain a given script. For context, the signature of "),t("code",[e._v("TaprootSpendInfo::as_script_map(&self)")]),e._v(" is:")]),e._v(" "),t("div",{staticClass:"language-rust extra-class"},[t("pre",{pre:!0,attrs:{class:"language-rust"}},[t("code",[t("span",{pre:!0,attrs:{class:"token comment"}},[e._v("/// Access the internal script map")]),e._v("\n"),t("span",{pre:!0,attrs:{class:"token keyword"}},[e._v("pub")]),e._v(" "),t("span",{pre:!0,attrs:{class:"token keyword"}},[e._v("fn")]),e._v(" "),t("span",{pre:!0,attrs:{class:"token function-definition function"}},[e._v("as_script_map")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v("(")]),t("span",{pre:!0,attrs:{class:"token operator"}},[e._v("&")]),t("span",{pre:!0,attrs:{class:"token keyword"}},[e._v("self")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(")")]),e._v(" "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v("->")]),e._v(" "),t("span",{pre:!0,attrs:{class:"token operator"}},[e._v("&")]),t("span",{pre:!0,attrs:{class:"token class-name"}},[e._v("BTreeMap")]),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 class-name"}},[e._v("Script")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(",")]),e._v(" "),t("span",{pre:!0,attrs:{class:"token class-name"}},[e._v("LeafVersion")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(")")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(",")]),e._v(" "),t("span",{pre:!0,attrs:{class:"token class-name"}},[e._v("BTreeSet")]),t("span",{pre:!0,attrs:{class:"token operator"}},[e._v("<")]),t("span",{pre:!0,attrs:{class:"token class-name"}},[e._v("TaprootMerkleBranch")]),t("span",{pre:!0,attrs:{class:"token operator"}},[e._v(">>")]),e._v(" "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v("{")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v("}")]),e._v("\n")])])]),t("p",[e._v('Then the code would look for the "shortest" path to that specific script, as it would save size in the final transaction (leaves that are more "deep" in the tree than others naturally have more hidden branches\nin their path to the root, and thus require a longer control block to reveal them all).')]),e._v(" "),t("p",[e._v("The issue here is that the "),t("code",[e._v("control_block")]),e._v(" variable is then serialized directly into the witness. But this is not a control block, it's just a set of merkle paths! A control block only has "),t("em",[e._v("one")]),e._v(" merkle path, and\nincludes the leaf version and the key parity bit.")]),e._v(" "),t("p",[e._v("Conveniently, the "),t("code",[e._v("TaprootSpendInfo")]),e._v(' struct also has this other method (I\'m including the implementation as well, because it shows that internally it does the same "trick" to find the shortest path):')]),e._v(" "),t("div",{staticClass:"language-rust extra-class"},[t("pre",{pre:!0,attrs:{class:"language-rust"}},[t("code",[t("span",{pre:!0,attrs:{class:"token comment"}},[e._v("/// Obtain a [`ControlBlock`] for particular script with the given version.")]),e._v("\n"),t("span",{pre:!0,attrs:{class:"token comment"}},[e._v("/// Returns [`None`] if the script is not contained in the [`TaprootSpendInfo`]")]),e._v("\n"),t("span",{pre:!0,attrs:{class:"token comment"}},[e._v("/// If there are multiple ControlBlocks possible, this returns the shortest one.")]),e._v("\n"),t("span",{pre:!0,attrs:{class:"token keyword"}},[e._v("pub")]),e._v(" "),t("span",{pre:!0,attrs:{class:"token keyword"}},[e._v("fn")]),e._v(" "),t("span",{pre:!0,attrs:{class:"token function-definition function"}},[e._v("control_block")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v("(")]),t("span",{pre:!0,attrs:{class:"token operator"}},[e._v("&")]),t("span",{pre:!0,attrs:{class:"token keyword"}},[e._v("self")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(",")]),e._v(" script_ver"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(":")]),e._v(" "),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 class-name"}},[e._v("Script")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(",")]),e._v(" "),t("span",{pre:!0,attrs:{class:"token class-name"}},[e._v("LeafVersion")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(")")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(")")]),e._v(" "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v("->")]),e._v(" "),t("span",{pre:!0,attrs:{class:"token class-name"}},[e._v("Option")]),t("span",{pre:!0,attrs:{class:"token operator"}},[e._v("<")]),t("span",{pre:!0,attrs:{class:"token class-name"}},[e._v("ControlBlock")]),t("span",{pre:!0,attrs:{class:"token operator"}},[e._v(">")]),e._v(" "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v("{")]),e._v("\n "),t("span",{pre:!0,attrs:{class:"token keyword"}},[e._v("let")]),e._v(" merkle_branch_set "),t("span",{pre:!0,attrs:{class:"token operator"}},[e._v("=")]),e._v(" "),t("span",{pre:!0,attrs:{class:"token keyword"}},[e._v("self")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(".")]),e._v("script_map"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(".")]),t("span",{pre:!0,attrs:{class:"token function"}},[e._v("get")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v("(")]),e._v("script_ver"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(")")]),t("span",{pre:!0,attrs:{class:"token operator"}},[e._v("?")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(";")]),e._v("\n "),t("span",{pre:!0,attrs:{class:"token comment"}},[e._v("// Choose the smallest one amongst the multiple script maps")]),e._v("\n "),t("span",{pre:!0,attrs:{class:"token keyword"}},[e._v("let")]),e._v(" smallest "),t("span",{pre:!0,attrs:{class:"token operator"}},[e._v("=")]),e._v(" merkle_branch_set\n "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(".")]),t("span",{pre:!0,attrs:{class:"token function"}},[e._v("iter")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v("(")]),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 function"}},[e._v("min_by")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v("(")]),t("span",{pre:!0,attrs:{class:"token closure-params"}},[t("span",{pre:!0,attrs:{class:"token closure-punctuation punctuation"}},[e._v("|")]),e._v("x"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(",")]),e._v(" y"),t("span",{pre:!0,attrs:{class:"token closure-punctuation punctuation"}},[e._v("|")])]),e._v(" x"),t("span",{pre:!0,attrs:{class:"token number"}},[e._v(".0")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(".")]),t("span",{pre:!0,attrs:{class:"token function"}},[e._v("len")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v("(")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(")")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(".")]),t("span",{pre:!0,attrs:{class:"token function"}},[e._v("cmp")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v("(")]),t("span",{pre:!0,attrs:{class:"token operator"}},[e._v("&")]),e._v("y"),t("span",{pre:!0,attrs:{class:"token number"}},[e._v(".0")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(".")]),t("span",{pre:!0,attrs:{class:"token function"}},[e._v("len")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v("(")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(")")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(")")]),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 function"}},[e._v("expect")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v("(")]),t("span",{pre:!0,attrs:{class:"token string"}},[e._v('"Non-empty iterator"')]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(")")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(";")]),e._v("\n "),t("span",{pre:!0,attrs:{class:"token class-name"}},[e._v("Some")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v("(")]),t("span",{pre:!0,attrs:{class:"token class-name"}},[e._v("ControlBlock")]),e._v(" "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v("{")]),e._v("\n internal_key"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(":")]),e._v(" "),t("span",{pre:!0,attrs:{class:"token keyword"}},[e._v("self")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(".")]),e._v("internal_key"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(",")]),e._v("\n output_key_parity"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(":")]),e._v(" "),t("span",{pre:!0,attrs:{class:"token keyword"}},[e._v("self")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(".")]),e._v("output_key_parity"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(",")]),e._v("\n leaf_version"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(":")]),e._v(" "),t("span",{pre:!0,attrs:{class:"token class-name"}},[e._v("LeafVersion")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v("::")]),t("span",{pre:!0,attrs:{class:"token function"}},[e._v("default")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v("(")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(")")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(",")]),e._v("\n merkle_branch"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(":")]),e._v(" smallest"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(".")]),t("span",{pre:!0,attrs:{class:"token function"}},[e._v("clone")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v("(")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(")")]),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 punctuation"}},[e._v(")")]),e._v("\n"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v("}")]),e._v("\n")])])]),t("p",[e._v("So to fix this code we just have to use that method instead, and we can get it done in one single line!")]),e._v(" "),t("p",[e._v('Instead of removing the old code at the time I only commented it out, because I initially thought I would still have to look for the shortest script myself, and I figured the "sorting" code would come in handy\nlater on.')]),e._v(" "),t("p",[e._v("Also, if you are an acute observer, you might have noticed that there's a bug in this last snippet of code. Feel free to think about it a little bit, then check out the "),t("a",{attrs:{href:"https://github.com/rust-bitcoin/rust-bitcoin/pull/703",target:"_blank",rel:"noopener noreferrer"}},[e._v("PR"),t("OutboundLink")],1),e._v(" I made\nif you wanna know the answer!")]),e._v(" "),t("div",{staticClass:"language- extra-class"},[t("pre",{pre:!0,attrs:{class:"language-text"}},[t("code",[e._v("git show 35378ad\n")])])]),t("div",{staticClass:"language-diff extra-class"},[t("pre",{pre:!0,attrs:{class:"language-diff"}},[t("code",[e._v("commit 35378ad01a6f2b8161a3f36448b24d031f8aeaec\nAuthor: Alekos Filini \nDate: Sat Nov 13 14:27:14 2021 +0100\n\n"),t("span",{pre:!0,attrs:{class:"token unchanged"}},[t("span",{pre:!0,attrs:{class:"token prefix unchanged"}},[e._v(" ")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" Consider key-spend max satisfaction weight\n")])]),e._v("\ndiff --git a/src/descriptor/tr.rs b/src/descriptor/tr.rs\nindex 8487d56..fabf860 100644\n"),t("span",{pre:!0,attrs:{class:"token coord"}},[e._v("--- a/src/descriptor/tr.rs")]),e._v("\n"),t("span",{pre:!0,attrs:{class:"token coord"}},[e._v("+++ b/src/descriptor/tr.rs")]),e._v("\n@@ -593,7 +593,7 @@ impl DescriptorTrait for Tr {\n"),t("span",{pre:!0,attrs:{class:"token unchanged"}},[t("span",{pre:!0,attrs:{class:"token prefix unchanged"}},[e._v(" ")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" }\n")])]),e._v("\n"),t("span",{pre:!0,attrs:{class:"token unchanged"}},[t("span",{pre:!0,attrs:{class:"token prefix unchanged"}},[e._v(" ")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" fn max_satisfaction_weight(&self) -> Result {\n")])]),t("span",{pre:!0,attrs:{class:"token deleted-sign deleted"}},[t("span",{pre:!0,attrs:{class:"token prefix deleted"}},[e._v("-")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" let mut max_wieght = None;\n")])]),t("span",{pre:!0,attrs:{class:"token inserted-sign inserted"}},[t("span",{pre:!0,attrs:{class:"token prefix inserted"}},[e._v("+")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" let mut max_wieght = Some(65);\n")])]),t("span",{pre:!0,attrs:{class:"token unchanged"}},[t("span",{pre:!0,attrs:{class:"token prefix unchanged"}},[e._v(" ")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" for (depth, ms) in self.iter_scripts() {\n")]),t("span",{pre:!0,attrs:{class:"token prefix unchanged"}},[e._v(" ")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" let script_size = ms.script_size();\n")]),t("span",{pre:!0,attrs:{class:"token prefix unchanged"}},[e._v(" ")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" let max_sat_elems = match ms.max_satisfaction_witness_elements() {\n")])])])])]),t("p",[e._v("This is a little bug in the code that tries to compute what the maximum satisfaction weight would be for a descriptor. For instance, we use this in BDK to compute how many extra sats of fees we need to pay\nin order to target a given fee rate, assuming the descriptor is satisfied with the worst (larger and most expensive) path.")]),e._v(" "),t("p",[e._v("For Taproot descriptors, it's just a matter of iterating over the leaves in the tree and pick the most expensive one... or is it? This doesn't take into account that Taproot outputs can also be spent with\nkey-spend, which means just pushing a signature to the witness. This signature is 64 bytes long when using the new "),t("a",{attrs:{href:"https://github.com/bitcoin/bips/blob/master/bip-0341.mediawiki",target:"_blank",rel:"noopener noreferrer"}},[t("code",[e._v("SIGHASH_DEFAULT")]),t("OutboundLink")],1),e._v(" sighash, or 65 otherwise. Since we are thinking about the maximum satisfaction\nweight, or the worst case possible, we naturally pick the latter.")]),e._v(" "),t("p",[e._v("Note that theoretically you could build a Taproot address \"without\" an available key-path spend (by using an unspendable Schnorr public key), but the code here in rust-miniscript doesn't take that into\naccount, as there's no way that I'm aware of to specificy in a "),t("code",[e._v("tr()")]),e._v(" descriptor that the key is unspendable. So, while theoretically here we should first check whether the key-spend path is available before\naccounting for its weight, in practice this is always true in miniscript so we just use that as our starting worst case and update it later if necessary while iterating the tree leaves.")]),e._v(" "),t("div",{staticClass:"language- extra-class"},[t("pre",{pre:!0,attrs:{class:"language-text"}},[t("code",[e._v("$ git show b4878f8\n")])])]),t("div",{staticClass:"language-diff extra-class"},[t("pre",{pre:!0,attrs:{class:"language-diff"}},[t("code",[e._v("commit b4878f816e9ede11d5ed947c06e03aa988e3e26f\nAuthor: Alekos Filini \nDate: Sat Nov 13 14:27:53 2021 +0100\n\n"),t("span",{pre:!0,attrs:{class:"token unchanged"}},[t("span",{pre:!0,attrs:{class:"token prefix unchanged"}},[e._v(" ")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" Look for taproot stuff in psbts\n")])]),e._v("\ndiff --git a/src/psbt/mod.rs b/src/psbt/mod.rs\nindex 9a8b17d..42c6ce8 100644\n"),t("span",{pre:!0,attrs:{class:"token coord"}},[e._v("--- a/src/psbt/mod.rs")]),e._v("\n"),t("span",{pre:!0,attrs:{class:"token coord"}},[e._v("+++ b/src/psbt/mod.rs")]),e._v("\n@@ -25,13 +25,14 @@ use bitcoin;\n"),t("span",{pre:!0,attrs:{class:"token unchanged"}},[t("span",{pre:!0,attrs:{class:"token prefix unchanged"}},[e._v(" ")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v("use bitcoin::hashes::{hash160, ripemd160, sha256, sha256d};\n")]),t("span",{pre:!0,attrs:{class:"token prefix unchanged"}},[e._v(" ")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v("use bitcoin::secp256k1::{self, Secp256k1};\n")]),t("span",{pre:!0,attrs:{class:"token prefix unchanged"}},[e._v(" ")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v("use bitcoin::util::psbt::PartiallySignedTransaction as Psbt;\n")])]),t("span",{pre:!0,attrs:{class:"token inserted-sign inserted"}},[t("span",{pre:!0,attrs:{class:"token prefix inserted"}},[e._v("+")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v("use bitcoin::util::taproot::TapLeafHash;\n")])]),t("span",{pre:!0,attrs:{class:"token unchanged"}},[t("span",{pre:!0,attrs:{class:"token prefix unchanged"}},[e._v(" ")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v("use bitcoin::Script;\n")])]),e._v("\n"),t("span",{pre:!0,attrs:{class:"token unchanged"}},[t("span",{pre:!0,attrs:{class:"token prefix unchanged"}},[e._v(" ")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v("use interpreter;\n")]),t("span",{pre:!0,attrs:{class:"token prefix unchanged"}},[e._v(" ")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v("use miniscript::limits::SEQUENCE_LOCKTIME_DISABLE_FLAG;\n")]),t("span",{pre:!0,attrs:{class:"token prefix unchanged"}},[e._v(" ")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v("use miniscript::satisfy::{After, Older};\n")]),t("span",{pre:!0,attrs:{class:"token prefix unchanged"}},[e._v(" ")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v("use Satisfier;\n")])]),t("span",{pre:!0,attrs:{class:"token deleted-sign deleted"}},[t("span",{pre:!0,attrs:{class:"token prefix deleted"}},[e._v("-")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v("use {BitcoinECSig, Preimage32};\n")])]),t("span",{pre:!0,attrs:{class:"token inserted-sign inserted"}},[t("span",{pre:!0,attrs:{class:"token prefix inserted"}},[e._v("+")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v("use {BitcoinECSig, BitcoinSchnorrSig, Preimage32};\n")])]),t("span",{pre:!0,attrs:{class:"token unchanged"}},[t("span",{pre:!0,attrs:{class:"token prefix unchanged"}},[e._v(" ")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v("use {MiniscriptKey, ToPublicKey};\n")])]),e._v("\n"),t("span",{pre:!0,attrs:{class:"token unchanged"}},[t("span",{pre:!0,attrs:{class:"token prefix unchanged"}},[e._v(" ")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v("mod finalizer;\n")])]),e._v("@@ -231,6 +232,24 @@ impl<'psbt> PsbtInputSatisfier<'psbt> {\n"),t("span",{pre:!0,attrs:{class:"token unchanged"}},[t("span",{pre:!0,attrs:{class:"token prefix unchanged"}},[e._v(" ")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v("}\n")])]),e._v("\n"),t("span",{pre:!0,attrs:{class:"token unchanged"}},[t("span",{pre:!0,attrs:{class:"token prefix unchanged"}},[e._v(" ")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v("impl<'psbt, Pk: MiniscriptKey + ToPublicKey> Satisfier for PsbtInputSatisfier<'psbt> {\n")])]),t("span",{pre:!0,attrs:{class:"token inserted-sign inserted"}},[t("span",{pre:!0,attrs:{class:"token prefix inserted"}},[e._v("+")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" fn lookup_tap_key_spend_sig(&self) -> Option {\n")]),t("span",{pre:!0,attrs:{class:"token prefix inserted"}},[e._v("+")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" if let Some((sig, hash_ty)) = self.psbt.inputs[self.index].tap_key_sig {\n")]),t("span",{pre:!0,attrs:{class:"token prefix inserted"}},[e._v("+")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" Some(BitcoinSchnorrSig { sig, hash_ty })\n")]),t("span",{pre:!0,attrs:{class:"token prefix inserted"}},[e._v("+")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" } else {\n")]),t("span",{pre:!0,attrs:{class:"token prefix inserted"}},[e._v("+")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" None\n")]),t("span",{pre:!0,attrs:{class:"token prefix inserted"}},[e._v("+")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" }\n")]),t("span",{pre:!0,attrs:{class:"token prefix inserted"}},[e._v("+")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" }\n")]),t("span",{pre:!0,attrs:{class:"token prefix inserted"}},[e._v("+")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v("\n")]),t("span",{pre:!0,attrs:{class:"token prefix inserted"}},[e._v("+")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" fn lookup_tap_leaf_script_sig(&self, pk: &Pk, lh: &TapLeafHash) -> Option {\n")]),t("span",{pre:!0,attrs:{class:"token prefix inserted"}},[e._v("+")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" let pk = pk.to_x_only_pubkey();\n")]),t("span",{pre:!0,attrs:{class:"token prefix inserted"}},[e._v("+")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v("\n")]),t("span",{pre:!0,attrs:{class:"token prefix inserted"}},[e._v("+")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" if let Some((sig, hash_ty)) = self.psbt.inputs[self.index].tap_script_sigs.get(&(pk, *lh)) {\n")]),t("span",{pre:!0,attrs:{class:"token prefix inserted"}},[e._v("+")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" Some(BitcoinSchnorrSig { sig: *sig, hash_ty: *hash_ty })\n")]),t("span",{pre:!0,attrs:{class:"token prefix inserted"}},[e._v("+")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" } else {\n")]),t("span",{pre:!0,attrs:{class:"token prefix inserted"}},[e._v("+")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" None\n")]),t("span",{pre:!0,attrs:{class:"token prefix inserted"}},[e._v("+")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" }\n")]),t("span",{pre:!0,attrs:{class:"token prefix inserted"}},[e._v("+")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" }\n")]),t("span",{pre:!0,attrs:{class:"token prefix inserted"}},[e._v("+")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v("\n")])]),t("span",{pre:!0,attrs:{class:"token unchanged"}},[t("span",{pre:!0,attrs:{class:"token prefix unchanged"}},[e._v(" ")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" fn lookup_ec_sig(&self, pk: &Pk) -> Option {\n")]),t("span",{pre:!0,attrs:{class:"token prefix unchanged"}},[e._v(" ")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" if let Some(rawsig) = self.psbt.inputs[self.index]\n")]),t("span",{pre:!0,attrs:{class:"token prefix unchanged"}},[e._v(" ")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" .partial_sigs\n")])])])])]),t("p",[e._v("This commit implements the Taproot-specific "),t("code",[e._v("Satisfier")]),e._v(" methods on "),t("code",[e._v("PsbtInputSatisfier")]),e._v(". The code to produce a valid witness (i.e. "),t("em",[e._v("satisfy")]),e._v(") a descriptor by looking for Taproot key-spend or script-spend signatures\nis already implemented, so it's just a matter of actually returning those, if they are present in a PSBT.")]),e._v(" "),t("div",{staticClass:"language- extra-class"},[t("pre",{pre:!0,attrs:{class:"language-text"}},[t("code",[e._v("$ git show 80da0ba\n")])])]),t("div",{staticClass:"language-diff extra-class"},[t("pre",{pre:!0,attrs:{class:"language-diff"}},[t("code",[e._v("commit 80da0ba9b742b2dee23e7302e2f95a6e96b1d6ed\nAuthor: Alekos Filini \nDate: Sat Nov 13 16:54:27 2021 +0100\n\n"),t("span",{pre:!0,attrs:{class:"token unchanged"}},[t("span",{pre:!0,attrs:{class:"token prefix unchanged"}},[e._v(" ")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" Iter keys in `MultiA`\n")])]),e._v("\ndiff --git a/src/miniscript/iter.rs b/src/miniscript/iter.rs\nindex 36c4b69..a54a371 100644\n"),t("span",{pre:!0,attrs:{class:"token coord"}},[e._v("--- a/src/miniscript/iter.rs")]),e._v("\n"),t("span",{pre:!0,attrs:{class:"token coord"}},[e._v("+++ b/src/miniscript/iter.rs")]),e._v("\n@@ -121,7 +121,7 @@ impl Miniscript {\n"),t("span",{pre:!0,attrs:{class:"token unchanged"}},[t("span",{pre:!0,attrs:{class:"token prefix unchanged"}},[e._v(" ")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" pub fn get_leaf_pk(&self) -> Vec {\n")]),t("span",{pre:!0,attrs:{class:"token prefix unchanged"}},[e._v(" ")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" match self.node {\n")]),t("span",{pre:!0,attrs:{class:"token prefix unchanged"}},[e._v(" ")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" Terminal::PkK(ref key) => vec![key.clone()],\n")])]),t("span",{pre:!0,attrs:{class:"token deleted-sign deleted"}},[t("span",{pre:!0,attrs:{class:"token prefix deleted"}},[e._v("-")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" Terminal::Multi(_, ref keys) => keys.clone(),\n")])]),t("span",{pre:!0,attrs:{class:"token inserted-sign inserted"}},[t("span",{pre:!0,attrs:{class:"token prefix inserted"}},[e._v("+")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" Terminal::Multi(_, ref keys) | Terminal::MultiA(_, ref keys) => keys.clone(),\n")])]),t("span",{pre:!0,attrs:{class:"token unchanged"}},[t("span",{pre:!0,attrs:{class:"token prefix unchanged"}},[e._v(" ")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" _ => vec![],\n")]),t("span",{pre:!0,attrs:{class:"token prefix unchanged"}},[e._v(" ")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" }\n")]),t("span",{pre:!0,attrs:{class:"token prefix unchanged"}},[e._v(" ")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" }\n")])]),e._v("@@ -139,7 +139,7 @@ impl Miniscript {\n"),t("span",{pre:!0,attrs:{class:"token unchanged"}},[t("span",{pre:!0,attrs:{class:"token prefix unchanged"}},[e._v(" ")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" match self.node {\n")]),t("span",{pre:!0,attrs:{class:"token prefix unchanged"}},[e._v(" ")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" Terminal::PkH(ref hash) => vec![hash.clone()],\n")]),t("span",{pre:!0,attrs:{class:"token prefix unchanged"}},[e._v(" ")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" Terminal::PkK(ref key) => vec![key.to_pubkeyhash()],\n")])]),t("span",{pre:!0,attrs:{class:"token deleted-sign deleted"}},[t("span",{pre:!0,attrs:{class:"token prefix deleted"}},[e._v("-")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" Terminal::Multi(_, ref keys) => keys.iter().map(Pk::to_pubkeyhash).collect(),\n")])]),t("span",{pre:!0,attrs:{class:"token inserted-sign inserted"}},[t("span",{pre:!0,attrs:{class:"token prefix inserted"}},[e._v("+")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" Terminal::Multi(_, ref keys) | Terminal::MultiA(_, ref keys) => keys.iter().map(Pk::to_pubkeyhash).collect(),\n")])]),t("span",{pre:!0,attrs:{class:"token unchanged"}},[t("span",{pre:!0,attrs:{class:"token prefix unchanged"}},[e._v(" ")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" _ => vec![],\n")]),t("span",{pre:!0,attrs:{class:"token prefix unchanged"}},[e._v(" ")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" }\n")]),t("span",{pre:!0,attrs:{class:"token prefix unchanged"}},[e._v(" ")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" }\n")])]),e._v("@@ -155,7 +155,7 @@ impl Miniscript {\n"),t("span",{pre:!0,attrs:{class:"token unchanged"}},[t("span",{pre:!0,attrs:{class:"token prefix unchanged"}},[e._v(" ")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" match self.node {\n")]),t("span",{pre:!0,attrs:{class:"token prefix unchanged"}},[e._v(" ")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" Terminal::PkH(ref hash) => vec![PkPkh::HashedPubkey(hash.clone())],\n")]),t("span",{pre:!0,attrs:{class:"token prefix unchanged"}},[e._v(" ")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" Terminal::PkK(ref key) => vec![PkPkh::PlainPubkey(key.clone())],\n")])]),t("span",{pre:!0,attrs:{class:"token deleted-sign deleted"}},[t("span",{pre:!0,attrs:{class:"token prefix deleted"}},[e._v("-")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" Terminal::Multi(_, ref keys) => keys\n")])]),t("span",{pre:!0,attrs:{class:"token inserted-sign inserted"}},[t("span",{pre:!0,attrs:{class:"token prefix inserted"}},[e._v("+")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" Terminal::Multi(_, ref keys) | Terminal::MultiA(_, ref keys) => keys\n")])]),t("span",{pre:!0,attrs:{class:"token unchanged"}},[t("span",{pre:!0,attrs:{class:"token prefix unchanged"}},[e._v(" ")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" .into_iter()\n")]),t("span",{pre:!0,attrs:{class:"token prefix unchanged"}},[e._v(" ")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" .map(|key| PkPkh::PlainPubkey(key.clone()))\n")]),t("span",{pre:!0,attrs:{class:"token prefix unchanged"}},[e._v(" ")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" .collect(),\n")])]),e._v("@@ -170,7 +170,7 @@ impl Miniscript {\n"),t("span",{pre:!0,attrs:{class:"token unchanged"}},[t("span",{pre:!0,attrs:{class:"token prefix unchanged"}},[e._v(" ")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" pub fn get_nth_pk(&self, n: usize) -> Option {\n")]),t("span",{pre:!0,attrs:{class:"token prefix unchanged"}},[e._v(" ")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" match (&self.node, n) {\n")]),t("span",{pre:!0,attrs:{class:"token prefix unchanged"}},[e._v(" ")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" (&Terminal::PkK(ref key), 0) => Some(key.clone()),\n")])]),t("span",{pre:!0,attrs:{class:"token deleted-sign deleted"}},[t("span",{pre:!0,attrs:{class:"token prefix deleted"}},[e._v("-")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" (&Terminal::Multi(_, ref keys), _) => keys.get(n).cloned(),\n")])]),t("span",{pre:!0,attrs:{class:"token inserted-sign inserted"}},[t("span",{pre:!0,attrs:{class:"token prefix inserted"}},[e._v("+")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" (&Terminal::Multi(_, ref keys), _) | (&Terminal::MultiA(_, ref keys), _) => keys.get(n).cloned(),\n")])]),t("span",{pre:!0,attrs:{class:"token unchanged"}},[t("span",{pre:!0,attrs:{class:"token prefix unchanged"}},[e._v(" ")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" _ => None,\n")]),t("span",{pre:!0,attrs:{class:"token prefix unchanged"}},[e._v(" ")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" }\n")]),t("span",{pre:!0,attrs:{class:"token prefix unchanged"}},[e._v(" ")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" }\n")])]),e._v("@@ -186,7 +186,7 @@ impl Miniscript {\n"),t("span",{pre:!0,attrs:{class:"token unchanged"}},[t("span",{pre:!0,attrs:{class:"token prefix unchanged"}},[e._v(" ")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" match (&self.node, n) {\n")]),t("span",{pre:!0,attrs:{class:"token prefix unchanged"}},[e._v(" ")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" (&Terminal::PkH(ref hash), 0) => Some(hash.clone()),\n")]),t("span",{pre:!0,attrs:{class:"token prefix unchanged"}},[e._v(" ")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" (&Terminal::PkK(ref key), 0) => Some(key.to_pubkeyhash()),\n")])]),t("span",{pre:!0,attrs:{class:"token deleted-sign deleted"}},[t("span",{pre:!0,attrs:{class:"token prefix deleted"}},[e._v("-")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" (&Terminal::Multi(_, ref keys), _) => keys.get(n).map(Pk::to_pubkeyhash),\n")])]),t("span",{pre:!0,attrs:{class:"token inserted-sign inserted"}},[t("span",{pre:!0,attrs:{class:"token prefix inserted"}},[e._v("+")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" (&Terminal::Multi(_, ref keys), _) | (&Terminal::MultiA(_, ref keys), _) => keys.get(n).map(Pk::to_pubkeyhash),\n")])]),t("span",{pre:!0,attrs:{class:"token unchanged"}},[t("span",{pre:!0,attrs:{class:"token prefix unchanged"}},[e._v(" ")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" _ => None,\n")]),t("span",{pre:!0,attrs:{class:"token prefix unchanged"}},[e._v(" ")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" }\n")]),t("span",{pre:!0,attrs:{class:"token prefix unchanged"}},[e._v(" ")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" }\n")])]),e._v("@@ -199,7 +199,7 @@ impl Miniscript {\n"),t("span",{pre:!0,attrs:{class:"token unchanged"}},[t("span",{pre:!0,attrs:{class:"token prefix unchanged"}},[e._v(" ")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" match (&self.node, n) {\n")]),t("span",{pre:!0,attrs:{class:"token prefix unchanged"}},[e._v(" ")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" (&Terminal::PkH(ref hash), 0) => Some(PkPkh::HashedPubkey(hash.clone())),\n")]),t("span",{pre:!0,attrs:{class:"token prefix unchanged"}},[e._v(" ")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" (&Terminal::PkK(ref key), 0) => Some(PkPkh::PlainPubkey(key.clone())),\n")])]),t("span",{pre:!0,attrs:{class:"token deleted-sign deleted"}},[t("span",{pre:!0,attrs:{class:"token prefix deleted"}},[e._v("-")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" (&Terminal::Multi(_, ref keys), _) => {\n")])]),t("span",{pre:!0,attrs:{class:"token inserted-sign inserted"}},[t("span",{pre:!0,attrs:{class:"token prefix inserted"}},[e._v("+")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" (&Terminal::Multi(_, ref keys), _) | (&Terminal::MultiA(_, ref keys), _) => {\n")])]),t("span",{pre:!0,attrs:{class:"token unchanged"}},[t("span",{pre:!0,attrs:{class:"token prefix unchanged"}},[e._v(" ")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" keys.get(n).map(|key| PkPkh::PlainPubkey(key.clone()))\n")]),t("span",{pre:!0,attrs:{class:"token prefix unchanged"}},[e._v(" ")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" }\n")]),t("span",{pre:!0,attrs:{class:"token prefix unchanged"}},[e._v(" ")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" _ => None,\n")])])])])]),t("p",[e._v("Taproot descriptors add a new miniscript operator called "),t("code",[e._v("multi_a()")]),e._v(" which behaves like "),t("code",[e._v("multi()")]),e._v(" in non-Taproot descriptors, but uses the new "),t("a",{attrs:{href:"https://github.com/bitcoin/bips/blob/master/bip-0342.mediawiki#script-execution",target:"_blank",rel:"noopener noreferrer"}},[t("code",[e._v("OP_CHECKSIGADD")]),t("OutboundLink")],1),e._v(" opcode when serialized in a script.")]),e._v(" "),t("p",[e._v("When this was added, somebody forgot to update the various methods that iterate over the public keys of a descriptor to correctly return the keys contained in "),t("code",[e._v("multi_a()")]),e._v(" - essentially, it was falling back in\nthe default case used by the operators that don't contain any key, but this one does!")]),e._v(" "),t("div",{staticClass:"language- extra-class"},[t("pre",{pre:!0,attrs:{class:"language-text"}},[t("code",[e._v("$ git show 8b108c5\n")])])]),t("div",{staticClass:"language-diff extra-class"},[t("pre",{pre:!0,attrs:{class:"language-diff"}},[t("code",[e._v("commit 8b108c5c0bf50b66b7220746525742b71f6cd4b4\nAuthor: Alekos Filini \nDate: Sat Nov 13 17:26:53 2021 +0100\n\n"),t("span",{pre:!0,attrs:{class:"token unchanged"}},[t("span",{pre:!0,attrs:{class:"token prefix unchanged"}},[e._v(" ")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" Fix witness generation for `MultiA`\n")])]),e._v("\ndiff --git a/src/miniscript/satisfy.rs b/src/miniscript/satisfy.rs\nindex 655436e..ab43707 100644\n"),t("span",{pre:!0,attrs:{class:"token coord"}},[e._v("--- a/src/miniscript/satisfy.rs")]),e._v("\n"),t("span",{pre:!0,attrs:{class:"token coord"}},[e._v("+++ b/src/miniscript/satisfy.rs")]),e._v("\n@@ -1264,7 +1264,7 @@ impl Satisfaction {\n"),t("span",{pre:!0,attrs:{class:"token unchanged"}},[t("span",{pre:!0,attrs:{class:"token prefix unchanged"}},[e._v(" ")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" // Collect all available signatures\n")]),t("span",{pre:!0,attrs:{class:"token prefix unchanged"}},[e._v(" ")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" let mut sig_count = 0;\n")]),t("span",{pre:!0,attrs:{class:"token prefix unchanged"}},[e._v(" ")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" let mut sigs = vec![vec![vec![]]; keys.len()];\n")])]),t("span",{pre:!0,attrs:{class:"token deleted-sign deleted"}},[t("span",{pre:!0,attrs:{class:"token prefix deleted"}},[e._v("-")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" for (i, pk) in keys.iter().enumerate() {\n")])]),t("span",{pre:!0,attrs:{class:"token inserted-sign inserted"}},[t("span",{pre:!0,attrs:{class:"token prefix inserted"}},[e._v("+")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" for (i, pk) in keys.iter().rev().enumerate() {\n")])]),t("span",{pre:!0,attrs:{class:"token unchanged"}},[t("span",{pre:!0,attrs:{class:"token prefix unchanged"}},[e._v(" ")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" match Witness::signature::<_, _, Ctx>(stfr, pk, leaf_hash) {\n")]),t("span",{pre:!0,attrs:{class:"token prefix unchanged"}},[e._v(" ")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" Witness::Stack(sig) => {\n")]),t("span",{pre:!0,attrs:{class:"token prefix unchanged"}},[e._v(" ")]),t("span",{pre:!0,attrs:{class:"token line"}},[e._v(" sigs[i] = sig;\n")])])])])]),t("p",[e._v("And finally, the last little fix: the "),t("code",[e._v("multi_a()")]),e._v(" operator is satisfied by pushing to the witness either a signature (if you have one available for that specific public key) or an empty vector. The problem is,\nthey have to be in the right order to match the order of public keys in your Taproot script.")]),e._v(" "),t("p",[e._v("rust-miniscript was pushing them in reverse order, so script validation was always failing for multisigs that had more than 1 key. Adding a "),t("code",[e._v(".rev()")]),e._v(" to the iterator fixed the issue.")]),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("And that was it! We now have a fully working "),t("a",{attrs:{href:"https://github.com/rust-bitcoin/rust-bitcoin",target:"_blank",rel:"noopener noreferrer"}},[e._v("rust-bitcoin"),t("OutboundLink")],1),e._v(" and "),t("a",{attrs:{href:"https://github.com/rust-bitcoin/rust-miniscript",target:"_blank",rel:"noopener noreferrer"}},[e._v("rust-miniscript"),t("OutboundLink")],1),e._v(" ready for Taproot.")]),e._v(" "),t("p",[e._v("In "),t("a",{attrs:{href:"/blog/2021/12/first-bdk-taproot-tx-look-at-the-code-part-2"}},[e._v("Part 2")]),e._v(" I will go over the code changes in BDK, but I think it's now time for you and I to take a break 😃")])])}),[],!1,null,null,null);t.default=a.exports}}]); \ No newline at end of file diff --git a/assets/js/60.b17bda16.js b/assets/js/60.915a8300.js similarity index 99% rename from assets/js/60.b17bda16.js rename to assets/js/60.915a8300.js index 0c2fcd1bc7..271974b97b 100644 --- a/assets/js/60.b17bda16.js +++ b/assets/js/60.915a8300.js @@ -1 +1 @@ -(window.webpackJsonp=window.webpackJsonp||[]).push([[60],{418:function(t,s,e){"use strict";e.r(s);var a=e(7),n=Object(a.a)({},(function(){var t=this,s=t._self._c;return s("ContentSlotsDistributor",{attrs:{"slot-key":t.$parent.slotKey}},[s("p",[t._v("This is the second part of a two-part blog series in which I talk through the changes made to BDK to make a Taproot transaction. If you haven't read it yet, check out "),s("a",{attrs:{href:"/blog/2021/11/first-bdk-taproot-tx-look-at-the-code-part-1"}},[t._v("Part 1")]),t._v(".")]),t._v(" "),s("p",[t._v("While in the first part I managed to show full raw commits, in this case I will only focus on the relevant changes, otherwise the post would get very long. You can always find the "),s("a",{attrs:{href:"https://github.com/bitcoindevkit/bdk/compare/aa075f0...afilini:taproot-testing",target:"_blank",rel:"noopener noreferrer"}},[t._v("full diff"),s("OutboundLink")],1),t._v(" here, if you are interested\nin that.")]),t._v(" "),s("h2",{attrs:{id:"shortcuts"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#shortcuts"}},[t._v("#")]),t._v(" Shortcuts")]),t._v(" "),s("p",[t._v("As mentioned previously, the main goal of this journey for me was to find out what it really takes to support Taproot in BDK. The code shown here wasn't written to be readable and/or maintainable, so\nsome shortcuts were taken, in particular:")]),t._v(" "),s("ul",[s("li",[t._v('No support for BIP32 extended keys: this is probably very quick to add, but in the first "proof of concept" I decided to only work with WIF keys for simplicity')]),t._v(" "),s("li",[t._v("No support for "),s("a",{attrs:{href:"https://github.com/bitcoin/bips/blob/master/bip-0341.mediawiki",target:"_blank",rel:"noopener noreferrer"}},[s("code",[t._v("SIGHASH_DEFAULT")]),s("OutboundLink")],1),t._v(': this would require some minor changes to a few traits in BDK that still use the "legacy" '),s("code",[t._v("SigHashType")]),t._v(" enum from "),s("a",{attrs:{href:"https://github.com/rust-bitcoin/rust-bitcoin",target:"_blank",rel:"noopener noreferrer"}},[t._v("rust-bitcoin"),s("OutboundLink")],1)])]),t._v(" "),s("h2",{attrs:{id:"utilities"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#utilities"}},[t._v("#")]),t._v(" Utilities")]),t._v(" "),s("p",[t._v("Let's start with some utilities:")]),t._v(" "),s("div",{staticClass:"language-rust extra-class"},[s("pre",{pre:!0,attrs:{class:"language-rust"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("pub")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("fn")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function-definition function"}},[t._v("ecdsa_to_schnorr")]),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(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),s("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("ecdsa"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")])]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("PublicKey")]),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 namespace"}},[t._v("schnorr"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")])]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("PublicKey")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("schnorr"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")])]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("PublicKey")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("from_slice")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),t._v("pk"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("to_bytes")]),s("span",{pre:!0,attrs:{class:"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 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 punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("expect")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Key conversion failure"')]),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("pub")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("fn")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function-definition function"}},[t._v("compute_merkle_root")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n leaf_hash"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),s("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("taproot"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")])]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("TapLeafHash")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n control_block"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),s("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("taproot"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")])]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("ControlBlock")]),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(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("->")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("taproot"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")])]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("TapBranchHash")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("taproot"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")])]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("TapBranchHash")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("from_inner")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n control_block\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("merkle_branch\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("as_inner")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("iter")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("fold")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("taproot"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")])]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("NodeInfo")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("new_hidden")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("sha256"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")])]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Hash")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("from_slice")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("leaf_hash"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("as_inner")]),s("span",{pre:!0,attrs:{class:"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("expect")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Invalid TapLeafHash"')]),s("span",{pre:!0,attrs:{class:"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 closure-params"}},[s("span",{pre:!0,attrs:{class:"token closure-punctuation punctuation"}},[t._v("|")]),t._v("acc"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" branch"),s("span",{pre:!0,attrs:{class:"token closure-punctuation 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 namespace"}},[t._v("taproot"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")])]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("NodeInfo")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("combine")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("acc"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("taproot"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")])]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("NodeInfo")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("new_hidden")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v("branch"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("expect")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Invalid tree"')]),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 punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("hash")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("into_inner")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),s("p",[t._v('The first function "converts" an ECDSA key to a Schnorr key by dropping the first byte that encodes the key parity, since Schnorr keys are "x-only".')]),t._v(" "),s("p",[t._v("The second one constructs the merkle root of a taptree given a leaf hash and the corresponding control block.")]),t._v(" "),s("h2",{attrs:{id:"wrap-fallible-methods"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#wrap-fallible-methods"}},[t._v("#")]),t._v(" Wrap Fallible Methods")]),t._v(" "),s("p",[t._v("Many of the methods exposed by a "),s("code",[t._v("Descriptor")]),t._v(' struct used to be infallible: for instance, it was always possible to "encode" a descriptor into a Bitcoin script by calling the '),s("code",[t._v("script_pubkey()")]),t._v(" method.")]),t._v(" "),s("p",[t._v("Unfortunately, taproot descriptors need some extra metadata to do that: they can be computed by calling the "),s("code",[t._v("spend_info()")]),t._v(" method, and they will be cached inside the descriptor, but since it's not guaranteed by the\ncompiler that the method will be called before trying to encode it, the infallible methods had to be changed to return a "),s("code",[t._v("Result")]),t._v(", so that they can fail if the spend info is not present.")]),t._v(" "),s("p",[t._v("In BDK we call the "),s("code",[t._v("spend_info()")]),t._v(' method right after "deriving" the descriptor, so it\'s guaranteed that we will never encounter that error: for this reason, we wrap those methods and call '),s("code",[t._v("expect()")]),t._v(" on them, to keep\nthe original code mostly unchanged.")]),t._v(" "),s("p",[t._v("Here we call "),s("code",[t._v("spend_info()")]),t._v(" right after deriving the descriptor, if it's a "),s("code",[t._v("Tr")]),t._v(" variant:")]),t._v(" "),s("div",{staticClass:"language-diff extra-class"},[s("pre",{pre:!0,attrs:{class:"language-diff"}},[s("code",[t._v("@@ -136,10 +133,16 @@ impl AsDerived for Descriptor {\n"),s("span",{pre:!0,attrs:{class:"token unchanged"}},[s("span",{pre:!0,attrs:{class:"token prefix unchanged"}},[t._v(" ")]),s("span",{pre:!0,attrs:{class:"token line"}},[t._v(" index: u32,\n")]),s("span",{pre:!0,attrs:{class:"token prefix unchanged"}},[t._v(" ")]),s("span",{pre:!0,attrs:{class:"token line"}},[t._v(" secp: &'s SecpCtx,\n")]),s("span",{pre:!0,attrs:{class:"token prefix unchanged"}},[t._v(" ")]),s("span",{pre:!0,attrs:{class:"token line"}},[t._v(" ) -> Descriptor> {\n")])]),s("span",{pre:!0,attrs:{class:"token deleted-sign deleted"}},[s("span",{pre:!0,attrs:{class:"token prefix deleted"}},[t._v("-")]),s("span",{pre:!0,attrs:{class:"token line"}},[t._v(" self.derive(index).translate_pk_infallible(\n")])]),s("span",{pre:!0,attrs:{class:"token inserted-sign inserted"}},[s("span",{pre:!0,attrs:{class:"token prefix inserted"}},[t._v("+")]),s("span",{pre:!0,attrs:{class:"token line"}},[t._v(" let mut derived = self.derive(index).translate_pk_infallible(\n")])]),s("span",{pre:!0,attrs:{class:"token unchanged"}},[s("span",{pre:!0,attrs:{class:"token prefix unchanged"}},[t._v(" ")]),s("span",{pre:!0,attrs:{class:"token line"}},[t._v(" |key| DerivedDescriptorKey::new(key.clone(), secp),\n")]),s("span",{pre:!0,attrs:{class:"token prefix unchanged"}},[t._v(" ")]),s("span",{pre:!0,attrs:{class:"token line"}},[t._v(" |key| DerivedDescriptorKey::new(key.clone(), secp),\n")])]),s("span",{pre:!0,attrs:{class:"token deleted-sign deleted"}},[s("span",{pre:!0,attrs:{class:"token prefix deleted"}},[t._v("-")]),s("span",{pre:!0,attrs:{class:"token line"}},[t._v(" )\n")])]),s("span",{pre:!0,attrs:{class:"token inserted-sign inserted"}},[s("span",{pre:!0,attrs:{class:"token prefix inserted"}},[t._v("+")]),s("span",{pre:!0,attrs:{class:"token line"}},[t._v(" );\n")]),s("span",{pre:!0,attrs:{class:"token prefix inserted"}},[t._v("+")]),s("span",{pre:!0,attrs:{class:"token line"}},[t._v("\n")]),s("span",{pre:!0,attrs:{class:"token prefix inserted"}},[t._v("+")]),s("span",{pre:!0,attrs:{class:"token line"}},[t._v(" if let Descriptor::Tr(tr) = &mut derived {\n")]),s("span",{pre:!0,attrs:{class:"token prefix inserted"}},[t._v("+")]),s("span",{pre:!0,attrs:{class:"token line"}},[t._v(" tr.spend_info(secp);\n")]),s("span",{pre:!0,attrs:{class:"token prefix inserted"}},[t._v("+")]),s("span",{pre:!0,attrs:{class:"token line"}},[t._v(" }\n")]),s("span",{pre:!0,attrs:{class:"token prefix inserted"}},[t._v("+")]),s("span",{pre:!0,attrs:{class:"token line"}},[t._v("\n")]),s("span",{pre:!0,attrs:{class:"token prefix inserted"}},[t._v("+")]),s("span",{pre:!0,attrs:{class:"token line"}},[t._v(" derived\n")])]),s("span",{pre:!0,attrs:{class:"token unchanged"}},[s("span",{pre:!0,attrs:{class:"token prefix unchanged"}},[t._v(" ")]),s("span",{pre:!0,attrs:{class:"token line"}},[t._v(" }\n")])])])])]),s("p",[t._v("And here we wrap the "),s("code",[t._v("script_pubkey()")]),t._v(" method and call "),s("code",[t._v("expect()")]),t._v(" on it. Note that we only implement it on "),s("code",[t._v("DerivedDescriptor")]),t._v(', because it\'s not guaranteed that "extended descriptors" will have the cached metadata inside.')]),t._v(" "),s("div",{staticClass:"language-rust extra-class"},[s("pre",{pre:!0,attrs:{class:"language-rust"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("pub")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("crate")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("trait")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token type-definition class-name"}},[t._v("DerivedDescriptorSafeOps")]),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("/// The [`Descriptor::script_pubkey`] method can fail on `Tr` descriptors that don't have the")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("/// `spend_info` inside. Since we generate those upon derivation, it's guaranteed that the")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("/// method will not fail on `DerivedDescriptor`s.")]),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("script_pubkey_derived")]),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("self")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("->")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Script")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("impl")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token lifetime-annotation symbol"}},[t._v("'s")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("DerivedDescriptorSafeOps")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("for")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Descriptor")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("DerivedDescriptorKey")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token lifetime-annotation symbol"}},[t._v("'s")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("fn")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function-definition function"}},[t._v("script_pubkey_derived")]),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("self")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("->")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Script")]),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("self")]),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(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("expect")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"`spend_info` is always present in `DerivedDescriptor`s"')]),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:"descriptor-metadata"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#descriptor-metadata"}},[t._v("#")]),t._v(" Descriptor Metadata")]),t._v(" "),s("p",[t._v('In BDK we have a few traits that in a way "unify" the interface of a descriptor: things like the '),s("code",[t._v("redeem_script")]),t._v(" of an input has to be computed differently depending on the type of descriptor. The traits we define\nare implemented on the "),s("code",[t._v("DerivedDescriptor")]),t._v(" or "),s("code",[t._v("ExtendedDescriptor")]),t._v(" structs and allow us to quickly get what we need without having to check the descriptor type manually.")]),t._v(" "),s("p",[t._v("Internally, they are essentially large "),s("code",[t._v("match")]),t._v("es that return different things depending on the descriptor variant. Due to some renaming that had been done recently in "),s("code",[t._v("miniscript")]),t._v(" (not necessarily related to taproot)\nwe have to update them:")]),t._v(" "),s("div",{staticClass:"language-diff extra-class"},[s("pre",{pre:!0,attrs:{class:"language-diff"}},[s("code",[t._v("@@ -337,6 +339,7 @@ pub(crate) trait DerivedDescriptorMeta {\n\n"),s("span",{pre:!0,attrs:{class:"token unchanged"}},[s("span",{pre:!0,attrs:{class:"token prefix unchanged"}},[t._v(" ")]),s("span",{pre:!0,attrs:{class:"token line"}},[t._v("pub(crate) trait DescriptorMeta {\n")]),s("span",{pre:!0,attrs:{class:"token prefix unchanged"}},[t._v(" ")]),s("span",{pre:!0,attrs:{class:"token line"}},[t._v(" fn is_witness(&self) -> bool;\n")])]),s("span",{pre:!0,attrs:{class:"token inserted-sign inserted"}},[s("span",{pre:!0,attrs:{class:"token prefix inserted"}},[t._v("+")]),s("span",{pre:!0,attrs:{class:"token line"}},[t._v(" fn is_tap(&self) -> bool;\n")])]),s("span",{pre:!0,attrs:{class:"token unchanged"}},[s("span",{pre:!0,attrs:{class:"token prefix unchanged"}},[t._v(" ")]),s("span",{pre:!0,attrs:{class:"token line"}},[t._v(" fn get_extended_keys(&self) -> Result>, DescriptorError>;\n")]),s("span",{pre:!0,attrs:{class:"token prefix unchanged"}},[t._v(" ")]),s("span",{pre:!0,attrs:{class:"token line"}},[t._v(" fn derive_from_hd_keypaths<'s>(\n")]),s("span",{pre:!0,attrs:{class:"token prefix unchanged"}},[t._v(" ")]),s("span",{pre:!0,attrs:{class:"token line"}},[t._v(" &self,\n")])]),t._v("@@ -358,23 +361,29 @@ pub(crate) trait DescriptorScripts {\n\n"),s("span",{pre:!0,attrs:{class:"token unchanged"}},[s("span",{pre:!0,attrs:{class:"token prefix unchanged"}},[t._v(" ")]),s("span",{pre:!0,attrs:{class:"token line"}},[t._v("impl<'s> DescriptorScripts for DerivedDescriptor<'s> {\n")]),s("span",{pre:!0,attrs:{class:"token prefix unchanged"}},[t._v(" ")]),s("span",{pre:!0,attrs:{class:"token line"}},[t._v(" fn psbt_redeem_script(&self) -> Option + diff --git a/bdk-cli/concept/index.html b/bdk-cli/concept/index.html index 64f062d5c6..bc21932ffd 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/installation/index.html b/bdk-cli/installation/index.html index 248f0b0500..0ce52151a1 100644 --- a/bdk-cli/installation/index.html +++ b/bdk-cli/installation/index.html @@ -35,7 +35,7 @@ - + @@ -112,7 +112,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
    -
    - + diff --git a/bdk-cli/interface/index.html b/bdk-cli/interface/index.html index 850781fd01..c813b8f5b2 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.

    - + diff --git a/bdk-cli/introduction/index.html b/bdk-cli/introduction/index.html index 80cdcf445a..da1b39c257 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 8cdabc8bbf..1609c84347 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 432337cbb6..613bd0cc13 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.

    - + diff --git a/blog/2020/12/hello-world/index.html b/blog/2020/12/hello-world/index.html index 81971697f6..aa93427597 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 db3688fab4..b34ba3c568 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/tags/bdk-cli/index.html b/blog/tags/bdk-cli/index.html index b81ba865de..4f5a6d02b4 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 b95626e287..02017e4ec5 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 ab199c49ef..56b4e9901a 100644 --- a/blog/tags/bdk/index.html +++ b/blog/tags/bdk/index.html @@ -25,7 +25,7 @@ - + @@ -180,6 +180,6 @@
    BDK Foundation
    - + diff --git a/blog/tags/bindings/index.html b/blog/tags/bindings/index.html index f7fb5899d9..0bfb7a4f59 100644 --- a/blog/tags/bindings/index.html +++ b/blog/tags/bindings/index.html @@ -25,7 +25,7 @@ - + @@ -92,6 +92,6 @@
    BDK Foundation
    - + diff --git a/blog/tags/bitcoin-cli/index.html b/blog/tags/bitcoin-cli/index.html index 5d752fccde..8fe5a32c2b 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 961438446b..53b5888bf3 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 dfbc92ecaf..b844ada8c6 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 df15d192b4..cfe27f088d 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 e5a123035a..249242f034 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 06ec5e0d46..1ab2d6812d 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 f0654b83a3..ff912a5b36 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 d2bb27cc23..ab0967cc99 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 2)

    + Fee, Machine learning


    Fee estimation for light-clients (Part 3)

    By Riccardo Casatta @@ -71,7 +71,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 @@ -103,6 +103,6 @@

    BDK Foundation
    - + diff --git a/blog/tags/getting started/index.html b/blog/tags/getting started/index.html index 36e7aaa01a..4104ba818d 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 0a6b754250..0872e4b259 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 348c7e2adc..a35f133733 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 58f182d854..d62848ffe6 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 7c60296ca8..55f0f85e3f 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 fcdaa2c132..bfec5b3b20 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 897ab04fd4..8b2d65634f 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 e6bae3b5d2..e98b4de56f 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 12edefce62..8bef0b8508 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 70f0c9a362..a5df9a12f9 100644 --- a/blog/tags/project/index.html +++ b/blog/tags/project/index.html @@ -25,7 +25,7 @@ - + @@ -92,6 +92,6 @@
    BDK Foundation
    - + diff --git a/blog/tags/release/index.html b/blog/tags/release/index.html index d35f3a148c..c510c02008 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 078db78b21..7eff97fa5a 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 a7532b59ca..fa3660faab 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 2c41999c00..1bca9879f0 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 26b15b7dea..8d80a565cf 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 89b5206cff..ae49a88768 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 93b41fecd5..05f216af50 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 cf40907c24..6cbc7c1713 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 ea630a149c..eaace3bd1d 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/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 9d464413ab..b9c800d826 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 @@ -7,7 +7,7 @@

    Trait Implementations§

    source§

    impl<A: Anchor, IA: Append> Append for ChangeSet<A, IA>

    source§

    fn append(&mut self, other: Self)

    Append another object of the same type onto self.
    source§

    fn is_empty(&self) -> bool

    Returns whether the structure is considered empty.
    source§

    fn take(&mut self) -> Option<Self>

    Take the value, replacing it with the default value.
    source§

    impl<A: Clone, IA: Clone> Clone for ChangeSet<A, IA>

    source§

    fn clone(&self) -> ChangeSet<A, IA>

    Returns a copy of the value. Read more
    1.0.0 · source§

    fn clone_from(&mut self, source: &Self)

    Performs copy-assignment from source. Read more
    source§

    impl<A: Debug, IA: Debug> Debug for ChangeSet<A, IA>

    source§

    fn fmt(&self, f: &mut Formatter<'_>) -> Result

    Formats the value using the given formatter. Read more
    source§

    impl<A, IA: Default> Default for ChangeSet<A, IA>

    source§

    fn default() -> Self

    Returns the “default value” for a type. Read more
    source§

    impl<'de, A, IA> Deserialize<'de> for ChangeSet<A, IA>
    where A: Ord + Deserialize<'de>, IA: Deserialize<'de>,

    source§

    fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>
    where - __D: Deserializer<'de>,

    Deserialize this value from the given Serde deserializer. Read more
    source§

    impl<A, IA: Default> From<ChangeSet<A>> for ChangeSet<A, IA>

    source§

    fn from(graph: ChangeSet<A>) -> Self

    Converts to this type from the input type.
    source§

    impl<K, A> From<ChangeSet<A, ChangeSet<K>>> for CombinedChangeSet<K, A>

    source§

    fn from(indexed_tx_graph: ChangeSet<A, ChangeSet<K>>) -> Self

    Converts to this type from the input type.
    source§

    impl<A, K> From<ChangeSet<K>> for ChangeSet<A, ChangeSet<K>>

    source§

    fn from(indexer: ChangeSet<K>) -> Self

    Converts to this type from the input type.
    source§

    impl<A: PartialEq, IA: PartialEq> PartialEq for ChangeSet<A, IA>

    source§

    fn eq(&self, other: &ChangeSet<A, IA>) -> bool

    This method tests for self and other values to be equal, and is used + __D: Deserializer<'de>,
    Deserialize this value from the given Serde deserializer. Read more
    source§

    impl<A, IA: Default> From<ChangeSet<A>> for ChangeSet<A, IA>

    source§

    fn from(graph: ChangeSet<A>) -> Self

    Converts to this type from the input type.
    source§

    impl<K, A> From<ChangeSet<A, ChangeSet<K>>> for CombinedChangeSet<K, A>

    source§

    fn from(indexed_tx_graph: ChangeSet<A, ChangeSet<K>>) -> Self

    Converts to this type from the input type.
    source§

    impl<A, K> From<ChangeSet<K>> for ChangeSet<A, ChangeSet<K>>

    source§

    fn from(indexer: ChangeSet<K>) -> Self

    Converts to this type from the input type.
    source§

    impl<A: PartialEq, IA: PartialEq> PartialEq for ChangeSet<A, IA>

    source§

    fn eq(&self, other: &ChangeSet<A, IA>) -> bool

    This method tests for self and other values to be equal, and is used by ==.
    1.0.0 · source§

    fn ne(&self, other: &Rhs) -> bool

    This method tests for !=. The default implementation is almost always sufficient, and should not be overridden without very good reason.
    source§

    impl<A, IA> Serialize for ChangeSet<A, IA>
    where A: Ord + Serialize, diff --git a/docs-rs/bdk/nightly/latest/bdk_chain/keychain/enum.InsertDescriptorError.html b/docs-rs/bdk/nightly/latest/bdk_chain/keychain/enum.InsertDescriptorError.html index c5eee17261..ba0114e42e 100644 --- a/docs-rs/bdk/nightly/latest/bdk_chain/keychain/enum.InsertDescriptorError.html +++ b/docs-rs/bdk/nightly/latest/bdk_chain/keychain/enum.InsertDescriptorError.html @@ -14,7 +14,7 @@

    §

    KeychainAlreadyAssigned

    The keychain is already assigned to a descriptor so you can’t reassign it

    Fields

    §keychain: K

    The keychain that you have attempted to reassign

    §existing_assignment: Descriptor<DescriptorPublicKey>

    The descriptor that the keychain is already assigned to

    -

    Trait Implementations§

    source§

    impl<K: Clone> Clone for InsertDescriptorError<K>

    source§

    fn clone(&self) -> InsertDescriptorError<K>

    Returns a copy of the value. Read more
    1.0.0 · source§

    fn clone_from(&mut self, source: &Self)

    Performs copy-assignment from source. Read more
    source§

    impl<K: Debug> Debug for InsertDescriptorError<K>

    source§

    fn fmt(&self, f: &mut Formatter<'_>) -> Result

    Formats the value using the given formatter. Read more
    source§

    impl<K: Debug> Display for InsertDescriptorError<K>

    source§

    fn fmt(&self, f: &mut Formatter<'_>) -> Result

    Formats the value using the given formatter. Read more
    source§

    impl<K: Debug> Error for InsertDescriptorError<K>

    1.30.0 · source§

    fn source(&self) -> Option<&(dyn Error + 'static)>

    The lower-level source of this error, if any. Read more
    1.0.0 · source§

    fn description(&self) -> &str

    👎Deprecated since 1.42.0: use the Display impl or to_string()
    1.0.0 · source§

    fn cause(&self) -> Option<&dyn Error>

    👎Deprecated since 1.33.0: replaced by Error::source, which can support downcasting
    source§

    fn provide<'a>(&'a self, request: &mut Request<'a>)

    🔬This is a nightly-only experimental API. (error_generic_member_access)
    Provides type based access to context intended for error reports. Read more
    source§

    impl<K: PartialEq> PartialEq for InsertDescriptorError<K>

    source§

    fn eq(&self, other: &InsertDescriptorError<K>) -> bool

    This method tests for self and other values to be equal, and is used +

    Trait Implementations§

    source§

    impl<K: Clone> Clone for InsertDescriptorError<K>

    source§

    fn clone(&self) -> InsertDescriptorError<K>

    Returns a copy of the value. Read more
    1.0.0 · source§

    fn clone_from(&mut self, source: &Self)

    Performs copy-assignment from source. Read more
    source§

    impl<K: Debug> Debug for InsertDescriptorError<K>

    source§

    fn fmt(&self, f: &mut Formatter<'_>) -> Result

    Formats the value using the given formatter. Read more
    source§

    impl<K: Debug> Display for InsertDescriptorError<K>

    source§

    fn fmt(&self, f: &mut Formatter<'_>) -> Result

    Formats the value using the given formatter. Read more
    source§

    impl<K: Debug> Error for InsertDescriptorError<K>

    1.30.0 · source§

    fn source(&self) -> Option<&(dyn Error + 'static)>

    The lower-level source of this error, if any. Read more
    1.0.0 · source§

    fn description(&self) -> &str

    👎Deprecated since 1.42.0: use the Display impl or to_string()
    1.0.0 · source§

    fn cause(&self) -> Option<&dyn Error>

    👎Deprecated since 1.33.0: replaced by Error::source, which can support downcasting
    source§

    fn provide<'a>(&'a self, request: &mut Request<'a>)

    🔬This is a nightly-only experimental API. (error_generic_member_access)
    Provides type based access to context intended for error reports. Read more
    source§

    impl<K: PartialEq> PartialEq for InsertDescriptorError<K>

    source§

    fn eq(&self, other: &InsertDescriptorError<K>) -> bool

    This method tests for self and other values to be equal, and is used by ==.
    1.0.0 · source§

    fn ne(&self, other: &Rhs) -> bool

    This method tests for !=. The default implementation is almost always sufficient, and should not be overridden without very good reason.
    source§

    impl<K> StructuralPartialEq for InsertDescriptorError<K>

    Auto Trait Implementations§

    §

    impl<K> !Freeze for InsertDescriptorError<K>

    §

    impl<K> RefUnwindSafe for InsertDescriptorError<K>
    where K: RefUnwindSafe,

    §

    impl<K> Send for InsertDescriptorError<K>
    where 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 f7e7d743c4..e5f1ff6f92 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,8 +12,8 @@

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

    source

    pub fn total(&self) -> Amount

    Get the whole balance visible to the wallet.

    -

    Trait Implementations§

    source§

    impl Add for Balance

    §

    type Output = Balance

    The resulting type after applying the + operator.
    source§

    fn add(self, other: Self) -> Self

    Performs the + operation. Read more
    source§

    impl Clone for Balance

    source§

    fn clone(&self) -> Balance

    Returns a copy of the value. Read more
    1.0.0 · source§

    fn clone_from(&mut self, source: &Self)

    Performs copy-assignment from source. Read more
    source§

    impl Debug for Balance

    source§

    fn fmt(&self, f: &mut Formatter<'_>) -> Result

    Formats the value using the given formatter. Read more
    source§

    impl Default for Balance

    source§

    fn default() -> Balance

    Returns the “default value” for a type. Read more
    source§

    impl<'de> Deserialize<'de> for Balance

    source§

    fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>
    where - __D: Deserializer<'de>,

    Deserialize this value from the given Serde deserializer. Read more
    source§

    impl Display for Balance

    source§

    fn fmt(&self, f: &mut Formatter<'_>) -> Result

    Formats the value using the given formatter. Read more
    source§

    impl PartialEq for Balance

    source§

    fn eq(&self, other: &Balance) -> bool

    This method tests for self and other values to be equal, and is used +

    Trait Implementations§

    source§

    impl Add for Balance

    §

    type Output = Balance

    The resulting type after applying the + operator.
    source§

    fn add(self, other: Self) -> Self

    Performs the + operation. Read more
    source§

    impl Clone for Balance

    source§

    fn clone(&self) -> Balance

    Returns a copy of the value. Read more
    1.0.0 · source§

    fn clone_from(&mut self, source: &Self)

    Performs copy-assignment from source. Read more
    source§

    impl Debug for Balance

    source§

    fn fmt(&self, f: &mut Formatter<'_>) -> Result

    Formats the value using the given formatter. Read more
    source§

    impl Default for Balance

    source§

    fn default() -> Balance

    Returns the “default value” for a type. Read more
    source§

    impl<'de> Deserialize<'de> for Balance

    source§

    fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>
    where + __D: Deserializer<'de>,

    Deserialize this value from the given Serde deserializer. Read more
    source§

    impl Display for Balance

    source§

    fn fmt(&self, f: &mut Formatter<'_>) -> Result

    Formats the value using the given formatter. Read more
    source§

    impl PartialEq for Balance

    source§

    fn eq(&self, other: &Balance) -> bool

    This method tests for self and other values to be equal, and is used by ==.
    1.0.0 · source§

    fn ne(&self, other: &Rhs) -> bool

    This method tests for !=. The default implementation is almost always sufficient, and should not be overridden without very good reason.
    source§

    impl Serialize for Balance

    source§

    fn serialize<__S>(&self, __serializer: __S) -> Result<__S::Ok, __S::Error>
    where __S: Serializer,

    Serialize this value into the given Serde serializer. Read more
    source§

    impl Eq for Balance

    source§

    impl StructuralPartialEq for Balance

    Auto Trait Implementations§

    §

    impl Freeze for Balance

    §

    impl RefUnwindSafe for Balance

    §

    impl Send for Balance

    §

    impl Sync for Balance

    §

    impl Unpin for Balance

    §

    impl UnwindSafe for Balance

    Blanket Implementations§

    source§

    impl<T> Any for T
    where 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 3c718cf7e7..8e54a0c4f4 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 @@ -15,7 +15,7 @@

    source§

    fn is_empty(&self) -> bool

    Returns whether the changeset are empty.

    source§

    fn take(&mut self) -> Option<Self>

    Take the value, replacing it with the default value.
    source§

    impl<K: Clone> Clone for ChangeSet<K>

    source§

    fn clone(&self) -> ChangeSet<K>

    Returns a copy of the value. Read more
    1.0.0 · source§

    fn clone_from(&mut self, source: &Self)

    Performs copy-assignment from source. Read more
    source§

    impl<K: Debug> Debug for ChangeSet<K>

    source§

    fn fmt(&self, f: &mut Formatter<'_>) -> Result

    Formats the value using the given formatter. Read more
    source§

    impl<K> Default for ChangeSet<K>

    source§

    fn default() -> Self

    Returns the “default value” for a type. Read more
    source§

    impl<'de, K> Deserialize<'de> for ChangeSet<K>
    where K: Ord + Deserialize<'de>,

    source§

    fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>
    where - __D: Deserializer<'de>,

    Deserialize this value from the given Serde deserializer. Read more
    source§

    impl<A, K> From<ChangeSet<K>> for ChangeSet<A, ChangeSet<K>>

    source§

    fn from(indexer: ChangeSet<K>) -> Self

    Converts to this type from the input type.
    source§

    impl<K, A> From<ChangeSet<K>> for CombinedChangeSet<K, A>

    source§

    fn from(indexer: ChangeSet<K>) -> Self

    Converts to this type from the input type.
    source§

    impl<K: PartialEq> PartialEq for ChangeSet<K>

    source§

    fn eq(&self, other: &ChangeSet<K>) -> bool

    This method tests for self and other values to be equal, and is used + __D: Deserializer<'de>,
    Deserialize this value from the given Serde deserializer. Read more
    source§

    impl<A, K> From<ChangeSet<K>> for ChangeSet<A, ChangeSet<K>>

    source§

    fn from(indexer: ChangeSet<K>) -> Self

    Converts to this type from the input type.
    source§

    impl<K, A> From<ChangeSet<K>> for CombinedChangeSet<K, A>

    source§

    fn from(indexer: ChangeSet<K>) -> Self

    Converts to this type from the input type.
    source§

    impl<K: PartialEq> PartialEq for ChangeSet<K>

    source§

    fn eq(&self, other: &ChangeSet<K>) -> bool

    This method tests for self and other values to be equal, and is used by ==.
    1.0.0 · source§

    fn ne(&self, other: &Rhs) -> bool

    This method tests for !=. The default implementation is almost always sufficient, and should not be overridden without very good reason.
    source§

    impl<K> Serialize for ChangeSet<K>
    where K: Ord + Serialize,

    source§

    fn serialize<__S>(&self, __serializer: __S) -> Result<__S::Ok, __S::Error>
    where diff --git a/docs-rs/bdk/nightly/latest/bdk_chain/local_chain/struct.MissingGenesisError.html b/docs-rs/bdk/nightly/latest/bdk_chain/local_chain/struct.MissingGenesisError.html index 866dea2d57..2ba7ebf4d7 100644 --- a/docs-rs/bdk/nightly/latest/bdk_chain/local_chain/struct.MissingGenesisError.html +++ b/docs-rs/bdk/nightly/latest/bdk_chain/local_chain/struct.MissingGenesisError.html @@ -1,5 +1,5 @@ MissingGenesisError in bdk_chain::local_chain - Rust

    Struct bdk_chain::local_chain::MissingGenesisError

    source ·
    pub struct MissingGenesisError;
    Expand description

    An error which occurs when a LocalChain is constructed without a genesis checkpoint.

    -

    Trait Implementations§

    source§

    impl Clone for MissingGenesisError

    source§

    fn clone(&self) -> MissingGenesisError

    Returns a copy of the value. Read more
    1.0.0 · source§

    fn clone_from(&mut self, source: &Self)

    Performs copy-assignment from source. Read more
    source§

    impl Debug for MissingGenesisError

    source§

    fn fmt(&self, f: &mut Formatter<'_>) -> Result

    Formats the value using the given formatter. Read more
    source§

    impl Display for MissingGenesisError

    source§

    fn fmt(&self, f: &mut Formatter<'_>) -> Result

    Formats the value using the given formatter. Read more
    source§

    impl Error for MissingGenesisError

    1.30.0 · source§

    fn source(&self) -> Option<&(dyn Error + 'static)>

    The lower-level source of this error, if any. Read more
    1.0.0 · source§

    fn description(&self) -> &str

    👎Deprecated since 1.42.0: use the Display impl or to_string()
    1.0.0 · source§

    fn cause(&self) -> Option<&dyn Error>

    👎Deprecated since 1.33.0: replaced by Error::source, which can support downcasting
    source§

    fn provide<'a>(&'a self, request: &mut Request<'a>)

    🔬This is a nightly-only experimental API. (error_generic_member_access)
    Provides type based access to context intended for error reports. Read more
    source§

    impl PartialEq for MissingGenesisError

    source§

    fn eq(&self, other: &MissingGenesisError) -> bool

    This method tests for self and other values to be equal, and is used +

    Trait Implementations§

    source§

    impl Clone for MissingGenesisError

    source§

    fn clone(&self) -> MissingGenesisError

    Returns a copy of the value. Read more
    1.0.0 · source§

    fn clone_from(&mut self, source: &Self)

    Performs copy-assignment from source. Read more
    source§

    impl Debug for MissingGenesisError

    source§

    fn fmt(&self, f: &mut Formatter<'_>) -> Result

    Formats the value using the given formatter. Read more
    source§

    impl Display for MissingGenesisError

    source§

    fn fmt(&self, f: &mut Formatter<'_>) -> Result

    Formats the value using the given formatter. Read more
    source§

    impl Error for MissingGenesisError

    1.30.0 · source§

    fn source(&self) -> Option<&(dyn Error + 'static)>

    The lower-level source of this error, if any. Read more
    1.0.0 · source§

    fn description(&self) -> &str

    👎Deprecated since 1.42.0: use the Display impl or to_string()
    1.0.0 · source§

    fn cause(&self) -> Option<&dyn Error>

    👎Deprecated since 1.33.0: replaced by Error::source, which can support downcasting
    source§

    fn provide<'a>(&'a self, request: &mut Request<'a>)

    🔬This is a nightly-only experimental API. (error_generic_member_access)
    Provides type based access to context intended for error reports. Read more
    source§

    impl PartialEq for MissingGenesisError

    source§

    fn eq(&self, other: &MissingGenesisError) -> bool

    This method tests for self and other values to be equal, and is used by ==.
    1.0.0 · source§

    fn ne(&self, other: &Rhs) -> bool

    This method tests for !=. The default implementation is almost always sufficient, and should not be overridden without very good reason.
    source§

    impl StructuralPartialEq for MissingGenesisError

    Auto Trait Implementations§

    Blanket Implementations§

    source§

    impl<T> Any for T
    where T: 'static + ?Sized,

    source§

    fn type_id(&self) -> TypeId

    Gets the TypeId of self. Read more
    source§

    impl<T> Borrow<T> for T
    where diff --git a/docs-rs/bdk/nightly/latest/bdk_chain/struct.CombinedChangeSet.html b/docs-rs/bdk/nightly/latest/bdk_chain/struct.CombinedChangeSet.html index 40def7567f..69a360c048 100644 --- a/docs-rs/bdk/nightly/latest/bdk_chain/struct.CombinedChangeSet.html +++ b/docs-rs/bdk/nightly/latest/bdk_chain/struct.CombinedChangeSet.html @@ -9,7 +9,7 @@

    Trait Implementations§

    source§

    impl<K: Ord, A: Anchor> Append for CombinedChangeSet<K, A>

    source§

    fn append(&mut self, other: Self)

    Append another object of the same type onto self.
    source§

    fn is_empty(&self) -> bool

    Returns whether the structure is considered empty.
    source§

    fn take(&mut self) -> Option<Self>

    Take the value, replacing it with the default value.
    source§

    impl<K: Clone, A: Clone> Clone for CombinedChangeSet<K, A>

    source§

    fn clone(&self) -> CombinedChangeSet<K, A>

    Returns a copy of the value. Read more
    1.0.0 · source§

    fn clone_from(&mut self, source: &Self)

    Performs copy-assignment from source. Read more
    source§

    impl<K: Debug, A: Debug> Debug for CombinedChangeSet<K, A>

    source§

    fn fmt(&self, f: &mut Formatter<'_>) -> Result

    Formats the value using the given formatter. Read more
    source§

    impl<K, A> Default for CombinedChangeSet<K, A>

    source§

    fn default() -> Self

    Returns the “default value” for a type. Read more
    source§

    impl<'de, K, A> Deserialize<'de> for CombinedChangeSet<K, A>
    where A: Ord + Deserialize<'de>, K: Ord + Deserialize<'de>,

    source§

    fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>
    where - __D: Deserializer<'de>,

    Deserialize this value from the given Serde deserializer. Read more
    source§

    impl<K, A> From<BTreeMap<u32, Option<BlockHash>>> for CombinedChangeSet<K, A>

    source§

    fn from(chain: ChangeSet) -> Self

    Converts to this type from the input type.
    source§

    impl<K, A> From<ChangeSet<A, ChangeSet<K>>> for CombinedChangeSet<K, A>

    source§

    fn from(indexed_tx_graph: ChangeSet<A, ChangeSet<K>>) -> Self

    Converts to this type from the input type.
    source§

    impl<K, A> From<ChangeSet<K>> for CombinedChangeSet<K, A>

    source§

    fn from(indexer: ChangeSet<K>) -> Self

    Converts to this type from the input type.
    source§

    impl<K: PartialEq, A: PartialEq> PartialEq for CombinedChangeSet<K, A>

    source§

    fn eq(&self, other: &CombinedChangeSet<K, A>) -> bool

    This method tests for self and other values to be equal, and is used + __D: Deserializer<'de>,

    Deserialize this value from the given Serde deserializer. Read more
    source§

    impl<K, A> From<BTreeMap<u32, Option<BlockHash>>> for CombinedChangeSet<K, A>

    source§

    fn from(chain: ChangeSet) -> Self

    Converts to this type from the input type.
    source§

    impl<K, A> From<ChangeSet<A, ChangeSet<K>>> for CombinedChangeSet<K, A>

    source§

    fn from(indexed_tx_graph: ChangeSet<A, ChangeSet<K>>) -> Self

    Converts to this type from the input type.
    source§

    impl<K, A> From<ChangeSet<K>> for CombinedChangeSet<K, A>

    source§

    fn from(indexer: ChangeSet<K>) -> Self

    Converts to this type from the input type.
    source§

    impl<K: PartialEq, A: PartialEq> PartialEq for CombinedChangeSet<K, A>

    source§

    fn eq(&self, other: &CombinedChangeSet<K, A>) -> bool

    This method tests for self and other values to be equal, and is used by ==.
    1.0.0 · source§

    fn ne(&self, other: &Rhs) -> bool

    This method tests for !=. The default implementation is almost always sufficient, and should not be overridden without very good reason.
    source§

    impl<K, A> Serialize for CombinedChangeSet<K, A>
    where A: Ord + Serialize, diff --git a/docs-rs/bdk/nightly/latest/bdk_chain/struct.DescriptorId.html b/docs-rs/bdk/nightly/latest/bdk_chain/struct.DescriptorId.html index c23089e7c4..210c26af2a 100644 --- a/docs-rs/bdk/nightly/latest/bdk_chain/struct.DescriptorId.html +++ b/docs-rs/bdk/nightly/latest/bdk_chain/struct.DescriptorId.html @@ -6,15 +6,15 @@

    Tuple Fields§

    §0: Hash

    Implementations§

    source§

    impl DescriptorId

    source

    pub fn from_raw_hash(inner: Hash) -> DescriptorId

    Creates this wrapper type from the inner hash type.

    source

    pub fn to_raw_hash(self) -> Hash

    Returns the inner hash (sha256, sh256d etc.).

    source

    pub fn as_raw_hash(&self) -> &Hash

    Returns a reference to the inner hash (sha256, sh256d etc.).

    -

    Trait Implementations§

    source§

    impl AsRef<[u8]> for DescriptorId

    source§

    fn as_ref(&self) -> &[u8]

    Converts this type into a shared reference of the (usually inferred) input type.
    source§

    impl AsRef<[u8; 32]> for DescriptorId

    source§

    fn as_ref(&self) -> &[u8; 32]

    Converts this type into a shared reference of the (usually inferred) input type.
    source§

    impl Borrow<[u8]> for DescriptorId

    source§

    fn borrow(&self) -> &[u8]

    Immutably borrows from an owned value. Read more
    source§

    impl Clone for DescriptorId

    source§

    fn clone(&self) -> DescriptorId

    Returns a copy of the value. Read more
    1.0.0 · source§

    fn clone_from(&mut self, source: &Self)

    Performs copy-assignment from source. Read more
    source§

    impl Debug for DescriptorId

    source§

    fn fmt(&self, f: &mut Formatter<'_>) -> Result

    Formats the value using the given formatter. Read more
    source§

    impl<'de> Deserialize<'de> for DescriptorId

    source§

    fn deserialize<D: Deserializer<'de>>(d: D) -> Result<DescriptorId, D::Error>

    Deserialize this value from the given Serde deserializer. Read more
    source§

    impl Display for DescriptorId

    source§

    fn fmt(&self, f: &mut Formatter<'_>) -> Result

    Formats the value using the given formatter. Read more
    source§

    impl From<DescriptorId> for Hash

    source§

    fn from(hashtype: DescriptorId) -> Hash

    Converts to this type from the input type.
    source§

    impl From<Hash> for DescriptorId

    source§

    fn from(inner: Hash) -> DescriptorId

    Converts to this type from the input type.
    source§

    impl FromStr for DescriptorId

    §

    type Err = HexToArrayError

    The associated error which can be returned from parsing.
    source§

    fn from_str(s: &str) -> Result<DescriptorId, Self::Err>

    Parses a string s to return a value of this type. Read more
    source§

    impl Hash for DescriptorId

    §

    type Engine = <Hash as Hash>::Engine

    A hashing engine which bytes can be serialized into. It is expected +

    Trait Implementations§

    source§

    impl AsRef<[u8]> for DescriptorId

    source§

    fn as_ref(&self) -> &[u8]

    Converts this type into a shared reference of the (usually inferred) input type.
    source§

    impl AsRef<[u8; 32]> for DescriptorId

    source§

    fn as_ref(&self) -> &[u8; 32]

    Converts this type into a shared reference of the (usually inferred) input type.
    source§

    impl Borrow<[u8]> for DescriptorId

    source§

    fn borrow(&self) -> &[u8]

    Immutably borrows from an owned value. Read more
    source§

    impl Clone for DescriptorId

    source§

    fn clone(&self) -> DescriptorId

    Returns a copy of the value. Read more
    1.0.0 · source§

    fn clone_from(&mut self, source: &Self)

    Performs copy-assignment from source. Read more
    source§

    impl Debug for DescriptorId

    source§

    fn fmt(&self, f: &mut Formatter<'_>) -> Result

    Formats the value using the given formatter. Read more
    source§

    impl<'de> Deserialize<'de> for DescriptorId

    source§

    fn deserialize<D: Deserializer<'de>>(d: D) -> Result<DescriptorId, D::Error>

    Deserialize this value from the given Serde deserializer. Read more
    source§

    impl Display for DescriptorId

    source§

    fn fmt(&self, f: &mut Formatter<'_>) -> Result

    Formats the value using the given formatter. Read more
    source§

    impl From<DescriptorId> for Hash

    source§

    fn from(hashtype: DescriptorId) -> Hash

    Converts to this type from the input type.
    source§

    impl From<Hash> for DescriptorId

    source§

    fn from(inner: Hash) -> DescriptorId

    Converts to this type from the input type.
    source§

    impl FromStr for DescriptorId

    §

    type Err = HexToArrayError

    The associated error which can be returned from parsing.
    source§

    fn from_str(s: &str) -> Result<DescriptorId, Self::Err>

    Parses a string s to return a value of this type. Read more
    source§

    impl Hash for DescriptorId

    source§

    fn hash<__H: Hasher>(&self, state: &mut __H)

    Feeds this value into the given Hasher. Read more
    1.3.0 · source§

    fn hash_slice<H>(data: &[Self], state: &mut H)
    where + H: Hasher, + Self: Sized,

    Feeds a slice of this type into the given Hasher. Read more
    source§

    impl Hash for DescriptorId

    §

    type Engine = <Hash as Hash>::Engine

    A hashing engine which bytes can be serialized into. It is expected to implement the io::Write trait, and to never return errors under any conditions.
    §

    type Bytes = <Hash as Hash>::Bytes

    The byte array that represents the hash internally.
    source§

    const LEN: usize = 32usize

    Length of the hash, in bytes.
    source§

    const DISPLAY_BACKWARD: bool = false

    Flag indicating whether user-visible serializations of this hash should be backward. For some reason Satoshi decided this should be -true for Sha256dHash, so here we are.
    source§

    fn engine() -> Self::Engine

    Constructs a new engine.
    source§

    fn from_engine(e: Self::Engine) -> Self

    Produces a hash from the current state of a given engine.
    source§

    fn from_slice(sl: &[u8]) -> Result<DescriptorId, FromSliceError>

    Copies a byte slice into a hash object.
    source§

    fn from_byte_array(bytes: Self::Bytes) -> Self

    Constructs a hash from the underlying byte array.
    source§

    fn to_byte_array(self) -> Self::Bytes

    Returns the underlying byte array.
    source§

    fn as_byte_array(&self) -> &Self::Bytes

    Returns a reference to the underlying byte array.
    source§

    fn all_zeros() -> Self

    Returns an all zero hash. Read more
    §

    fn hash(data: &[u8]) -> Self

    Hashes some bytes.
    §

    fn hash_byte_chunks<B, I>(byte_slices: I) -> Self
    where +true for Sha256dHash, so here we are.

    source§

    fn engine() -> Self::Engine

    Constructs a new engine.
    source§

    fn from_engine(e: Self::Engine) -> Self

    Produces a hash from the current state of a given engine.
    source§

    fn from_slice(sl: &[u8]) -> Result<DescriptorId, FromSliceError>

    Copies a byte slice into a hash object.
    source§

    fn from_byte_array(bytes: Self::Bytes) -> Self

    Constructs a hash from the underlying byte array.
    source§

    fn to_byte_array(self) -> Self::Bytes

    Returns the underlying byte array.
    source§

    fn as_byte_array(&self) -> &Self::Bytes

    Returns a reference to the underlying byte array.
    source§

    fn all_zeros() -> Self

    Returns an all zero hash. Read more
    §

    fn hash(data: &[u8]) -> Self

    Hashes some bytes.
    §

    fn hash_byte_chunks<B, I>(byte_slices: I) -> Self
    where B: AsRef<[u8]>, - I: IntoIterator<Item = B>,

    Hashes all the byte slices retrieved from the iterator together.
    source§

    impl Hash for DescriptorId

    source§

    fn hash<__H: Hasher>(&self, state: &mut __H)

    Feeds this value into the given Hasher. Read more
    1.3.0 · source§

    fn hash_slice<H>(data: &[Self], state: &mut H)
    where - H: Hasher, - Self: Sized,

    Feeds a slice of this type into the given Hasher. Read more
    source§

    impl<I: SliceIndex<[u8]>> Index<I> for DescriptorId

    §

    type Output = <I as SliceIndex<[u8]>>::Output

    The returned type after indexing.
    source§

    fn index(&self, index: I) -> &Self::Output

    Performs the indexing (container[index]) operation. Read more
    source§

    impl LowerHex for DescriptorId

    source§

    fn fmt(&self, f: &mut Formatter<'_>) -> Result

    Formats the value using the given formatter. Read more
    source§

    impl Ord for DescriptorId

    source§

    fn cmp(&self, other: &DescriptorId) -> Ordering

    This method returns an Ordering between self and other. Read more
    1.21.0 · source§

    fn max(self, other: Self) -> Self
    where + I: IntoIterator<Item = B>,

    Hashes all the byte slices retrieved from the iterator together.
    source§

    impl<I: SliceIndex<[u8]>> Index<I> for DescriptorId

    §

    type Output = <I as SliceIndex<[u8]>>::Output

    The returned type after indexing.
    source§

    fn index(&self, index: I) -> &Self::Output

    Performs the indexing (container[index]) operation. Read more
    source§

    impl LowerHex for DescriptorId

    source§

    fn fmt(&self, f: &mut Formatter<'_>) -> Result

    Formats the value using the given formatter. Read more
    source§

    impl Ord for DescriptorId

    source§

    fn cmp(&self, other: &DescriptorId) -> Ordering

    This method returns an Ordering between self and other. Read more
    1.21.0 · source§

    fn max(self, other: Self) -> Self
    where Self: Sized,

    Compares and returns the maximum of two values. Read more
    1.21.0 · source§

    fn min(self, other: Self) -> Self
    where Self: Sized,

    Compares and returns the minimum of two values. Read more
    1.50.0 · source§

    fn clamp(self, min: Self, max: Self) -> Self
    where Self: Sized + PartialOrd,

    Restrict a value to a certain interval. Read more
    source§

    impl PartialEq for DescriptorId

    source§

    fn eq(&self, other: &DescriptorId) -> bool

    This method tests for self and other values to be equal, and is used @@ -25,8 +25,8 @@ &self, s: S ) -> Result<<S as Serializer>::Ok, <S as Serializer>::Error>
    where - S: Serializer,
    Do serde serialization.
    §

    fn deserialize<'de, D>(d: D) -> Result<Self, <D as Deserializer<'de>>::Error>
    where - D: Deserializer<'de>,

    Do serde deserialization.
    source§

    impl Serialize for DescriptorId

    source§

    fn serialize<S: Serializer>(&self, s: S) -> Result<S::Ok, S::Error>

    Serialize this value into the given Serde serializer. Read more
    source§

    impl UpperHex for DescriptorId

    source§

    fn fmt(&self, f: &mut Formatter<'_>) -> Result

    Formats the value using the given formatter. Read more
    source§

    impl Copy for DescriptorId

    source§

    impl Eq for DescriptorId

    source§

    impl StructuralPartialEq for DescriptorId

    Auto Trait Implementations§

    §

    impl Freeze for DescriptorId

    §

    impl RefUnwindSafe for DescriptorId

    §

    impl Send for DescriptorId

    §

    impl Sync for DescriptorId

    §

    impl Unpin for DescriptorId

    §

    impl UnwindSafe for DescriptorId

    Blanket Implementations§

    source§

    impl<T> Any for T
    where + S: Serializer,

    Do serde serialization.
    §

    fn deserialize<'de, D>(d: D) -> Result<Self, <D as Deserializer<'de>>::Error>
    where + D: Deserializer<'de>,

    Do serde deserialization.
    source§

    impl Serialize for DescriptorId

    source§

    fn serialize<S: Serializer>(&self, s: S) -> Result<S::Ok, S::Error>

    Serialize this value into the given Serde serializer. Read more
    source§

    impl UpperHex for DescriptorId

    source§

    fn fmt(&self, f: &mut Formatter<'_>) -> Result

    Formats the value using the given formatter. Read more
    source§

    impl Copy for DescriptorId

    source§

    impl Eq for DescriptorId

    source§

    impl StructuralPartialEq for DescriptorId

    Auto Trait Implementations§

    §

    impl Freeze for DescriptorId

    §

    impl RefUnwindSafe for DescriptorId

    §

    impl Send for DescriptorId

    §

    impl Sync for DescriptorId

    §

    impl Unpin for DescriptorId

    §

    impl UnwindSafe for DescriptorId

    Blanket Implementations§

    source§

    impl<T> Any for T
    where T: 'static + ?Sized,

    source§

    fn type_id(&self) -> TypeId

    Gets the TypeId of self. Read more
    source§

    impl<T> Borrow<T> for T
    where T: ?Sized,

    source§

    fn borrow(&self) -> &T

    Immutably borrows from an owned value. Read more
    source§

    impl<T> BorrowMut<T> for T
    where T: ?Sized,

    source§

    fn borrow_mut(&mut self) -> &mut T

    Mutably borrows from an owned value. Read more
    source§

    impl<T> From<T> for T

    source§

    fn from(t: T) -> T

    Returns the argument unchanged.

    diff --git a/docs-rs/bdk/nightly/latest/bdk_chain/tx_graph/struct.TxGraph.html b/docs-rs/bdk/nightly/latest/bdk_chain/tx_graph/struct.TxGraph.html index a578b2837b..24beb02cc6 100644 --- a/docs-rs/bdk/nightly/latest/bdk_chain/tx_graph/struct.TxGraph.html +++ b/docs-rs/bdk/nightly/latest/bdk_chain/tx_graph/struct.TxGraph.html @@ -276,7 +276,7 @@
    §Error
    trust_predicate: impl FnMut(&OI, &Script) -> bool ) -> Balance

    Get the total balance of outpoints that are in chain of chain_tip.

    This is the infallible version of try_balance.

    -

    Trait Implementations§

    source§

    impl<A, I> AsRef<TxGraph<A>> for IndexedTxGraph<A, I>

    source§

    fn as_ref(&self) -> &TxGraph<A>

    Converts this type into a shared reference of the (usually inferred) input type.
    source§

    impl<A> AsRef<TxGraph<A>> for TxGraph<A>

    source§

    fn as_ref(&self) -> &TxGraph<A>

    Converts this type into a shared reference of the (usually inferred) input type.
    source§

    impl<A: Clone> Clone for TxGraph<A>

    source§

    fn clone(&self) -> TxGraph<A>

    Returns a copy of the value. Read more
    1.0.0 · source§

    fn clone_from(&mut self, source: &Self)

    Performs copy-assignment from source. Read more
    source§

    impl<A: Debug> Debug for TxGraph<A>

    source§

    fn fmt(&self, f: &mut Formatter<'_>) -> Result

    Formats the value using the given formatter. Read more
    source§

    impl<A> Default for TxGraph<A>

    source§

    fn default() -> Self

    Returns the “default value” for a type. Read more
    source§

    impl<A: PartialEq> PartialEq for TxGraph<A>

    source§

    fn eq(&self, other: &TxGraph<A>) -> bool

    This method tests for self and other values to be equal, and is used +

    Trait Implementations§

    source§

    impl<A, I> AsRef<TxGraph<A>> for IndexedTxGraph<A, I>

    source§

    fn as_ref(&self) -> &TxGraph<A>

    Converts this type into a shared reference of the (usually inferred) input type.
    source§

    impl<A> AsRef<TxGraph<A>> for TxGraph<A>

    source§

    fn as_ref(&self) -> &TxGraph<A>

    Converts this type into a shared reference of the (usually inferred) input type.
    source§

    impl<A: Clone> Clone for TxGraph<A>

    source§

    fn clone(&self) -> TxGraph<A>

    Returns a copy of the value. Read more
    1.0.0 · source§

    fn clone_from(&mut self, source: &Self)

    Performs copy-assignment from source. Read more
    source§

    impl<A: Debug> Debug for TxGraph<A>

    source§

    fn fmt(&self, f: &mut Formatter<'_>) -> Result

    Formats the value using the given formatter. Read more
    source§

    impl<A> Default for TxGraph<A>

    source§

    fn default() -> Self

    Returns the “default value” for a type. Read more
    source§

    impl<A: PartialEq> PartialEq for TxGraph<A>

    source§

    fn eq(&self, other: &TxGraph<A>) -> bool

    This method tests for self and other values to be equal, and is used by ==.
    1.0.0 · source§

    fn ne(&self, other: &Rhs) -> bool

    This method tests for !=. The default implementation is almost always sufficient, and should not be overridden without very good reason.
    source§

    impl<A> StructuralPartialEq for TxGraph<A>

    Auto Trait Implementations§

    §

    impl<A> Freeze for TxGraph<A>

    §

    impl<A> RefUnwindSafe for TxGraph<A>
    where A: RefUnwindSafe,

    §

    impl<A> Send for TxGraph<A>
    where diff --git a/docs-rs/bdk/nightly/latest/bdk_coin_select/enum.BnbLimit.html b/docs-rs/bdk/nightly/latest/bdk_coin_select/enum.BnbLimit.html index 772e048ae5..6f84ac3e06 100644 --- a/docs-rs/bdk/nightly/latest/bdk_coin_select/enum.BnbLimit.html +++ b/docs-rs/bdk/nightly/latest/bdk_coin_select/enum.BnbLimit.html @@ -2,7 +2,7 @@ Rounds(usize), Duration(Duration), }
    Expand description

    Determines how we should limit rounds of branch and bound.

    -

    Variants§

    §

    Rounds(usize)

    §

    Duration(Duration)

    Trait Implementations§

    source§

    impl From<Duration> for BnbLimit

    source§

    fn from(v: Duration) -> Self

    Converts to this type from the input type.
    source§

    impl From<usize> for BnbLimit

    source§

    fn from(v: usize) -> Self

    Converts to this type from the input type.

    Auto Trait Implementations§

    Blanket Implementations§

    source§

    impl<T> Any for T
    where +

    Variants§

    §

    Rounds(usize)

    §

    Duration(Duration)

    Trait Implementations§

    source§

    impl From<Duration> for BnbLimit

    source§

    fn from(v: Duration) -> Self

    Converts to this type from the input type.
    source§

    impl From<usize> for BnbLimit

    source§

    fn from(v: usize) -> Self

    Converts to this type from the input type.

    Auto Trait Implementations§

    Blanket Implementations§

    source§

    impl<T> Any for T
    where T: 'static + ?Sized,

    source§

    fn type_id(&self) -> TypeId

    Gets the TypeId of self. Read more
    source§

    impl<T> Borrow<T> for T
    where T: ?Sized,

    source§

    fn borrow(&self) -> &T

    Immutably borrows from an owned value. Read more
    source§

    impl<T> BorrowMut<T> for T
    where T: ?Sized,

    source§

    fn borrow_mut(&mut self) -> &mut T

    Mutably borrows from an owned value. Read more
    source§

    impl<T> From<T> for T

    source§

    fn from(t: T) -> T

    Returns the argument unchanged.

    diff --git a/docs-rs/bdk/nightly/latest/bdk_coin_select/enum.ExcessStrategyKind.html b/docs-rs/bdk/nightly/latest/bdk_coin_select/enum.ExcessStrategyKind.html index 54033098a4..717004edae 100644 --- a/docs-rs/bdk/nightly/latest/bdk_coin_select/enum.ExcessStrategyKind.html +++ b/docs-rs/bdk/nightly/latest/bdk_coin_select/enum.ExcessStrategyKind.html @@ -2,7 +2,7 @@ ToFee, ToRecipient, ToDrain, -}

    Variants§

    §

    ToFee

    §

    ToRecipient

    §

    ToDrain

    Trait Implementations§

    source§

    impl Clone for ExcessStrategyKind

    source§

    fn clone(&self) -> ExcessStrategyKind

    Returns a copy of the value. Read more
    1.0.0 · source§

    fn clone_from(&mut self, source: &Self)

    Performs copy-assignment from source. Read more
    source§

    impl Debug for ExcessStrategyKind

    source§

    fn fmt(&self, f: &mut Formatter<'_>) -> Result

    Formats the value using the given formatter. Read more
    source§

    impl Display for ExcessStrategyKind

    source§

    fn fmt(&self, f: &mut Formatter<'_>) -> Result

    Formats the value using the given formatter. Read more
    source§

    impl Hash for ExcessStrategyKind

    source§

    fn hash<__H: Hasher>(&self, state: &mut __H)

    Feeds this value into the given Hasher. Read more
    1.3.0 · source§

    fn hash_slice<H>(data: &[Self], state: &mut H)
    where +}

    Variants§

    §

    ToFee

    §

    ToRecipient

    §

    ToDrain

    Trait Implementations§

    source§

    impl Clone for ExcessStrategyKind

    source§

    fn clone(&self) -> ExcessStrategyKind

    Returns a copy of the value. Read more
    1.0.0 · source§

    fn clone_from(&mut self, source: &Self)

    Performs copy-assignment from source. Read more
    source§

    impl Debug for ExcessStrategyKind

    source§

    fn fmt(&self, f: &mut Formatter<'_>) -> Result

    Formats the value using the given formatter. Read more
    source§

    impl Display for ExcessStrategyKind

    source§

    fn fmt(&self, f: &mut Formatter<'_>) -> Result

    Formats the value using the given formatter. Read more
    source§

    impl Hash for ExcessStrategyKind

    source§

    fn hash<__H: Hasher>(&self, state: &mut __H)

    Feeds this value into the given Hasher. Read more
    1.3.0 · source§

    fn hash_slice<H>(data: &[Self], state: &mut H)
    where H: Hasher, Self: Sized,

    Feeds a slice of this type into the given Hasher. Read more
    source§

    impl Ord for ExcessStrategyKind

    source§

    fn cmp(&self, other: &ExcessStrategyKind) -> Ordering

    This method returns an Ordering between self and other. Read more
    1.21.0 · source§

    fn max(self, other: Self) -> Self
    where Self: Sized,

    Compares and returns the maximum of two values. Read more
    1.21.0 · source§

    fn min(self, other: Self) -> Self
    where diff --git a/docs-rs/bdk/nightly/latest/bdk_coin_select/enum.SelectionConstraint.html b/docs-rs/bdk/nightly/latest/bdk_coin_select/enum.SelectionConstraint.html index 502fd1ffe5..3aa459992e 100644 --- a/docs-rs/bdk/nightly/latest/bdk_coin_select/enum.SelectionConstraint.html +++ b/docs-rs/bdk/nightly/latest/bdk_coin_select/enum.SelectionConstraint.html @@ -7,7 +7,7 @@
    §

    TargetFee

    The target fee (given the feerate) is not met

    §

    MinAbsoluteFee

    Min absolute fee is not met

    §

    MinDrainValue

    Min drain value is not met

    -

    Trait Implementations§

    source§

    impl Clone for SelectionConstraint

    source§

    fn clone(&self) -> SelectionConstraint

    Returns a copy of the value. Read more
    1.0.0 · source§

    fn clone_from(&mut self, source: &Self)

    Performs copy-assignment from source. Read more
    source§

    impl Debug for SelectionConstraint

    source§

    fn fmt(&self, f: &mut Formatter<'_>) -> Result

    Formats the value using the given formatter. Read more
    source§

    impl Display for SelectionConstraint

    source§

    fn fmt(&self, f: &mut Formatter<'_>) -> Result

    Formats the value using the given formatter. Read more
    source§

    impl PartialEq for SelectionConstraint

    source§

    fn eq(&self, other: &SelectionConstraint) -> bool

    This method tests for self and other values to be equal, and is used +

    Trait Implementations§

    source§

    impl Clone for SelectionConstraint

    source§

    fn clone(&self) -> SelectionConstraint

    Returns a copy of the value. Read more
    1.0.0 · source§

    fn clone_from(&mut self, source: &Self)

    Performs copy-assignment from source. Read more
    source§

    impl Debug for SelectionConstraint

    source§

    fn fmt(&self, f: &mut Formatter<'_>) -> Result

    Formats the value using the given formatter. Read more
    source§

    impl Display for SelectionConstraint

    source§

    fn fmt(&self, f: &mut Formatter<'_>) -> Result

    Formats the value using the given formatter. Read more
    source§

    impl PartialEq for SelectionConstraint

    source§

    fn eq(&self, other: &SelectionConstraint) -> bool

    This method tests for self and other values to be equal, and is used by ==.
    1.0.0 · source§

    fn ne(&self, other: &Rhs) -> bool

    This method tests for !=. The default implementation is almost always sufficient, and should not be overridden without very good reason.
    source§

    impl Copy for SelectionConstraint

    source§

    impl Eq for SelectionConstraint

    source§

    impl StructuralPartialEq for SelectionConstraint

    Auto Trait Implementations§

    Blanket Implementations§

    source§

    impl<T> Any for T
    where T: 'static + ?Sized,

    source§

    fn type_id(&self) -> TypeId

    Gets the TypeId of self. Read more
    source§

    impl<T> Borrow<T> for T
    where diff --git a/docs-rs/bdk/nightly/latest/bdk_coin_select/struct.SelectionError.html b/docs-rs/bdk/nightly/latest/bdk_coin_select/struct.SelectionError.html index 8858f44b2f..888e52bff1 100644 --- a/docs-rs/bdk/nightly/latest/bdk_coin_select/struct.SelectionError.html +++ b/docs-rs/bdk/nightly/latest/bdk_coin_select/struct.SelectionError.html @@ -1,4 +1,4 @@ -SelectionError in bdk_coin_select - Rust

    Struct bdk_coin_select::SelectionError

    source ·
    pub struct SelectionError { /* private fields */ }

    Trait Implementations§

    source§

    impl Clone for SelectionError

    source§

    fn clone(&self) -> SelectionError

    Returns a copy of the value. Read more
    1.0.0 · source§

    fn clone_from(&mut self, source: &Self)

    Performs copy-assignment from source. Read more
    source§

    impl Debug for SelectionError

    source§

    fn fmt(&self, f: &mut Formatter<'_>) -> Result

    Formats the value using the given formatter. Read more
    source§

    impl Display for SelectionError

    source§

    fn fmt(&self, f: &mut Formatter<'_>) -> Result

    Formats the value using the given formatter. Read more
    source§

    impl Error for SelectionError

    1.30.0 · source§

    fn source(&self) -> Option<&(dyn Error + 'static)>

    The lower-level source of this error, if any. Read more
    1.0.0 · source§

    fn description(&self) -> &str

    👎Deprecated since 1.42.0: use the Display impl or to_string()
    1.0.0 · source§

    fn cause(&self) -> Option<&dyn Error>

    👎Deprecated since 1.33.0: replaced by Error::source, which can support downcasting
    source§

    fn provide<'a>(&'a self, request: &mut Request<'a>)

    🔬This is a nightly-only experimental API. (error_generic_member_access)
    Provides type based access to context intended for error reports. Read more

    Auto Trait Implementations§

    Blanket Implementations§

    source§

    impl<T> Any for T
    where +SelectionError in bdk_coin_select - Rust

    Struct bdk_coin_select::SelectionError

    source ·
    pub struct SelectionError { /* private fields */ }

    Trait Implementations§

    source§

    impl Clone for SelectionError

    source§

    fn clone(&self) -> SelectionError

    Returns a copy of the value. Read more
    1.0.0 · source§

    fn clone_from(&mut self, source: &Self)

    Performs copy-assignment from source. Read more
    source§

    impl Debug for SelectionError

    source§

    fn fmt(&self, f: &mut Formatter<'_>) -> Result

    Formats the value using the given formatter. Read more
    source§

    impl Display for SelectionError

    source§

    fn fmt(&self, f: &mut Formatter<'_>) -> Result

    Formats the value using the given formatter. Read more
    source§

    impl Error for SelectionError

    1.30.0 · source§

    fn source(&self) -> Option<&(dyn Error + 'static)>

    The lower-level source of this error, if any. Read more
    1.0.0 · source§

    fn description(&self) -> &str

    👎Deprecated since 1.42.0: use the Display impl or to_string()
    1.0.0 · source§

    fn cause(&self) -> Option<&dyn Error>

    👎Deprecated since 1.33.0: replaced by Error::source, which can support downcasting
    source§

    fn provide<'a>(&'a self, request: &mut Request<'a>)

    🔬This is a nightly-only experimental API. (error_generic_member_access)
    Provides type based access to context intended for error reports. Read more

    Auto Trait Implementations§

    Blanket Implementations§

    source§

    impl<T> Any for T
    where T: 'static + ?Sized,

    source§

    fn type_id(&self) -> TypeId

    Gets the TypeId of self. Read more
    source§

    impl<T> Borrow<T> for T
    where T: ?Sized,

    source§

    fn borrow(&self) -> &T

    Immutably borrows from an owned value. Read more
    source§

    impl<T> BorrowMut<T> for T
    where T: ?Sized,

    source§

    fn borrow_mut(&mut self) -> &mut T

    Mutably borrows from an owned value. Read more
    source§

    impl<T> From<T> for T

    source§

    fn from(t: T) -> T

    Returns the argument unchanged.

    diff --git a/docs-rs/bdk/nightly/latest/bdk_esplora/trait.EsploraExt.html b/docs-rs/bdk/nightly/latest/bdk_esplora/trait.EsploraExt.html index d92a311c41..ef6f96d2d4 100644 --- a/docs-rs/bdk/nightly/latest/bdk_esplora/trait.EsploraExt.html +++ b/docs-rs/bdk/nightly/latest/bdk_esplora/trait.EsploraExt.html @@ -1,4 +1,4 @@ -EsploraExt in bdk_esplora - Rust

    Trait bdk_esplora::EsploraExt

    source ·
    pub trait EsploraExt {
    +EsploraExt in bdk_esplora - Rust

    Trait bdk_esplora::EsploraExt

    source ·
    pub trait EsploraExt {
         // Required methods
         fn full_scan<K: Ord + Clone>(
             &self,
    @@ -13,7 +13,7 @@
         ) -> Result<SyncResult, Error>;
     }
    Expand description

    Trait to extend the functionality of [esplora_client::BlockingClient].

    Refer to crate-level documentation for more.

    -

    Required Methods§

    Required Methods§

    source

    fn full_scan<K: Ord + Clone>( &self, request: FullScanRequest<K>, stop_gap: usize, @@ -36,7 +36,7 @@

    §Note
    BTCPay Server, and Sparrow.

    A stop_gap of 0 will be treated as a stop_gap of 1.

    -
    source

    fn sync( +

    source

    fn sync( &self, request: SyncRequest, parallel_requests: usize @@ -48,12 +48,12 @@

    §Note

    If the scripts to sync are unknown, such as when restoring or importing a keychain that may include scripts that have been used, use full_scan with the keychain.

    -

    Object Safety§

    This trait is not object safe.

    Implementations on Foreign Types§

    source§

    impl EsploraExt for BlockingClient

    Object Safety§

    This trait is not object safe.

    Implementations on Foreign Types§

    source§

    impl EsploraExt for BlockingClient

    source§

    fn full_scan<K: Ord + Clone>( &self, request: FullScanRequest<K>, stop_gap: usize, parallel_requests: usize -) -> Result<FullScanResult<K>, Error>

    source§

    fn sync( +) -> Result<FullScanResult<K>, Error>

    source§

    fn sync( &self, request: SyncRequest, parallel_requests: usize diff --git a/docs-rs/bdk/nightly/latest/bdk_esplora/type.Error.html b/docs-rs/bdk/nightly/latest/bdk_esplora/type.Error.html index ef36d38dd5..a747392a67 100644 --- a/docs-rs/bdk/nightly/latest/bdk_esplora/type.Error.html +++ b/docs-rs/bdk/nightly/latest/bdk_esplora/type.Error.html @@ -1,2 +1,2 @@ -Error in bdk_esplora - Rust

    Type Alias bdk_esplora::Error

    source ·
    pub type Error = Box<Error>;
    Expand description

    [esplora_client::Error]

    +Error in bdk_esplora - Rust

    Type Alias bdk_esplora::Error

    source ·
    pub type Error = Box<Error>;
    Expand description

    [esplora_client::Error]

    Aliased Type§

    struct Error(/* private fields */);
    \ No newline at end of file diff --git a/docs-rs/bdk/nightly/latest/bdk_file_store/enum.IterError.html b/docs-rs/bdk/nightly/latest/bdk_file_store/enum.IterError.html index 2c58c8c765..38a18a3108 100644 --- a/docs-rs/bdk/nightly/latest/bdk_file_store/enum.IterError.html +++ b/docs-rs/bdk/nightly/latest/bdk_file_store/enum.IterError.html @@ -4,7 +4,7 @@ }
    Expand description

    Error type for EntryIter.

    Variants§

    §

    Io(Error)

    Failure to read from the file.

    §

    Bincode(ErrorKind)

    Failure to decode data from the file.

    -

    Trait Implementations§

    source§

    impl Debug for IterError

    source§

    fn fmt(&self, f: &mut Formatter<'_>) -> Result

    Formats the value using the given formatter. Read more
    source§

    impl Display for IterError

    source§

    fn fmt(&self, f: &mut Formatter<'_>) -> Result

    Formats the value using the given formatter. Read more
    source§

    impl Error for IterError

    1.30.0 · source§

    fn source(&self) -> Option<&(dyn Error + 'static)>

    The lower-level source of this error, if any. Read more
    1.0.0 · source§

    fn description(&self) -> &str

    👎Deprecated since 1.42.0: use the Display impl or to_string()
    1.0.0 · source§

    fn cause(&self) -> Option<&dyn Error>

    👎Deprecated since 1.33.0: replaced by Error::source, which can support downcasting
    source§

    fn provide<'a>(&'a self, request: &mut Request<'a>)

    🔬This is a nightly-only experimental API. (error_generic_member_access)
    Provides type based access to context intended for error reports. Read more
    source§

    impl From<Error> for IterError

    source§

    fn from(value: Error) -> Self

    Converts to this type from the input type.

    Auto Trait Implementations§

    Blanket Implementations§

    source§

    impl<T> Any for T
    where +

    Trait Implementations§

    source§

    impl Debug for IterError

    source§

    fn fmt(&self, f: &mut Formatter<'_>) -> Result

    Formats the value using the given formatter. Read more
    source§

    impl Display for IterError

    source§

    fn fmt(&self, f: &mut Formatter<'_>) -> Result

    Formats the value using the given formatter. Read more
    source§

    impl Error for IterError

    1.30.0 · source§

    fn source(&self) -> Option<&(dyn Error + 'static)>

    The lower-level source of this error, if any. Read more
    1.0.0 · source§

    fn description(&self) -> &str

    👎Deprecated since 1.42.0: use the Display impl or to_string()
    1.0.0 · source§

    fn cause(&self) -> Option<&dyn Error>

    👎Deprecated since 1.33.0: replaced by Error::source, which can support downcasting
    source§

    fn provide<'a>(&'a self, request: &mut Request<'a>)

    🔬This is a nightly-only experimental API. (error_generic_member_access)
    Provides type based access to context intended for error reports. Read more
    source§

    impl From<Error> for IterError

    source§

    fn from(value: Error) -> Self

    Converts to this type from the input type.

    Auto Trait Implementations§

    Blanket Implementations§

    source§

    impl<T> Any for T
    where T: 'static + ?Sized,

    source§

    fn type_id(&self) -> TypeId

    Gets the TypeId of self. Read more
    source§

    impl<T> Borrow<T> for T
    where T: ?Sized,

    source§

    fn borrow(&self) -> &T

    Immutably borrows from an owned value. Read more
    source§

    impl<T> BorrowMut<T> for T
    where T: ?Sized,

    source§

    fn borrow_mut(&mut self) -> &mut T

    Mutably borrows from an owned value. Read more
    source§

    impl<T> From<T> for T

    source§

    fn from(t: T) -> T

    Returns the argument unchanged.

    diff --git a/docs-rs/bdk/nightly/latest/bdk_file_store/struct.AggregateChangesetsError.html b/docs-rs/bdk/nightly/latest/bdk_file_store/struct.AggregateChangesetsError.html index 84c23d6e0b..1a6586014d 100644 --- a/docs-rs/bdk/nightly/latest/bdk_file_store/struct.AggregateChangesetsError.html +++ b/docs-rs/bdk/nightly/latest/bdk_file_store/struct.AggregateChangesetsError.html @@ -4,7 +4,7 @@ }
    Expand description

    Fields§

    §changeset: Option<C>

    The partially-aggregated changeset.

    §iter_error: IterError

    The error returned by EntryIter.

    -

    Trait Implementations§

    source§

    impl<C: Debug> Debug for AggregateChangesetsError<C>

    source§

    fn fmt(&self, f: &mut Formatter<'_>) -> Result

    Formats the value using the given formatter. Read more
    source§

    impl<C> Display for AggregateChangesetsError<C>

    source§

    fn fmt(&self, f: &mut Formatter<'_>) -> Result

    Formats the value using the given formatter. Read more
    source§

    impl<C: Debug> Error for AggregateChangesetsError<C>

    1.30.0 · source§

    fn source(&self) -> Option<&(dyn Error + 'static)>

    The lower-level source of this error, if any. Read more
    1.0.0 · source§

    fn description(&self) -> &str

    👎Deprecated since 1.42.0: use the Display impl or to_string()
    1.0.0 · source§

    fn cause(&self) -> Option<&dyn Error>

    👎Deprecated since 1.33.0: replaced by Error::source, which can support downcasting
    source§

    fn provide<'a>(&'a self, request: &mut Request<'a>)

    🔬This is a nightly-only experimental API. (error_generic_member_access)
    Provides type based access to context intended for error reports. Read more

    Auto Trait Implementations§

    §

    impl<C> Freeze for AggregateChangesetsError<C>
    where +

    Trait Implementations§

    source§

    impl<C: Debug> Debug for AggregateChangesetsError<C>

    source§

    fn fmt(&self, f: &mut Formatter<'_>) -> Result

    Formats the value using the given formatter. Read more
    source§

    impl<C> Display for AggregateChangesetsError<C>

    source§

    fn fmt(&self, f: &mut Formatter<'_>) -> Result

    Formats the value using the given formatter. Read more
    source§

    impl<C: Debug> Error for AggregateChangesetsError<C>

    1.30.0 · source§

    fn source(&self) -> Option<&(dyn Error + 'static)>

    The lower-level source of this error, if any. Read more
    1.0.0 · source§

    fn description(&self) -> &str

    👎Deprecated since 1.42.0: use the Display impl or to_string()
    1.0.0 · source§

    fn cause(&self) -> Option<&dyn Error>

    👎Deprecated since 1.33.0: replaced by Error::source, which can support downcasting
    source§

    fn provide<'a>(&'a self, request: &mut Request<'a>)

    🔬This is a nightly-only experimental API. (error_generic_member_access)
    Provides type based access to context intended for error reports. Read more

    Auto Trait Implementations§

    §

    impl<C> Freeze for AggregateChangesetsError<C>
    where C: Freeze,

    §

    impl<C> !RefUnwindSafe for AggregateChangesetsError<C>

    §

    impl<C> Send for AggregateChangesetsError<C>
    where C: Send,

    §

    impl<C> Sync for AggregateChangesetsError<C>
    where C: Sync,

    §

    impl<C> Unpin for AggregateChangesetsError<C>
    where diff --git a/docs-rs/bdk/nightly/latest/bdk_sqlite/enum.Error.html b/docs-rs/bdk/nightly/latest/bdk_sqlite/enum.Error.html index 86727d4294..32c2fe81fd 100644 --- a/docs-rs/bdk/nightly/latest/bdk_sqlite/enum.Error.html +++ b/docs-rs/bdk/nightly/latest/bdk_sqlite/enum.Error.html @@ -7,7 +7,7 @@ }
    Expand description

    Error that occurs while reading or writing change sets with the SQLite database.

    Variants§

    §

    Network

    Invalid network, cannot change the one already stored in the database.

    Fields

    §expected: Network
    §given: Network
    §

    Sqlite(Error)

    SQLite error.

    -

    Trait Implementations§

    source§

    impl Debug for Error

    source§

    fn fmt(&self, f: &mut Formatter<'_>) -> Result

    Formats the value using the given formatter. Read more
    source§

    impl Display for Error

    source§

    fn fmt(&self, f: &mut Formatter<'_>) -> Result

    Formats the value using the given formatter. Read more
    source§

    impl Error for Error

    1.30.0 · source§

    fn source(&self) -> Option<&(dyn Error + 'static)>

    The lower-level source of this error, if any. Read more
    1.0.0 · source§

    fn description(&self) -> &str

    👎Deprecated since 1.42.0: use the Display impl or to_string()
    1.0.0 · source§

    fn cause(&self) -> Option<&dyn Error>

    👎Deprecated since 1.33.0: replaced by Error::source, which can support downcasting
    source§

    fn provide<'a>(&'a self, request: &mut Request<'a>)

    🔬This is a nightly-only experimental API. (error_generic_member_access)
    Provides type based access to context intended for error reports. Read more

    Auto Trait Implementations§

    §

    impl Freeze for Error

    §

    impl !RefUnwindSafe for Error

    §

    impl Send for Error

    §

    impl Sync for Error

    §

    impl Unpin for Error

    §

    impl !UnwindSafe for Error

    Blanket Implementations§

    source§

    impl<T> Any for T
    where +

    Trait Implementations§

    source§

    impl Debug for Error

    source§

    fn fmt(&self, f: &mut Formatter<'_>) -> Result

    Formats the value using the given formatter. Read more
    source§

    impl Display for Error

    source§

    fn fmt(&self, f: &mut Formatter<'_>) -> Result

    Formats the value using the given formatter. Read more
    source§

    impl Error for Error

    1.30.0 · source§

    fn source(&self) -> Option<&(dyn Error + 'static)>

    The lower-level source of this error, if any. Read more
    1.0.0 · source§

    fn description(&self) -> &str

    👎Deprecated since 1.42.0: use the Display impl or to_string()
    1.0.0 · source§

    fn cause(&self) -> Option<&dyn Error>

    👎Deprecated since 1.33.0: replaced by Error::source, which can support downcasting
    source§

    fn provide<'a>(&'a self, request: &mut Request<'a>)

    🔬This is a nightly-only experimental API. (error_generic_member_access)
    Provides type based access to context intended for error reports. Read more

    Auto Trait Implementations§

    §

    impl Freeze for Error

    §

    impl !RefUnwindSafe for Error

    §

    impl Send for Error

    §

    impl Sync for Error

    §

    impl Unpin for Error

    §

    impl !UnwindSafe for Error

    Blanket Implementations§

    source§

    impl<T> Any for T
    where T: 'static + ?Sized,

    source§

    fn type_id(&self) -> TypeId

    Gets the TypeId of self. Read more
    source§

    impl<T> Borrow<T> for T
    where T: ?Sized,

    source§

    fn borrow(&self) -> &T

    Immutably borrows from an owned value. Read more
    source§

    impl<T> BorrowMut<T> for T
    where T: ?Sized,

    source§

    fn borrow_mut(&mut self) -> &mut T

    Mutably borrows from an owned value. Read more
    source§

    impl<T> From<T> for T

    source§

    fn from(t: T) -> T

    Returns the argument unchanged.

    diff --git a/docs-rs/bdk/nightly/latest/bdk_tmp_plan/enum.SigningError.html b/docs-rs/bdk/nightly/latest/bdk_tmp_plan/enum.SigningError.html index 86474994ea..c3a4667dfd 100644 --- a/docs-rs/bdk/nightly/latest/bdk_tmp_plan/enum.SigningError.html +++ b/docs-rs/bdk/nightly/latest/bdk_tmp_plan/enum.SigningError.html @@ -2,7 +2,7 @@ SigHashP2wpkh(P2wpkhError), SigHashTaproot(TaprootError), DerivationError(Error), -}

    Variants§

    §

    SigHashP2wpkh(P2wpkhError)

    §

    SigHashTaproot(TaprootError)

    §

    DerivationError(Error)

    Trait Implementations§

    source§

    impl Clone for SigningError

    source§

    fn clone(&self) -> SigningError

    Returns a copy of the value. Read more
    1.0.0 · source§

    fn clone_from(&mut self, source: &Self)

    Performs copy-assignment from source. Read more
    source§

    impl Debug for SigningError

    source§

    fn fmt(&self, f: &mut Formatter<'_>) -> Result

    Formats the value using the given formatter. Read more
    source§

    impl Display for SigningError

    source§

    fn fmt(&self, f: &mut Formatter<'_>) -> Result

    Formats the value using the given formatter. Read more
    source§

    impl Error for SigningError

    1.30.0 · source§

    fn source(&self) -> Option<&(dyn Error + 'static)>

    The lower-level source of this error, if any. Read more
    1.0.0 · source§

    fn description(&self) -> &str

    👎Deprecated since 1.42.0: use the Display impl or to_string()
    1.0.0 · source§

    fn cause(&self) -> Option<&dyn Error>

    👎Deprecated since 1.33.0: replaced by Error::source, which can support downcasting
    source§

    fn provide<'a>(&'a self, request: &mut Request<'a>)

    🔬This is a nightly-only experimental API. (error_generic_member_access)
    Provides type based access to context intended for error reports. Read more
    source§

    impl From<Error> for SigningError

    source§

    fn from(e: Error) -> Self

    Converts to this type from the input type.
    source§

    impl From<P2wpkhError> for SigningError

    source§

    fn from(v: P2wpkhError) -> Self

    Converts to this type from the input type.
    source§

    impl From<TaprootError> for SigningError

    source§

    fn from(v: TaprootError) -> Self

    Converts to this type from the input type.

    Auto Trait Implementations§

    Blanket Implementations§

    source§

    impl<T> Any for T
    where +}

    Variants§

    §

    SigHashP2wpkh(P2wpkhError)

    §

    SigHashTaproot(TaprootError)

    §

    DerivationError(Error)

    Trait Implementations§

    source§

    impl Clone for SigningError

    source§

    fn clone(&self) -> SigningError

    Returns a copy of the value. Read more
    1.0.0 · source§

    fn clone_from(&mut self, source: &Self)

    Performs copy-assignment from source. Read more
    source§

    impl Debug for SigningError

    source§

    fn fmt(&self, f: &mut Formatter<'_>) -> Result

    Formats the value using the given formatter. Read more
    source§

    impl Display for SigningError

    source§

    fn fmt(&self, f: &mut Formatter<'_>) -> Result

    Formats the value using the given formatter. Read more
    source§

    impl Error for SigningError

    1.30.0 · source§

    fn source(&self) -> Option<&(dyn Error + 'static)>

    The lower-level source of this error, if any. Read more
    1.0.0 · source§

    fn description(&self) -> &str

    👎Deprecated since 1.42.0: use the Display impl or to_string()
    1.0.0 · source§

    fn cause(&self) -> Option<&dyn Error>

    👎Deprecated since 1.33.0: replaced by Error::source, which can support downcasting
    source§

    fn provide<'a>(&'a self, request: &mut Request<'a>)

    🔬This is a nightly-only experimental API. (error_generic_member_access)
    Provides type based access to context intended for error reports. Read more
    source§

    impl From<Error> for SigningError

    source§

    fn from(e: Error) -> Self

    Converts to this type from the input type.
    source§

    impl From<P2wpkhError> for SigningError

    source§

    fn from(v: P2wpkhError) -> Self

    Converts to this type from the input type.
    source§

    impl From<TaprootError> for SigningError

    source§

    fn from(v: TaprootError) -> Self

    Converts to this type from the input type.

    Auto Trait Implementations§

    Blanket Implementations§

    source§

    impl<T> Any for T
    where T: 'static + ?Sized,

    source§

    fn type_id(&self) -> TypeId

    Gets the TypeId of self. Read more
    source§

    impl<T> Borrow<T> for T
    where T: ?Sized,

    source§

    fn borrow(&self) -> &T

    Immutably borrows from an owned value. Read more
    source§

    impl<T> BorrowMut<T> for T
    where T: ?Sized,

    source§

    fn borrow_mut(&mut self) -> &mut T

    Mutably borrows from an owned value. Read more
    source§

    impl<T> From<T> for T

    source§

    fn from(t: T) -> T

    Returns the argument unchanged.

    diff --git a/docs-rs/bdk/nightly/latest/bdk_wallet/descriptor/enum.Descriptor.html b/docs-rs/bdk/nightly/latest/bdk_wallet/descriptor/enum.Descriptor.html index 6fb42daec0..15f0077bec 100644 --- a/docs-rs/bdk/nightly/latest/bdk_wallet/descriptor/enum.Descriptor.html +++ b/docs-rs/bdk/nightly/latest/bdk_wallet/descriptor/enum.Descriptor.html @@ -255,12 +255,12 @@
    §Errors
    F: FnMut(&'a Pk) -> bool, Pk: 'a,

    Run a predicate on every key in the descriptor, returning whether the predicate returned true for any key
    §

    impl<Pk> From<Bare<Pk>> for Descriptor<Pk>
    where - Pk: MiniscriptKey,

    §

    fn from(inner: Bare<Pk>) -> Descriptor<Pk>

    Converts to this type from the input type.
    §

    impl<Pk> From<Pkh<Pk>> for Descriptor<Pk>
    where + Pk: MiniscriptKey,

    §

    fn from(inner: Bare<Pk>) -> Descriptor<Pk>

    Converts to this type from the input type.
    §

    impl<Pk> From<Pkh<Pk>> for Descriptor<Pk>
    where Pk: MiniscriptKey,

    §

    fn from(inner: Pkh<Pk>) -> Descriptor<Pk>

    Converts to this type from the input type.
    §

    impl<Pk> From<Sh<Pk>> for Descriptor<Pk>
    where Pk: MiniscriptKey,

    §

    fn from(inner: Sh<Pk>) -> Descriptor<Pk>

    Converts to this type from the input type.
    §

    impl<Pk> From<Tr<Pk>> for Descriptor<Pk>
    where - Pk: MiniscriptKey,

    §

    fn from(inner: Tr<Pk>) -> Descriptor<Pk>

    Converts to this type from the input type.
    §

    impl<Pk> From<Wpkh<Pk>> for Descriptor<Pk>
    where - Pk: MiniscriptKey,

    §

    fn from(inner: Wpkh<Pk>) -> Descriptor<Pk>

    Converts to this type from the input type.
    §

    impl<Pk> From<Wsh<Pk>> for Descriptor<Pk>
    where - Pk: MiniscriptKey,

    §

    fn from(inner: Wsh<Pk>) -> Descriptor<Pk>

    Converts to this type from the input type.
    §

    impl<Pk> FromStr for Descriptor<Pk>
    where + Pk: MiniscriptKey,

    §

    fn from(inner: Tr<Pk>) -> Descriptor<Pk>

    Converts to this type from the input type.
    §

    impl<Pk> From<Wpkh<Pk>> for Descriptor<Pk>
    where + Pk: MiniscriptKey,

    §

    fn from(inner: Wpkh<Pk>) -> Descriptor<Pk>

    Converts to this type from the input type.
    §

    impl<Pk> From<Wsh<Pk>> for Descriptor<Pk>
    where + Pk: MiniscriptKey,

    §

    fn from(inner: Wsh<Pk>) -> Descriptor<Pk>

    Converts to this type from the input type.
    §

    impl<Pk> FromStr for Descriptor<Pk>
    where Pk: FromStrKey,

    §

    type Err = Error

    The associated error which can be returned from parsing.
    §

    fn from_str(s: &str) -> Result<Descriptor<Pk>, Error>

    Parses a string s to return a value of this type. Read more
    §

    impl<Pk> FromTree for Descriptor<Pk>
    where Pk: FromStrKey,

    §

    fn from_tree(top: &Tree<'_>) -> Result<Descriptor<Pk>, Error>

    Parse an expression tree into a descriptor.

    §

    impl<Pk> Hash for Descriptor<Pk>
    where diff --git a/docs-rs/bdk/nightly/latest/bdk_wallet/descriptor/enum.DescriptorPublicKey.html b/docs-rs/bdk/nightly/latest/bdk_wallet/descriptor/enum.DescriptorPublicKey.html index fa0ce7b5da..d046385a0d 100644 --- a/docs-rs/bdk/nightly/latest/bdk_wallet/descriptor/enum.DescriptorPublicKey.html +++ b/docs-rs/bdk/nightly/latest/bdk_wallet/descriptor/enum.DescriptorPublicKey.html @@ -52,7 +52,7 @@
    §Errors
    ) -> Result<DescriptorPublicKey, <DescriptorPublicKey as FromStr>::Err>

    Parses a string s to return a value of this type. Read more
    §

    impl Hash for DescriptorPublicKey

    §

    fn hash<__H>(&self, state: &mut __H)
    where __H: Hasher,

    Feeds this value into the given Hasher. Read more
    1.3.0 · source§

    fn hash_slice<H>(data: &[Self], state: &mut H)
    where H: Hasher, - Self: Sized,

    Feeds a slice of this type into the given Hasher. Read more
    §

    impl IntoAssets for DescriptorPublicKey

    §

    fn into_assets(self) -> Assets

    Convert self into a Assets struct
    source§

    impl<Ctx: ScriptContext> IntoDescriptorKey<Ctx> for DescriptorPublicKey

    source§

    fn into_descriptor_key(self) -> Result<DescriptorKey<Ctx>, KeyError>

    Turn the key into a DescriptorKey within the requested ScriptContext
    §

    impl MiniscriptKey for DescriptorPublicKey

    §

    type Sha256 = Hash

    The associated [bitcoin::hashes::sha256::Hash] for this [MiniscriptKey], used in the + Self: Sized,

    Feeds a slice of this type into the given Hasher. Read more
    §

    impl IntoAssets for DescriptorPublicKey

    §

    fn into_assets(self) -> Assets

    Convert self into a Assets struct
    source§

    impl<Ctx: ScriptContext> IntoDescriptorKey<Ctx> for DescriptorPublicKey

    source§

    fn into_descriptor_key(self) -> Result<DescriptorKey<Ctx>, KeyError>

    Turn the key into a DescriptorKey within the requested ScriptContext
    §

    impl MiniscriptKey for DescriptorPublicKey

    §

    type Sha256 = Hash

    The associated [bitcoin::hashes::sha256::Hash] for this [MiniscriptKey], used in the sha256 fragment.
    §

    type Hash256 = Hash

    The associated [miniscript::hash256::Hash] for this [MiniscriptKey], used in the hash256 fragment.
    §

    type Ripemd160 = Hash

    The associated [bitcoin::hashes::ripemd160::Hash] for this [MiniscriptKey] type, used in the ripemd160 fragment.
    §

    type Hash160 = Hash

    The associated [bitcoin::hashes::hash160::Hash] for this [MiniscriptKey] type, used in diff --git a/docs-rs/bdk/nightly/latest/bdk_wallet/descriptor/enum.Legacy.html b/docs-rs/bdk/nightly/latest/bdk_wallet/descriptor/enum.Legacy.html index f296525bec..45513d6ff1 100644 --- a/docs-rs/bdk/nightly/latest/bdk_wallet/descriptor/enum.Legacy.html +++ b/docs-rs/bdk/nightly/latest/bdk_wallet/descriptor/enum.Legacy.html @@ -82,8 +82,8 @@ Pk: MiniscriptKey,

    Check top level consensus rules.
    §

    impl Eq for Legacy

    §

    impl StructuralPartialEq for Legacy

    Auto Trait Implementations§

    §

    impl Freeze for Legacy

    §

    impl RefUnwindSafe for Legacy

    §

    impl Send for Legacy

    §

    impl Sync for Legacy

    §

    impl Unpin for Legacy

    §

    impl UnwindSafe for Legacy

    Blanket Implementations§

    source§

    impl<T> Any for T
    where T: 'static + ?Sized,

    source§

    fn type_id(&self) -> TypeId

    Gets the TypeId of self. Read more
    source§

    impl<T> Borrow<T> for T
    where T: ?Sized,

    source§

    fn borrow(&self) -> &T

    Immutably borrows from an owned value. Read more
    source§

    impl<T> BorrowMut<T> for T
    where - T: ?Sized,

    source§

    fn borrow_mut(&mut self) -> &mut T

    Mutably borrows from an owned value. Read more
    source§

    impl<Ctx> ExtScriptContext for Ctx
    where - Ctx: ScriptContext + 'static,

    source§

    fn as_enum() -> ScriptContextEnum

    source§

    fn is_legacy() -> bool

    Returns whether the script context is Legacy
    source§

    fn is_segwit_v0() -> bool

    Returns whether the script context is Segwitv0
    source§

    fn is_taproot() -> bool

    Returns whether the script context is Tap, aka Taproot or Segwit V1
    source§

    impl<T> From<T> for T

    source§

    fn from(t: T) -> T

    Returns the argument unchanged.

    + T: ?Sized,
    source§

    fn borrow_mut(&mut self) -> &mut T

    Mutably borrows from an owned value. Read more
    source§

    impl<Ctx> ExtScriptContext for Ctx
    where + Ctx: ScriptContext + 'static,

    source§

    fn as_enum() -> ScriptContextEnum

    source§

    fn is_legacy() -> bool

    Returns whether the script context is Legacy
    source§

    fn is_segwit_v0() -> bool

    Returns whether the script context is Segwitv0
    source§

    fn is_taproot() -> bool

    Returns whether the script context is Tap, aka Taproot or Segwit V1
    source§

    impl<T> From<T> for T

    source§

    fn from(t: T) -> T

    Returns the argument unchanged.

    source§

    impl<T, U> Into<U> for T
    where U: From<T>,

    source§

    fn into(self) -> U

    Calls U::from(self).

    That is, this conversion is whatever the implementation of diff --git a/docs-rs/bdk/nightly/latest/bdk_wallet/descriptor/enum.Segwitv0.html b/docs-rs/bdk/nightly/latest/bdk_wallet/descriptor/enum.Segwitv0.html index 5e8b714fac..4f02256169 100644 --- a/docs-rs/bdk/nightly/latest/bdk_wallet/descriptor/enum.Segwitv0.html +++ b/docs-rs/bdk/nightly/latest/bdk_wallet/descriptor/enum.Segwitv0.html @@ -79,8 +79,8 @@ Pk: MiniscriptKey,

    Check top level consensus rules.
    §

    impl Eq for Segwitv0

    §

    impl StructuralPartialEq for Segwitv0

    Auto Trait Implementations§

    Blanket Implementations§

    source§

    impl<T> Any for T
    where T: 'static + ?Sized,

    source§

    fn type_id(&self) -> TypeId

    Gets the TypeId of self. Read more
    source§

    impl<T> Borrow<T> for T
    where T: ?Sized,

    source§

    fn borrow(&self) -> &T

    Immutably borrows from an owned value. Read more
    source§

    impl<T> BorrowMut<T> for T
    where - T: ?Sized,

    source§

    fn borrow_mut(&mut self) -> &mut T

    Mutably borrows from an owned value. Read more
    source§

    impl<Ctx> ExtScriptContext for Ctx
    where - Ctx: ScriptContext + 'static,

    source§

    fn as_enum() -> ScriptContextEnum

    source§

    fn is_legacy() -> bool

    Returns whether the script context is Legacy
    source§

    fn is_segwit_v0() -> bool

    Returns whether the script context is Segwitv0
    source§

    fn is_taproot() -> bool

    Returns whether the script context is Tap, aka Taproot or Segwit V1
    source§

    impl<T> From<T> for T

    source§

    fn from(t: T) -> T

    Returns the argument unchanged.

    + T: ?Sized,
    source§

    fn borrow_mut(&mut self) -> &mut T

    Mutably borrows from an owned value. Read more
    source§

    impl<Ctx> ExtScriptContext for Ctx
    where + Ctx: ScriptContext + 'static,

    source§

    fn as_enum() -> ScriptContextEnum

    source§

    fn is_legacy() -> bool

    Returns whether the script context is Legacy
    source§

    fn is_segwit_v0() -> bool

    Returns whether the script context is Segwitv0
    source§

    fn is_taproot() -> bool

    Returns whether the script context is Tap, aka Taproot or Segwit V1
    source§

    impl<T> From<T> for T

    source§

    fn from(t: T) -> T

    Returns the argument unchanged.

    source§

    impl<T, U> Into<U> for T
    where U: From<T>,

    source§

    fn into(self) -> U

    Calls U::from(self).

    That is, this conversion is whatever the implementation of diff --git a/docs-rs/bdk/nightly/latest/bdk_wallet/descriptor/error/enum.Error.html b/docs-rs/bdk/nightly/latest/bdk_wallet/descriptor/error/enum.Error.html index 46b5c7fb21..c2431ab8e2 100644 --- a/docs-rs/bdk/nightly/latest/bdk_wallet/descriptor/error/enum.Error.html +++ b/docs-rs/bdk/nightly/latest/bdk_wallet/descriptor/error/enum.Error.html @@ -26,7 +26,7 @@

    §

    Miniscript(Error)

    Miniscript error

    §

    Hex(HexToBytesError)

    Hex decoding error

    §

    ExternalAndInternalAreTheSame

    The provided wallet descriptors are identical

    -

    Trait Implementations§

    source§

    impl Debug for Error

    source§

    fn fmt(&self, f: &mut Formatter<'_>) -> Result

    Formats the value using the given formatter. Read more
    source§

    impl Display for Error

    source§

    fn fmt(&self, f: &mut Formatter<'_>) -> Result

    Formats the value using the given formatter. Read more
    source§

    impl Error for Error

    1.30.0 · source§

    fn source(&self) -> Option<&(dyn Error + 'static)>

    The lower-level source of this error, if any. Read more
    1.0.0 · source§

    fn description(&self) -> &str

    👎Deprecated since 1.42.0: use the Display impl or to_string()
    1.0.0 · source§

    fn cause(&self) -> Option<&dyn Error>

    👎Deprecated since 1.33.0: replaced by Error::source, which can support downcasting
    source§

    fn provide<'a>(&'a self, request: &mut Request<'a>)

    🔬This is a nightly-only experimental API. (error_generic_member_access)
    Provides type based access to context intended for error reports. Read more
    source§

    impl From<Error> for CreateTxError

    source§

    fn from(err: Error) -> Self

    Converts to this type from the input type.
    source§

    impl From<Error> for Error

    source§

    fn from(err: Error) -> Self

    Converts to this type from the input type.
    source§

    impl From<Error> for Error

    source§

    fn from(err: Error) -> Self

    Converts to this type from the input type.
    source§

    impl From<Error> for Error

    source§

    fn from(err: Error) -> Self

    Converts to this type from the input type.
    source§

    impl From<HexToBytesError> for Error

    source§

    fn from(err: HexToBytesError) -> Self

    Converts to this type from the input type.
    source§

    impl From<KeyError> for Error

    source§

    fn from(key_error: KeyError) -> Error

    Converts to this type from the input type.
    source§

    impl From<ParsePublicKeyError> for Error

    source§

    fn from(err: ParsePublicKeyError) -> Self

    Converts to this type from the input type.
    source§

    impl From<PolicyError> for Error

    source§

    fn from(err: PolicyError) -> Self

    Converts to this type from the input type.

    Auto Trait Implementations§

    §

    impl Freeze for Error

    §

    impl RefUnwindSafe for Error

    §

    impl Send for Error

    §

    impl Sync for Error

    §

    impl Unpin for Error

    §

    impl UnwindSafe for Error

    Blanket Implementations§

    source§

    impl<T> Any for T
    where +

    Trait Implementations§

    source§

    impl Debug for Error

    source§

    fn fmt(&self, f: &mut Formatter<'_>) -> Result

    Formats the value using the given formatter. Read more
    source§

    impl Display for Error

    source§

    fn fmt(&self, f: &mut Formatter<'_>) -> Result

    Formats the value using the given formatter. Read more
    source§

    impl Error for Error

    1.30.0 · source§

    fn source(&self) -> Option<&(dyn Error + 'static)>

    The lower-level source of this error, if any. Read more
    1.0.0 · source§

    fn description(&self) -> &str

    👎Deprecated since 1.42.0: use the Display impl or to_string()
    1.0.0 · source§

    fn cause(&self) -> Option<&dyn Error>

    👎Deprecated since 1.33.0: replaced by Error::source, which can support downcasting
    source§

    fn provide<'a>(&'a self, request: &mut Request<'a>)

    🔬This is a nightly-only experimental API. (error_generic_member_access)
    Provides type based access to context intended for error reports. Read more
    source§

    impl From<Error> for CreateTxError

    source§

    fn from(err: Error) -> Self

    Converts to this type from the input type.
    source§

    impl From<Error> for Error

    source§

    fn from(err: Error) -> Self

    Converts to this type from the input type.
    source§

    impl From<Error> for Error

    source§

    fn from(err: Error) -> Self

    Converts to this type from the input type.
    source§

    impl From<Error> for Error

    source§

    fn from(err: Error) -> Self

    Converts to this type from the input type.
    source§

    impl From<HexToBytesError> for Error

    source§

    fn from(err: HexToBytesError) -> Self

    Converts to this type from the input type.
    source§

    impl From<KeyError> for Error

    source§

    fn from(key_error: KeyError) -> Error

    Converts to this type from the input type.
    source§

    impl From<ParsePublicKeyError> for Error

    source§

    fn from(err: ParsePublicKeyError) -> Self

    Converts to this type from the input type.
    source§

    impl From<PolicyError> for Error

    source§

    fn from(err: PolicyError) -> Self

    Converts to this type from the input type.

    Auto Trait Implementations§

    §

    impl Freeze for Error

    §

    impl RefUnwindSafe for Error

    §

    impl Send for Error

    §

    impl Sync for Error

    §

    impl Unpin for Error

    §

    impl UnwindSafe for Error

    Blanket Implementations§

    source§

    impl<T> Any for T
    where T: 'static + ?Sized,

    source§

    fn type_id(&self) -> TypeId

    Gets the TypeId of self. Read more
    source§

    impl<T> Borrow<T> for T
    where T: ?Sized,

    source§

    fn borrow(&self) -> &T

    Immutably borrows from an owned value. Read more
    source§

    impl<T> BorrowMut<T> for T
    where T: ?Sized,

    source§

    fn borrow_mut(&mut self) -> &mut T

    Mutably borrows from an owned value. Read more
    source§

    impl<T> From<T> for T

    source§

    fn from(t: T) -> T

    Returns the argument unchanged.

    diff --git a/docs-rs/bdk/nightly/latest/bdk_wallet/descriptor/policy/enum.PolicyError.html b/docs-rs/bdk/nightly/latest/bdk_wallet/descriptor/policy/enum.PolicyError.html index 43d71a502e..8bac101f36 100644 --- a/docs-rs/bdk/nightly/latest/bdk_wallet/descriptor/policy/enum.PolicyError.html +++ b/docs-rs/bdk/nightly/latest/bdk_wallet/descriptor/policy/enum.PolicyError.html @@ -12,7 +12,7 @@
    §

    AddOnPartialComplete

    Can not add to an item that is Satisfaction::PartialComplete

    §

    MixedTimelockUnits

    Can not merge CSV or timelock values unless both are less than or both are equal or greater than 500_000_000

    §

    IncompatibleConditions

    Incompatible conditions (not currently used)

    -

    Trait Implementations§

    source§

    impl Debug for PolicyError

    source§

    fn fmt(&self, f: &mut Formatter<'_>) -> Result

    Formats the value using the given formatter. Read more
    source§

    impl Display for PolicyError

    source§

    fn fmt(&self, f: &mut Formatter<'_>) -> Result

    Formats the value using the given formatter. Read more
    source§

    impl Error for PolicyError

    1.30.0 · source§

    fn source(&self) -> Option<&(dyn Error + 'static)>

    The lower-level source of this error, if any. Read more
    1.0.0 · source§

    fn description(&self) -> &str

    👎Deprecated since 1.42.0: use the Display impl or to_string()
    1.0.0 · source§

    fn cause(&self) -> Option<&dyn Error>

    👎Deprecated since 1.33.0: replaced by Error::source, which can support downcasting
    source§

    fn provide<'a>(&'a self, request: &mut Request<'a>)

    🔬This is a nightly-only experimental API. (error_generic_member_access)
    Provides type based access to context intended for error reports. Read more
    source§

    impl From<PolicyError> for CreateTxError

    source§

    fn from(err: PolicyError) -> Self

    Converts to this type from the input type.
    source§

    impl From<PolicyError> for Error

    source§

    fn from(err: PolicyError) -> Self

    Converts to this type from the input type.
    source§

    impl PartialEq for PolicyError

    source§

    fn eq(&self, other: &PolicyError) -> bool

    This method tests for self and other values to be equal, and is used +

    Trait Implementations§

    source§

    impl Debug for PolicyError

    source§

    fn fmt(&self, f: &mut Formatter<'_>) -> Result

    Formats the value using the given formatter. Read more
    source§

    impl Display for PolicyError

    source§

    fn fmt(&self, f: &mut Formatter<'_>) -> Result

    Formats the value using the given formatter. Read more
    source§

    impl Error for PolicyError

    1.30.0 · source§

    fn source(&self) -> Option<&(dyn Error + 'static)>

    The lower-level source of this error, if any. Read more
    1.0.0 · source§

    fn description(&self) -> &str

    👎Deprecated since 1.42.0: use the Display impl or to_string()
    1.0.0 · source§

    fn cause(&self) -> Option<&dyn Error>

    👎Deprecated since 1.33.0: replaced by Error::source, which can support downcasting
    source§

    fn provide<'a>(&'a self, request: &mut Request<'a>)

    🔬This is a nightly-only experimental API. (error_generic_member_access)
    Provides type based access to context intended for error reports. Read more
    source§

    impl From<PolicyError> for CreateTxError

    source§

    fn from(err: PolicyError) -> Self

    Converts to this type from the input type.
    source§

    impl From<PolicyError> for Error

    source§

    fn from(err: PolicyError) -> Self

    Converts to this type from the input type.
    source§

    impl PartialEq for PolicyError

    source§

    fn eq(&self, other: &PolicyError) -> bool

    This method tests for self and other values to be equal, and is used by ==.
    1.0.0 · source§

    fn ne(&self, other: &Rhs) -> bool

    This method tests for !=. The default implementation is almost always sufficient, and should not be overridden without very good reason.
    source§

    impl Eq for PolicyError

    source§

    impl StructuralPartialEq for PolicyError

    Auto Trait Implementations§

    Blanket Implementations§

    source§

    impl<T> Any for T
    where T: 'static + ?Sized,

    source§

    fn type_id(&self) -> TypeId

    Gets the TypeId of self. Read more
    source§

    impl<T> Borrow<T> for T
    where diff --git a/docs-rs/bdk/nightly/latest/bdk_wallet/index.html b/docs-rs/bdk/nightly/latest/bdk_wallet/index.html index b08c21566e..83d163d6f5 100644 --- a/docs-rs/bdk/nightly/latest/bdk_wallet/index.html +++ b/docs-rs/bdk/nightly/latest/bdk_wallet/index.html @@ -57,30 +57,28 @@

    §Persistence
    use bdk_wallet::{bitcoin::Network, KeychainKind, wallet::{ChangeSet, Wallet}};
     
    -fn main() {
    -    // Open or create a new file store for wallet data.
    -    let mut db =
    -        bdk_file_store::Store::<ChangeSet>::open_or_create_new(b"magic_bytes", "/tmp/my_wallet.db")
    -            .expect("create store");
    +// Open or create a new file store for wallet data.
    +let mut db =
    +    bdk_file_store::Store::<ChangeSet>::open_or_create_new(b"magic_bytes", "/tmp/my_wallet.db")
    +        .expect("create store");
     
    -    // Create a wallet with initial wallet data read from the file store.
    -    let descriptor = "wpkh(tprv8ZgxMBicQKsPdcAqYBpzAFwU5yxBUo88ggoBqu1qPcHUfSbKK1sKMLmC7EAk438btHQrSdu3jGGQa6PA71nvH5nkDexhLteJqkM4dQmWF9g/84'/1'/0'/0/*)";
    -    let change_descriptor = "wpkh(tprv8ZgxMBicQKsPdcAqYBpzAFwU5yxBUo88ggoBqu1qPcHUfSbKK1sKMLmC7EAk438btHQrSdu3jGGQa6PA71nvH5nkDexhLteJqkM4dQmWF9g/84'/1'/0'/1/*)";
    -    let changeset = db.aggregate_changesets().expect("changeset loaded");
    -    let mut wallet =
    -        Wallet::new_or_load(descriptor, change_descriptor, changeset, Network::Testnet)
    -            .expect("create or load wallet");
    +// Create a wallet with initial wallet data read from the file store.
    +let descriptor = "wpkh(tprv8ZgxMBicQKsPdcAqYBpzAFwU5yxBUo88ggoBqu1qPcHUfSbKK1sKMLmC7EAk438btHQrSdu3jGGQa6PA71nvH5nkDexhLteJqkM4dQmWF9g/84'/1'/0'/0/*)";
    +let change_descriptor = "wpkh(tprv8ZgxMBicQKsPdcAqYBpzAFwU5yxBUo88ggoBqu1qPcHUfSbKK1sKMLmC7EAk438btHQrSdu3jGGQa6PA71nvH5nkDexhLteJqkM4dQmWF9g/84'/1'/0'/1/*)";
    +let changeset = db.aggregate_changesets().expect("changeset loaded");
    +let mut wallet =
    +    Wallet::new_or_load(descriptor, change_descriptor, changeset, Network::Testnet)
    +        .expect("create or load wallet");
     
    -    // Get a new address to receive bitcoin.
    -    let receive_address = wallet.reveal_next_address(KeychainKind::External);
    -    // Persist staged wallet data changes to the file store.
    -    let staged_changeset = wallet.take_staged();
    -    if let Some(changeset) = staged_changeset {
    -        db.append_changeset(&changeset)
    -            .expect("must commit changes to database");
    -    }
    -    println!("Your new receive address is: {}", receive_address.address);
    -}
    +// Get a new address to receive bitcoin. +let receive_address = wallet.reveal_next_address(KeychainKind::External); +// Persist staged wallet data changes to the file store. +let staged_changeset = wallet.take_staged(); +if let Some(changeset) = staged_changeset { + db.append_changeset(&changeset) + .expect("must commit changes to database"); +} +println!("Your new receive address is: {}", receive_address.address);

    diff --git a/docs-rs/bdk/nightly/latest/bdk_wallet/keys/enum.DescriptorKey.html b/docs-rs/bdk/nightly/latest/bdk_wallet/keys/enum.DescriptorKey.html index e85af60660..eb10b74bd5 100644 --- a/docs-rs/bdk/nightly/latest/bdk_wallet/keys/enum.DescriptorKey.html +++ b/docs-rs/bdk/nightly/latest/bdk_wallet/keys/enum.DescriptorKey.html @@ -1,11 +1,11 @@ -DescriptorKey in bdk_wallet::keys - Rust

    Enum bdk_wallet::keys::DescriptorKey

    source ·
    pub enum DescriptorKey<Ctx: ScriptContext> {
    +DescriptorKey in bdk_wallet::keys - Rust

    Enum bdk_wallet::keys::DescriptorKey

    source ·
    pub enum DescriptorKey<Ctx: ScriptContext> {
         // some variants omitted
     }
    Expand description

    Container for public or secret keys

    -

    Implementations§

    source§

    impl<Ctx: ScriptContext> DescriptorKey<Ctx>

    source

    pub fn from_public(public: DescriptorPublicKey, networks: ValidNetworks) -> Self

    Create an instance given a public key and a set of valid networks

    -
    source

    pub fn from_secret(secret: DescriptorSecretKey, networks: ValidNetworks) -> Self

    Create an instance given a secret key and a set of valid networks

    -
    source

    pub fn override_valid_networks(self, networks: ValidNetworks) -> Self

    Override the computed set of valid networks

    -

    Trait Implementations§

    source§

    impl<Ctx: Debug + ScriptContext> Debug for DescriptorKey<Ctx>

    source§

    fn fmt(&self, f: &mut Formatter<'_>) -> Result

    Formats the value using the given formatter. Read more
    source§

    impl<Ctx: ScriptContext> IntoDescriptorKey<Ctx> for DescriptorKey<Ctx>

    The “identity” conversion is used internally by some bdk_wallet::fragments

    -
    source§

    fn into_descriptor_key(self) -> Result<DescriptorKey<Ctx>, KeyError>

    Turn the key into a DescriptorKey within the requested ScriptContext

    Auto Trait Implementations§

    §

    impl<Ctx> Freeze for DescriptorKey<Ctx>

    §

    impl<Ctx> RefUnwindSafe for DescriptorKey<Ctx>
    where +

    Implementations§

    source§

    impl<Ctx: ScriptContext> DescriptorKey<Ctx>

    source

    pub fn from_public(public: DescriptorPublicKey, networks: ValidNetworks) -> Self

    Create an instance given a public key and a set of valid networks

    +
    source

    pub fn from_secret(secret: DescriptorSecretKey, networks: ValidNetworks) -> Self

    Create an instance given a secret key and a set of valid networks

    +
    source

    pub fn override_valid_networks(self, networks: ValidNetworks) -> Self

    Override the computed set of valid networks

    +

    Trait Implementations§

    source§

    impl<Ctx: Debug + ScriptContext> Debug for DescriptorKey<Ctx>

    source§

    fn fmt(&self, f: &mut Formatter<'_>) -> Result

    Formats the value using the given formatter. Read more
    source§

    impl<Ctx: ScriptContext> IntoDescriptorKey<Ctx> for DescriptorKey<Ctx>

    The “identity” conversion is used internally by some bdk_wallet::fragments

    +
    source§

    fn into_descriptor_key(self) -> Result<DescriptorKey<Ctx>, KeyError>

    Turn the key into a DescriptorKey within the requested ScriptContext

    Auto Trait Implementations§

    §

    impl<Ctx> Freeze for DescriptorKey<Ctx>

    §

    impl<Ctx> RefUnwindSafe for DescriptorKey<Ctx>
    where Ctx: RefUnwindSafe,

    §

    impl<Ctx> Send for DescriptorKey<Ctx>
    where Ctx: Send,

    §

    impl<Ctx> Sync for DescriptorKey<Ctx>
    where Ctx: Sync,

    §

    impl<Ctx> Unpin for DescriptorKey<Ctx>
    where diff --git a/docs-rs/bdk/nightly/latest/bdk_wallet/keys/enum.DescriptorPublicKey.html b/docs-rs/bdk/nightly/latest/bdk_wallet/keys/enum.DescriptorPublicKey.html index 6bfda325fd..b6e1d7c3b2 100644 --- a/docs-rs/bdk/nightly/latest/bdk_wallet/keys/enum.DescriptorPublicKey.html +++ b/docs-rs/bdk/nightly/latest/bdk_wallet/keys/enum.DescriptorPublicKey.html @@ -52,7 +52,7 @@
    §Errors
    ) -> Result<DescriptorPublicKey, <DescriptorPublicKey as FromStr>::Err>

    Parses a string s to return a value of this type. Read more
    §

    impl Hash for DescriptorPublicKey

    §

    fn hash<__H>(&self, state: &mut __H)
    where __H: Hasher,

    Feeds this value into the given Hasher. Read more
    1.3.0 · source§

    fn hash_slice<H>(data: &[Self], state: &mut H)
    where H: Hasher, - Self: Sized,

    Feeds a slice of this type into the given Hasher. Read more
    §

    impl IntoAssets for DescriptorPublicKey

    §

    fn into_assets(self) -> Assets

    Convert self into a Assets struct
    source§

    impl<Ctx: ScriptContext> IntoDescriptorKey<Ctx> for DescriptorPublicKey

    source§

    fn into_descriptor_key(self) -> Result<DescriptorKey<Ctx>, KeyError>

    Turn the key into a DescriptorKey within the requested ScriptContext
    §

    impl MiniscriptKey for DescriptorPublicKey

    §

    type Sha256 = Hash

    The associated [bitcoin::hashes::sha256::Hash] for this [MiniscriptKey], used in the + Self: Sized,
    Feeds a slice of this type into the given Hasher. Read more
    §

    impl IntoAssets for DescriptorPublicKey

    §

    fn into_assets(self) -> Assets

    Convert self into a Assets struct
    source§

    impl<Ctx: ScriptContext> IntoDescriptorKey<Ctx> for DescriptorPublicKey

    source§

    fn into_descriptor_key(self) -> Result<DescriptorKey<Ctx>, KeyError>

    Turn the key into a DescriptorKey within the requested ScriptContext
    §

    impl MiniscriptKey for DescriptorPublicKey

    §

    type Sha256 = Hash

    The associated [bitcoin::hashes::sha256::Hash] for this [MiniscriptKey], used in the sha256 fragment.
    §

    type Hash256 = Hash

    The associated [miniscript::hash256::Hash] for this [MiniscriptKey], used in the hash256 fragment.
    §

    type Ripemd160 = Hash

    The associated [bitcoin::hashes::ripemd160::Hash] for this [MiniscriptKey] type, used in the ripemd160 fragment.
    §

    type Hash160 = Hash

    The associated [bitcoin::hashes::hash160::Hash] for this [MiniscriptKey] type, used in diff --git a/docs-rs/bdk/nightly/latest/bdk_wallet/keys/enum.DescriptorSecretKey.html b/docs-rs/bdk/nightly/latest/bdk_wallet/keys/enum.DescriptorSecretKey.html index afb4e9b8db..598766547f 100644 --- a/docs-rs/bdk/nightly/latest/bdk_wallet/keys/enum.DescriptorSecretKey.html +++ b/docs-rs/bdk/nightly/latest/bdk_wallet/keys/enum.DescriptorSecretKey.html @@ -23,7 +23,7 @@ path.

    Trait Implementations§

    §

    impl Clone for DescriptorSecretKey

    §

    fn clone(&self) -> DescriptorSecretKey

    Returns a copy of the value. Read more
    1.0.0 · source§

    fn clone_from(&mut self, source: &Self)

    Performs copy-assignment from source. Read more
    §

    impl Debug for DescriptorSecretKey

    §

    fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

    Formats the value using the given formatter. Read more
    §

    impl Display for DescriptorSecretKey

    §

    fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

    Formats the value using the given formatter. Read more
    §

    impl FromStr for DescriptorSecretKey

    §

    type Err = DescriptorKeyParseError

    The associated error which can be returned from parsing.
    §

    fn from_str( s: &str -) -> Result<DescriptorSecretKey, <DescriptorSecretKey as FromStr>::Err>

    Parses a string s to return a value of this type. Read more
    source§

    impl<Ctx: ScriptContext> IntoDescriptorKey<Ctx> for DescriptorSecretKey

    source§

    fn into_descriptor_key(self) -> Result<DescriptorKey<Ctx>, KeyError>

    Turn the key into a DescriptorKey within the requested ScriptContext
    §

    impl PartialEq for DescriptorSecretKey

    §

    fn eq(&self, other: &DescriptorSecretKey) -> bool

    This method tests for self and other values to be equal, and is used +) -> Result<DescriptorSecretKey, <DescriptorSecretKey as FromStr>::Err>
    Parses a string s to return a value of this type. Read more
    source§

    impl<Ctx: ScriptContext> IntoDescriptorKey<Ctx> for DescriptorSecretKey

    source§

    fn into_descriptor_key(self) -> Result<DescriptorKey<Ctx>, KeyError>

    Turn the key into a DescriptorKey within the requested ScriptContext
    §

    impl PartialEq for DescriptorSecretKey

    §

    fn eq(&self, other: &DescriptorSecretKey) -> bool

    This method tests for self and other values to be equal, and is used by ==.
    1.0.0 · source§

    fn ne(&self, other: &Rhs) -> bool

    This method tests for !=. The default implementation is almost always sufficient, and should not be overridden without very good reason.
    §

    impl Eq for DescriptorSecretKey

    §

    impl StructuralPartialEq for DescriptorSecretKey

    Auto Trait Implementations§

    Blanket Implementations§

    source§

    impl<T> Any for T
    where T: 'static + ?Sized,

    source§

    fn type_id(&self) -> TypeId

    Gets the TypeId of self. Read more
    source§

    impl<T> Borrow<T> for T
    where diff --git a/docs-rs/bdk/nightly/latest/bdk_wallet/keys/enum.ExtendedKey.html b/docs-rs/bdk/nightly/latest/bdk_wallet/keys/enum.ExtendedKey.html index 6e9aad882f..4dc408b9dc 100644 --- a/docs-rs/bdk/nightly/latest/bdk_wallet/keys/enum.ExtendedKey.html +++ b/docs-rs/bdk/nightly/latest/bdk_wallet/keys/enum.ExtendedKey.html @@ -1,4 +1,4 @@ -ExtendedKey in bdk_wallet::keys - Rust

    Enum bdk_wallet::keys::ExtendedKey

    source ·
    pub enum ExtendedKey<Ctx: ScriptContext = Legacy> {
    +ExtendedKey in bdk_wallet::keys - Rust

    Enum bdk_wallet::keys::ExtendedKey

    source ·
    pub enum ExtendedKey<Ctx: ScriptContext = Legacy> {
         Private((Xpriv, PhantomData<Ctx>)),
         Public((Xpub, PhantomData<Ctx>)),
     }
    Expand description

    Enum for extended keys that can be either xprv or xpub

    @@ -7,22 +7,22 @@

    Defaults to the Legacy context.

    Variants§

    §

    Private((Xpriv, PhantomData<Ctx>))

    A private extended key, aka an xprv

    §

    Public((Xpub, PhantomData<Ctx>))

    A public extended key, aka an xpub

    -

    Implementations§

    source§

    impl<Ctx: ScriptContext> ExtendedKey<Ctx>

    source

    pub fn has_secret(&self) -> bool

    Return whether or not the key contains the private data

    -
    source

    pub fn into_xprv(self, network: Network) -> Option<Xpriv>

    Transform the ExtendedKey into an Xpriv for the +

    Implementations§

    source§

    impl<Ctx: ScriptContext> ExtendedKey<Ctx>

    source

    pub fn has_secret(&self) -> bool

    Return whether or not the key contains the private data

    +
    source

    pub fn into_xprv(self, network: Network) -> Option<Xpriv>

    Transform the ExtendedKey into an Xpriv for the given [Network], if the key contains the private data

    -
    source

    pub fn into_xpub<C: Signing>( +

    source

    pub fn into_xpub<C: Signing>( self, network: Network, secp: &Secp256k1<C> ) -> Xpub

    Transform the ExtendedKey into an Xpub for the given [Network]

    -

    Trait Implementations§

    source§

    impl<Ctx: ScriptContext> DerivableKey<Ctx> for ExtendedKey<Ctx>

    Identity conversion

    -
    source§

    fn into_extended_key(self) -> Result<ExtendedKey<Ctx>, KeyError>

    Consume self and turn it into an ExtendedKey
    source§

    fn into_descriptor_key( +

    Trait Implementations§

    source§

    impl<Ctx: ScriptContext> DerivableKey<Ctx> for ExtendedKey<Ctx>

    Identity conversion

    +
    source§

    fn into_extended_key(self) -> Result<ExtendedKey<Ctx>, KeyError>

    Consume self and turn it into an ExtendedKey
    source§

    fn into_descriptor_key( self, origin: Option<KeySource>, derivation_path: DerivationPath ) -> Result<DescriptorKey<Ctx>, KeyError>

    Consume self and turn it into a DescriptorKey by adding the extra metadata, such as -key origin and derivation path
    source§

    impl<Ctx: ScriptContext> From<Xpriv> for ExtendedKey<Ctx>

    source§

    fn from(xprv: Xpriv) -> Self

    Converts to this type from the input type.
    source§

    impl<Ctx: ScriptContext> From<Xpub> for ExtendedKey<Ctx>

    source§

    fn from(xpub: Xpub) -> Self

    Converts to this type from the input type.

    Auto Trait Implementations§

    §

    impl<Ctx> Freeze for ExtendedKey<Ctx>

    §

    impl<Ctx> RefUnwindSafe for ExtendedKey<Ctx>
    where +key origin and derivation path

    source§

    impl<Ctx: ScriptContext> From<Xpriv> for ExtendedKey<Ctx>

    source§

    fn from(xprv: Xpriv) -> Self

    Converts to this type from the input type.
    source§

    impl<Ctx: ScriptContext> From<Xpub> for ExtendedKey<Ctx>

    source§

    fn from(xpub: Xpub) -> Self

    Converts to this type from the input type.

    Auto Trait Implementations§

    §

    impl<Ctx> Freeze for ExtendedKey<Ctx>

    §

    impl<Ctx> RefUnwindSafe for ExtendedKey<Ctx>
    where Ctx: RefUnwindSafe,

    §

    impl<Ctx> Send for ExtendedKey<Ctx>
    where Ctx: Send,

    §

    impl<Ctx> Sync for ExtendedKey<Ctx>
    where Ctx: Sync,

    §

    impl<Ctx> Unpin for ExtendedKey<Ctx>
    where diff --git a/docs-rs/bdk/nightly/latest/bdk_wallet/keys/enum.KeyError.html b/docs-rs/bdk/nightly/latest/bdk_wallet/keys/enum.KeyError.html index d4787f644c..1ad7a50661 100644 --- a/docs-rs/bdk/nightly/latest/bdk_wallet/keys/enum.KeyError.html +++ b/docs-rs/bdk/nightly/latest/bdk_wallet/keys/enum.KeyError.html @@ -1,4 +1,4 @@ -KeyError in bdk_wallet::keys - Rust

    Enum bdk_wallet::keys::KeyError

    source ·
    pub enum KeyError {
    +KeyError in bdk_wallet::keys - Rust

    Enum bdk_wallet::keys::KeyError

    source ·
    pub enum KeyError {
         InvalidScriptContext,
         InvalidNetwork,
         InvalidChecksum,
    @@ -12,7 +12,7 @@
     
    §

    Message(String)

    Custom error message

    §

    Bip32(Error)

    BIP32 error

    §

    Miniscript(Error)

    Miniscript error

    -

    Trait Implementations§

    source§

    impl Debug for KeyError

    source§

    fn fmt(&self, f: &mut Formatter<'_>) -> Result

    Formats the value using the given formatter. Read more
    source§

    impl Display for KeyError

    source§

    fn fmt(&self, f: &mut Formatter<'_>) -> Result

    Formats the value using the given formatter. Read more
    source§

    impl Error for KeyError

    1.30.0 · source§

    fn source(&self) -> Option<&(dyn Error + 'static)>

    The lower-level source of this error, if any. Read more
    1.0.0 · source§

    fn description(&self) -> &str

    👎Deprecated since 1.42.0: use the Display impl or to_string()
    1.0.0 · source§

    fn cause(&self) -> Option<&dyn Error>

    👎Deprecated since 1.33.0: replaced by Error::source, which can support downcasting
    source§

    fn provide<'a>(&'a self, request: &mut Request<'a>)

    🔬This is a nightly-only experimental API. (error_generic_member_access)
    Provides type based access to context intended for error reports. Read more
    source§

    impl From<Error> for KeyError

    source§

    fn from(err: Error) -> Self

    Converts to this type from the input type.
    source§

    impl From<Error> for KeyError

    source§

    fn from(err: Error) -> Self

    Converts to this type from the input type.
    source§

    impl From<KeyError> for Error

    source§

    fn from(key_error: KeyError) -> Error

    Converts to this type from the input type.

    Auto Trait Implementations§

    Blanket Implementations§

    source§

    impl<T> Any for T
    where +

    Trait Implementations§

    source§

    impl Debug for KeyError

    source§

    fn fmt(&self, f: &mut Formatter<'_>) -> Result

    Formats the value using the given formatter. Read more
    source§

    impl Display for KeyError

    source§

    fn fmt(&self, f: &mut Formatter<'_>) -> Result

    Formats the value using the given formatter. Read more
    source§

    impl Error for KeyError

    1.30.0 · source§

    fn source(&self) -> Option<&(dyn Error + 'static)>

    The lower-level source of this error, if any. Read more
    1.0.0 · source§

    fn description(&self) -> &str

    👎Deprecated since 1.42.0: use the Display impl or to_string()
    1.0.0 · source§

    fn cause(&self) -> Option<&dyn Error>

    👎Deprecated since 1.33.0: replaced by Error::source, which can support downcasting
    source§

    fn provide<'a>(&'a self, request: &mut Request<'a>)

    🔬This is a nightly-only experimental API. (error_generic_member_access)
    Provides type based access to context intended for error reports. Read more
    source§

    impl From<Error> for KeyError

    source§

    fn from(err: Error) -> Self

    Converts to this type from the input type.
    source§

    impl From<Error> for KeyError

    source§

    fn from(err: Error) -> Self

    Converts to this type from the input type.
    source§

    impl From<KeyError> for Error

    source§

    fn from(key_error: KeyError) -> Error

    Converts to this type from the input type.

    Auto Trait Implementations§

    Blanket Implementations§

    source§

    impl<T> Any for T
    where T: 'static + ?Sized,

    source§

    fn type_id(&self) -> TypeId

    Gets the TypeId of self. Read more
    source§

    impl<T> Borrow<T> for T
    where T: ?Sized,

    source§

    fn borrow(&self) -> &T

    Immutably borrows from an owned value. Read more
    source§

    impl<T> BorrowMut<T> for T
    where T: ?Sized,

    source§

    fn borrow_mut(&mut self) -> &mut T

    Mutably borrows from an owned value. Read more
    source§

    impl<T> From<T> for T

    source§

    fn from(t: T) -> T

    Returns the argument unchanged.

    diff --git a/docs-rs/bdk/nightly/latest/bdk_wallet/keys/enum.ScriptContextEnum.html b/docs-rs/bdk/nightly/latest/bdk_wallet/keys/enum.ScriptContextEnum.html index 05356abfa7..44a688a401 100644 --- a/docs-rs/bdk/nightly/latest/bdk_wallet/keys/enum.ScriptContextEnum.html +++ b/docs-rs/bdk/nightly/latest/bdk_wallet/keys/enum.ScriptContextEnum.html @@ -1,4 +1,4 @@ -ScriptContextEnum in bdk_wallet::keys - Rust

    Enum bdk_wallet::keys::ScriptContextEnum

    source ·
    pub enum ScriptContextEnum {
    +ScriptContextEnum in bdk_wallet::keys - Rust

    Enum bdk_wallet::keys::ScriptContextEnum

    source ·
    pub enum ScriptContextEnum {
         Legacy,
         Segwitv0,
         Tap,
    @@ -6,12 +6,12 @@
     

    Variants§

    §

    Legacy

    Legacy scripts

    §

    Segwitv0

    Segwitv0 scripts

    §

    Tap

    Taproot scripts

    -

    Implementations§

    source§

    impl ScriptContextEnum

    source

    pub fn is_legacy(&self) -> bool

    Returns whether the script context is ScriptContextEnum::Legacy

    -
    source

    pub fn is_segwit_v0(&self) -> bool

    Returns whether the script context is ScriptContextEnum::Segwitv0

    -
    source

    pub fn is_taproot(&self) -> bool

    Returns whether the script context is ScriptContextEnum::Tap

    -

    Trait Implementations§

    source§

    impl Clone for ScriptContextEnum

    source§

    fn clone(&self) -> ScriptContextEnum

    Returns a copy of the value. Read more
    1.0.0 · source§

    fn clone_from(&mut self, source: &Self)

    Performs copy-assignment from source. Read more
    source§

    impl Debug for ScriptContextEnum

    source§

    fn fmt(&self, f: &mut Formatter<'_>) -> Result

    Formats the value using the given formatter. Read more
    source§

    impl PartialEq for ScriptContextEnum

    source§

    fn eq(&self, other: &ScriptContextEnum) -> bool

    This method tests for self and other values to be equal, and is used +

    Implementations§

    source§

    impl ScriptContextEnum

    source

    pub fn is_legacy(&self) -> bool

    Returns whether the script context is ScriptContextEnum::Legacy

    +
    source

    pub fn is_segwit_v0(&self) -> bool

    Returns whether the script context is ScriptContextEnum::Segwitv0

    +
    source

    pub fn is_taproot(&self) -> bool

    Returns whether the script context is ScriptContextEnum::Tap

    +

    Trait Implementations§

    source§

    impl Clone for ScriptContextEnum

    source§

    fn clone(&self) -> ScriptContextEnum

    Returns a copy of the value. Read more
    1.0.0 · source§

    fn clone_from(&mut self, source: &Self)

    Performs copy-assignment from source. Read more
    source§

    impl Debug for ScriptContextEnum

    source§

    fn fmt(&self, f: &mut Formatter<'_>) -> Result

    Formats the value using the given formatter. Read more
    source§

    impl PartialEq for ScriptContextEnum

    source§

    fn eq(&self, other: &ScriptContextEnum) -> bool

    This method tests for self and other values to be equal, and is used by ==.
    1.0.0 · source§

    fn ne(&self, other: &Rhs) -> bool

    This method tests for !=. The default implementation is almost always -sufficient, and should not be overridden without very good reason.
    source§

    impl Copy for ScriptContextEnum

    source§

    impl Eq for ScriptContextEnum

    source§

    impl StructuralPartialEq for ScriptContextEnum

    Auto Trait Implementations§

    Blanket Implementations§

    source§

    impl<T> Any for T
    where +sufficient, and should not be overridden without very good reason.

    source§

    impl Copy for ScriptContextEnum

    source§

    impl Eq for ScriptContextEnum

    source§

    impl StructuralPartialEq for ScriptContextEnum

    Auto Trait Implementations§

    Blanket Implementations§

    source§

    impl<T> Any for T
    where T: 'static + ?Sized,

    source§

    fn type_id(&self) -> TypeId

    Gets the TypeId of self. Read more
    source§

    impl<T> Borrow<T> for T
    where T: ?Sized,

    source§

    fn borrow(&self) -> &T

    Immutably borrows from an owned value. Read more
    source§

    impl<T> BorrowMut<T> for T
    where T: ?Sized,

    source§

    fn borrow_mut(&mut self) -> &mut T

    Mutably borrows from an owned value. Read more
    source§

    impl<T> From<T> for T

    source§

    fn from(t: T) -> T

    Returns the argument unchanged.

    diff --git a/docs-rs/bdk/nightly/latest/bdk_wallet/keys/fn.any_network.html b/docs-rs/bdk/nightly/latest/bdk_wallet/keys/fn.any_network.html index e192f6d87d..77f03324cf 100644 --- a/docs-rs/bdk/nightly/latest/bdk_wallet/keys/fn.any_network.html +++ b/docs-rs/bdk/nightly/latest/bdk_wallet/keys/fn.any_network.html @@ -1,2 +1,2 @@ -any_network in bdk_wallet::keys - Rust

    Function bdk_wallet::keys::any_network

    source ·
    pub fn any_network() -> ValidNetworks
    Expand description

    Create a set containing mainnet, testnet, signet, and regtest

    +any_network in bdk_wallet::keys - Rust

    Function bdk_wallet::keys::any_network

    source ·
    pub fn any_network() -> ValidNetworks
    Expand description

    Create a set containing mainnet, testnet, signet, and regtest

    \ No newline at end of file diff --git a/docs-rs/bdk/nightly/latest/bdk_wallet/keys/fn.mainnet_network.html b/docs-rs/bdk/nightly/latest/bdk_wallet/keys/fn.mainnet_network.html index 06b6d4c5eb..9ad3615d49 100644 --- a/docs-rs/bdk/nightly/latest/bdk_wallet/keys/fn.mainnet_network.html +++ b/docs-rs/bdk/nightly/latest/bdk_wallet/keys/fn.mainnet_network.html @@ -1,2 +1,2 @@ -mainnet_network in bdk_wallet::keys - Rust

    Function bdk_wallet::keys::mainnet_network

    source ·
    pub fn mainnet_network() -> ValidNetworks
    Expand description

    Create a set only containing mainnet

    +mainnet_network in bdk_wallet::keys - Rust

    Function bdk_wallet::keys::mainnet_network

    source ·
    pub fn mainnet_network() -> ValidNetworks
    Expand description

    Create a set only containing mainnet

    \ No newline at end of file diff --git a/docs-rs/bdk/nightly/latest/bdk_wallet/keys/fn.merge_networks.html b/docs-rs/bdk/nightly/latest/bdk_wallet/keys/fn.merge_networks.html index 774894c522..fb889c9f21 100644 --- a/docs-rs/bdk/nightly/latest/bdk_wallet/keys/fn.merge_networks.html +++ b/docs-rs/bdk/nightly/latest/bdk_wallet/keys/fn.merge_networks.html @@ -1,2 +1,2 @@ -merge_networks in bdk_wallet::keys - Rust

    Function bdk_wallet::keys::merge_networks

    source ·
    pub fn merge_networks(a: &ValidNetworks, b: &ValidNetworks) -> ValidNetworks
    Expand description

    Compute the intersection of two sets

    +merge_networks in bdk_wallet::keys - Rust

    Function bdk_wallet::keys::merge_networks

    source ·
    pub fn merge_networks(a: &ValidNetworks, b: &ValidNetworks) -> ValidNetworks
    Expand description

    Compute the intersection of two sets

    \ No newline at end of file diff --git a/docs-rs/bdk/nightly/latest/bdk_wallet/keys/fn.test_networks.html b/docs-rs/bdk/nightly/latest/bdk_wallet/keys/fn.test_networks.html index 0973484ec0..fc05ca1509 100644 --- a/docs-rs/bdk/nightly/latest/bdk_wallet/keys/fn.test_networks.html +++ b/docs-rs/bdk/nightly/latest/bdk_wallet/keys/fn.test_networks.html @@ -1,2 +1,2 @@ -test_networks in bdk_wallet::keys - Rust

    Function bdk_wallet::keys::test_networks

    source ·
    pub fn test_networks() -> ValidNetworks
    Expand description

    Create a set containing testnet and regtest

    +test_networks in bdk_wallet::keys - Rust

    Function bdk_wallet::keys::test_networks

    source ·
    pub fn test_networks() -> ValidNetworks
    Expand description

    Create a set containing testnet and regtest

    \ No newline at end of file diff --git a/docs-rs/bdk/nightly/latest/bdk_wallet/keys/index.html b/docs-rs/bdk/nightly/latest/bdk_wallet/keys/index.html index 73b57f23bd..6fb3240128 100644 --- a/docs-rs/bdk/nightly/latest/bdk_wallet/keys/index.html +++ b/docs-rs/bdk/nightly/latest/bdk_wallet/keys/index.html @@ -1,4 +1,4 @@ -bdk_wallet::keys - Rust

    Module bdk_wallet::keys

    source ·
    Expand description

    Key formats

    +bdk_wallet::keys - Rust

    Module bdk_wallet::keys

    source ·
    Expand description

    Key formats

    Structs§

    Enums§

    Traits§

    source§

    impl<Ctx, K> IntoDescriptorKey<Ctx> for GeneratedKey<K, Ctx>
    where Ctx: ScriptContext, - K: IntoDescriptorKey<Ctx>,

    source§

    fn into_descriptor_key(self) -> Result<DescriptorKey<Ctx>, KeyError>

    Turn the key into a DescriptorKey within the requested ScriptContext

    Auto Trait Implementations§

    §

    impl<K, Ctx> Freeze for GeneratedKey<K, Ctx>
    where + K: IntoDescriptorKey<Ctx>,

    source§

    fn into_descriptor_key(self) -> Result<DescriptorKey<Ctx>, KeyError>

    Turn the key into a DescriptorKey within the requested ScriptContext

    Auto Trait Implementations§

    §

    impl<K, Ctx> Freeze for GeneratedKey<K, Ctx>
    where K: Freeze,

    §

    impl<K, Ctx> RefUnwindSafe for GeneratedKey<K, Ctx>

    §

    impl<K, Ctx> Send for GeneratedKey<K, Ctx>
    where diff --git a/docs-rs/bdk/nightly/latest/bdk_wallet/keys/struct.PrivateKeyGenerateOptions.html b/docs-rs/bdk/nightly/latest/bdk_wallet/keys/struct.PrivateKeyGenerateOptions.html index 7fdd8a4578..befb16e539 100644 --- a/docs-rs/bdk/nightly/latest/bdk_wallet/keys/struct.PrivateKeyGenerateOptions.html +++ b/docs-rs/bdk/nightly/latest/bdk_wallet/keys/struct.PrivateKeyGenerateOptions.html @@ -1,9 +1,9 @@ -PrivateKeyGenerateOptions in bdk_wallet::keys - Rust

    Struct bdk_wallet::keys::PrivateKeyGenerateOptions

    source ·
    pub struct PrivateKeyGenerateOptions {
    +PrivateKeyGenerateOptions in bdk_wallet::keys - Rust

    Struct bdk_wallet::keys::PrivateKeyGenerateOptions

    source ·
    pub struct PrivateKeyGenerateOptions {
         pub compressed: bool,
     }
    Expand description

    Options for generating a [PrivateKey]

    Defaults to creating compressed keys, which save on-chain bytes and fees

    Fields§

    §compressed: bool

    Whether the generated key should be “compressed” or not

    -

    Trait Implementations§

    source§

    impl Clone for PrivateKeyGenerateOptions

    source§

    fn clone(&self) -> PrivateKeyGenerateOptions

    Returns a copy of the value. Read more
    1.0.0 · source§

    fn clone_from(&mut self, source: &Self)

    Performs copy-assignment from source. Read more
    source§

    impl Debug for PrivateKeyGenerateOptions

    source§

    fn fmt(&self, f: &mut Formatter<'_>) -> Result

    Formats the value using the given formatter. Read more
    source§

    impl Default for PrivateKeyGenerateOptions

    source§

    fn default() -> Self

    Returns the “default value” for a type. Read more
    source§

    impl Copy for PrivateKeyGenerateOptions

    Auto Trait Implementations§

    Blanket Implementations§

    source§

    impl<T> Any for T
    where +

    Trait Implementations§

    source§

    impl Clone for PrivateKeyGenerateOptions

    source§

    fn clone(&self) -> PrivateKeyGenerateOptions

    Returns a copy of the value. Read more
    1.0.0 · source§

    fn clone_from(&mut self, source: &Self)

    Performs copy-assignment from source. Read more
    source§

    impl Debug for PrivateKeyGenerateOptions

    source§

    fn fmt(&self, f: &mut Formatter<'_>) -> Result

    Formats the value using the given formatter. Read more
    source§

    impl Default for PrivateKeyGenerateOptions

    source§

    fn default() -> Self

    Returns the “default value” for a type. Read more
    source§

    impl Copy for PrivateKeyGenerateOptions

    Auto Trait Implementations§

    Blanket Implementations§

    source§

    impl<T> Any for T
    where T: 'static + ?Sized,

    source§

    fn type_id(&self) -> TypeId

    Gets the TypeId of self. Read more
    source§

    impl<T> Borrow<T> for T
    where T: ?Sized,

    source§

    fn borrow(&self) -> &T

    Immutably borrows from an owned value. Read more
    source§

    impl<T> BorrowMut<T> for T
    where T: ?Sized,

    source§

    fn borrow_mut(&mut self) -> &mut T

    Mutably borrows from an owned value. Read more
    source§

    impl<T> From<T> for T

    source§

    fn from(t: T) -> T

    Returns the argument unchanged.

    diff --git a/docs-rs/bdk/nightly/latest/bdk_wallet/keys/trait.DerivableKey.html b/docs-rs/bdk/nightly/latest/bdk_wallet/keys/trait.DerivableKey.html index e5891209ea..44f701039f 100644 --- a/docs-rs/bdk/nightly/latest/bdk_wallet/keys/trait.DerivableKey.html +++ b/docs-rs/bdk/nightly/latest/bdk_wallet/keys/trait.DerivableKey.html @@ -1,4 +1,4 @@ -DerivableKey in bdk_wallet::keys - Rust

    Trait bdk_wallet::keys::DerivableKey

    source ·
    pub trait DerivableKey<Ctx: ScriptContext = Legacy>: Sized {
    +DerivableKey in bdk_wallet::keys - Rust

    Trait bdk_wallet::keys::DerivableKey

    source ·
    pub trait DerivableKey<Ctx: ScriptContext = Legacy>: Sized {
         // Required method
         fn into_extended_key(self) -> Result<ExtendedKey<Ctx>, KeyError>;
     
    @@ -86,14 +86,14 @@ 

    §Examples

    Ok(descriptor_key.override_valid_networks(any_network())) } }
    -

    Required Methods§

    source

    fn into_extended_key(self) -> Result<ExtendedKey<Ctx>, KeyError>

    Consume self and turn it into an ExtendedKey

    -

    Provided Methods§

    Required Methods§

    source

    fn into_extended_key(self) -> Result<ExtendedKey<Ctx>, KeyError>

    Consume self and turn it into an ExtendedKey

    +

    Provided Methods§

    source

    fn into_descriptor_key( self, origin: Option<KeySource>, derivation_path: DerivationPath ) -> Result<DescriptorKey<Ctx>, KeyError>

    Consume self and turn it into a DescriptorKey by adding the extra metadata, such as key origin and derivation path

    -

    Object Safety§

    This trait is not object safe.

    Implementations on Foreign Types§

    source§

    impl<Ctx: ScriptContext> DerivableKey<Ctx> for Xpriv

    source§

    impl<Ctx: ScriptContext> DerivableKey<Ctx> for Xpub

    Implementors§

    source§

    impl<Ctx, K> DerivableKey<Ctx> for GeneratedKey<K, Ctx>
    where +

    Object Safety§

    This trait is not object safe.

    Implementations on Foreign Types§

    source§

    impl<Ctx: ScriptContext> DerivableKey<Ctx> for Xpriv

    source§

    impl<Ctx: ScriptContext> DerivableKey<Ctx> for Xpub

    Implementors§

    source§

    impl<Ctx, K> DerivableKey<Ctx> for GeneratedKey<K, Ctx>
    where Ctx: ScriptContext, - K: DerivableKey<Ctx>,

    source§

    impl<Ctx: ScriptContext> DerivableKey<Ctx> for ExtendedKey<Ctx>

    Identity conversion

    + K: DerivableKey<Ctx>,

    source§

    impl<Ctx: ScriptContext> DerivableKey<Ctx> for ExtendedKey<Ctx>

    Identity conversion

    \ No newline at end of file diff --git a/docs-rs/bdk/nightly/latest/bdk_wallet/keys/trait.ExtScriptContext.html b/docs-rs/bdk/nightly/latest/bdk_wallet/keys/trait.ExtScriptContext.html index 5a6413a081..a28d1e328b 100644 --- a/docs-rs/bdk/nightly/latest/bdk_wallet/keys/trait.ExtScriptContext.html +++ b/docs-rs/bdk/nightly/latest/bdk_wallet/keys/trait.ExtScriptContext.html @@ -1,4 +1,4 @@ -ExtScriptContext in bdk_wallet::keys - Rust

    Trait bdk_wallet::keys::ExtScriptContext

    source ·
    pub trait ExtScriptContext: ScriptContext {
    +ExtScriptContext in bdk_wallet::keys - Rust

    Trait bdk_wallet::keys::ExtScriptContext

    source ·
    pub trait ExtScriptContext: ScriptContext {
         // Required method
         fn as_enum() -> ScriptContextEnum;
     
    @@ -7,8 +7,8 @@
         fn is_segwit_v0() -> bool { ... }
         fn is_taproot() -> bool { ... }
     }
    Expand description

    Trait that adds extra useful methods to ScriptContexts

    -

    Required Methods§

    Provided Methods§

    source

    fn is_legacy() -> bool

    Returns whether the script context is Legacy

    -
    source

    fn is_segwit_v0() -> bool

    Returns whether the script context is Segwitv0

    -
    source

    fn is_taproot() -> bool

    Returns whether the script context is Tap, aka Taproot or Segwit V1

    -

    Object Safety§

    This trait is not object safe.

    Implementors§

    source§

    impl<Ctx: ScriptContext + 'static> ExtScriptContext for Ctx

    \ No newline at end of file +

    Required Methods§

    Provided Methods§

    source

    fn is_legacy() -> bool

    Returns whether the script context is Legacy

    +
    source

    fn is_segwit_v0() -> bool

    Returns whether the script context is Segwitv0

    +
    source

    fn is_taproot() -> bool

    Returns whether the script context is Tap, aka Taproot or Segwit V1

    +

    Object Safety§

    This trait is not object safe.

    Implementors§

    source§

    impl<Ctx: ScriptContext + 'static> ExtScriptContext for Ctx

    \ No newline at end of file diff --git a/docs-rs/bdk/nightly/latest/bdk_wallet/keys/trait.GeneratableDefaultOptions.html b/docs-rs/bdk/nightly/latest/bdk_wallet/keys/trait.GeneratableDefaultOptions.html index d2d16f8508..a12d1282e2 100644 --- a/docs-rs/bdk/nightly/latest/bdk_wallet/keys/trait.GeneratableDefaultOptions.html +++ b/docs-rs/bdk/nightly/latest/bdk_wallet/keys/trait.GeneratableDefaultOptions.html @@ -1,4 +1,4 @@ -GeneratableDefaultOptions in bdk_wallet::keys - Rust

    Trait bdk_wallet::keys::GeneratableDefaultOptions

    source ·
    pub trait GeneratableDefaultOptions<Ctx>: GeneratableKey<Ctx>
    where +GeneratableDefaultOptions in bdk_wallet::keys - Rust

    Trait bdk_wallet::keys::GeneratableDefaultOptions

    source ·
    pub trait GeneratableDefaultOptions<Ctx>: GeneratableKey<Ctx>
    where Ctx: ScriptContext, <Self as GeneratableKey<Ctx>>::Options: Default,
    { // Provided methods @@ -6,13 +6,21 @@ entropy: Self::Entropy ) -> Result<GeneratedKey<Self, Ctx>, Self::Error> { ... } fn generate_default() -> Result<GeneratedKey<Self, Ctx>, Self::Error> { ... } + fn generate_default_with_aux_rand( + rng: &mut (impl CryptoRng + RngCore) + ) -> Result<GeneratedKey<Self, Ctx>, Self::Error> { ... } }
    Expand description

    Trait that allows generating a key with the default options

    This trait is automatically implemented if the GeneratableKey::Options implements Default.

    -

    Provided Methods§

    Provided Methods§

    source

    fn generate_with_entropy_default( entropy: Self::Entropy ) -> Result<GeneratedKey<Self, Ctx>, Self::Error>

    Generate a key with the default options and a given entropy

    -
    source

    fn generate_default() -> Result<GeneratedKey<Self, Ctx>, Self::Error>

    Generate a key with the default options and a random entropy

    -

    Object Safety§

    This trait is not object safe.

    Implementors§

    source§

    impl<Ctx, K> GeneratableDefaultOptions<Ctx> for K
    where +

    source

    fn generate_default() -> Result<GeneratedKey<Self, Ctx>, Self::Error>

    Generate a key with the default options and a random entropy

    +

    Uses the thread-local random number generator.

    +
    source

    fn generate_default_with_aux_rand( + rng: &mut (impl CryptoRng + RngCore) +) -> Result<GeneratedKey<Self, Ctx>, Self::Error>

    Generate a key with the default options and a random entropy

    +

    Uses a provided random number generator (rng).

    +

    Object Safety§

    This trait is not object safe.

    Implementors§

    source§

    impl<Ctx, K> GeneratableDefaultOptions<Ctx> for K
    where Ctx: ScriptContext, K: GeneratableKey<Ctx>, <K as GeneratableKey<Ctx>>::Options: Default,

    Automatic implementation of GeneratableDefaultOptions for GeneratableKeys where diff --git a/docs-rs/bdk/nightly/latest/bdk_wallet/keys/trait.GeneratableKey.html b/docs-rs/bdk/nightly/latest/bdk_wallet/keys/trait.GeneratableKey.html index 7110824ef7..38004fde09 100644 --- a/docs-rs/bdk/nightly/latest/bdk_wallet/keys/trait.GeneratableKey.html +++ b/docs-rs/bdk/nightly/latest/bdk_wallet/keys/trait.GeneratableKey.html @@ -1,4 +1,4 @@ -GeneratableKey in bdk_wallet::keys - Rust

    Trait bdk_wallet::keys::GeneratableKey

    source ·
    pub trait GeneratableKey<Ctx: ScriptContext>: Sized {
    +GeneratableKey in bdk_wallet::keys - Rust

    Trait bdk_wallet::keys::GeneratableKey

    source ·
    pub trait GeneratableKey<Ctx: ScriptContext>: Sized {
         type Entropy: AsMut<[u8]> + Default;
         type Options;
         type Error: Debug;
    @@ -9,30 +9,40 @@
             entropy: Self::Entropy
         ) -> Result<GeneratedKey<Self, Ctx>, Self::Error>;
     
    -    // Provided method
    +    // Provided methods
         fn generate(
             options: Self::Options
         ) -> Result<GeneratedKey<Self, Ctx>, Self::Error> { ... }
    +    fn generate_with_aux_rand(
    +        options: Self::Options,
    +        rng: &mut (impl CryptoRng + RngCore)
    +    ) -> Result<GeneratedKey<Self, Ctx>, Self::Error> { ... }
     }
    Expand description

    Trait for keys that can be generated

    The same rules about ScriptContext and ValidNetworks from IntoDescriptorKey apply.

    This trait is particularly useful when combined with DerivableKey: if Self implements it, the returned GeneratedKey will also implement it. The same is true for IntoDescriptorKey: the generated keys can be directly used in descriptors if Self is also IntoDescriptorKey.

    -

    Required Associated Types§

    source

    type Entropy: AsMut<[u8]> + Default

    Type specifying the amount of entropy required e.g. [u8;32]

    -
    source

    type Options

    Extra options required by the generate_with_entropy

    -
    source

    type Error: Debug

    Returned error in case of failure

    -

    Required Methods§

    Required Associated Types§

    source

    type Entropy: AsMut<[u8]> + Default

    Type specifying the amount of entropy required e.g. [u8;32]

    +
    source

    type Options

    Extra options required by the generate_with_entropy

    +
    source

    type Error: Debug

    Returned error in case of failure

    +

    Required Methods§

    source

    fn generate_with_entropy( options: Self::Options, entropy: Self::Entropy ) -> Result<GeneratedKey<Self, Ctx>, Self::Error>

    Generate a key given the extra options and the entropy

    -

    Provided Methods§

    Provided Methods§

    source

    fn generate( options: Self::Options -) -> Result<GeneratedKey<Self, Ctx>, Self::Error>

    Generate a key given the options with a random entropy

    -

    Object Safety§

    This trait is not object safe.

    Implementations on Foreign Types§

    source§

    impl<Ctx: ScriptContext> GeneratableKey<Ctx> for PrivateKey

    §

    type Entropy = [u8; 32]

    §

    type Options = PrivateKeyGenerateOptions

    §

    type Error = Error

    source§

    fn generate_with_entropy( +) -> Result<GeneratedKey<Self, Ctx>, Self::Error>

    Generate a key given the options with random entropy.

    +

    Uses the thread-local random number generator.

    +
    source

    fn generate_with_aux_rand( + options: Self::Options, + rng: &mut (impl CryptoRng + RngCore) +) -> Result<GeneratedKey<Self, Ctx>, Self::Error>

    Generate a key given the options with random entropy.

    +

    Uses a provided random number generator (rng).

    +

    Object Safety§

    This trait is not object safe.

    Implementations on Foreign Types§

    source§

    impl<Ctx: ScriptContext> GeneratableKey<Ctx> for PrivateKey

    §

    type Entropy = [u8; 32]

    §

    type Options = PrivateKeyGenerateOptions

    §

    type Error = Error

    source§

    fn generate_with_entropy( options: Self::Options, entropy: Self::Entropy -) -> Result<GeneratedKey<Self, Ctx>, Self::Error>

    source§

    impl<Ctx: ScriptContext> GeneratableKey<Ctx> for Xpriv

    §

    type Entropy = [u8; 32]

    §

    type Options = ()

    §

    type Error = Error

    source§

    fn generate_with_entropy( +) -> Result<GeneratedKey<Self, Ctx>, Self::Error>

    source§

    impl<Ctx: ScriptContext> GeneratableKey<Ctx> for Xpriv

    §

    type Entropy = [u8; 32]

    §

    type Options = ()

    §

    type Error = Error

    source§

    fn generate_with_entropy( _: Self::Options, entropy: Self::Entropy ) -> Result<GeneratedKey<Self, Ctx>, Self::Error>

    Implementors§

    \ No newline at end of file diff --git a/docs-rs/bdk/nightly/latest/bdk_wallet/keys/trait.IntoDescriptorKey.html b/docs-rs/bdk/nightly/latest/bdk_wallet/keys/trait.IntoDescriptorKey.html index c1af88c61c..64ac3842ce 100644 --- a/docs-rs/bdk/nightly/latest/bdk_wallet/keys/trait.IntoDescriptorKey.html +++ b/docs-rs/bdk/nightly/latest/bdk_wallet/keys/trait.IntoDescriptorKey.html @@ -1,4 +1,4 @@ -IntoDescriptorKey in bdk_wallet::keys - Rust

    Trait bdk_wallet::keys::IntoDescriptorKey

    source ·
    pub trait IntoDescriptorKey<Ctx: ScriptContext>: Sized {
    +IntoDescriptorKey in bdk_wallet::keys - Rust

    Trait bdk_wallet::keys::IntoDescriptorKey

    source ·
    pub trait IntoDescriptorKey<Ctx: ScriptContext>: Sized {
         // Required method
         fn into_descriptor_key(self) -> Result<DescriptorKey<Ctx>, KeyError>;
     }
    Expand description

    Trait for objects that can be turned into a public or secret DescriptorKey

    @@ -103,8 +103,8 @@

    §Examples

    let (descriptor, _, _) = bdk_wallet::descriptor!(pkh(key))?; // ^^^^^ changing this to `wpkh` would make it compile
    -

    Required Methods§

    source

    fn into_descriptor_key(self) -> Result<DescriptorKey<Ctx>, KeyError>

    Turn the key into a DescriptorKey within the requested ScriptContext

    -

    Object Safety§

    This trait is not object safe.

    Implementations on Foreign Types§

    source§

    impl<Ctx: ScriptContext> IntoDescriptorKey<Ctx> for &str

    source§

    impl<Ctx: ScriptContext> IntoDescriptorKey<Ctx> for PrivateKey

    source§

    impl<Ctx: ScriptContext> IntoDescriptorKey<Ctx> for PublicKey

    source§

    impl<Ctx: ScriptContext> IntoDescriptorKey<Ctx> for XOnlyPublicKey

    source§

    impl<Ctx: ScriptContext, T: DerivableKey<Ctx>> IntoDescriptorKey<Ctx> for (T, DerivationPath)

    source§

    impl<Ctx: ScriptContext, T: DerivableKey<Ctx>> IntoDescriptorKey<Ctx> for (T, KeySource, DerivationPath)

    Implementors§

    source§

    impl<Ctx, K> IntoDescriptorKey<Ctx> for GeneratedKey<K, Ctx>
    where +

    Required Methods§

    source

    fn into_descriptor_key(self) -> Result<DescriptorKey<Ctx>, KeyError>

    Turn the key into a DescriptorKey within the requested ScriptContext

    +

    Object Safety§

    This trait is not object safe.

    Implementations on Foreign Types§

    source§

    impl<Ctx: ScriptContext> IntoDescriptorKey<Ctx> for &str

    source§

    impl<Ctx: ScriptContext> IntoDescriptorKey<Ctx> for PrivateKey

    source§

    impl<Ctx: ScriptContext> IntoDescriptorKey<Ctx> for PublicKey

    source§

    impl<Ctx: ScriptContext> IntoDescriptorKey<Ctx> for XOnlyPublicKey

    source§

    impl<Ctx: ScriptContext, T: DerivableKey<Ctx>> IntoDescriptorKey<Ctx> for (T, DerivationPath)

    source§

    impl<Ctx: ScriptContext, T: DerivableKey<Ctx>> IntoDescriptorKey<Ctx> for (T, KeySource, DerivationPath)

    Implementors§

    source§

    impl<Ctx, K> IntoDescriptorKey<Ctx> for GeneratedKey<K, Ctx>
    where Ctx: ScriptContext, - K: IntoDescriptorKey<Ctx>,

    source§

    impl<Ctx: ScriptContext> IntoDescriptorKey<Ctx> for DescriptorKey<Ctx>

    The “identity” conversion is used internally by some bdk_wallet::fragments

    -
    source§

    impl<Ctx: ScriptContext> IntoDescriptorKey<Ctx> for DescriptorPublicKey

    source§

    impl<Ctx: ScriptContext> IntoDescriptorKey<Ctx> for DescriptorSecretKey

    \ No newline at end of file + K: IntoDescriptorKey<Ctx>,
    source§

    impl<Ctx: ScriptContext> IntoDescriptorKey<Ctx> for DescriptorKey<Ctx>

    The “identity” conversion is used internally by some bdk_wallet::fragments

    +
    source§

    impl<Ctx: ScriptContext> IntoDescriptorKey<Ctx> for DescriptorPublicKey

    source§

    impl<Ctx: ScriptContext> IntoDescriptorKey<Ctx> for DescriptorSecretKey

    \ No newline at end of file diff --git a/docs-rs/bdk/nightly/latest/bdk_wallet/keys/type.ValidNetworks.html b/docs-rs/bdk/nightly/latest/bdk_wallet/keys/type.ValidNetworks.html index 9ab0a6a4af..571760f4a9 100644 --- a/docs-rs/bdk/nightly/latest/bdk_wallet/keys/type.ValidNetworks.html +++ b/docs-rs/bdk/nightly/latest/bdk_wallet/keys/type.ValidNetworks.html @@ -1,2 +1,2 @@ -ValidNetworks in bdk_wallet::keys - Rust

    Type Alias bdk_wallet::keys::ValidNetworks

    source ·
    pub type ValidNetworks = HashSet<Network>;
    Expand description

    Set of valid networks for a key

    +ValidNetworks in bdk_wallet::keys - Rust

    Type Alias bdk_wallet::keys::ValidNetworks

    source ·
    pub type ValidNetworks = HashSet<Network>;
    Expand description

    Set of valid networks for a key

    Aliased Type§

    struct ValidNetworks { /* private fields */ }
    \ No newline at end of file diff --git a/docs-rs/bdk/nightly/latest/bdk_wallet/wallet/coin_selection/enum.Error.html b/docs-rs/bdk/nightly/latest/bdk_wallet/wallet/coin_selection/enum.Error.html index 0408ce4e64..ce71f733ec 100644 --- a/docs-rs/bdk/nightly/latest/bdk_wallet/wallet/coin_selection/enum.Error.html +++ b/docs-rs/bdk/nightly/latest/bdk_wallet/wallet/coin_selection/enum.Error.html @@ -1,4 +1,4 @@ -Error in bdk_wallet::wallet::coin_selection - Rust

    Enum bdk_wallet::wallet::coin_selection::Error

    source ·
    pub enum Error {
    +Error in bdk_wallet::wallet::coin_selection - Rust

    Enum bdk_wallet::wallet::coin_selection::Error

    source ·
    pub enum Error {
         InsufficientFunds {
             needed: u64,
             available: u64,
    @@ -13,7 +13,7 @@
     the desired outputs plus fee, if there is not such combination this error is thrown

    §

    BnBTotalTriesExceeded

    Branch and bound coin selection possible attempts with sufficiently big UTXO set could grow exponentially, thus a limit is set, and when hit, this error is thrown

    -

    Trait Implementations§

    source§

    impl Debug for Error

    source§

    fn fmt(&self, f: &mut Formatter<'_>) -> Result

    Formats the value using the given formatter. Read more
    source§

    impl Display for Error

    source§

    fn fmt(&self, f: &mut Formatter<'_>) -> Result

    Formats the value using the given formatter. Read more
    source§

    impl Error for Error

    1.30.0 · source§

    fn source(&self) -> Option<&(dyn Error + 'static)>

    The lower-level source of this error, if any. Read more
    1.0.0 · source§

    fn description(&self) -> &str

    👎Deprecated since 1.42.0: use the Display impl or to_string()
    1.0.0 · source§

    fn cause(&self) -> Option<&dyn Error>

    👎Deprecated since 1.33.0: replaced by Error::source, which can support downcasting
    source§

    fn provide<'a>(&'a self, request: &mut Request<'a>)

    🔬This is a nightly-only experimental API. (error_generic_member_access)
    Provides type based access to context intended for error reports. Read more
    source§

    impl From<Error> for CreateTxError

    source§

    fn from(err: Error) -> Self

    Converts to this type from the input type.

    Auto Trait Implementations§

    §

    impl Freeze for Error

    §

    impl RefUnwindSafe for Error

    §

    impl Send for Error

    §

    impl Sync for Error

    §

    impl Unpin for Error

    §

    impl UnwindSafe for Error

    Blanket Implementations§

    source§

    impl<T> Any for T
    where +

    Trait Implementations§

    source§

    impl Debug for Error

    source§

    fn fmt(&self, f: &mut Formatter<'_>) -> Result

    Formats the value using the given formatter. Read more
    source§

    impl Display for Error

    source§

    fn fmt(&self, f: &mut Formatter<'_>) -> Result

    Formats the value using the given formatter. Read more
    source§

    impl Error for Error

    1.30.0 · source§

    fn source(&self) -> Option<&(dyn Error + 'static)>

    The lower-level source of this error, if any. Read more
    1.0.0 · source§

    fn description(&self) -> &str

    👎Deprecated since 1.42.0: use the Display impl or to_string()
    1.0.0 · source§

    fn cause(&self) -> Option<&dyn Error>

    👎Deprecated since 1.33.0: replaced by Error::source, which can support downcasting
    source§

    fn provide<'a>(&'a self, request: &mut Request<'a>)

    🔬This is a nightly-only experimental API. (error_generic_member_access)
    Provides type based access to context intended for error reports. Read more
    source§

    impl From<Error> for CreateTxError

    source§

    fn from(err: Error) -> Self

    Converts to this type from the input type.

    Auto Trait Implementations§

    §

    impl Freeze for Error

    §

    impl RefUnwindSafe for Error

    §

    impl Send for Error

    §

    impl Sync for Error

    §

    impl Unpin for Error

    §

    impl UnwindSafe for Error

    Blanket Implementations§

    source§

    impl<T> Any for T
    where T: 'static + ?Sized,

    source§

    fn type_id(&self) -> TypeId

    Gets the TypeId of self. Read more
    source§

    impl<T> Borrow<T> for T
    where T: ?Sized,

    source§

    fn borrow(&self) -> &T

    Immutably borrows from an owned value. Read more
    source§

    impl<T> BorrowMut<T> for T
    where T: ?Sized,

    source§

    fn borrow_mut(&mut self) -> &mut T

    Mutably borrows from an owned value. Read more
    source§

    impl<T> From<T> for T

    source§

    fn from(t: T) -> T

    Returns the argument unchanged.

    diff --git a/docs-rs/bdk/nightly/latest/bdk_wallet/wallet/coin_selection/enum.Excess.html b/docs-rs/bdk/nightly/latest/bdk_wallet/wallet/coin_selection/enum.Excess.html index e4b6ea33ea..f3f48f4d26 100644 --- a/docs-rs/bdk/nightly/latest/bdk_wallet/wallet/coin_selection/enum.Excess.html +++ b/docs-rs/bdk/nightly/latest/bdk_wallet/wallet/coin_selection/enum.Excess.html @@ -1,4 +1,4 @@ -Excess in bdk_wallet::wallet::coin_selection - Rust

    Enum bdk_wallet::wallet::coin_selection::Excess

    source ·
    pub enum Excess {
    +Excess in bdk_wallet::wallet::coin_selection - Rust

    Enum bdk_wallet::wallet::coin_selection::Excess

    source ·
    pub enum Excess {
         NoChange {
             dust_threshold: u64,
             remaining_amount: u64,
    @@ -16,7 +16,7 @@
     
    §

    Change

    It’s possible to create spendable output from excess using the current drain output

    Fields

    §amount: u64

    Effective amount available to create change after deducting the change output fee

    §fee: u64

    The deducted change output fee

    -

    Trait Implementations§

    source§

    impl Debug for Excess

    source§

    fn fmt(&self, f: &mut Formatter<'_>) -> Result

    Formats the value using the given formatter. Read more

    Auto Trait Implementations§

    §

    impl Freeze for Excess

    §

    impl RefUnwindSafe for Excess

    §

    impl Send for Excess

    §

    impl Sync for Excess

    §

    impl Unpin for Excess

    §

    impl UnwindSafe for Excess

    Blanket Implementations§

    source§

    impl<T> Any for T
    where +

    Trait Implementations§

    source§

    impl Debug for Excess

    source§

    fn fmt(&self, f: &mut Formatter<'_>) -> Result

    Formats the value using the given formatter. Read more

    Auto Trait Implementations§

    §

    impl Freeze for Excess

    §

    impl RefUnwindSafe for Excess

    §

    impl Send for Excess

    §

    impl Sync for Excess

    §

    impl Unpin for Excess

    §

    impl UnwindSafe for Excess

    Blanket Implementations§

    source§

    impl<T> Any for T
    where T: 'static + ?Sized,

    source§

    fn type_id(&self) -> TypeId

    Gets the TypeId of self. Read more
    source§

    impl<T> Borrow<T> for T
    where T: ?Sized,

    source§

    fn borrow(&self) -> &T

    Immutably borrows from an owned value. Read more
    source§

    impl<T> BorrowMut<T> for T
    where T: ?Sized,

    source§

    fn borrow_mut(&mut self) -> &mut T

    Mutably borrows from an owned value. Read more
    source§

    impl<T> From<T> for T

    source§

    fn from(t: T) -> T

    Returns the argument unchanged.

    diff --git a/docs-rs/bdk/nightly/latest/bdk_wallet/wallet/coin_selection/fn.decide_change.html b/docs-rs/bdk/nightly/latest/bdk_wallet/wallet/coin_selection/fn.decide_change.html index e433ddd9a6..5bc7d6d523 100644 --- a/docs-rs/bdk/nightly/latest/bdk_wallet/wallet/coin_selection/fn.decide_change.html +++ b/docs-rs/bdk/nightly/latest/bdk_wallet/wallet/coin_selection/fn.decide_change.html @@ -1,4 +1,4 @@ -decide_change in bdk_wallet::wallet::coin_selection - Rust

    Function bdk_wallet::wallet::coin_selection::decide_change

    source ·
    pub fn decide_change(
    +decide_change in bdk_wallet::wallet::coin_selection - Rust

    Function bdk_wallet::wallet::coin_selection::decide_change

    source ·
    pub fn decide_change(
         remaining_amount: u64,
         fee_rate: FeeRate,
         drain_script: &Script
    diff --git a/docs-rs/bdk/nightly/latest/bdk_wallet/wallet/coin_selection/struct.BranchAndBoundCoinSelection.html b/docs-rs/bdk/nightly/latest/bdk_wallet/wallet/coin_selection/struct.BranchAndBoundCoinSelection.html
    index 201b3ef630..721bb37f40 100644
    --- a/docs-rs/bdk/nightly/latest/bdk_wallet/wallet/coin_selection/struct.BranchAndBoundCoinSelection.html
    +++ b/docs-rs/bdk/nightly/latest/bdk_wallet/wallet/coin_selection/struct.BranchAndBoundCoinSelection.html
    @@ -1,14 +1,14 @@
    -BranchAndBoundCoinSelection in bdk_wallet::wallet::coin_selection - Rust
    pub struct BranchAndBoundCoinSelection { /* private fields */ }
    Expand description

    Branch and bound coin selection

    +BranchAndBoundCoinSelection in bdk_wallet::wallet::coin_selection - Rust
    pub struct BranchAndBoundCoinSelection { /* private fields */ }
    Expand description

    Branch and bound coin selection

    Code adapted from Bitcoin Core’s implementation and from Mark Erhardt Master’s Thesis: http://murch.one/wp-content/uploads/2016/11/erhardt2016coinselection.pdf

    -

    Implementations§

    source§

    impl BranchAndBoundCoinSelection

    source

    pub fn new(size_of_change: u64) -> Self

    Create new instance with target size for change output

    -

    Trait Implementations§

    source§

    impl Clone for BranchAndBoundCoinSelection

    source§

    fn clone(&self) -> BranchAndBoundCoinSelection

    Returns a copy of the value. Read more
    1.0.0 · source§

    fn clone_from(&mut self, source: &Self)

    Performs copy-assignment from source. Read more
    source§

    impl CoinSelectionAlgorithm for BranchAndBoundCoinSelection

    Implementations§

    source§

    impl BranchAndBoundCoinSelection

    source

    pub fn new(size_of_change: u64) -> Self

    Create new instance with target size for change output

    +

    Trait Implementations§

    source§

    impl Clone for BranchAndBoundCoinSelection

    source§

    fn clone(&self) -> BranchAndBoundCoinSelection

    Returns a copy of the value. Read more
    1.0.0 · source§

    fn clone_from(&mut self, source: &Self)

    Performs copy-assignment from source. Read more
    source§

    impl CoinSelectionAlgorithm for BranchAndBoundCoinSelection

    source§

    fn coin_select( &self, required_utxos: Vec<WeightedUtxo>, optional_utxos: Vec<WeightedUtxo>, fee_rate: FeeRate, target_amount: u64, drain_script: &Script -) -> Result<CoinSelectionResult, Error>

    Perform the coin selection Read more
    source§

    impl Debug for BranchAndBoundCoinSelection

    source§

    fn fmt(&self, f: &mut Formatter<'_>) -> Result

    Formats the value using the given formatter. Read more
    source§

    impl Default for BranchAndBoundCoinSelection

    source§

    fn default() -> Self

    Returns the “default value” for a type. Read more

    Auto Trait Implementations§

    Blanket Implementations§

    source§

    impl<T> Any for T

    Perform the coin selection Read more
    source§

    impl Debug for BranchAndBoundCoinSelection

    source§

    fn fmt(&self, f: &mut Formatter<'_>) -> Result

    Formats the value using the given formatter. Read more
    source§

    impl Default for BranchAndBoundCoinSelection

    source§

    fn default() -> Self

    Returns the “default value” for a type. Read more

    Auto Trait Implementations§

    Blanket Implementations§

    source§

    impl<T> Any for T
    where T: 'static + ?Sized,

    source§

    fn type_id(&self) -> TypeId

    Gets the TypeId of self. Read more
    source§

    impl<T> Borrow<T> for T
    where T: ?Sized,

    source§

    fn borrow(&self) -> &T

    Immutably borrows from an owned value. Read more
    source§

    impl<T> BorrowMut<T> for T
    where T: ?Sized,

    source§

    fn borrow_mut(&mut self) -> &mut T

    Mutably borrows from an owned value. Read more
    source§

    impl<T> From<T> for T

    source§

    fn from(t: T) -> T

    Returns the argument unchanged.

    diff --git a/docs-rs/bdk/nightly/latest/bdk_wallet/wallet/coin_selection/struct.CoinSelectionResult.html b/docs-rs/bdk/nightly/latest/bdk_wallet/wallet/coin_selection/struct.CoinSelectionResult.html index d088dd4331..4abcc5ec95 100644 --- a/docs-rs/bdk/nightly/latest/bdk_wallet/wallet/coin_selection/struct.CoinSelectionResult.html +++ b/docs-rs/bdk/nightly/latest/bdk_wallet/wallet/coin_selection/struct.CoinSelectionResult.html @@ -1,4 +1,4 @@ -CoinSelectionResult in bdk_wallet::wallet::coin_selection - Rust
    pub struct CoinSelectionResult {
    +CoinSelectionResult in bdk_wallet::wallet::coin_selection - Rust
    pub struct CoinSelectionResult {
         pub selected: Vec<Utxo>,
         pub fee_amount: u64,
         pub excess: Excess,
    @@ -6,9 +6,9 @@
     

    Fields§

    §selected: Vec<Utxo>

    List of outputs selected for use as inputs

    §fee_amount: u64

    Total fee amount for the selected utxos in satoshis

    §excess: Excess

    Remaining amount after deducing fees and outgoing outputs

    -

    Implementations§

    source§

    impl CoinSelectionResult

    source

    pub fn selected_amount(&self) -> u64

    The total value of the inputs selected.

    -
    source

    pub fn local_selected_amount(&self) -> u64

    The total value of the inputs selected from the local wallet.

    -

    Trait Implementations§

    source§

    impl Debug for CoinSelectionResult

    source§

    fn fmt(&self, f: &mut Formatter<'_>) -> Result

    Formats the value using the given formatter. Read more

    Auto Trait Implementations§

    Blanket Implementations§

    source§

    impl<T> Any for T
    where +

    Implementations§

    source§

    impl CoinSelectionResult

    source

    pub fn selected_amount(&self) -> u64

    The total value of the inputs selected.

    +
    source

    pub fn local_selected_amount(&self) -> u64

    The total value of the inputs selected from the local wallet.

    +

    Trait Implementations§

    source§

    impl Debug for CoinSelectionResult

    source§

    fn fmt(&self, f: &mut Formatter<'_>) -> Result

    Formats the value using the given formatter. Read more

    Auto Trait Implementations§

    Blanket Implementations§

    source§

    impl<T> Any for T
    where T: 'static + ?Sized,

    source§

    fn type_id(&self) -> TypeId

    Gets the TypeId of self. Read more
    source§

    impl<T> Borrow<T> for T
    where T: ?Sized,

    source§

    fn borrow(&self) -> &T

    Immutably borrows from an owned value. Read more
    source§

    impl<T> BorrowMut<T> for T
    where T: ?Sized,

    source§

    fn borrow_mut(&mut self) -> &mut T

    Mutably borrows from an owned value. Read more
    source§

    impl<T> From<T> for T

    source§

    fn from(t: T) -> T

    Returns the argument unchanged.

    diff --git a/docs-rs/bdk/nightly/latest/bdk_wallet/wallet/coin_selection/struct.LargestFirstCoinSelection.html b/docs-rs/bdk/nightly/latest/bdk_wallet/wallet/coin_selection/struct.LargestFirstCoinSelection.html index accd3d12d8..34162f06dd 100644 --- a/docs-rs/bdk/nightly/latest/bdk_wallet/wallet/coin_selection/struct.LargestFirstCoinSelection.html +++ b/docs-rs/bdk/nightly/latest/bdk_wallet/wallet/coin_selection/struct.LargestFirstCoinSelection.html @@ -1,14 +1,14 @@ -LargestFirstCoinSelection in bdk_wallet::wallet::coin_selection - Rust
    pub struct LargestFirstCoinSelection;
    Expand description

    Simple and dumb coin selection

    +LargestFirstCoinSelection in bdk_wallet::wallet::coin_selection - Rust
    pub struct LargestFirstCoinSelection;
    Expand description

    Simple and dumb coin selection

    This coin selection algorithm sorts the available UTXOs by value and then picks them starting from the largest ones until the required amount is reached.

    -

    Trait Implementations§

    source§

    impl Clone for LargestFirstCoinSelection

    source§

    fn clone(&self) -> LargestFirstCoinSelection

    Returns a copy of the value. Read more
    1.0.0 · source§

    fn clone_from(&mut self, source: &Self)

    Performs copy-assignment from source. Read more
    source§

    impl CoinSelectionAlgorithm for LargestFirstCoinSelection

    Trait Implementations§

    source§

    impl Clone for LargestFirstCoinSelection

    source§

    fn clone(&self) -> LargestFirstCoinSelection

    Returns a copy of the value. Read more
    1.0.0 · source§

    fn clone_from(&mut self, source: &Self)

    Performs copy-assignment from source. Read more
    source§

    impl CoinSelectionAlgorithm for LargestFirstCoinSelection

    source§

    fn coin_select( &self, required_utxos: Vec<WeightedUtxo>, optional_utxos: Vec<WeightedUtxo>, fee_rate: FeeRate, target_amount: u64, drain_script: &Script -) -> Result<CoinSelectionResult, Error>

    Perform the coin selection Read more
    source§

    impl Debug for LargestFirstCoinSelection

    source§

    fn fmt(&self, f: &mut Formatter<'_>) -> Result

    Formats the value using the given formatter. Read more
    source§

    impl Default for LargestFirstCoinSelection

    source§

    fn default() -> LargestFirstCoinSelection

    Returns the “default value” for a type. Read more
    source§

    impl Copy for LargestFirstCoinSelection

    Auto Trait Implementations§

    Blanket Implementations§

    source§

    impl<T> Any for T

    Perform the coin selection Read more
    source§

    impl Debug for LargestFirstCoinSelection

    source§

    fn fmt(&self, f: &mut Formatter<'_>) -> Result

    Formats the value using the given formatter. Read more
    source§

    impl Default for LargestFirstCoinSelection

    source§

    fn default() -> LargestFirstCoinSelection

    Returns the “default value” for a type. Read more
    source§

    impl Copy for LargestFirstCoinSelection

    Auto Trait Implementations§

    Blanket Implementations§

    source§

    impl<T> Any for T
    where T: 'static + ?Sized,

    source§

    fn type_id(&self) -> TypeId

    Gets the TypeId of self. Read more
    source§

    impl<T> Borrow<T> for T
    where T: ?Sized,

    source§

    fn borrow(&self) -> &T

    Immutably borrows from an owned value. Read more
    source§

    impl<T> BorrowMut<T> for T
    where T: ?Sized,

    source§

    fn borrow_mut(&mut self) -> &mut T

    Mutably borrows from an owned value. Read more
    source§

    impl<T> From<T> for T

    source§

    fn from(t: T) -> T

    Returns the argument unchanged.

    diff --git a/docs-rs/bdk/nightly/latest/bdk_wallet/wallet/coin_selection/struct.OldestFirstCoinSelection.html b/docs-rs/bdk/nightly/latest/bdk_wallet/wallet/coin_selection/struct.OldestFirstCoinSelection.html index c856390a75..350a88542e 100644 --- a/docs-rs/bdk/nightly/latest/bdk_wallet/wallet/coin_selection/struct.OldestFirstCoinSelection.html +++ b/docs-rs/bdk/nightly/latest/bdk_wallet/wallet/coin_selection/struct.OldestFirstCoinSelection.html @@ -1,14 +1,14 @@ -OldestFirstCoinSelection in bdk_wallet::wallet::coin_selection - Rust
    pub struct OldestFirstCoinSelection;
    Expand description

    OldestFirstCoinSelection always picks the utxo with the smallest blockheight to add to the selected coins next

    +OldestFirstCoinSelection in bdk_wallet::wallet::coin_selection - Rust
    pub struct OldestFirstCoinSelection;
    Expand description

    OldestFirstCoinSelection always picks the utxo with the smallest blockheight to add to the selected coins next

    This coin selection algorithm sorts the available UTXOs by blockheight and then picks them starting from the oldest ones until the required amount is reached.

    -

    Trait Implementations§

    source§

    impl Clone for OldestFirstCoinSelection

    source§

    fn clone(&self) -> OldestFirstCoinSelection

    Returns a copy of the value. Read more
    1.0.0 · source§

    fn clone_from(&mut self, source: &Self)

    Performs copy-assignment from source. Read more
    source§

    impl CoinSelectionAlgorithm for OldestFirstCoinSelection

    Trait Implementations§

    source§

    impl Clone for OldestFirstCoinSelection

    source§

    fn clone(&self) -> OldestFirstCoinSelection

    Returns a copy of the value. Read more
    1.0.0 · source§

    fn clone_from(&mut self, source: &Self)

    Performs copy-assignment from source. Read more
    source§

    impl CoinSelectionAlgorithm for OldestFirstCoinSelection

    source§

    fn coin_select( &self, required_utxos: Vec<WeightedUtxo>, optional_utxos: Vec<WeightedUtxo>, fee_rate: FeeRate, target_amount: u64, drain_script: &Script -) -> Result<CoinSelectionResult, Error>

    Perform the coin selection Read more
    source§

    impl Debug for OldestFirstCoinSelection

    source§

    fn fmt(&self, f: &mut Formatter<'_>) -> Result

    Formats the value using the given formatter. Read more
    source§

    impl Default for OldestFirstCoinSelection

    source§

    fn default() -> OldestFirstCoinSelection

    Returns the “default value” for a type. Read more
    source§

    impl Copy for OldestFirstCoinSelection

    Auto Trait Implementations§

    Blanket Implementations§

    source§

    impl<T> Any for T

    Perform the coin selection Read more
    source§

    impl Debug for OldestFirstCoinSelection

    source§

    fn fmt(&self, f: &mut Formatter<'_>) -> Result

    Formats the value using the given formatter. Read more
    source§

    impl Default for OldestFirstCoinSelection

    source§

    fn default() -> OldestFirstCoinSelection

    Returns the “default value” for a type. Read more
    source§

    impl Copy for OldestFirstCoinSelection

    Auto Trait Implementations§

    Blanket Implementations§

    source§

    impl<T> Any for T
    where T: 'static + ?Sized,

    source§

    fn type_id(&self) -> TypeId

    Gets the TypeId of self. Read more
    source§

    impl<T> Borrow<T> for T
    where T: ?Sized,

    source§

    fn borrow(&self) -> &T

    Immutably borrows from an owned value. Read more
    source§

    impl<T> BorrowMut<T> for T
    where T: ?Sized,

    source§

    fn borrow_mut(&mut self) -> &mut T

    Mutably borrows from an owned value. Read more
    source§

    impl<T> From<T> for T

    source§

    fn from(t: T) -> T

    Returns the argument unchanged.

    diff --git a/docs-rs/bdk/nightly/latest/bdk_wallet/wallet/coin_selection/trait.CoinSelectionAlgorithm.html b/docs-rs/bdk/nightly/latest/bdk_wallet/wallet/coin_selection/trait.CoinSelectionAlgorithm.html index e260bc0847..13b07f0b92 100644 --- a/docs-rs/bdk/nightly/latest/bdk_wallet/wallet/coin_selection/trait.CoinSelectionAlgorithm.html +++ b/docs-rs/bdk/nightly/latest/bdk_wallet/wallet/coin_selection/trait.CoinSelectionAlgorithm.html @@ -1,4 +1,4 @@ -CoinSelectionAlgorithm in bdk_wallet::wallet::coin_selection - Rust
    pub trait CoinSelectionAlgorithm: Debug {
    +CoinSelectionAlgorithm in bdk_wallet::wallet::coin_selection - Rust
    pub trait CoinSelectionAlgorithm: Debug {
         // Required method
         fn coin_select(
             &self,
    @@ -12,7 +12,7 @@
     

    This trait can be implemented to make the Wallet use a customized coin selection algorithm when it creates transactions.

    For an example see this module’s documentation.

    -

    Required Methods§

    Required Methods§

    source

    fn coin_select( &self, required_utxos: Vec<WeightedUtxo>, optional_utxos: Vec<WeightedUtxo>, @@ -32,4 +32,4 @@ accumulated from added outputs and transaction’s header.
  • drain_script: the script to use in case of change
  • -

    Implementors§

    \ No newline at end of file +

    Implementors§

    \ No newline at end of file diff --git a/docs-rs/bdk/nightly/latest/bdk_wallet/wallet/coin_selection/type.DefaultCoinSelectionAlgorithm.html b/docs-rs/bdk/nightly/latest/bdk_wallet/wallet/coin_selection/type.DefaultCoinSelectionAlgorithm.html index d3dcb32599..3c2adab102 100644 --- a/docs-rs/bdk/nightly/latest/bdk_wallet/wallet/coin_selection/type.DefaultCoinSelectionAlgorithm.html +++ b/docs-rs/bdk/nightly/latest/bdk_wallet/wallet/coin_selection/type.DefaultCoinSelectionAlgorithm.html @@ -1,3 +1,3 @@ -DefaultCoinSelectionAlgorithm in bdk_wallet::wallet::coin_selection - Rust
    pub type DefaultCoinSelectionAlgorithm = BranchAndBoundCoinSelection;
    Expand description

    Default coin selection algorithm used by TxBuilder if not +DefaultCoinSelectionAlgorithm in bdk_wallet::wallet::coin_selection - Rust

    pub type DefaultCoinSelectionAlgorithm = BranchAndBoundCoinSelection;
    Expand description

    Default coin selection algorithm used by TxBuilder if not overridden

    Aliased Type§

    struct DefaultCoinSelectionAlgorithm { /* private fields */ }
    \ No newline at end of file diff --git a/docs-rs/bdk/nightly/latest/bdk_wallet/wallet/enum.ApplyBlockError.html b/docs-rs/bdk/nightly/latest/bdk_wallet/wallet/enum.ApplyBlockError.html index d6b099efe4..928b0fe47a 100644 --- a/docs-rs/bdk/nightly/latest/bdk_wallet/wallet/enum.ApplyBlockError.html +++ b/docs-rs/bdk/nightly/latest/bdk_wallet/wallet/enum.ApplyBlockError.html @@ -1,4 +1,4 @@ -ApplyBlockError in bdk_wallet::wallet - Rust

    Enum bdk_wallet::wallet::ApplyBlockError

    source ·
    pub enum ApplyBlockError {
    +ApplyBlockError in bdk_wallet::wallet - Rust

    Enum bdk_wallet::wallet::ApplyBlockError

    source ·
    pub enum ApplyBlockError {
         CannotConnect(CannotConnectError),
         UnexpectedConnectedToHash {
             connected_to_hash: BlockHash,
    @@ -9,7 +9,7 @@
     
    §

    UnexpectedConnectedToHash

    Occurs when the connected_to hash does not match the hash derived from block.

    Fields

    §connected_to_hash: BlockHash

    Block hash of connected_to.

    §expected_hash: BlockHash

    Expected block hash of connected_to, as derived from block.

    -

    Trait Implementations§

    source§

    impl Debug for ApplyBlockError

    source§

    fn fmt(&self, f: &mut Formatter<'_>) -> Result

    Formats the value using the given formatter. Read more
    source§

    impl Display for ApplyBlockError

    source§

    fn fmt(&self, f: &mut Formatter<'_>) -> Result

    Formats the value using the given formatter. Read more
    source§

    impl Error for ApplyBlockError

    1.30.0 · source§

    fn source(&self) -> Option<&(dyn Error + 'static)>

    The lower-level source of this error, if any. Read more
    1.0.0 · source§

    fn description(&self) -> &str

    👎Deprecated since 1.42.0: use the Display impl or to_string()
    1.0.0 · source§

    fn cause(&self) -> Option<&dyn Error>

    👎Deprecated since 1.33.0: replaced by Error::source, which can support downcasting
    source§

    fn provide<'a>(&'a self, request: &mut Request<'a>)

    🔬This is a nightly-only experimental API. (error_generic_member_access)
    Provides type based access to context intended for error reports. Read more

    Auto Trait Implementations§

    Blanket Implementations§

    source§

    impl<T> Any for T
    where +

    Trait Implementations§

    source§

    impl Debug for ApplyBlockError

    source§

    fn fmt(&self, f: &mut Formatter<'_>) -> Result

    Formats the value using the given formatter. Read more
    source§

    impl Display for ApplyBlockError

    source§

    fn fmt(&self, f: &mut Formatter<'_>) -> Result

    Formats the value using the given formatter. Read more
    source§

    impl Error for ApplyBlockError

    1.30.0 · source§

    fn source(&self) -> Option<&(dyn Error + 'static)>

    The lower-level source of this error, if any. Read more
    1.0.0 · source§

    fn description(&self) -> &str

    👎Deprecated since 1.42.0: use the Display impl or to_string()
    1.0.0 · source§

    fn cause(&self) -> Option<&dyn Error>

    👎Deprecated since 1.33.0: replaced by Error::source, which can support downcasting
    source§

    fn provide<'a>(&'a self, request: &mut Request<'a>)

    🔬This is a nightly-only experimental API. (error_generic_member_access)
    Provides type based access to context intended for error reports. Read more

    Auto Trait Implementations§

    Blanket Implementations§

    source§

    impl<T> Any for T
    where T: 'static + ?Sized,

    source§

    fn type_id(&self) -> TypeId

    Gets the TypeId of self. Read more
    source§

    impl<T> Borrow<T> for T
    where T: ?Sized,

    source§

    fn borrow(&self) -> &T

    Immutably borrows from an owned value. Read more
    source§

    impl<T> BorrowMut<T> for T
    where T: ?Sized,

    source§

    fn borrow_mut(&mut self) -> &mut T

    Mutably borrows from an owned value. Read more
    source§

    impl<T> From<T> for T

    source§

    fn from(t: T) -> T

    Returns the argument unchanged.

    diff --git a/docs-rs/bdk/nightly/latest/bdk_wallet/wallet/enum.InsertTxError.html b/docs-rs/bdk/nightly/latest/bdk_wallet/wallet/enum.InsertTxError.html index 941c5d28ed..bf9f8642f0 100644 --- a/docs-rs/bdk/nightly/latest/bdk_wallet/wallet/enum.InsertTxError.html +++ b/docs-rs/bdk/nightly/latest/bdk_wallet/wallet/enum.InsertTxError.html @@ -1,4 +1,4 @@ -InsertTxError in bdk_wallet::wallet - Rust

    Enum bdk_wallet::wallet::InsertTxError

    source ·
    pub enum InsertTxError {
    +InsertTxError in bdk_wallet::wallet - Rust

    Enum bdk_wallet::wallet::InsertTxError

    source ·
    pub enum InsertTxError {
         ConfirmationHeightCannotBeGreaterThanTip {
             tip_height: u32,
             tx_height: u32,
    @@ -8,7 +8,7 @@
     confirmation height that is greater than the internal chain tip.

    Fields

    §tip_height: u32

    The internal chain’s tip height.

    §tx_height: u32

    The introduced transaction’s confirmation height.

    -

    Trait Implementations§

    source§

    impl Debug for InsertTxError

    source§

    fn fmt(&self, f: &mut Formatter<'_>) -> Result

    Formats the value using the given formatter. Read more
    source§

    impl Display for InsertTxError

    source§

    fn fmt(&self, f: &mut Formatter<'_>) -> Result

    Formats the value using the given formatter. Read more
    source§

    impl Error for InsertTxError

    1.30.0 · source§

    fn source(&self) -> Option<&(dyn Error + 'static)>

    The lower-level source of this error, if any. Read more
    1.0.0 · source§

    fn description(&self) -> &str

    👎Deprecated since 1.42.0: use the Display impl or to_string()
    1.0.0 · source§

    fn cause(&self) -> Option<&dyn Error>

    👎Deprecated since 1.33.0: replaced by Error::source, which can support downcasting
    source§

    fn provide<'a>(&'a self, request: &mut Request<'a>)

    🔬This is a nightly-only experimental API. (error_generic_member_access)
    Provides type based access to context intended for error reports. Read more

    Auto Trait Implementations§

    Blanket Implementations§

    source§

    impl<T> Any for T
    where +

    Trait Implementations§

    source§

    impl Debug for InsertTxError

    source§

    fn fmt(&self, f: &mut Formatter<'_>) -> Result

    Formats the value using the given formatter. Read more
    source§

    impl Display for InsertTxError

    source§

    fn fmt(&self, f: &mut Formatter<'_>) -> Result

    Formats the value using the given formatter. Read more
    source§

    impl Error for InsertTxError

    1.30.0 · source§

    fn source(&self) -> Option<&(dyn Error + 'static)>

    The lower-level source of this error, if any. Read more
    1.0.0 · source§

    fn description(&self) -> &str

    👎Deprecated since 1.42.0: use the Display impl or to_string()
    1.0.0 · source§

    fn cause(&self) -> Option<&dyn Error>

    👎Deprecated since 1.33.0: replaced by Error::source, which can support downcasting
    source§

    fn provide<'a>(&'a self, request: &mut Request<'a>)

    🔬This is a nightly-only experimental API. (error_generic_member_access)
    Provides type based access to context intended for error reports. Read more

    Auto Trait Implementations§

    Blanket Implementations§

    source§

    impl<T> Any for T
    where T: 'static + ?Sized,

    source§

    fn type_id(&self) -> TypeId

    Gets the TypeId of self. Read more
    source§

    impl<T> Borrow<T> for T
    where T: ?Sized,

    source§

    fn borrow(&self) -> &T

    Immutably borrows from an owned value. Read more
    source§

    impl<T> BorrowMut<T> for T
    where T: ?Sized,

    source§

    fn borrow_mut(&mut self) -> &mut T

    Mutably borrows from an owned value. Read more
    source§

    impl<T> From<T> for T

    source§

    fn from(t: T) -> T

    Returns the argument unchanged.

    diff --git a/docs-rs/bdk/nightly/latest/bdk_wallet/wallet/enum.LoadError.html b/docs-rs/bdk/nightly/latest/bdk_wallet/wallet/enum.LoadError.html index 5b78826396..3b1feafc51 100644 --- a/docs-rs/bdk/nightly/latest/bdk_wallet/wallet/enum.LoadError.html +++ b/docs-rs/bdk/nightly/latest/bdk_wallet/wallet/enum.LoadError.html @@ -1,4 +1,4 @@ -LoadError in bdk_wallet::wallet - Rust

    Enum bdk_wallet::wallet::LoadError

    source ·
    pub enum LoadError {
    +LoadError in bdk_wallet::wallet - Rust

    Enum bdk_wallet::wallet::LoadError

    source ·
    pub enum LoadError {
         Descriptor(DescriptorError),
         MissingNetwork,
         MissingGenesis,
    @@ -9,7 +9,7 @@
     
    §

    MissingNetwork

    Data loaded from persistence is missing network type.

    §

    MissingGenesis

    Data loaded from persistence is missing genesis hash.

    §

    MissingDescriptor(KeychainKind)

    Data loaded from persistence is missing descriptor.

    -

    Trait Implementations§

    source§

    impl Debug for LoadError

    source§

    fn fmt(&self, f: &mut Formatter<'_>) -> Result

    Formats the value using the given formatter. Read more
    source§

    impl Display for LoadError

    source§

    fn fmt(&self, f: &mut Formatter<'_>) -> Result

    Formats the value using the given formatter. Read more
    source§

    impl Error for LoadError

    1.30.0 · source§

    fn source(&self) -> Option<&(dyn Error + 'static)>

    The lower-level source of this error, if any. Read more
    1.0.0 · source§

    fn description(&self) -> &str

    👎Deprecated since 1.42.0: use the Display impl or to_string()
    1.0.0 · source§

    fn cause(&self) -> Option<&dyn Error>

    👎Deprecated since 1.33.0: replaced by Error::source, which can support downcasting
    source§

    fn provide<'a>(&'a self, request: &mut Request<'a>)

    🔬This is a nightly-only experimental API. (error_generic_member_access)
    Provides type based access to context intended for error reports. Read more

    Auto Trait Implementations§

    Blanket Implementations§

    source§

    impl<T> Any for T
    where +

    Trait Implementations§

    source§

    impl Debug for LoadError

    source§

    fn fmt(&self, f: &mut Formatter<'_>) -> Result

    Formats the value using the given formatter. Read more
    source§

    impl Display for LoadError

    source§

    fn fmt(&self, f: &mut Formatter<'_>) -> Result

    Formats the value using the given formatter. Read more
    source§

    impl Error for LoadError

    1.30.0 · source§

    fn source(&self) -> Option<&(dyn Error + 'static)>

    The lower-level source of this error, if any. Read more
    1.0.0 · source§

    fn description(&self) -> &str

    👎Deprecated since 1.42.0: use the Display impl or to_string()
    1.0.0 · source§

    fn cause(&self) -> Option<&dyn Error>

    👎Deprecated since 1.33.0: replaced by Error::source, which can support downcasting
    source§

    fn provide<'a>(&'a self, request: &mut Request<'a>)

    🔬This is a nightly-only experimental API. (error_generic_member_access)
    Provides type based access to context intended for error reports. Read more

    Auto Trait Implementations§

    Blanket Implementations§

    source§

    impl<T> Any for T
    where T: 'static + ?Sized,

    source§

    fn type_id(&self) -> TypeId

    Gets the TypeId of self. Read more
    source§

    impl<T> Borrow<T> for T
    where T: ?Sized,

    source§

    fn borrow(&self) -> &T

    Immutably borrows from an owned value. Read more
    source§

    impl<T> BorrowMut<T> for T
    where T: ?Sized,

    source§

    fn borrow_mut(&mut self) -> &mut T

    Mutably borrows from an owned value. Read more
    source§

    impl<T> From<T> for T

    source§

    fn from(t: T) -> T

    Returns the argument unchanged.

    diff --git a/docs-rs/bdk/nightly/latest/bdk_wallet/wallet/enum.NewError.html b/docs-rs/bdk/nightly/latest/bdk_wallet/wallet/enum.NewError.html index 45e5d67c3f..3a5157fb19 100644 --- a/docs-rs/bdk/nightly/latest/bdk_wallet/wallet/enum.NewError.html +++ b/docs-rs/bdk/nightly/latest/bdk_wallet/wallet/enum.NewError.html @@ -1,9 +1,9 @@ -NewError in bdk_wallet::wallet - Rust

    Enum bdk_wallet::wallet::NewError

    source ·
    pub enum NewError {
    +NewError in bdk_wallet::wallet - Rust

    Enum bdk_wallet::wallet::NewError

    source ·
    pub enum NewError {
         Descriptor(DescriptorError),
     }
    Expand description

    The error type when constructing a fresh Wallet.

    Methods new and new_with_genesis_hash may return this error.

    Variants§

    §

    Descriptor(DescriptorError)

    There was problem with the passed-in descriptor(s).

    -

    Trait Implementations§

    source§

    impl Debug for NewError

    source§

    fn fmt(&self, f: &mut Formatter<'_>) -> Result

    Formats the value using the given formatter. Read more
    source§

    impl Display for NewError

    source§

    fn fmt(&self, f: &mut Formatter<'_>) -> Result

    Formats the value using the given formatter. Read more
    source§

    impl Error for NewError

    1.30.0 · source§

    fn source(&self) -> Option<&(dyn Error + 'static)>

    The lower-level source of this error, if any. Read more
    1.0.0 · source§

    fn description(&self) -> &str

    👎Deprecated since 1.42.0: use the Display impl or to_string()
    1.0.0 · source§

    fn cause(&self) -> Option<&dyn Error>

    👎Deprecated since 1.33.0: replaced by Error::source, which can support downcasting
    source§

    fn provide<'a>(&'a self, request: &mut Request<'a>)

    🔬This is a nightly-only experimental API. (error_generic_member_access)
    Provides type based access to context intended for error reports. Read more

    Auto Trait Implementations§

    Blanket Implementations§

    source§

    impl<T> Any for T
    where +

    Trait Implementations§

    source§

    impl Debug for NewError

    source§

    fn fmt(&self, f: &mut Formatter<'_>) -> Result

    Formats the value using the given formatter. Read more
    source§

    impl Display for NewError

    source§

    fn fmt(&self, f: &mut Formatter<'_>) -> Result

    Formats the value using the given formatter. Read more
    source§

    impl Error for NewError

    1.30.0 · source§

    fn source(&self) -> Option<&(dyn Error + 'static)>

    The lower-level source of this error, if any. Read more
    1.0.0 · source§

    fn description(&self) -> &str

    👎Deprecated since 1.42.0: use the Display impl or to_string()
    1.0.0 · source§

    fn cause(&self) -> Option<&dyn Error>

    👎Deprecated since 1.33.0: replaced by Error::source, which can support downcasting
    source§

    fn provide<'a>(&'a self, request: &mut Request<'a>)

    🔬This is a nightly-only experimental API. (error_generic_member_access)
    Provides type based access to context intended for error reports. Read more

    Auto Trait Implementations§

    Blanket Implementations§

    source§

    impl<T> Any for T
    where T: 'static + ?Sized,

    source§

    fn type_id(&self) -> TypeId

    Gets the TypeId of self. Read more
    source§

    impl<T> Borrow<T> for T
    where T: ?Sized,

    source§

    fn borrow(&self) -> &T

    Immutably borrows from an owned value. Read more
    source§

    impl<T> BorrowMut<T> for T
    where T: ?Sized,

    source§

    fn borrow_mut(&mut self) -> &mut T

    Mutably borrows from an owned value. Read more
    source§

    impl<T> From<T> for T

    source§

    fn from(t: T) -> T

    Returns the argument unchanged.

    diff --git a/docs-rs/bdk/nightly/latest/bdk_wallet/wallet/enum.NewOrLoadError.html b/docs-rs/bdk/nightly/latest/bdk_wallet/wallet/enum.NewOrLoadError.html index d93742ca33..d32b8a88b4 100644 --- a/docs-rs/bdk/nightly/latest/bdk_wallet/wallet/enum.NewOrLoadError.html +++ b/docs-rs/bdk/nightly/latest/bdk_wallet/wallet/enum.NewOrLoadError.html @@ -1,4 +1,4 @@ -NewOrLoadError in bdk_wallet::wallet - Rust

    Enum bdk_wallet::wallet::NewOrLoadError

    source ·
    pub enum NewOrLoadError {
    +NewOrLoadError in bdk_wallet::wallet - Rust

    Enum bdk_wallet::wallet::NewOrLoadError

    source ·
    pub enum NewOrLoadError {
         Descriptor(DescriptorError),
         LoadedGenesisDoesNotMatch {
             expected: BlockHash,
    @@ -24,7 +24,7 @@
     
    §

    LoadedDescriptorDoesNotMatch

    The loaded desccriptor does not match what was provided.

    Fields

    §got: Option<ExtendedDescriptor>

    The descriptor loaded from persistence.

    §keychain: KeychainKind

    The keychain of the descriptor not matching

    -

    Trait Implementations§

    source§

    impl Debug for NewOrLoadError

    source§

    fn fmt(&self, f: &mut Formatter<'_>) -> Result

    Formats the value using the given formatter. Read more
    source§

    impl Display for NewOrLoadError

    source§

    fn fmt(&self, f: &mut Formatter<'_>) -> Result

    Formats the value using the given formatter. Read more
    source§

    impl Error for NewOrLoadError

    1.30.0 · source§

    fn source(&self) -> Option<&(dyn Error + 'static)>

    The lower-level source of this error, if any. Read more
    1.0.0 · source§

    fn description(&self) -> &str

    👎Deprecated since 1.42.0: use the Display impl or to_string()
    1.0.0 · source§

    fn cause(&self) -> Option<&dyn Error>

    👎Deprecated since 1.33.0: replaced by Error::source, which can support downcasting
    source§

    fn provide<'a>(&'a self, request: &mut Request<'a>)

    🔬This is a nightly-only experimental API. (error_generic_member_access)
    Provides type based access to context intended for error reports. Read more

    Auto Trait Implementations§

    Blanket Implementations§

    source§

    impl<T> Any for T
    where +

    Trait Implementations§

    source§

    impl Debug for NewOrLoadError

    source§

    fn fmt(&self, f: &mut Formatter<'_>) -> Result

    Formats the value using the given formatter. Read more
    source§

    impl Display for NewOrLoadError

    source§

    fn fmt(&self, f: &mut Formatter<'_>) -> Result

    Formats the value using the given formatter. Read more
    source§

    impl Error for NewOrLoadError

    1.30.0 · source§

    fn source(&self) -> Option<&(dyn Error + 'static)>

    The lower-level source of this error, if any. Read more
    1.0.0 · source§

    fn description(&self) -> &str

    👎Deprecated since 1.42.0: use the Display impl or to_string()
    1.0.0 · source§

    fn cause(&self) -> Option<&dyn Error>

    👎Deprecated since 1.33.0: replaced by Error::source, which can support downcasting
    source§

    fn provide<'a>(&'a self, request: &mut Request<'a>)

    🔬This is a nightly-only experimental API. (error_generic_member_access)
    Provides type based access to context intended for error reports. Read more

    Auto Trait Implementations§

    Blanket Implementations§

    source§

    impl<T> Any for T
    where T: 'static + ?Sized,

    source§

    fn type_id(&self) -> TypeId

    Gets the TypeId of self. Read more
    source§

    impl<T> Borrow<T> for T
    where T: ?Sized,

    source§

    fn borrow(&self) -> &T

    Immutably borrows from an owned value. Read more
    source§

    impl<T> BorrowMut<T> for T
    where T: ?Sized,

    source§

    fn borrow_mut(&mut self) -> &mut T

    Mutably borrows from an owned value. Read more
    source§

    impl<T> From<T> for T

    source§

    fn from(t: T) -> T

    Returns the argument unchanged.

    diff --git a/docs-rs/bdk/nightly/latest/bdk_wallet/wallet/error/enum.BuildFeeBumpError.html b/docs-rs/bdk/nightly/latest/bdk_wallet/wallet/error/enum.BuildFeeBumpError.html index 96861cd32c..8b1db41358 100644 --- a/docs-rs/bdk/nightly/latest/bdk_wallet/wallet/error/enum.BuildFeeBumpError.html +++ b/docs-rs/bdk/nightly/latest/bdk_wallet/wallet/error/enum.BuildFeeBumpError.html @@ -10,7 +10,7 @@
    §

    TransactionConfirmed(Txid)

    Happens when trying to bump a transaction that is already confirmed

    §

    IrreplaceableTransaction(Txid)

    Trying to replace a tx that has a sequence >= 0xFFFFFFFE

    §

    FeeRateUnavailable

    Node doesn’t have data to estimate a fee rate

    -

    Trait Implementations§

    source§

    impl Debug for BuildFeeBumpError

    source§

    fn fmt(&self, f: &mut Formatter<'_>) -> Result

    Formats the value using the given formatter. Read more
    source§

    impl Display for BuildFeeBumpError

    source§

    fn fmt(&self, f: &mut Formatter<'_>) -> Result

    Formats the value using the given formatter. Read more
    source§

    impl Error for BuildFeeBumpError

    1.30.0 · source§

    fn source(&self) -> Option<&(dyn Error + 'static)>

    The lower-level source of this error, if any. Read more
    1.0.0 · source§

    fn description(&self) -> &str

    👎Deprecated since 1.42.0: use the Display impl or to_string()
    1.0.0 · source§

    fn cause(&self) -> Option<&dyn Error>

    👎Deprecated since 1.33.0: replaced by Error::source, which can support downcasting
    source§

    fn provide<'a>(&'a self, request: &mut Request<'a>)

    🔬This is a nightly-only experimental API. (error_generic_member_access)
    Provides type based access to context intended for error reports. Read more

    Auto Trait Implementations§

    Blanket Implementations§

    source§

    impl<T> Any for T
    where +

    Trait Implementations§

    source§

    impl Debug for BuildFeeBumpError

    source§

    fn fmt(&self, f: &mut Formatter<'_>) -> Result

    Formats the value using the given formatter. Read more
    source§

    impl Display for BuildFeeBumpError

    source§

    fn fmt(&self, f: &mut Formatter<'_>) -> Result

    Formats the value using the given formatter. Read more
    source§

    impl Error for BuildFeeBumpError

    1.30.0 · source§

    fn source(&self) -> Option<&(dyn Error + 'static)>

    The lower-level source of this error, if any. Read more
    1.0.0 · source§

    fn description(&self) -> &str

    👎Deprecated since 1.42.0: use the Display impl or to_string()
    1.0.0 · source§

    fn cause(&self) -> Option<&dyn Error>

    👎Deprecated since 1.33.0: replaced by Error::source, which can support downcasting
    source§

    fn provide<'a>(&'a self, request: &mut Request<'a>)

    🔬This is a nightly-only experimental API. (error_generic_member_access)
    Provides type based access to context intended for error reports. Read more

    Auto Trait Implementations§

    Blanket Implementations§

    source§

    impl<T> Any for T
    where T: 'static + ?Sized,

    source§

    fn type_id(&self) -> TypeId

    Gets the TypeId of self. Read more
    source§

    impl<T> Borrow<T> for T
    where T: ?Sized,

    source§

    fn borrow(&self) -> &T

    Immutably borrows from an owned value. Read more
    source§

    impl<T> BorrowMut<T> for T
    where T: ?Sized,

    source§

    fn borrow_mut(&mut self) -> &mut T

    Mutably borrows from an owned value. Read more
    source§

    impl<T> From<T> for T

    source§

    fn from(t: T) -> T

    Returns the argument unchanged.

    diff --git a/docs-rs/bdk/nightly/latest/bdk_wallet/wallet/error/enum.CreateTxError.html b/docs-rs/bdk/nightly/latest/bdk_wallet/wallet/error/enum.CreateTxError.html index 3e903d0c59..3e699e9f1e 100644 --- a/docs-rs/bdk/nightly/latest/bdk_wallet/wallet/error/enum.CreateTxError.html +++ b/docs-rs/bdk/nightly/latest/bdk_wallet/wallet/error/enum.CreateTxError.html @@ -56,7 +56,7 @@
    §

    UnknownUtxo

    Happens when trying to spend an UTXO that is not in the internal database

    §

    MissingNonWitnessUtxo(OutPoint)

    Missing non_witness_utxo on foreign utxo for given OutPoint

    §

    MiniscriptPsbt(MiniscriptPsbtError)

    Miniscript PSBT error

    -

    Trait Implementations§

    source§

    impl Debug for CreateTxError

    source§

    fn fmt(&self, f: &mut Formatter<'_>) -> Result

    Formats the value using the given formatter. Read more
    source§

    impl Display for CreateTxError

    source§

    fn fmt(&self, f: &mut Formatter<'_>) -> Result

    Formats the value using the given formatter. Read more
    source§

    impl Error for CreateTxError

    1.30.0 · source§

    fn source(&self) -> Option<&(dyn Error + 'static)>

    The lower-level source of this error, if any. Read more
    1.0.0 · source§

    fn description(&self) -> &str

    👎Deprecated since 1.42.0: use the Display impl or to_string()
    1.0.0 · source§

    fn cause(&self) -> Option<&dyn Error>

    👎Deprecated since 1.33.0: replaced by Error::source, which can support downcasting
    source§

    fn provide<'a>(&'a self, request: &mut Request<'a>)

    🔬This is a nightly-only experimental API. (error_generic_member_access)
    Provides type based access to context intended for error reports. Read more
    source§

    impl From<Error> for CreateTxError

    source§

    fn from(err: Error) -> Self

    Converts to this type from the input type.
    source§

    impl From<Error> for CreateTxError

    source§

    fn from(err: Error) -> Self

    Converts to this type from the input type.
    source§

    impl From<Error> for CreateTxError

    source§

    fn from(err: Error) -> Self

    Converts to this type from the input type.
    source§

    impl From<MiniscriptPsbtError> for CreateTxError

    source§

    fn from(err: MiniscriptPsbtError) -> Self

    Converts to this type from the input type.
    source§

    impl From<PolicyError> for CreateTxError

    source§

    fn from(err: PolicyError) -> Self

    Converts to this type from the input type.

    Auto Trait Implementations§

    Blanket Implementations§

    source§

    impl<T> Any for T
    where +

    Trait Implementations§

    source§

    impl Debug for CreateTxError

    source§

    fn fmt(&self, f: &mut Formatter<'_>) -> Result

    Formats the value using the given formatter. Read more
    source§

    impl Display for CreateTxError

    source§

    fn fmt(&self, f: &mut Formatter<'_>) -> Result

    Formats the value using the given formatter. Read more
    source§

    impl Error for CreateTxError

    1.30.0 · source§

    fn source(&self) -> Option<&(dyn Error + 'static)>

    The lower-level source of this error, if any. Read more
    1.0.0 · source§

    fn description(&self) -> &str

    👎Deprecated since 1.42.0: use the Display impl or to_string()
    1.0.0 · source§

    fn cause(&self) -> Option<&dyn Error>

    👎Deprecated since 1.33.0: replaced by Error::source, which can support downcasting
    source§

    fn provide<'a>(&'a self, request: &mut Request<'a>)

    🔬This is a nightly-only experimental API. (error_generic_member_access)
    Provides type based access to context intended for error reports. Read more
    source§

    impl From<Error> for CreateTxError

    source§

    fn from(err: Error) -> Self

    Converts to this type from the input type.
    source§

    impl From<Error> for CreateTxError

    source§

    fn from(err: Error) -> Self

    Converts to this type from the input type.
    source§

    impl From<Error> for CreateTxError

    source§

    fn from(err: Error) -> Self

    Converts to this type from the input type.
    source§

    impl From<MiniscriptPsbtError> for CreateTxError

    source§

    fn from(err: MiniscriptPsbtError) -> Self

    Converts to this type from the input type.
    source§

    impl From<PolicyError> for CreateTxError

    source§

    fn from(err: PolicyError) -> Self

    Converts to this type from the input type.

    Auto Trait Implementations§

    Blanket Implementations§

    source§

    impl<T> Any for T
    where T: 'static + ?Sized,

    source§

    fn type_id(&self) -> TypeId

    Gets the TypeId of self. Read more
    source§

    impl<T> Borrow<T> for T
    where T: ?Sized,

    source§

    fn borrow(&self) -> &T

    Immutably borrows from an owned value. Read more
    source§

    impl<T> BorrowMut<T> for T
    where T: ?Sized,

    source§

    fn borrow_mut(&mut self) -> &mut T

    Mutably borrows from an owned value. Read more
    source§

    impl<T> From<T> for T

    source§

    fn from(t: T) -> T

    Returns the argument unchanged.

    diff --git a/docs-rs/bdk/nightly/latest/bdk_wallet/wallet/error/enum.MiniscriptPsbtError.html b/docs-rs/bdk/nightly/latest/bdk_wallet/wallet/error/enum.MiniscriptPsbtError.html index 35501dd927..41160c80c5 100644 --- a/docs-rs/bdk/nightly/latest/bdk_wallet/wallet/error/enum.MiniscriptPsbtError.html +++ b/docs-rs/bdk/nightly/latest/bdk_wallet/wallet/error/enum.MiniscriptPsbtError.html @@ -6,7 +6,7 @@

    Variants§

    §

    Conversion(ConversionError)

    Descriptor key conversion error

    §

    UtxoUpdate(UtxoUpdateError)

    Return error type for PsbtExt::update_input_with_descriptor

    §

    OutputUpdate(OutputUpdateError)

    Return error type for PsbtExt::update_output_with_descriptor

    -

    Trait Implementations§

    source§

    impl Clone for MiniscriptPsbtError

    source§

    fn clone(&self) -> MiniscriptPsbtError

    Returns a copy of the value. Read more
    1.0.0 · source§

    fn clone_from(&mut self, source: &Self)

    Performs copy-assignment from source. Read more
    source§

    impl Debug for MiniscriptPsbtError

    source§

    fn fmt(&self, f: &mut Formatter<'_>) -> Result

    Formats the value using the given formatter. Read more
    source§

    impl Display for MiniscriptPsbtError

    source§

    fn fmt(&self, f: &mut Formatter<'_>) -> Result

    Formats the value using the given formatter. Read more
    source§

    impl Error for MiniscriptPsbtError

    1.30.0 · source§

    fn source(&self) -> Option<&(dyn Error + 'static)>

    The lower-level source of this error, if any. Read more
    1.0.0 · source§

    fn description(&self) -> &str

    👎Deprecated since 1.42.0: use the Display impl or to_string()
    1.0.0 · source§

    fn cause(&self) -> Option<&dyn Error>

    👎Deprecated since 1.33.0: replaced by Error::source, which can support downcasting
    source§

    fn provide<'a>(&'a self, request: &mut Request<'a>)

    🔬This is a nightly-only experimental API. (error_generic_member_access)
    Provides type based access to context intended for error reports. Read more
    source§

    impl From<MiniscriptPsbtError> for CreateTxError

    source§

    fn from(err: MiniscriptPsbtError) -> Self

    Converts to this type from the input type.

    Auto Trait Implementations§

    Blanket Implementations§

    source§

    impl<T> Any for T
    where +

    Trait Implementations§

    source§

    impl Clone for MiniscriptPsbtError

    source§

    fn clone(&self) -> MiniscriptPsbtError

    Returns a copy of the value. Read more
    1.0.0 · source§

    fn clone_from(&mut self, source: &Self)

    Performs copy-assignment from source. Read more
    source§

    impl Debug for MiniscriptPsbtError

    source§

    fn fmt(&self, f: &mut Formatter<'_>) -> Result

    Formats the value using the given formatter. Read more
    source§

    impl Display for MiniscriptPsbtError

    source§

    fn fmt(&self, f: &mut Formatter<'_>) -> Result

    Formats the value using the given formatter. Read more
    source§

    impl Error for MiniscriptPsbtError

    1.30.0 · source§

    fn source(&self) -> Option<&(dyn Error + 'static)>

    The lower-level source of this error, if any. Read more
    1.0.0 · source§

    fn description(&self) -> &str

    👎Deprecated since 1.42.0: use the Display impl or to_string()
    1.0.0 · source§

    fn cause(&self) -> Option<&dyn Error>

    👎Deprecated since 1.33.0: replaced by Error::source, which can support downcasting
    source§

    fn provide<'a>(&'a self, request: &mut Request<'a>)

    🔬This is a nightly-only experimental API. (error_generic_member_access)
    Provides type based access to context intended for error reports. Read more
    source§

    impl From<MiniscriptPsbtError> for CreateTxError

    source§

    fn from(err: MiniscriptPsbtError) -> Self

    Converts to this type from the input type.

    Auto Trait Implementations§

    Blanket Implementations§

    source§

    impl<T> Any for T
    where T: 'static + ?Sized,

    source§

    fn type_id(&self) -> TypeId

    Gets the TypeId of self. Read more
    source§

    impl<T> Borrow<T> for T
    where T: ?Sized,

    source§

    fn borrow(&self) -> &T

    Immutably borrows from an owned value. Read more
    source§

    impl<T> BorrowMut<T> for T
    where T: ?Sized,

    source§

    fn borrow_mut(&mut self) -> &mut T

    Mutably borrows from an owned value. Read more
    source§

    impl<T> From<T> for T

    source§

    fn from(t: T) -> T

    Returns the argument unchanged.

    diff --git a/docs-rs/bdk/nightly/latest/bdk_wallet/wallet/fn.wallet_name_from_descriptor.html b/docs-rs/bdk/nightly/latest/bdk_wallet/wallet/fn.wallet_name_from_descriptor.html index a1c401f850..ecf7a26ab7 100644 --- a/docs-rs/bdk/nightly/latest/bdk_wallet/wallet/fn.wallet_name_from_descriptor.html +++ b/docs-rs/bdk/nightly/latest/bdk_wallet/wallet/fn.wallet_name_from_descriptor.html @@ -1,4 +1,4 @@ -wallet_name_from_descriptor in bdk_wallet::wallet - Rust

    Function bdk_wallet::wallet::wallet_name_from_descriptor

    source ·
    pub fn wallet_name_from_descriptor<T>(
    +wallet_name_from_descriptor in bdk_wallet::wallet - Rust

    Function bdk_wallet::wallet::wallet_name_from_descriptor

    source ·
    pub fn wallet_name_from_descriptor<T>(
         descriptor: T,
         change_descriptor: Option<T>,
         network: Network,
    diff --git a/docs-rs/bdk/nightly/latest/bdk_wallet/wallet/index.html b/docs-rs/bdk/nightly/latest/bdk_wallet/wallet/index.html
    index d659dc4a69..2d42cf3a50 100644
    --- a/docs-rs/bdk/nightly/latest/bdk_wallet/wallet/index.html
    +++ b/docs-rs/bdk/nightly/latest/bdk_wallet/wallet/index.html
    @@ -1,4 +1,4 @@
    -bdk_wallet::wallet - Rust

    Module bdk_wallet::wallet

    source ·
    Expand description

    Wallet

    +bdk_wallet::wallet - Rust

    Module bdk_wallet::wallet

    source ·
    Expand description

    Wallet

    This module defines the Wallet.

    Modules§

    Structs§

    • A derived address and the index it was found at. For convenience this automatically derefs to Address
    • Balance, differentiated into various categories.
    • An update to Wallet.
    • A Bitcoin wallet

    Enums§

    Traits§

    • Trait to check if a value is below the dust limit. diff --git a/docs-rs/bdk/nightly/latest/bdk_wallet/wallet/signer/enum.SignerError.html b/docs-rs/bdk/nightly/latest/bdk_wallet/wallet/signer/enum.SignerError.html index c7d65fc8dc..88a0633899 100644 --- a/docs-rs/bdk/nightly/latest/bdk_wallet/wallet/signer/enum.SignerError.html +++ b/docs-rs/bdk/nightly/latest/bdk_wallet/wallet/signer/enum.SignerError.html @@ -37,7 +37,7 @@
      §

      External(String)

      To be used only by external libraries implementing InputSigner or TransactionSigner, so that they can return their own custom errors, without having to modify SignerError in BDK.

      -

    Trait Implementations§

    source§

    impl Debug for SignerError

    source§

    fn fmt(&self, f: &mut Formatter<'_>) -> Result

    Formats the value using the given formatter. Read more
    source§

    impl Display for SignerError

    source§

    fn fmt(&self, f: &mut Formatter<'_>) -> Result

    Formats the value using the given formatter. Read more
    source§

    impl Error for SignerError

    1.30.0 · source§

    fn source(&self) -> Option<&(dyn Error + 'static)>

    The lower-level source of this error, if any. Read more
    1.0.0 · source§

    fn description(&self) -> &str

    👎Deprecated since 1.42.0: use the Display impl or to_string()
    1.0.0 · source§

    fn cause(&self) -> Option<&dyn Error>

    👎Deprecated since 1.33.0: replaced by Error::source, which can support downcasting
    source§

    fn provide<'a>(&'a self, request: &mut Request<'a>)

    🔬This is a nightly-only experimental API. (error_generic_member_access)
    Provides type based access to context intended for error reports. Read more
    source§

    impl From<InputsIndexError> for SignerError

    source§

    fn from(v: InputsIndexError) -> Self

    Converts to this type from the input type.
    source§

    impl From<P2wpkhError> for SignerError

    source§

    fn from(e: P2wpkhError) -> Self

    Converts to this type from the input type.
    source§

    impl From<TaprootError> for SignerError

    source§

    fn from(e: TaprootError) -> Self

    Converts to this type from the input type.

    Auto Trait Implementations§

    Blanket Implementations§

    source§

    impl<T> Any for T
    where +

    Trait Implementations§

    source§

    impl Debug for SignerError

    source§

    fn fmt(&self, f: &mut Formatter<'_>) -> Result

    Formats the value using the given formatter. Read more
    source§

    impl Display for SignerError

    source§

    fn fmt(&self, f: &mut Formatter<'_>) -> Result

    Formats the value using the given formatter. Read more
    source§

    impl Error for SignerError

    1.30.0 · source§

    fn source(&self) -> Option<&(dyn Error + 'static)>

    The lower-level source of this error, if any. Read more
    1.0.0 · source§

    fn description(&self) -> &str

    👎Deprecated since 1.42.0: use the Display impl or to_string()
    1.0.0 · source§

    fn cause(&self) -> Option<&dyn Error>

    👎Deprecated since 1.33.0: replaced by Error::source, which can support downcasting
    source§

    fn provide<'a>(&'a self, request: &mut Request<'a>)

    🔬This is a nightly-only experimental API. (error_generic_member_access)
    Provides type based access to context intended for error reports. Read more
    source§

    impl From<InputsIndexError> for SignerError

    source§

    fn from(v: InputsIndexError) -> Self

    Converts to this type from the input type.
    source§

    impl From<P2wpkhError> for SignerError

    source§

    fn from(e: P2wpkhError) -> Self

    Converts to this type from the input type.
    source§

    impl From<TaprootError> for SignerError

    source§

    fn from(e: TaprootError) -> Self

    Converts to this type from the input type.

    Auto Trait Implementations§

    Blanket Implementations§

    source§

    impl<T> Any for T
    where T: 'static + ?Sized,

    source§

    fn type_id(&self) -> TypeId

    Gets the TypeId of self. Read more
    source§

    impl<T> Borrow<T> for T
    where T: ?Sized,

    source§

    fn borrow(&self) -> &T

    Immutably borrows from an owned value. Read more
    source§

    impl<T> BorrowMut<T> for T
    where T: ?Sized,

    source§

    fn borrow_mut(&mut self) -> &mut T

    Mutably borrows from an owned value. Read more
    source§

    impl<T> From<T> for T

    source§

    fn from(t: T) -> T

    Returns the argument unchanged.

    diff --git a/docs-rs/bdk/nightly/latest/bdk_wallet/wallet/signer/enum.SignerId.html b/docs-rs/bdk/nightly/latest/bdk_wallet/wallet/signer/enum.SignerId.html index 07f85e51fd..5143c21755 100644 --- a/docs-rs/bdk/nightly/latest/bdk_wallet/wallet/signer/enum.SignerId.html +++ b/docs-rs/bdk/nightly/latest/bdk_wallet/wallet/signer/enum.SignerId.html @@ -7,7 +7,7 @@

    Variants§

    §

    PkHash(Hash)

    Bitcoin HASH160 (RIPEMD160 after SHA256) hash of an ECDSA public key

    §

    Fingerprint(Fingerprint)

    The fingerprint of a BIP32 extended key

    §

    Dummy(u64)

    Dummy identifier

    -

    Trait Implementations§

    source§

    impl Clone for SignerId

    source§

    fn clone(&self) -> SignerId

    Returns a copy of the value. Read more
    1.0.0 · source§

    fn clone_from(&mut self, source: &Self)

    Performs copy-assignment from source. Read more
    source§

    impl Debug for SignerId

    source§

    fn fmt(&self, f: &mut Formatter<'_>) -> Result

    Formats the value using the given formatter. Read more
    source§

    impl From<Fingerprint> for SignerId

    source§

    fn from(fing: Fingerprint) -> SignerId

    Converts to this type from the input type.
    source§

    impl From<Hash> for SignerId

    source§

    fn from(hash: Hash) -> SignerId

    Converts to this type from the input type.
    source§

    impl Hash for SignerId

    source§

    fn hash<__H: Hasher>(&self, state: &mut __H)

    Feeds this value into the given Hasher. Read more
    1.3.0 · source§

    fn hash_slice<H>(data: &[Self], state: &mut H)
    where +

    Trait Implementations§

    source§

    impl Clone for SignerId

    source§

    fn clone(&self) -> SignerId

    Returns a copy of the value. Read more
    1.0.0 · source§

    fn clone_from(&mut self, source: &Self)

    Performs copy-assignment from source. Read more
    source§

    impl Debug for SignerId

    source§

    fn fmt(&self, f: &mut Formatter<'_>) -> Result

    Formats the value using the given formatter. Read more
    source§

    impl From<Fingerprint> for SignerId

    source§

    fn from(fing: Fingerprint) -> SignerId

    Converts to this type from the input type.
    source§

    impl From<Hash> for SignerId

    source§

    fn from(hash: Hash) -> SignerId

    Converts to this type from the input type.
    source§

    impl Hash for SignerId

    source§

    fn hash<__H: Hasher>(&self, state: &mut __H)

    Feeds this value into the given Hasher. Read more
    1.3.0 · source§

    fn hash_slice<H>(data: &[Self], state: &mut H)
    where H: Hasher, Self: Sized,

    Feeds a slice of this type into the given Hasher. Read more
    source§

    impl Ord for SignerId

    source§

    fn cmp(&self, other: &SignerId) -> Ordering

    This method returns an Ordering between self and other. Read more
    1.21.0 · source§

    fn max(self, other: Self) -> Self
    where Self: Sized,

    Compares and returns the maximum of two values. Read more
    1.21.0 · source§

    fn min(self, other: Self) -> Self
    where diff --git a/docs-rs/bdk/nightly/latest/bdk_wallet/wallet/signer/struct.SignerWrapper.html b/docs-rs/bdk/nightly/latest/bdk_wallet/wallet/signer/struct.SignerWrapper.html index 0bf4b6e7f7..c8c1abb326 100644 --- a/docs-rs/bdk/nightly/latest/bdk_wallet/wallet/signer/struct.SignerWrapper.html +++ b/docs-rs/bdk/nightly/latest/bdk_wallet/wallet/signer/struct.SignerWrapper.html @@ -6,19 +6,19 @@ input_index: usize, sign_options: &SignOptions, secp: &Secp256k1<All> -) -> Result<(), SignerError>

    Sign a single psbt input
    source§

    impl InputSigner for SignerWrapper<DescriptorXKey<Xpriv>>

    source§

    fn sign_input( +) -> Result<(), SignerError>

    Sign a single psbt input
    source§

    impl InputSigner for SignerWrapper<DescriptorXKey<Xpriv>>

    source§

    fn sign_input( &self, psbt: &mut Psbt, input_index: usize, sign_options: &SignOptions, secp: &Secp256k1<All> -) -> Result<(), SignerError>

    Sign a single psbt input
    source§

    impl InputSigner for SignerWrapper<PrivateKey>

    source§

    fn sign_input( +) -> Result<(), SignerError>

    Sign a single psbt input
    source§

    impl InputSigner for SignerWrapper<PrivateKey>

    source§

    fn sign_input( &self, psbt: &mut Psbt, input_index: usize, sign_options: &SignOptions, secp: &Secp256k1<All> -) -> Result<(), SignerError>

    Sign a single psbt input
    source§

    impl SignerCommon for SignerWrapper<DescriptorMultiXKey<Xpriv>>

    source§

    fn id(&self, secp: &Secp256k1<All>) -> SignerId

    Return the SignerId for this signer Read more
    source§

    fn descriptor_secret_key(&self) -> Option<DescriptorSecretKey>

    Return the secret key for the signer Read more
    source§

    impl SignerCommon for SignerWrapper<DescriptorXKey<Xpriv>>

    source§

    fn id(&self, secp: &Secp256k1<All>) -> SignerId

    Return the SignerId for this signer Read more
    source§

    fn descriptor_secret_key(&self) -> Option<DescriptorSecretKey>

    Return the secret key for the signer Read more
    source§

    impl SignerCommon for SignerWrapper<PrivateKey>

    source§

    fn id(&self, secp: &Secp256k1<All>) -> SignerId

    Return the SignerId for this signer Read more
    source§

    fn descriptor_secret_key(&self) -> Option<DescriptorSecretKey>

    Return the secret key for the signer Read more

    Auto Trait Implementations§

    §

    impl<S> Freeze for SignerWrapper<S>
    where +) -> Result<(), SignerError>

    Sign a single psbt input
    source§

    impl SignerCommon for SignerWrapper<DescriptorMultiXKey<Xpriv>>

    source§

    fn id(&self, secp: &Secp256k1<All>) -> SignerId

    Return the SignerId for this signer Read more
    source§

    fn descriptor_secret_key(&self) -> Option<DescriptorSecretKey>

    Return the secret key for the signer Read more
    source§

    impl SignerCommon for SignerWrapper<DescriptorXKey<Xpriv>>

    source§

    fn id(&self, secp: &Secp256k1<All>) -> SignerId

    Return the SignerId for this signer Read more
    source§

    fn descriptor_secret_key(&self) -> Option<DescriptorSecretKey>

    Return the secret key for the signer Read more
    source§

    impl SignerCommon for SignerWrapper<PrivateKey>

    source§

    fn id(&self, secp: &Secp256k1<All>) -> SignerId

    Return the SignerId for this signer Read more
    source§

    fn descriptor_secret_key(&self) -> Option<DescriptorSecretKey>

    Return the secret key for the signer Read more

    Auto Trait Implementations§

    §

    impl<S> Freeze for SignerWrapper<S>
    where S: Freeze,

    §

    impl<S> RefUnwindSafe for SignerWrapper<S>
    where S: RefUnwindSafe,

    §

    impl<S> Send for SignerWrapper<S>
    where S: Send,

    §

    impl<S> Sync for SignerWrapper<S>
    where diff --git a/docs-rs/bdk/nightly/latest/bdk_wallet/wallet/struct.AddressInfo.html b/docs-rs/bdk/nightly/latest/bdk_wallet/wallet/struct.AddressInfo.html index 789b6d446c..f4753129b0 100644 --- a/docs-rs/bdk/nightly/latest/bdk_wallet/wallet/struct.AddressInfo.html +++ b/docs-rs/bdk/nightly/latest/bdk_wallet/wallet/struct.AddressInfo.html @@ -1,4 +1,4 @@ -AddressInfo in bdk_wallet::wallet - Rust

    Struct bdk_wallet::wallet::AddressInfo

    source ·
    pub struct AddressInfo {
    +AddressInfo in bdk_wallet::wallet - Rust

    Struct bdk_wallet::wallet::AddressInfo

    source ·
    pub struct AddressInfo {
         pub index: u32,
         pub address: Address,
         pub keychain: KeychainKind,
    @@ -68,9 +68,9 @@ 
    §Returns
    let address: Address<NetworkUnchecked> = "32iVBEu4dxkUQk9dJbZUiBiQdmypcEyJRf".parse().unwrap(); assert!(address.is_valid_for_network(Network::Bitcoin)); assert_eq!(address.is_valid_for_network(Network::Testnet), false);
    -

    Trait Implementations§

    source§

    impl Debug for AddressInfo

    source§

    fn fmt(&self, f: &mut Formatter<'_>) -> Result

    Formats the value using the given formatter. Read more
    source§

    impl Deref for AddressInfo

    §

    type Target = Address

    The resulting type after dereferencing.
    source§

    fn deref(&self) -> &Self::Target

    Dereferences the value.
    source§

    impl Display for AddressInfo

    source§

    fn fmt(&self, f: &mut Formatter<'_>) -> Result

    Formats the value using the given formatter. Read more
    source§

    impl PartialEq for AddressInfo

    source§

    fn eq(&self, other: &AddressInfo) -> bool

    This method tests for self and other values to be equal, and is used +

    Trait Implementations§

    source§

    impl Debug for AddressInfo

    source§

    fn fmt(&self, f: &mut Formatter<'_>) -> Result

    Formats the value using the given formatter. Read more
    source§

    impl Deref for AddressInfo

    §

    type Target = Address

    The resulting type after dereferencing.
    source§

    fn deref(&self) -> &Self::Target

    Dereferences the value.
    source§

    impl Display for AddressInfo

    source§

    fn fmt(&self, f: &mut Formatter<'_>) -> Result

    Formats the value using the given formatter. Read more
    source§

    impl PartialEq for AddressInfo

    source§

    fn eq(&self, other: &AddressInfo) -> bool

    This method tests for self and other values to be equal, and is used by ==.
    1.0.0 · source§

    fn ne(&self, other: &Rhs) -> bool

    This method tests for !=. The default implementation is almost always -sufficient, and should not be overridden without very good reason.
    source§

    impl Eq for AddressInfo

    source§

    impl StructuralPartialEq for AddressInfo

    Auto Trait Implementations§

    Blanket Implementations§

    source§

    impl<T> Any for T
    where +sufficient, and should not be overridden without very good reason.

    source§

    impl Eq for AddressInfo

    source§

    impl StructuralPartialEq for AddressInfo

    Auto Trait Implementations§

    Blanket Implementations§

    source§

    impl<T> Any for T
    where T: 'static + ?Sized,

    source§

    fn type_id(&self) -> TypeId

    Gets the TypeId of self. Read more
    source§

    impl<T> Borrow<T> for T
    where T: ?Sized,

    source§

    fn borrow(&self) -> &T

    Immutably borrows from an owned value. Read more
    source§

    impl<T> BorrowMut<T> for T
    where T: ?Sized,

    source§

    fn borrow_mut(&mut self) -> &mut T

    Mutably borrows from an owned value. Read more
    source§

    impl<T> From<T> for T

    source§

    fn from(t: T) -> T

    Returns the argument unchanged.

    diff --git a/docs-rs/bdk/nightly/latest/bdk_wallet/wallet/struct.Update.html b/docs-rs/bdk/nightly/latest/bdk_wallet/wallet/struct.Update.html index b8851b6093..cce549c8b3 100644 --- a/docs-rs/bdk/nightly/latest/bdk_wallet/wallet/struct.Update.html +++ b/docs-rs/bdk/nightly/latest/bdk_wallet/wallet/struct.Update.html @@ -1,4 +1,4 @@ -Update in bdk_wallet::wallet - Rust

    Struct bdk_wallet::wallet::Update

    source ·
    pub struct Update {
    +Update in bdk_wallet::wallet - Rust

    Struct bdk_wallet::wallet::Update

    source ·
    pub struct Update {
         pub last_active_indices: BTreeMap<KeychainKind, u32>,
         pub graph: TxGraph<ConfirmationTimeHeightAnchor>,
         pub chain: Option<CheckPoint>,
    @@ -8,7 +8,7 @@
     [KeychainTxOutIndex].

    §graph: TxGraph<ConfirmationTimeHeightAnchor>

    Update for the wallet’s internal [TxGraph].

    §chain: Option<CheckPoint>

    Update for the wallet’s internal LocalChain.

    -

    Trait Implementations§

    source§

    impl Clone for Update

    source§

    fn clone(&self) -> Update

    Returns a copy of the value. Read more
    1.0.0 · source§

    fn clone_from(&mut self, source: &Self)

    Performs copy-assignment from source. Read more
    source§

    impl Debug for Update

    source§

    fn fmt(&self, f: &mut Formatter<'_>) -> Result

    Formats the value using the given formatter. Read more
    source§

    impl Default for Update

    source§

    fn default() -> Update

    Returns the “default value” for a type. Read more
    source§

    impl From<FullScanResult<KeychainKind>> for Update

    source§

    fn from(value: FullScanResult<KeychainKind>) -> Self

    Converts to this type from the input type.
    source§

    impl From<SyncResult> for Update

    source§

    fn from(value: SyncResult) -> Self

    Converts to this type from the input type.

    Auto Trait Implementations§

    §

    impl Freeze for Update

    §

    impl RefUnwindSafe for Update

    §

    impl Send for Update

    §

    impl Sync for Update

    §

    impl Unpin for Update

    §

    impl UnwindSafe for Update

    Blanket Implementations§

    source§

    impl<T> Any for T
    where +

    Trait Implementations§

    source§

    impl Clone for Update

    source§

    fn clone(&self) -> Update

    Returns a copy of the value. Read more
    1.0.0 · source§

    fn clone_from(&mut self, source: &Self)

    Performs copy-assignment from source. Read more
    source§

    impl Debug for Update

    source§

    fn fmt(&self, f: &mut Formatter<'_>) -> Result

    Formats the value using the given formatter. Read more
    source§

    impl Default for Update

    source§

    fn default() -> Update

    Returns the “default value” for a type. Read more
    source§

    impl From<FullScanResult<KeychainKind>> for Update

    source§

    fn from(value: FullScanResult<KeychainKind>) -> Self

    Converts to this type from the input type.
    source§

    impl From<SyncResult> for Update

    source§

    fn from(value: SyncResult) -> Self

    Converts to this type from the input type.

    Auto Trait Implementations§

    §

    impl Freeze for Update

    §

    impl RefUnwindSafe for Update

    §

    impl Send for Update

    §

    impl Sync for Update

    §

    impl Unpin for Update

    §

    impl UnwindSafe for Update

    Blanket Implementations§

    source§

    impl<T> Any for T
    where T: 'static + ?Sized,

    source§

    fn type_id(&self) -> TypeId

    Gets the TypeId of self. Read more
    source§

    impl<T> Borrow<T> for T
    where T: ?Sized,

    source§

    fn borrow(&self) -> &T

    Immutably borrows from an owned value. Read more
    source§

    impl<T> BorrowMut<T> for T
    where T: ?Sized,

    source§

    fn borrow_mut(&mut self) -> &mut T

    Mutably borrows from an owned value. Read more
    source§

    impl<T> From<T> for T

    source§

    fn from(t: T) -> T

    Returns the argument unchanged.

    diff --git a/docs-rs/bdk/nightly/latest/bdk_wallet/wallet/struct.Wallet.html b/docs-rs/bdk/nightly/latest/bdk_wallet/wallet/struct.Wallet.html index e45f128f2a..9db6d954d2 100644 --- a/docs-rs/bdk/nightly/latest/bdk_wallet/wallet/struct.Wallet.html +++ b/docs-rs/bdk/nightly/latest/bdk_wallet/wallet/struct.Wallet.html @@ -1,4 +1,4 @@ -Wallet in bdk_wallet::wallet - Rust

    Struct bdk_wallet::wallet::Wallet

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

    A Bitcoin wallet

    +Wallet in bdk_wallet::wallet - Rust

    Struct bdk_wallet::wallet::Wallet

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

    A Bitcoin wallet

    The Wallet acts as a way of coherently interfacing with output descriptors and related transactions. Its main components are:

      @@ -8,12 +8,12 @@

      The user is responsible for loading and writing wallet changes which are represented as ChangeSets (see take_staged). Also see individual functions and example for instructions on when Wallet state needs to be persisted.

      -

    Implementations§

    source§

    impl Wallet

    Implementations§

    source§

    impl Wallet

    source

    pub fn new<E: IntoWalletDescriptor>( descriptor: E, change_descriptor: E, network: Network ) -> Result<Self, NewError>

    Initialize an empty Wallet.

    -
    source

    pub fn new_with_genesis_hash<E: IntoWalletDescriptor>( +

    source

    pub fn new_with_genesis_hash<E: IntoWalletDescriptor>( descriptor: E, change_descriptor: E, network: Network, @@ -21,7 +21,7 @@ ) -> Result<Self, NewError>

    Initialize an empty Wallet with a custom genesis hash.

    This is like Wallet::new with an additional genesis_hash parameter. This is useful for syncing from alternative networks.

    -
    source

    pub fn load_from_changeset(changeset: ChangeSet) -> Result<Self, LoadError>

    Load Wallet from the given previously persisted ChangeSet.

    +
    source

    pub fn load_from_changeset(changeset: ChangeSet) -> Result<Self, LoadError>

    Load Wallet from the given previously persisted ChangeSet.

    Note that the descriptor secret keys are not persisted to the db; this means that after calling this method the Wallet won’t know the secret keys, and as such, won’t be able to sign transactions.

    @@ -47,7 +47,7 @@ .for_each(|s| wallet.add_signer(KeychainKind::Internal, SignerOrdering::default(), s.clone()));

    Alternatively, you can call Wallet::new_or_load, which will add the private keys of the passed-in descriptors to the Wallet.

    -
    source

    pub fn new_or_load<E: IntoWalletDescriptor>( +

    source

    pub fn new_or_load<E: IntoWalletDescriptor>( descriptor: E, change_descriptor: E, changeset: Option<ChangeSet>, @@ -64,7 +64,7 @@ let internal_descriptor = "wpkh(tprv8ZgxMBicQKsPdy6LMhUtFHAgpocR8GC6QmwMSFpZs7h6Eziw3SpThFfczTDh5rW2krkqffa11UpX3XkeTTB2FvzZKWXqPY54Y6Rq4AQ5R8L/84'/1'/0'/1/*)"; let mut wallet = Wallet::new_or_load(external_descriptor, internal_descriptor, changeset, Testnet)?;

    -
    source

    pub fn new_or_load_with_genesis_hash<E: IntoWalletDescriptor>( +

    source

    pub fn new_or_load_with_genesis_hash<E: IntoWalletDescriptor>( descriptor: E, change_descriptor: E, changeset: Option<ChangeSet>, @@ -75,16 +75,16 @@

    This method will fail if the loaded ChangeSet has different parameters to those provided. This is like Wallet::new_or_load with an additional genesis_hash parameter. This is useful for syncing from alternative networks.

    -

    source

    pub fn network(&self) -> Network

    Get the Bitcoin network the wallet is using.

    -
    source

    pub fn keychains( +

    source

    pub fn network(&self) -> Network

    Get the Bitcoin network the wallet is using.

    +
    source

    pub fn keychains( &self ) -> impl Iterator<Item = (&KeychainKind, &ExtendedDescriptor)>

    Iterator over all keychains in this wallet

    -
    source

    pub fn peek_address(&self, keychain: KeychainKind, index: u32) -> AddressInfo

    Peek an address of the given keychain at index without revealing it.

    +
    source

    pub fn peek_address(&self, keychain: KeychainKind, index: u32) -> AddressInfo

    Peek an address of the given keychain at index without revealing it.

    For non-wildcard descriptors this returns the same address at every provided index.

    §Panics

    This panics when the caller requests for an address of derivation index greater than the BIP32 max index.

    -
    source

    pub fn reveal_next_address(&mut self, keychain: KeychainKind) -> AddressInfo

    Attempt to reveal the next address of the given keychain.

    +
    source

    pub fn reveal_next_address(&mut self, keychain: KeychainKind) -> AddressInfo

    Attempt to reveal the next address of the given keychain.

    This will increment the keychain’s derivation index. If the keychain’s descriptor doesn’t contain a wildcard or every address is already revealed up to the maximum derivation index defined in BIP32, @@ -102,7 +102,7 @@

    §Panics
    // Now it's safe to show the user their next address! println!("Next address: {}", next_address.address);
    -
    source

    pub fn reveal_addresses_to( +

    source

    pub fn reveal_addresses_to( &mut self, keychain: KeychainKind, index: u32 @@ -113,35 +113,35 @@

    §Panics
    no new addresses are returned.

    WARNING: To avoid address reuse you must persist the changes resulting from one or more calls to this method before closing the wallet. See Wallet::reveal_next_address.

    -
    source

    pub fn next_unused_address(&mut self, keychain: KeychainKind) -> AddressInfo

    Get the next unused address for the given keychain, i.e. the address with the lowest +

    source

    pub fn next_unused_address(&mut self, keychain: KeychainKind) -> AddressInfo

    Get the next unused address for the given keychain, i.e. the address with the lowest derivation index that hasn’t been used.

    This will attempt to derive and reveal a new address if no newly revealed addresses are available. See also reveal_next_address.

    WARNING: To avoid address reuse you must persist the changes resulting from one or more calls to this method before closing the wallet. See Wallet::reveal_next_address.

    -
    source

    pub fn mark_used(&mut self, keychain: KeychainKind, index: u32) -> bool

    Marks an address used of the given keychain at index.

    +
    source

    pub fn mark_used(&mut self, keychain: KeychainKind, index: u32) -> bool

    Marks an address used of the given keychain at index.

    Returns whether the given index was present and then removed from the unused set.

    -
    source

    pub fn unmark_used(&mut self, keychain: KeychainKind, index: u32) -> bool

    Undoes the effect of mark_used and returns whether the index was inserted +

    source

    pub fn unmark_used(&mut self, keychain: KeychainKind, index: u32) -> bool

    Undoes the effect of mark_used and returns whether the index was inserted back into the unused set.

    Since this is only a superficial marker, it will have no effect if the address at the given index was actually used, i.e. the wallet has previously indexed a tx output for the derived spk.

    -
    source

    pub fn list_unused_addresses( +

    source

    pub fn list_unused_addresses( &self, keychain: KeychainKind ) -> impl DoubleEndedIterator<Item = AddressInfo> + '_

    List addresses that are revealed but unused.

    Note if the returned iterator is empty you can reveal more addresses by using reveal_next_address or reveal_addresses_to.

    -
    source

    pub fn is_mine(&self, script: &Script) -> bool

    Return whether or not a script is part of this wallet (either internal or external)

    -
    source

    pub fn derivation_of_spk(&self, spk: &Script) -> Option<(KeychainKind, u32)>

    Finds how the wallet derived the script pubkey spk.

    +
    source

    pub fn is_mine(&self, script: &Script) -> bool

    Return whether or not a script is part of this wallet (either internal or external)

    +
    source

    pub fn derivation_of_spk(&self, spk: &Script) -> Option<(KeychainKind, u32)>

    Finds how the wallet derived the script pubkey spk.

    Will only return Some(_) if the wallet has given out the spk.

    -
    source

    pub fn list_unspent(&self) -> impl Iterator<Item = LocalOutput> + '_

    Return the list of unspent outputs of this wallet

    -
    source

    pub fn list_output(&self) -> impl Iterator<Item = LocalOutput> + '_

    List all relevant outputs (includes both spent and unspent, confirmed and unconfirmed).

    +
    source

    pub fn list_unspent(&self) -> impl Iterator<Item = LocalOutput> + '_

    Return the list of unspent outputs of this wallet

    +
    source

    pub fn list_output(&self) -> impl Iterator<Item = LocalOutput> + '_

    List all relevant outputs (includes both spent and unspent, confirmed and unconfirmed).

    To list only unspent outputs (UTXOs), use Wallet::list_unspent instead.

    -
    source

    pub fn checkpoints(&self) -> CheckPointIter

    Get all the checkpoints the wallet is currently storing indexed by height.

    -
    source

    pub fn latest_checkpoint(&self) -> CheckPoint

    Returns the latest checkpoint.

    -
    source

    pub fn all_unbounded_spk_iters( +

    source

    pub fn checkpoints(&self) -> CheckPointIter

    Get all the checkpoints the wallet is currently storing indexed by height.

    +
    source

    pub fn latest_checkpoint(&self) -> CheckPoint

    Returns the latest checkpoint.

    +
    source

    pub fn all_unbounded_spk_iters( &self ) -> BTreeMap<KeychainKind, impl Iterator<Item = Indexed<ScriptBuf>> + Clone>

    Get unbounded script pubkey iterators for both Internal and External keychains.

    This is intended to be used when doing a full scan of your addresses (e.g. after restoring @@ -149,14 +149,14 @@

    §Panics
    electrum server) which will go through each address until it reaches a stop gap.

    Note carefully that iterators go over all script pubkeys on the keychains (not what script pubkeys the wallet is storing internally).

    -
    source

    pub fn unbounded_spk_iter( +

    source

    pub fn unbounded_spk_iter( &self, keychain: KeychainKind ) -> impl Iterator<Item = Indexed<ScriptBuf>> + Clone

    Get an unbounded script pubkey iterator for the given keychain.

    See all_unbounded_spk_iters for more documentation

    -
    source

    pub fn get_utxo(&self, op: OutPoint) -> Option<LocalOutput>

    Returns the utxo owned by this wallet corresponding to outpoint if it exists in the +

    source

    pub fn get_utxo(&self, op: OutPoint) -> Option<LocalOutput>

    Returns the utxo owned by this wallet corresponding to outpoint if it exists in the wallet’s database.

    -
    source

    pub fn insert_txout(&mut self, outpoint: OutPoint, txout: TxOut)

    Inserts a [TxOut] at [OutPoint] into the wallet’s transaction graph.

    +
    source

    pub fn insert_txout(&mut self, outpoint: OutPoint, txout: TxOut)

    Inserts a [TxOut] at [OutPoint] into the wallet’s transaction graph.

    This is used for providing a previous output’s value so that we can use calculate_fee or calculate_fee_rate on a given transaction. Outputs inserted with this method will not be returned in list_unspent or list_output.

    @@ -165,7 +165,7 @@
    §Panics

    You must persist the changes resulting from one or more calls to this method if you need the inserted TxOut data to be reloaded after closing the wallet. See Wallet::reveal_next_address.

    -
    source

    pub fn calculate_fee( +

    source

    pub fn calculate_fee( &self, tx: &Transaction ) -> Result<Amount, CalculateFeeError>

    Calculates the fee of a given transaction. Returns [Amount::ZERO] if tx is a coinbase transaction.

    @@ -178,7 +178,7 @@
    §Examples
    let tx = &psbt.clone().extract_tx().expect("tx");
     let fee = wallet.calculate_fee(tx).expect("fee");
    -
    source

    pub fn calculate_fee_rate( +

    source

    pub fn calculate_fee_rate( &self, tx: &Transaction ) -> Result<FeeRate, CalculateFeeError>

    Calculate the [FeeRate] for a given transaction.

    @@ -191,7 +191,7 @@
    §Examples
    let tx = &psbt.clone().extract_tx().expect("tx");
     let fee_rate = wallet.calculate_fee_rate(tx).expect("fee rate");
    -
    source

    pub fn sent_and_received(&self, tx: &Transaction) -> (Amount, Amount)

    Compute the tx’s sent and received [Amount]s.

    +
    source

    pub fn sent_and_received(&self, tx: &Transaction) -> (Amount, Amount)

    Compute the tx’s sent and received [Amount]s.

    This method returns a tuple (sent, received). Sent is the sum of the txin amounts that spend from previous txouts tracked by this wallet. Received is the summation of this tx’s outputs that send to script pubkeys tracked by this wallet.

    @@ -201,7 +201,7 @@
    §Examples
    let tx = &psbt.clone().extract_tx().expect("tx");
     let (sent, received) = wallet.sent_and_received(tx);
    -
    source

    pub fn get_tx( +

    source

    pub fn get_tx( &self, txid: Txid ) -> Option<CanonicalTx<'_, Arc<Transaction>, ConfirmationTimeHeightAnchor>>

    Get a single transaction from the wallet as a [CanonicalTx] (if the transaction exists).

    @@ -242,7 +242,7 @@
    §Examples
    last_seen, ), }
    -
    source

    pub fn insert_checkpoint( +

    source

    pub fn insert_checkpoint( &mut self, block_id: BlockId ) -> Result<bool, AlterCheckPointError>

    Add a new checkpoint to the wallet’s internal view of the chain.

    @@ -251,7 +251,7 @@
    §Examples

    WARNING: You must persist the changes resulting from one or more calls to this method if you need the inserted checkpoint data to be reloaded after closing the wallet. See Wallet::reveal_next_address.

    -
    source

    pub fn insert_tx( +

    source

    pub fn insert_tx( &mut self, tx: Transaction, position: ConfirmationTime @@ -267,19 +267,19 @@

    §Examples
    local view of the best chain’s history.

    You must persist the changes resulting from one or more calls to this method if you need the inserted tx to be reloaded after closing the wallet.

    -
    source

    pub fn transactions( +

    source

    pub fn transactions( &self ) -> impl Iterator<Item = CanonicalTx<'_, Arc<Transaction>, ConfirmationTimeHeightAnchor>> + '_

    Iterate over the transactions in the wallet.

    -
    source

    pub fn balance(&self) -> Balance

    Return the balance, separated into available, trusted-pending, untrusted-pending and immature +

    source

    pub fn balance(&self) -> Balance

    Return the balance, separated into available, trusted-pending, untrusted-pending and immature values.

    -
    source

    pub fn add_signer( +

    source

    pub fn add_signer( &mut self, keychain: KeychainKind, ordering: SignerOrdering, signer: Arc<dyn TransactionSigner> )

    Add an external signer

    See the signer module for an example.

    -
    source

    pub fn get_signers(&self, keychain: KeychainKind) -> Arc<SignersContainer>

    Get the signers

    +
    source

    pub fn get_signers(&self, keychain: KeychainKind) -> Arc<SignersContainer>

    Get the signers

    §Example
    let descriptor = "wpkh(tprv8ZgxMBicQKsPe73PBRSmNbTfbcsZnwWhz5eVmhHpi31HW29Z7mc9B4cWGRQzopNUzZUT391DeDJxL2PefNunWyLgqCKRMDkU1s2s8bAfoSk/84'/1'/0'/0/*)";
     let change_descriptor = "wpkh(tprv8ZgxMBicQKsPe73PBRSmNbTfbcsZnwWhz5eVmhHpi31HW29Z7mc9B4cWGRQzopNUzZUT391DeDJxL2PefNunWyLgqCKRMDkU1s2s8bAfoSk/84'/1'/0'/1/*)";
    @@ -290,7 +290,7 @@ 
    §Example
    } Ok::<(), Box<dyn std::error::Error>>(())
    -
    source

    pub fn build_tx(&mut self) -> TxBuilder<'_, DefaultCoinSelectionAlgorithm>

    Start building a transaction.

    +
    source

    pub fn build_tx(&mut self) -> TxBuilder<'_, DefaultCoinSelectionAlgorithm>

    Start building a transaction.

    This returns a blank TxBuilder from which you can specify the parameters for the transaction.

    §Example
    let psbt = {
    @@ -301,7 +301,7 @@ 
    §Example
    }; // sign and broadcast ...
    -
    source

    pub fn build_fee_bump( +

    source

    pub fn build_fee_bump( &mut self, txid: Txid ) -> Result<TxBuilder<'_, DefaultCoinSelectionAlgorithm>, BuildFeeBumpError>

    Bump the fee of a transaction previously created with this wallet.

    @@ -329,7 +329,7 @@
    §Example
    let _ = wallet.sign(&mut psbt, SignOptions::default())?; let fee_bumped_tx = psbt.extract_tx(); // broadcast fee_bumped_tx to replace original
    -
    source

    pub fn sign( +

    source

    pub fn sign( &self, psbt: &mut Psbt, sign_options: SignOptions @@ -347,14 +347,14 @@

    §Example
    }; let finalized = wallet.sign(&mut psbt, SignOptions::default())?; assert!(finalized, "we should have signed all the inputs"); -
    source

    pub fn policies( +

    source

    pub fn policies( &self, keychain: KeychainKind ) -> Result<Option<Policy>, DescriptorError>

    Return the spending policies for the wallet’s descriptor

    -
    source

    pub fn public_descriptor(&self, keychain: KeychainKind) -> &ExtendedDescriptor

    Return the “public” version of the wallet’s descriptor, meaning a new descriptor that has +

    source

    pub fn public_descriptor(&self, keychain: KeychainKind) -> &ExtendedDescriptor

    Return the “public” version of the wallet’s descriptor, meaning a new descriptor that has the same structure but with every secret key removed

    This can be used to build a watch-only version of a wallet

    -
    source

    pub fn finalize_psbt( +

    source

    pub fn finalize_psbt( &self, psbt: &mut Psbt, sign_options: SignOptions @@ -365,25 +365,25 @@

    §Example
    for further information.

    Returns true if the PSBT could be finalized, and false otherwise.

    The SignOptions can be used to tweak the behavior of the finalizer.

    -
    source

    pub fn secp_ctx(&self) -> &Secp256k1<All>

    Return the secp256k1 context used for all signing operations

    -
    source

    pub fn get_descriptor_for_keychain( +

    source

    pub fn secp_ctx(&self) -> &Secp256k1<All>

    Return the secp256k1 context used for all signing operations

    +
    source

    pub fn get_descriptor_for_keychain( &self, keychain: KeychainKind ) -> &ExtendedDescriptor

    Returns the descriptor used to create addresses for a particular keychain.

    -
    source

    pub fn derivation_index(&self, keychain: KeychainKind) -> Option<u32>

    The derivation index of this wallet. It will return None if it has not derived any addresses. +

    source

    pub fn derivation_index(&self, keychain: KeychainKind) -> Option<u32>

    The derivation index of this wallet. It will return None if it has not derived any addresses. Otherwise, it will return the index of the highest address it has derived.

    -
    source

    pub fn next_derivation_index(&self, keychain: KeychainKind) -> u32

    The index of the next address that you would get if you were to ask the wallet for a new address

    -
    source

    pub fn cancel_tx(&mut self, tx: &Transaction)

    Informs the wallet that you no longer intend to broadcast a tx that was built from it.

    +
    source

    pub fn next_derivation_index(&self, keychain: KeychainKind) -> u32

    The index of the next address that you would get if you were to ask the wallet for a new address

    +
    source

    pub fn cancel_tx(&mut self, tx: &Transaction)

    Informs the wallet that you no longer intend to broadcast a tx that was built from it.

    This frees up the change address used when creating the tx for use in future transactions.

    -
    source

    pub fn get_psbt_input( +

    source

    pub fn get_psbt_input( &self, utxo: LocalOutput, sighash_type: Option<PsbtSighashType>, only_witness_utxo: bool ) -> Result<Input, CreateTxError>

    get the corresponding PSBT Input for a LocalUtxo

    -
    source

    pub fn descriptor_checksum(&self, keychain: KeychainKind) -> String

    Return the checksum of the public descriptor associated to keychain

    +
    source

    pub fn descriptor_checksum(&self, keychain: KeychainKind) -> String

    Return the checksum of the public descriptor associated to keychain

    Internally calls Self::get_descriptor_for_keychain to fetch the right descriptor

    -
    source

    pub fn apply_update( +

    source

    pub fn apply_update( &mut self, update: impl Into<Update> ) -> Result<(), CannotConnectError>

    Applies an update to the wallet and stages the changes (but does not persist them).

    @@ -391,12 +391,12 @@
    §Example
    transactions related to your wallet into it.

    After applying updates you should persist the staged wallet changes. For an example of how to persist staged wallet changes see Wallet::reveal_next_address. `

    -
    source

    pub fn staged(&self) -> Option<&ChangeSet>

    Get a reference of the staged ChangeSet that are yet to be committed (if any).

    -
    source

    pub fn take_staged(&mut self) -> Option<ChangeSet>

    Take the staged ChangeSet to be persisted now (if any).

    -
    source

    pub fn tx_graph(&self) -> &TxGraph<ConfirmationTimeHeightAnchor>

    Get a reference to the inner [TxGraph].

    -
    source

    pub fn spk_index(&self) -> &KeychainTxOutIndex<KeychainKind>

    Get a reference to the inner [KeychainTxOutIndex].

    -
    source

    pub fn local_chain(&self) -> &LocalChain

    Get a reference to the inner [LocalChain].

    -
    source

    pub fn apply_block( +

    source

    pub fn staged(&self) -> Option<&ChangeSet>

    Get a reference of the staged ChangeSet that are yet to be committed (if any).

    +
    source

    pub fn take_staged(&mut self) -> Option<ChangeSet>

    Take the staged ChangeSet to be persisted now (if any).

    +
    source

    pub fn tx_graph(&self) -> &TxGraph<ConfirmationTimeHeightAnchor>

    Get a reference to the inner [TxGraph].

    +
    source

    pub fn spk_index(&self) -> &KeychainTxOutIndex<KeychainKind>

    Get a reference to the inner [KeychainTxOutIndex].

    +
    source

    pub fn local_chain(&self) -> &LocalChain

    Get a reference to the inner [LocalChain].

    +
    source

    pub fn apply_block( &mut self, block: &Block, height: u32 @@ -404,7 +404,7 @@

    §Example
    prev_blockhash of the block’s header.

    This is a convenience method that is equivalent to calling apply_block_connected_to with prev_blockhash and height-1 as the connected_to parameter.

    -
    source

    pub fn apply_block_connected_to( +

    source

    pub fn apply_block_connected_to( &mut self, block: &Block, height: u32, @@ -417,7 +417,7 @@

    §Example

    WARNING: You must persist the changes resulting from one or more calls to this method if you need the inserted block data to be reloaded after closing the wallet. See Wallet::reveal_next_address.

    -
    source

    pub fn apply_unconfirmed_txs<'t>( +

    source

    pub fn apply_unconfirmed_txs<'t>( &mut self, unconfirmed_txs: impl IntoIterator<Item = (&'t Transaction, u64)> )

    Apply relevant unconfirmed transactions to the wallet.

    @@ -429,18 +429,18 @@
    §Example

    WARNING: You must persist the changes resulting from one or more calls to this method if you need the applied unconfirmed transactions to be reloaded after closing the wallet. See Wallet::reveal_next_address.

    -
    source§

    impl Wallet

    Methods to construct sync/full-scan requests for spk-based chain sources.

    -
    source

    pub fn start_sync_with_revealed_spks(&self) -> SyncRequest

    Create a partial [SyncRequest] for this wallet for all revealed spks.

    +
    source§

    impl Wallet

    Methods to construct sync/full-scan requests for spk-based chain sources.

    +
    source

    pub fn start_sync_with_revealed_spks(&self) -> SyncRequest

    Create a partial [SyncRequest] for this wallet for all revealed spks.

    This is the first step when performing a spk-based wallet partial sync, the returned [SyncRequest] collects all revealed script pubkeys from the wallet keychain needed to start a blockchain sync with a spk based blockchain client.

    -
    source

    pub fn start_full_scan(&self) -> FullScanRequest<KeychainKind>

    Create a [`FullScanRequest] for this wallet.

    +
    source

    pub fn start_full_scan(&self) -> FullScanRequest<KeychainKind>

    Create a [`FullScanRequest] for this wallet.

    This is the first step when performing a spk-based wallet full scan, the returned [`FullScanRequest] collects iterators for the wallet’s keychain script pub keys needed to start a blockchain full scan with a spk based blockchain client.

    This operation is generally only used when importing or restoring a previously used wallet in which the list of used scripts is not known.

    -

    Trait Implementations§

    source§

    impl AsRef<TxGraph<ConfirmationTimeHeightAnchor>> for Wallet

    source§

    fn as_ref(&self) -> &TxGraph<ConfirmationTimeHeightAnchor>

    Converts this type into a shared reference of the (usually inferred) input type.
    source§

    impl Debug for Wallet

    source§

    fn fmt(&self, f: &mut Formatter<'_>) -> Result

    Formats the value using the given formatter. Read more

    Auto Trait Implementations§

    §

    impl Freeze for Wallet

    §

    impl !RefUnwindSafe for Wallet

    §

    impl Send for Wallet

    §

    impl Sync for Wallet

    §

    impl Unpin for Wallet

    §

    impl !UnwindSafe for Wallet

    Blanket Implementations§

    source§

    impl<T> Any for T
    where +

    Trait Implementations§

    source§

    impl AsRef<TxGraph<ConfirmationTimeHeightAnchor>> for Wallet

    source§

    fn as_ref(&self) -> &TxGraph<ConfirmationTimeHeightAnchor>

    Converts this type into a shared reference of the (usually inferred) input type.
    source§

    impl Debug for Wallet

    source§

    fn fmt(&self, f: &mut Formatter<'_>) -> Result

    Formats the value using the given formatter. Read more

    Auto Trait Implementations§

    §

    impl Freeze for Wallet

    §

    impl !RefUnwindSafe for Wallet

    §

    impl Send for Wallet

    §

    impl Sync for Wallet

    §

    impl Unpin for Wallet

    §

    impl !UnwindSafe for Wallet

    Blanket Implementations§

    source§

    impl<T> Any for T
    where T: 'static + ?Sized,

    source§

    fn type_id(&self) -> TypeId

    Gets the TypeId of self. Read more
    source§

    impl<T> Borrow<T> for T
    where T: ?Sized,

    source§

    fn borrow(&self) -> &T

    Immutably borrows from an owned value. Read more
    source§

    impl<T> BorrowMut<T> for T
    where T: ?Sized,

    source§

    fn borrow_mut(&mut self) -> &mut T

    Mutably borrows from an owned value. Read more
    source§

    impl<T> From<T> for T

    source§

    fn from(t: T) -> T

    Returns the argument unchanged.

    diff --git a/docs-rs/bdk/nightly/latest/bdk_wallet/wallet/trait.IsDust.html b/docs-rs/bdk/nightly/latest/bdk_wallet/wallet/trait.IsDust.html index e3302c3b12..01848e294b 100644 --- a/docs-rs/bdk/nightly/latest/bdk_wallet/wallet/trait.IsDust.html +++ b/docs-rs/bdk/nightly/latest/bdk_wallet/wallet/trait.IsDust.html @@ -1,8 +1,8 @@ -IsDust in bdk_wallet::wallet - Rust

    Trait bdk_wallet::wallet::IsDust

    source ·
    pub trait IsDust {
    +IsDust in bdk_wallet::wallet - Rust

    Trait bdk_wallet::wallet::IsDust

    source ·
    pub trait IsDust {
         // Required method
         fn is_dust(&self, script: &Script) -> bool;
     }
    Expand description

    Trait to check if a value is below the dust limit. We are performing dust value calculation for a given script public key using rust-bitcoin to keep it compatible with network dust rate

    -

    Required Methods§

    source

    fn is_dust(&self, script: &Script) -> bool

    Check whether or not a value is below dust limit

    -

    Implementations on Foreign Types§

    source§

    impl IsDust for u64

    source§

    fn is_dust(&self, script: &Script) -> bool

    Implementors§

    \ No newline at end of file +

    Required Methods§

    source

    fn is_dust(&self, script: &Script) -> bool

    Check whether or not a value is below dust limit

    +

    Implementations on Foreign Types§

    source§

    impl IsDust for u64

    source§

    fn is_dust(&self, script: &Script) -> bool

    Implementors§

    \ No newline at end of file diff --git a/docs-rs/bdk/nightly/latest/bdk_wallet/wallet/tx_builder/enum.AddForeignUtxoError.html b/docs-rs/bdk/nightly/latest/bdk_wallet/wallet/tx_builder/enum.AddForeignUtxoError.html index 05098e0012..547b51897c 100644 --- a/docs-rs/bdk/nightly/latest/bdk_wallet/wallet/tx_builder/enum.AddForeignUtxoError.html +++ b/docs-rs/bdk/nightly/latest/bdk_wallet/wallet/tx_builder/enum.AddForeignUtxoError.html @@ -1,4 +1,4 @@ -AddForeignUtxoError in bdk_wallet::wallet::tx_builder - Rust

    Enum bdk_wallet::wallet::tx_builder::AddForeignUtxoError

    source ·
    pub enum AddForeignUtxoError {
    +AddForeignUtxoError in bdk_wallet::wallet::tx_builder - Rust

    Enum bdk_wallet::wallet::tx_builder::AddForeignUtxoError

    source ·
    pub enum AddForeignUtxoError {
         InvalidTxid {
             input_txid: Txid,
             foreign_utxo: OutPoint,
    @@ -11,7 +11,7 @@
     
    §foreign_utxo: OutPoint

    Foreign UTXO outpoint

    §

    InvalidOutpoint(OutPoint)

    Requested outpoint doesn’t exist in the tx (vout greater than available outputs)

    §

    MissingUtxo

    Foreign utxo missing witness_utxo or non_witness_utxo

    -

    Trait Implementations§

    source§

    impl Debug for AddForeignUtxoError

    source§

    fn fmt(&self, f: &mut Formatter<'_>) -> Result

    Formats the value using the given formatter. Read more
    source§

    impl Display for AddForeignUtxoError

    source§

    fn fmt(&self, f: &mut Formatter<'_>) -> Result

    Formats the value using the given formatter. Read more
    source§

    impl Error for AddForeignUtxoError

    1.30.0 · source§

    fn source(&self) -> Option<&(dyn Error + 'static)>

    The lower-level source of this error, if any. Read more
    1.0.0 · source§

    fn description(&self) -> &str

    👎Deprecated since 1.42.0: use the Display impl or to_string()
    1.0.0 · source§

    fn cause(&self) -> Option<&dyn Error>

    👎Deprecated since 1.33.0: replaced by Error::source, which can support downcasting
    source§

    fn provide<'a>(&'a self, request: &mut Request<'a>)

    🔬This is a nightly-only experimental API. (error_generic_member_access)
    Provides type based access to context intended for error reports. Read more

    Auto Trait Implementations§

    Blanket Implementations§

    source§

    impl<T> Any for T
    where +

    Trait Implementations§

    source§

    impl Debug for AddForeignUtxoError

    source§

    fn fmt(&self, f: &mut Formatter<'_>) -> Result

    Formats the value using the given formatter. Read more
    source§

    impl Display for AddForeignUtxoError

    source§

    fn fmt(&self, f: &mut Formatter<'_>) -> Result

    Formats the value using the given formatter. Read more
    source§

    impl Error for AddForeignUtxoError

    1.30.0 · source§

    fn source(&self) -> Option<&(dyn Error + 'static)>

    The lower-level source of this error, if any. Read more
    1.0.0 · source§

    fn description(&self) -> &str

    👎Deprecated since 1.42.0: use the Display impl or to_string()
    1.0.0 · source§

    fn cause(&self) -> Option<&dyn Error>

    👎Deprecated since 1.33.0: replaced by Error::source, which can support downcasting
    source§

    fn provide<'a>(&'a self, request: &mut Request<'a>)

    🔬This is a nightly-only experimental API. (error_generic_member_access)
    Provides type based access to context intended for error reports. Read more

    Auto Trait Implementations§

    Blanket Implementations§

    source§

    impl<T> Any for T
    where T: 'static + ?Sized,

    source§

    fn type_id(&self) -> TypeId

    Gets the TypeId of self. Read more
    source§

    impl<T> Borrow<T> for T
    where T: ?Sized,

    source§

    fn borrow(&self) -> &T

    Immutably borrows from an owned value. Read more
    source§

    impl<T> BorrowMut<T> for T
    where T: ?Sized,

    source§

    fn borrow_mut(&mut self) -> &mut T

    Mutably borrows from an owned value. Read more
    source§

    impl<T> From<T> for T

    source§

    fn from(t: T) -> T

    Returns the argument unchanged.

    diff --git a/docs-rs/bdk/nightly/latest/bdk_wallet/wallet/tx_builder/enum.AddUtxoError.html b/docs-rs/bdk/nightly/latest/bdk_wallet/wallet/tx_builder/enum.AddUtxoError.html index b9ca56e45d..231d0ff230 100644 --- a/docs-rs/bdk/nightly/latest/bdk_wallet/wallet/tx_builder/enum.AddUtxoError.html +++ b/docs-rs/bdk/nightly/latest/bdk_wallet/wallet/tx_builder/enum.AddUtxoError.html @@ -1,8 +1,8 @@ -AddUtxoError in bdk_wallet::wallet::tx_builder - Rust

    Enum bdk_wallet::wallet::tx_builder::AddUtxoError

    source ·
    pub enum AddUtxoError {
    +AddUtxoError in bdk_wallet::wallet::tx_builder - Rust

    Enum bdk_wallet::wallet::tx_builder::AddUtxoError

    source ·
    pub enum AddUtxoError {
         UnknownUtxo(OutPoint),
     }
    Expand description

    Error returned from TxBuilder::add_utxo and TxBuilder::add_utxos

    Variants§

    §

    UnknownUtxo(OutPoint)

    Happens when trying to spend an UTXO that is not in the internal database

    -

    Trait Implementations§

    source§

    impl Debug for AddUtxoError

    source§

    fn fmt(&self, f: &mut Formatter<'_>) -> Result

    Formats the value using the given formatter. Read more
    source§

    impl Display for AddUtxoError

    source§

    fn fmt(&self, f: &mut Formatter<'_>) -> Result

    Formats the value using the given formatter. Read more
    source§

    impl Error for AddUtxoError

    1.30.0 · source§

    fn source(&self) -> Option<&(dyn Error + 'static)>

    The lower-level source of this error, if any. Read more
    1.0.0 · source§

    fn description(&self) -> &str

    👎Deprecated since 1.42.0: use the Display impl or to_string()
    1.0.0 · source§

    fn cause(&self) -> Option<&dyn Error>

    👎Deprecated since 1.33.0: replaced by Error::source, which can support downcasting
    source§

    fn provide<'a>(&'a self, request: &mut Request<'a>)

    🔬This is a nightly-only experimental API. (error_generic_member_access)
    Provides type based access to context intended for error reports. Read more

    Auto Trait Implementations§

    Blanket Implementations§

    source§

    impl<T> Any for T
    where +

    Trait Implementations§

    source§

    impl Debug for AddUtxoError

    source§

    fn fmt(&self, f: &mut Formatter<'_>) -> Result

    Formats the value using the given formatter. Read more
    source§

    impl Display for AddUtxoError

    source§

    fn fmt(&self, f: &mut Formatter<'_>) -> Result

    Formats the value using the given formatter. Read more
    source§

    impl Error for AddUtxoError

    1.30.0 · source§

    fn source(&self) -> Option<&(dyn Error + 'static)>

    The lower-level source of this error, if any. Read more
    1.0.0 · source§

    fn description(&self) -> &str

    👎Deprecated since 1.42.0: use the Display impl or to_string()
    1.0.0 · source§

    fn cause(&self) -> Option<&dyn Error>

    👎Deprecated since 1.33.0: replaced by Error::source, which can support downcasting
    source§

    fn provide<'a>(&'a self, request: &mut Request<'a>)

    🔬This is a nightly-only experimental API. (error_generic_member_access)
    Provides type based access to context intended for error reports. Read more

    Auto Trait Implementations§

    Blanket Implementations§

    source§

    impl<T> Any for T
    where T: 'static + ?Sized,

    source§

    fn type_id(&self) -> TypeId

    Gets the TypeId of self. Read more
    source§

    impl<T> Borrow<T> for T
    where T: ?Sized,

    source§

    fn borrow(&self) -> &T

    Immutably borrows from an owned value. Read more
    source§

    impl<T> BorrowMut<T> for T
    where T: ?Sized,

    source§

    fn borrow_mut(&mut self) -> &mut T

    Mutably borrows from an owned value. Read more
    source§

    impl<T> From<T> for T

    source§

    fn from(t: T) -> T

    Returns the argument unchanged.

    diff --git a/docs-rs/bdk/nightly/latest/bdk_wallet/wallet/tx_builder/enum.ChangeSpendPolicy.html b/docs-rs/bdk/nightly/latest/bdk_wallet/wallet/tx_builder/enum.ChangeSpendPolicy.html index 70a041d7d2..404ba206b4 100644 --- a/docs-rs/bdk/nightly/latest/bdk_wallet/wallet/tx_builder/enum.ChangeSpendPolicy.html +++ b/docs-rs/bdk/nightly/latest/bdk_wallet/wallet/tx_builder/enum.ChangeSpendPolicy.html @@ -1,4 +1,4 @@ -ChangeSpendPolicy in bdk_wallet::wallet::tx_builder - Rust

    Enum bdk_wallet::wallet::tx_builder::ChangeSpendPolicy

    source ·
    pub enum ChangeSpendPolicy {
    +ChangeSpendPolicy in bdk_wallet::wallet::tx_builder - Rust

    Enum bdk_wallet::wallet::tx_builder::ChangeSpendPolicy

    source ·
    pub enum ChangeSpendPolicy {
         ChangeAllowed,
         OnlyChange,
         ChangeForbidden,
    @@ -6,16 +6,16 @@
     

    Variants§

    §

    ChangeAllowed

    Use both change and non-change outputs (default)

    §

    OnlyChange

    Only use change outputs (see TxBuilder::only_spend_change)

    §

    ChangeForbidden

    Only use non-change outputs (see TxBuilder::do_not_spend_change)

    -

    Trait Implementations§

    source§

    impl Clone for ChangeSpendPolicy

    source§

    fn clone(&self) -> ChangeSpendPolicy

    Returns a copy of the value. Read more
    1.0.0 · source§

    fn clone_from(&mut self, source: &Self)

    Performs copy-assignment from source. Read more
    source§

    impl Debug for ChangeSpendPolicy

    source§

    fn fmt(&self, f: &mut Formatter<'_>) -> Result

    Formats the value using the given formatter. Read more
    source§

    impl Default for ChangeSpendPolicy

    source§

    fn default() -> ChangeSpendPolicy

    Returns the “default value” for a type. Read more
    source§

    impl Hash for ChangeSpendPolicy

    source§

    fn hash<__H: Hasher>(&self, state: &mut __H)

    Feeds this value into the given Hasher. Read more
    1.3.0 · source§

    fn hash_slice<H>(data: &[Self], state: &mut H)
    where +

    Trait Implementations§

    source§

    impl Clone for ChangeSpendPolicy

    source§

    fn clone(&self) -> ChangeSpendPolicy

    Returns a copy of the value. Read more
    1.0.0 · source§

    fn clone_from(&mut self, source: &Self)

    Performs copy-assignment from source. Read more
    source§

    impl Debug for ChangeSpendPolicy

    source§

    fn fmt(&self, f: &mut Formatter<'_>) -> Result

    Formats the value using the given formatter. Read more
    source§

    impl Default for ChangeSpendPolicy

    source§

    fn default() -> ChangeSpendPolicy

    Returns the “default value” for a type. Read more
    source§

    impl Hash for ChangeSpendPolicy

    source§

    fn hash<__H: Hasher>(&self, state: &mut __H)

    Feeds this value into the given Hasher. Read more
    1.3.0 · source§

    fn hash_slice<H>(data: &[Self], state: &mut H)
    where H: Hasher, - Self: Sized,

    Feeds a slice of this type into the given Hasher. Read more
    source§

    impl Ord for ChangeSpendPolicy

    source§

    fn cmp(&self, other: &ChangeSpendPolicy) -> Ordering

    This method returns an Ordering between self and other. Read more
    1.21.0 · source§

    fn max(self, other: Self) -> Self
    where + Self: Sized,

    Feeds a slice of this type into the given Hasher. Read more
    source§

    impl Ord for ChangeSpendPolicy

    source§

    fn cmp(&self, other: &ChangeSpendPolicy) -> Ordering

    This method returns an Ordering between self and other. Read more
    1.21.0 · source§

    fn max(self, other: Self) -> Self
    where Self: Sized,

    Compares and returns the maximum of two values. Read more
    1.21.0 · source§

    fn min(self, other: Self) -> Self
    where Self: Sized,

    Compares and returns the minimum of two values. Read more
    1.50.0 · source§

    fn clamp(self, min: Self, max: Self) -> Self
    where - Self: Sized + PartialOrd,

    Restrict a value to a certain interval. Read more
    source§

    impl PartialEq for ChangeSpendPolicy

    source§

    fn eq(&self, other: &ChangeSpendPolicy) -> bool

    This method tests for self and other values to be equal, and is used + Self: Sized + PartialOrd,
    Restrict a value to a certain interval. Read more
    source§

    impl PartialEq for ChangeSpendPolicy

    source§

    fn eq(&self, other: &ChangeSpendPolicy) -> bool

    This method tests for self and other values to be equal, and is used by ==.
    1.0.0 · source§

    fn ne(&self, other: &Rhs) -> bool

    This method tests for !=. The default implementation is almost always -sufficient, and should not be overridden without very good reason.
    source§

    impl PartialOrd for ChangeSpendPolicy

    source§

    fn partial_cmp(&self, other: &ChangeSpendPolicy) -> Option<Ordering>

    This method returns an ordering between self and other values if one exists. Read more
    1.0.0 · source§

    fn lt(&self, other: &Rhs) -> bool

    This method tests less than (for self and other) and is used by the < operator. Read more
    1.0.0 · source§

    fn le(&self, other: &Rhs) -> bool

    This method tests less than or equal to (for self and other) and is used by the <= +sufficient, and should not be overridden without very good reason.
    source§

    impl PartialOrd for ChangeSpendPolicy

    source§

    fn partial_cmp(&self, other: &ChangeSpendPolicy) -> Option<Ordering>

    This method returns an ordering between self and other values if one exists. Read more
    1.0.0 · source§

    fn lt(&self, other: &Rhs) -> bool

    This method tests less than (for self and other) and is used by the < operator. Read more
    1.0.0 · source§

    fn le(&self, other: &Rhs) -> bool

    This method tests less than or equal to (for self and other) and is used by the <= operator. Read more
    1.0.0 · source§

    fn gt(&self, other: &Rhs) -> bool

    This method tests greater than (for self and other) and is used by the > operator. Read more
    1.0.0 · source§

    fn ge(&self, other: &Rhs) -> bool

    This method tests greater than or equal to (for self and other) and is used by the >= -operator. Read more
    source§

    impl Copy for ChangeSpendPolicy

    source§

    impl Eq for ChangeSpendPolicy

    source§

    impl StructuralPartialEq for ChangeSpendPolicy

    Auto Trait Implementations§

    Blanket Implementations§

    source§

    impl<T> Any for T
    where +operator. Read more

    source§

    impl Copy for ChangeSpendPolicy

    source§

    impl Eq for ChangeSpendPolicy

    source§

    impl StructuralPartialEq for ChangeSpendPolicy

    Auto Trait Implementations§

    Blanket Implementations§

    source§

    impl<T> Any for T
    where T: 'static + ?Sized,

    source§

    fn type_id(&self) -> TypeId

    Gets the TypeId of self. Read more
    source§

    impl<T> Borrow<T> for T
    where T: ?Sized,

    source§

    fn borrow(&self) -> &T

    Immutably borrows from an owned value. Read more
    source§

    impl<T> BorrowMut<T> for T
    where T: ?Sized,

    source§

    fn borrow_mut(&mut self) -> &mut T

    Mutably borrows from an owned value. Read more
    source§

    impl<T> From<T> for T

    source§

    fn from(t: T) -> T

    Returns the argument unchanged.

    diff --git a/docs-rs/bdk/nightly/latest/bdk_wallet/wallet/tx_builder/enum.TxOrdering.html b/docs-rs/bdk/nightly/latest/bdk_wallet/wallet/tx_builder/enum.TxOrdering.html index 793a745395..842427d0a4 100644 --- a/docs-rs/bdk/nightly/latest/bdk_wallet/wallet/tx_builder/enum.TxOrdering.html +++ b/docs-rs/bdk/nightly/latest/bdk_wallet/wallet/tx_builder/enum.TxOrdering.html @@ -1,4 +1,4 @@ -TxOrdering in bdk_wallet::wallet::tx_builder - Rust

    Enum bdk_wallet::wallet::tx_builder::TxOrdering

    source ·
    pub enum TxOrdering {
    +TxOrdering in bdk_wallet::wallet::tx_builder - Rust

    Enum bdk_wallet::wallet::tx_builder::TxOrdering

    source ·
    pub enum TxOrdering {
         Shuffle,
         Untouched,
         Bip69Lexicographic,
    @@ -6,17 +6,20 @@
     

    Variants§

    §

    Shuffle

    Randomized (default)

    §

    Untouched

    Unchanged

    §

    Bip69Lexicographic

    BIP69 / Lexicographic

    -

    Implementations§

    source§

    impl TxOrdering

    source

    pub fn sort_tx(&self, tx: &mut Transaction)

    Sort transaction inputs and outputs by TxOrdering variant

    -

    Trait Implementations§

    source§

    impl Clone for TxOrdering

    source§

    fn clone(&self) -> TxOrdering

    Returns a copy of the value. Read more
    1.0.0 · source§

    fn clone_from(&mut self, source: &Self)

    Performs copy-assignment from source. Read more
    source§

    impl Debug for TxOrdering

    source§

    fn fmt(&self, f: &mut Formatter<'_>) -> Result

    Formats the value using the given formatter. Read more
    source§

    impl Default for TxOrdering

    source§

    fn default() -> TxOrdering

    Returns the “default value” for a type. Read more
    source§

    impl Hash for TxOrdering

    source§

    fn hash<__H: Hasher>(&self, state: &mut __H)

    Feeds this value into the given Hasher. Read more
    1.3.0 · source§

    fn hash_slice<H>(data: &[Self], state: &mut H)
    where +

    Implementations§

    source§

    impl TxOrdering

    source

    pub fn sort_tx(self, tx: &mut Transaction)

    Sort transaction inputs and outputs by TxOrdering variant.

    +

    Uses the thread-local random number generator (rng).

    +
    source

    pub fn sort_tx_with_aux_rand(self, tx: &mut Transaction, rng: &mut impl RngCore)

    Sort transaction inputs and outputs by TxOrdering variant.

    +

    Uses a provided random number generator (rng).

    +

    Trait Implementations§

    source§

    impl Clone for TxOrdering

    source§

    fn clone(&self) -> TxOrdering

    Returns a copy of the value. Read more
    1.0.0 · source§

    fn clone_from(&mut self, source: &Self)

    Performs copy-assignment from source. Read more
    source§

    impl Debug for TxOrdering

    source§

    fn fmt(&self, f: &mut Formatter<'_>) -> Result

    Formats the value using the given formatter. Read more
    source§

    impl Default for TxOrdering

    source§

    fn default() -> TxOrdering

    Returns the “default value” for a type. Read more
    source§

    impl Hash for TxOrdering

    source§

    fn hash<__H: Hasher>(&self, state: &mut __H)

    Feeds this value into the given Hasher. Read more
    1.3.0 · source§

    fn hash_slice<H>(data: &[Self], state: &mut H)
    where H: Hasher, - Self: Sized,

    Feeds a slice of this type into the given Hasher. Read more
    source§

    impl Ord for TxOrdering

    source§

    fn cmp(&self, other: &TxOrdering) -> Ordering

    This method returns an Ordering between self and other. Read more
    1.21.0 · source§

    fn max(self, other: Self) -> Self
    where + Self: Sized,

    Feeds a slice of this type into the given Hasher. Read more
    source§

    impl Ord for TxOrdering

    source§

    fn cmp(&self, other: &TxOrdering) -> Ordering

    This method returns an Ordering between self and other. Read more
    1.21.0 · source§

    fn max(self, other: Self) -> Self
    where Self: Sized,

    Compares and returns the maximum of two values. Read more
    1.21.0 · source§

    fn min(self, other: Self) -> Self
    where Self: Sized,

    Compares and returns the minimum of two values. Read more
    1.50.0 · source§

    fn clamp(self, min: Self, max: Self) -> Self
    where - Self: Sized + PartialOrd,

    Restrict a value to a certain interval. Read more
    source§

    impl PartialEq for TxOrdering

    source§

    fn eq(&self, other: &TxOrdering) -> bool

    This method tests for self and other values to be equal, and is used + Self: Sized + PartialOrd,
    Restrict a value to a certain interval. Read more
    source§

    impl PartialEq for TxOrdering

    source§

    fn eq(&self, other: &TxOrdering) -> bool

    This method tests for self and other values to be equal, and is used by ==.
    1.0.0 · source§

    fn ne(&self, other: &Rhs) -> bool

    This method tests for !=. The default implementation is almost always -sufficient, and should not be overridden without very good reason.
    source§

    impl PartialOrd for TxOrdering

    source§

    fn partial_cmp(&self, other: &TxOrdering) -> Option<Ordering>

    This method returns an ordering between self and other values if one exists. Read more
    1.0.0 · source§

    fn lt(&self, other: &Rhs) -> bool

    This method tests less than (for self and other) and is used by the < operator. Read more
    1.0.0 · source§

    fn le(&self, other: &Rhs) -> bool

    This method tests less than or equal to (for self and other) and is used by the <= +sufficient, and should not be overridden without very good reason.
    source§

    impl PartialOrd for TxOrdering

    source§

    fn partial_cmp(&self, other: &TxOrdering) -> Option<Ordering>

    This method returns an ordering between self and other values if one exists. Read more
    1.0.0 · source§

    fn lt(&self, other: &Rhs) -> bool

    This method tests less than (for self and other) and is used by the < operator. Read more
    1.0.0 · source§

    fn le(&self, other: &Rhs) -> bool

    This method tests less than or equal to (for self and other) and is used by the <= operator. Read more
    1.0.0 · source§

    fn gt(&self, other: &Rhs) -> bool

    This method tests greater than (for self and other) and is used by the > operator. Read more
    1.0.0 · source§

    fn ge(&self, other: &Rhs) -> bool

    This method tests greater than or equal to (for self and other) and is used by the >= -operator. Read more
    source§

    impl Copy for TxOrdering

    source§

    impl Eq for TxOrdering

    source§

    impl StructuralPartialEq for TxOrdering

    Auto Trait Implementations§

    Blanket Implementations§

    source§

    impl<T> Any for T
    where +operator. Read more

    source§

    impl Copy for TxOrdering

    source§

    impl Eq for TxOrdering

    source§

    impl StructuralPartialEq for TxOrdering

    Auto Trait Implementations§

    Blanket Implementations§

    source§

    impl<T> Any for T
    where T: 'static + ?Sized,

    source§

    fn type_id(&self) -> TypeId

    Gets the TypeId of self. Read more
    source§

    impl<T> Borrow<T> for T
    where T: ?Sized,

    source§

    fn borrow(&self) -> &T

    Immutably borrows from an owned value. Read more
    source§

    impl<T> BorrowMut<T> for T
    where T: ?Sized,

    source§

    fn borrow_mut(&mut self) -> &mut T

    Mutably borrows from an owned value. Read more
    source§

    impl<T> From<T> for T

    source§

    fn from(t: T) -> T

    Returns the argument unchanged.

    diff --git a/docs-rs/bdk/nightly/latest/bdk_wallet/wallet/tx_builder/index.html b/docs-rs/bdk/nightly/latest/bdk_wallet/wallet/tx_builder/index.html index dbf325c0f7..d044866dce 100644 --- a/docs-rs/bdk/nightly/latest/bdk_wallet/wallet/tx_builder/index.html +++ b/docs-rs/bdk/nightly/latest/bdk_wallet/wallet/tx_builder/index.html @@ -1,4 +1,4 @@ -bdk_wallet::wallet::tx_builder - Rust

    Module bdk_wallet::wallet::tx_builder

    source ·
    Expand description

    Transaction builder

    +bdk_wallet::wallet::tx_builder - Rust

    Module bdk_wallet::wallet::tx_builder

    source ·
    Expand description

    Transaction builder

    §Example

    // create a TxBuilder from a wallet
     let mut tx_builder = wallet.build_tx();
    diff --git a/docs-rs/bdk/nightly/latest/bdk_wallet/wallet/tx_builder/struct.TxBuilder.html b/docs-rs/bdk/nightly/latest/bdk_wallet/wallet/tx_builder/struct.TxBuilder.html
    index 76860c499a..f6770a0580 100644
    --- a/docs-rs/bdk/nightly/latest/bdk_wallet/wallet/tx_builder/struct.TxBuilder.html
    +++ b/docs-rs/bdk/nightly/latest/bdk_wallet/wallet/tx_builder/struct.TxBuilder.html
    @@ -1,4 +1,4 @@
    -TxBuilder in bdk_wallet::wallet::tx_builder - Rust

    Struct bdk_wallet::wallet::tx_builder::TxBuilder

    source ·
    pub struct TxBuilder<'a, Cs> { /* private fields */ }
    Expand description

    A transaction builder

    +TxBuilder in bdk_wallet::wallet::tx_builder - Rust

    Struct bdk_wallet::wallet::tx_builder::TxBuilder

    source ·
    pub struct TxBuilder<'a, Cs> { /* private fields */ }
    Expand description

    A transaction builder

    A TxBuilder is created by calling build_tx or build_fee_bump on a wallet. After assigning it, you set options on it until finally calling finish to consume the builder and generate the transaction.

    @@ -29,7 +29,7 @@

    At the moment coin_selection is an exception to the rule as it consumes self. This means it is usually best to call coin_selection on the return value of build_tx before assigning it.

    For further examples see this module’s documentation;

    -

    Implementations§

    source§

    impl<'a, Cs> TxBuilder<'a, Cs>

    source

    pub fn fee_rate(&mut self, fee_rate: FeeRate) -> &mut Self

    Set a custom fee rate.

    +

    Implementations§

    source§

    impl<'a, Cs> TxBuilder<'a, Cs>

    source

    pub fn fee_rate(&mut self, fee_rate: FeeRate) -> &mut Self

    Set a custom fee rate.

    This method sets the mining fee paid by the transaction as a rate on its size. This means that the total fee paid is equal to fee_rate times the size of the transaction. Default is 1 sat/vB in accordance with Bitcoin Core’s default @@ -37,7 +37,7 @@

    Note that this is really a minimum feerate – it’s possible to overshoot it slightly since adding a change output to drain the remaining excess might not be viable.

    -
    source

    pub fn fee_absolute(&mut self, fee_amount: Amount) -> &mut Self

    Set an absolute fee +

    source

    pub fn fee_absolute(&mut self, fee_amount: Amount) -> &mut Self

    Set an absolute fee The fee_absolute method refers to the absolute transaction fee in [Amount]. If anyone sets both the fee_absolute method and the fee_rate method, the FeePolicy enum will be set by whichever method was called last, @@ -45,7 +45,7 @@

    Note that this is really a minimum absolute fee – it’s possible to overshoot it slightly since adding a change output to drain the remaining excess might not be viable.

    -
    source

    pub fn policy_path( +

    source

    pub fn policy_path( &mut self, policy_path: BTreeMap<String, Vec<usize>>, keychain: KeychainKind @@ -96,20 +96,20 @@

    §Example
    .add_recipient(to_address.script_pubkey(), Amount::from_sat(50_000)) .policy_path(path, KeychainKind::External);
    -
    source

    pub fn add_utxos( +

    source

    pub fn add_utxos( &mut self, outpoints: &[OutPoint] ) -> Result<&mut Self, AddUtxoError>

    Add the list of outpoints to the internal list of UTXOs that must be spent.

    If an error occurs while adding any of the UTXOs then none of them are added and the error is returned.

    These have priority over the “unspendable” utxos, meaning that if a utxo is present both in the “utxos” and the “unspendable” list, it will be spent.

    -
    source

    pub fn add_utxo( +

    source

    pub fn add_utxo( &mut self, outpoint: OutPoint ) -> Result<&mut Self, AddUtxoError>

    Add a utxo to the internal list of utxos that must be spent

    These have priority over the “unspendable” utxos, meaning that if a utxo is present both in the “utxos” and the “unspendable” list, it will be spent.

    -
    source

    pub fn add_foreign_utxo( +

    source

    pub fn add_foreign_utxo( &mut self, outpoint: OutPoint, psbt_input: Input, @@ -149,64 +149,64 @@

    §Errors

    Note unless you set only_witness_utxo any non-taproot psbt_input you pass to this method must have non_witness_utxo set otherwise you will get an error when finish is called.

    -
    source

    pub fn add_foreign_utxo_with_sequence( +

    source

    pub fn add_foreign_utxo_with_sequence( &mut self, outpoint: OutPoint, psbt_input: Input, satisfaction_weight: usize, sequence: Sequence ) -> Result<&mut Self, AddForeignUtxoError>

    Same as add_foreign_utxo but allows to set the nSequence value.

    -
    source

    pub fn manually_selected_only(&mut self) -> &mut Self

    Only spend utxos added by add_utxo.

    +
    source

    pub fn manually_selected_only(&mut self) -> &mut Self

    Only spend utxos added by add_utxo.

    The wallet will not add additional utxos to the transaction even if they are needed to make the transaction valid.

    -
    source

    pub fn unspendable(&mut self, unspendable: Vec<OutPoint>) -> &mut Self

    Replace the internal list of unspendable utxos with a new list

    +
    source

    pub fn unspendable(&mut self, unspendable: Vec<OutPoint>) -> &mut Self

    Replace the internal list of unspendable utxos with a new list

    It’s important to note that the “must-be-spent” utxos added with TxBuilder::add_utxo have priority over these. See the docs of the two linked methods for more details.

    -
    source

    pub fn add_unspendable(&mut self, unspendable: OutPoint) -> &mut Self

    Add a utxo to the internal list of unspendable utxos

    +
    source

    pub fn add_unspendable(&mut self, unspendable: OutPoint) -> &mut Self

    Add a utxo to the internal list of unspendable utxos

    It’s important to note that the “must-be-spent” utxos added with TxBuilder::add_utxo have priority over this. See the docs of the two linked methods for more details.

    -
    source

    pub fn sighash(&mut self, sighash: PsbtSighashType) -> &mut Self

    Sign with a specific sig hash

    +
    source

    pub fn sighash(&mut self, sighash: PsbtSighashType) -> &mut Self

    Sign with a specific sig hash

    Use this option very carefully

    -
    source

    pub fn ordering(&mut self, ordering: TxOrdering) -> &mut Self

    Choose the ordering for inputs and outputs of the transaction

    -
    source

    pub fn nlocktime(&mut self, locktime: LockTime) -> &mut Self

    Use a specific nLockTime while creating the transaction

    +
    source

    pub fn ordering(&mut self, ordering: TxOrdering) -> &mut Self

    Choose the ordering for inputs and outputs of the transaction

    +
    source

    pub fn nlocktime(&mut self, locktime: LockTime) -> &mut Self

    Use a specific nLockTime while creating the transaction

    This can cause conflicts if the wallet’s descriptors contain an “after” (OP_CLTV) operator.

    -
    source

    pub fn version(&mut self, version: i32) -> &mut Self

    Build a transaction with a specific version

    +
    source

    pub fn version(&mut self, version: i32) -> &mut Self

    Build a transaction with a specific version

    The version should always be greater than 0 and greater than 1 if the wallet’s descriptors contain an “older” (OP_CSV) operator.

    -
    source

    pub fn do_not_spend_change(&mut self) -> &mut Self

    Do not spend change outputs

    +
    source

    pub fn do_not_spend_change(&mut self) -> &mut Self

    Do not spend change outputs

    This effectively adds all the change outputs to the “unspendable” list. See TxBuilder::unspendable.

    -
    source

    pub fn only_spend_change(&mut self) -> &mut Self

    Only spend change outputs

    +
    source

    pub fn only_spend_change(&mut self) -> &mut Self

    Only spend change outputs

    This effectively adds all the non-change outputs to the “unspendable” list. See TxBuilder::unspendable.

    -
    source

    pub fn change_policy(&mut self, change_policy: ChangeSpendPolicy) -> &mut Self

    source

    pub fn change_policy(&mut self, change_policy: ChangeSpendPolicy) -> &mut Self

    source

    pub fn only_witness_utxo(&mut self) -> &mut Self

    Only Fill-in the psbt::Input::witness_utxo field when spending from +

    source

    pub fn only_witness_utxo(&mut self) -> &mut Self

    Only Fill-in the psbt::Input::witness_utxo field when spending from SegWit descriptors.

    This reduces the size of the PSBT, but some signers might reject them due to the lack of the non_witness_utxo.

    -
    source

    pub fn include_output_redeem_witness_script(&mut self) -> &mut Self

    Fill-in the psbt::Output::redeem_script and +

    source

    pub fn include_output_redeem_witness_script(&mut self) -> &mut Self

    Fill-in the psbt::Output::redeem_script and psbt::Output::witness_script fields.

    This is useful for signers which always require it, like ColdCard hardware wallets.

    -
    source

    pub fn add_global_xpubs(&mut self) -> &mut Self

    Fill-in the PSBT_GLOBAL_XPUB field with the extended keys contained in both the external +

    source

    pub fn add_global_xpubs(&mut self) -> &mut Self

    Fill-in the PSBT_GLOBAL_XPUB field with the extended keys contained in both the external and internal descriptors

    This is useful for offline signers that take part to a multisig. Some hardware wallets like BitBox and ColdCard are known to require this.

    -
    source

    pub fn drain_wallet(&mut self) -> &mut Self

    Spend all the available inputs. This respects filters like TxBuilder::unspendable and the change policy.

    -
    source

    pub fn coin_selection<P: CoinSelectionAlgorithm>( +

    source

    pub fn drain_wallet(&mut self) -> &mut Self

    Spend all the available inputs. This respects filters like TxBuilder::unspendable and the change policy.

    +
    source

    pub fn coin_selection<P: CoinSelectionAlgorithm>( self, coin_selection: P ) -> TxBuilder<'a, P>

    Choose the coin selection algorithm

    Overrides the CoinSelectionAlgorithm.

    Note that this function consumes the builder and returns it so it is usually best to put this as the first call on the builder.

    -
    source

    pub fn enable_rbf(&mut self) -> &mut Self

    Enable signaling RBF

    +
    source

    pub fn enable_rbf(&mut self) -> &mut Self

    Enable signaling RBF

    This will use the default nSequence value of 0xFFFFFFFD.

    -
    source

    pub fn enable_rbf_with_sequence(&mut self, nsequence: Sequence) -> &mut Self

    Enable signaling RBF with a specific nSequence value

    +
    source

    pub fn enable_rbf_with_sequence(&mut self, nsequence: Sequence) -> &mut Self

    Enable signaling RBF with a specific nSequence value

    This can cause conflicts if the wallet’s descriptors contain an “older” (OP_CSV) operator and the given nsequence is lower than the CSV value.

    If the nsequence is higher than 0xFFFFFFFD an error will be thrown, since it would not be a valid nSequence to signal RBF.

    -
    source

    pub fn current_height(&mut self, height: u32) -> &mut Self

    Set the current blockchain height.

    +
    source

    pub fn current_height(&mut self, height: u32) -> &mut Self

    Set the current blockchain height.

    This will be used to:

    1. Set the nLockTime for preventing fee sniping. @@ -217,19 +217,19 @@
      §Errors
      add them using TxBuilder::add_utxos.

    In both cases, if you don’t provide a current height, we use the last sync height.

    -
    source

    pub fn allow_dust(&mut self, allow_dust: bool) -> &mut Self

    Set whether or not the dust limit is checked.

    +
    source

    pub fn allow_dust(&mut self, allow_dust: bool) -> &mut Self

    Set whether or not the dust limit is checked.

    Note: by avoiding a dust limit check you may end up with a transaction that is non-standard.

    -
    source

    pub fn set_recipients( +

    source

    pub fn set_recipients( &mut self, recipients: Vec<(ScriptBuf, Amount)> ) -> &mut Self

    Replace the recipients already added with a new list

    -
    source

    pub fn add_recipient( +

    source

    pub fn add_recipient( &mut self, script_pubkey: ScriptBuf, amount: Amount ) -> &mut Self

    Add a recipient to the internal list

    -
    source

    pub fn add_data<T: AsRef<PushBytes>>(&mut self, data: &T) -> &mut Self

    Add data as an output, using OP_RETURN

    -
    source

    pub fn drain_to(&mut self, script_pubkey: ScriptBuf) -> &mut Self

    Sets the address to drain excess coins to.

    +
    source

    pub fn add_data<T: AsRef<PushBytes>>(&mut self, data: &T) -> &mut Self

    Add data as an output, using OP_RETURN

    +
    source

    pub fn drain_to(&mut self, script_pubkey: ScriptBuf) -> &mut Self

    Sets the address to drain excess coins to.

    Usually, when there are excess coins they are sent to a change address generated by the wallet. This option replaces the usual change address with an arbitrary script_pubkey of your choosing. Just as with a change output, if the drain output is not needed (the excess @@ -255,11 +255,20 @@

    §Example
    .fee_rate(FeeRate::from_sat_per_vb(5).expect("valid feerate")) .enable_rbf(); let psbt = tx_builder.finish()?;
    -
    source§

    impl<'a, Cs: CoinSelectionAlgorithm> TxBuilder<'a, Cs>

    source

    pub fn finish(self) -> Result<Psbt, CreateTxError>

    Finish building the transaction.

    +
    source§

    impl<'a, Cs: CoinSelectionAlgorithm> TxBuilder<'a, Cs>

    source

    pub fn finish(self) -> Result<Psbt, CreateTxError>

    Finish building the transaction.

    +

    Uses the thread-local random number generator (rng).

    Returns a new [Psbt] per BIP174.

    WARNING: To avoid change address reuse you must persist the changes resulting from one or more calls to this method before closing the wallet. See Wallet::reveal_next_address.

    -

    Trait Implementations§

    source§

    impl<'a, Cs: Clone> Clone for TxBuilder<'a, Cs>

    source§

    fn clone(&self) -> Self

    Returns a copy of the value. Read more
    1.0.0 · source§

    fn clone_from(&mut self, source: &Self)

    Performs copy-assignment from source. Read more
    source§

    impl<'a, Cs: Debug> Debug for TxBuilder<'a, Cs>

    source§

    fn fmt(&self, f: &mut Formatter<'_>) -> Result

    Formats the value using the given formatter. Read more

    Auto Trait Implementations§

    §

    impl<'a, Cs> Freeze for TxBuilder<'a, Cs>
    where +
    source

    pub fn finish_with_aux_rand( + self, + rng: &mut impl RngCore +) -> Result<Psbt, CreateTxError>

    Finish building the transaction.

    +

    Uses a provided random number generator (rng).

    +

    Returns a new [Psbt] per BIP174.

    +

    WARNING: To avoid change address reuse you must persist the changes resulting from one +or more calls to this method before closing the wallet. See Wallet::reveal_next_address.

    +

    Trait Implementations§

    source§

    impl<'a, Cs: Clone> Clone for TxBuilder<'a, Cs>

    source§

    fn clone(&self) -> Self

    Returns a copy of the value. Read more
    1.0.0 · source§

    fn clone_from(&mut self, source: &Self)

    Performs copy-assignment from source. Read more
    source§

    impl<'a, Cs: Debug> Debug for TxBuilder<'a, Cs>

    source§

    fn fmt(&self, f: &mut Formatter<'_>) -> Result

    Formats the value using the given formatter. Read more

    Auto Trait Implementations§

    §

    impl<'a, Cs> Freeze for TxBuilder<'a, Cs>
    where Cs: Freeze,

    §

    impl<'a, Cs> !RefUnwindSafe for TxBuilder<'a, Cs>

    §

    impl<'a, Cs> !Send for TxBuilder<'a, Cs>

    §

    impl<'a, Cs> !Sync for TxBuilder<'a, Cs>

    §

    impl<'a, Cs> Unpin for TxBuilder<'a, Cs>
    where Cs: Unpin,

    §

    impl<'a, Cs> !UnwindSafe for TxBuilder<'a, Cs>

    Blanket Implementations§

    source§

    impl<T> Any for T
    where T: 'static + ?Sized,

    source§

    fn type_id(&self) -> TypeId

    Gets the TypeId of self. Read more
    source§

    impl<T> Borrow<T> for T
    where diff --git a/docs-rs/bdk/nightly/latest/bdk_wallet/wallet/type.ChangeSet.html b/docs-rs/bdk/nightly/latest/bdk_wallet/wallet/type.ChangeSet.html index c0078e489a..3123f5d695 100644 --- a/docs-rs/bdk/nightly/latest/bdk_wallet/wallet/type.ChangeSet.html +++ b/docs-rs/bdk/nightly/latest/bdk_wallet/wallet/type.ChangeSet.html @@ -1,4 +1,4 @@ -ChangeSet in bdk_wallet::wallet - Rust

    Type Alias bdk_wallet::wallet::ChangeSet

    source ·
    pub type ChangeSet = CombinedChangeSet<KeychainKind, ConfirmationTimeHeightAnchor>;
    Expand description

    The changes made to a wallet by applying an Update.

    +ChangeSet in bdk_wallet::wallet - Rust

    Type Alias bdk_wallet::wallet::ChangeSet

    source ·
    pub type ChangeSet = CombinedChangeSet<KeychainKind, ConfirmationTimeHeightAnchor>;
    Expand description

    The changes made to a wallet by applying an Update.

    Aliased Type§

    struct ChangeSet {
         pub chain: BTreeMap<u32, Option<BlockHash>>,
         pub indexed_tx_graph: ChangeSet<ConfirmationTimeHeightAnchor, ChangeSet<KeychainKind>>,
    diff --git a/docs-rs/bdk/nightly/latest/example_cli/enum.CoinSelectionAlgo.html b/docs-rs/bdk/nightly/latest/example_cli/enum.CoinSelectionAlgo.html
    index 172fcdd28b..1d53aa72d4 100644
    --- a/docs-rs/bdk/nightly/latest/example_cli/enum.CoinSelectionAlgo.html
    +++ b/docs-rs/bdk/nightly/latest/example_cli/enum.CoinSelectionAlgo.html
    @@ -4,7 +4,7 @@
         OldestFirst,
         NewestFirst,
         BranchAndBound,
    -}

    Variants§

    §

    LargestFirst

    §

    SmallestFirst

    §

    OldestFirst

    §

    NewestFirst

    §

    BranchAndBound

    Trait Implementations§

    source§

    impl Clone for CoinSelectionAlgo

    source§

    fn clone(&self) -> CoinSelectionAlgo

    Returns a copy of the value. Read more
    1.0.0 · source§

    fn clone_from(&mut self, source: &Self)

    Performs copy-assignment from source. Read more
    source§

    impl Debug for CoinSelectionAlgo

    source§

    fn fmt(&self, f: &mut Formatter<'_>) -> Result

    Formats the value using the given formatter. Read more
    source§

    impl Default for CoinSelectionAlgo

    source§

    fn default() -> Self

    Returns the “default value” for a type. Read more
    source§

    impl Display for CoinSelectionAlgo

    source§

    fn fmt(&self, f: &mut Formatter<'_>) -> Result

    Formats the value using the given formatter. Read more
    source§

    impl FromStr for CoinSelectionAlgo

    §

    type Err = Error

    The associated error which can be returned from parsing.
    source§

    fn from_str(s: &str) -> Result<Self, Self::Err>

    Parses a string s to return a value of this type. Read more

    Auto Trait Implementations§

    Blanket Implementations§

    source§

    impl<T> Any for T
    where +}

    Variants§

    §

    LargestFirst

    §

    SmallestFirst

    §

    OldestFirst

    §

    NewestFirst

    §

    BranchAndBound

    Trait Implementations§

    source§

    impl Clone for CoinSelectionAlgo

    source§

    fn clone(&self) -> CoinSelectionAlgo

    Returns a copy of the value. Read more
    1.0.0 · source§

    fn clone_from(&mut self, source: &Self)

    Performs copy-assignment from source. Read more
    source§

    impl Debug for CoinSelectionAlgo

    source§

    fn fmt(&self, f: &mut Formatter<'_>) -> Result

    Formats the value using the given formatter. Read more
    source§

    impl Default for CoinSelectionAlgo

    source§

    fn default() -> Self

    Returns the “default value” for a type. Read more
    source§

    impl Display for CoinSelectionAlgo

    source§

    fn fmt(&self, f: &mut Formatter<'_>) -> Result

    Formats the value using the given formatter. Read more
    source§

    impl FromStr for CoinSelectionAlgo

    §

    type Err = Error

    The associated error which can be returned from parsing.
    source§

    fn from_str(s: &str) -> Result<Self, Self::Err>

    Parses a string s to return a value of this type. Read more

    Auto Trait Implementations§

    Blanket Implementations§

    source§

    impl<T> Any for T
    where T: 'static + ?Sized,

    source§

    fn type_id(&self) -> TypeId

    Gets the TypeId of self. Read more
    source§

    impl<T> Borrow<T> for T
    where T: ?Sized,

    source§

    fn borrow(&self) -> &T

    Immutably borrows from an owned value. Read more
    source§

    impl<T> BorrowMut<T> for T
    where T: ?Sized,

    source§

    fn borrow_mut(&mut self) -> &mut T

    Mutably borrows from an owned value. Read more
    source§

    impl<T> From<T> for T

    source§

    fn from(t: T) -> T

    Returns the argument unchanged.

    diff --git a/docs-rs/bdk/nightly/latest/search-index.js b/docs-rs/bdk/nightly/latest/search-index.js index a336abe9b4..b8ffa47938 100644 --- a/docs-rs/bdk/nightly/latest/search-index.js +++ b/docs-rs/bdk/nightly/latest/search-index.js @@ -1,17 +1,17 @@ var searchIndex = new Map(JSON.parse('[\ ["bdk_bitcoind_rpc",{"t":"KFFEONNNNNNONNNNNNMNNNNNNNNNNNN","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":[[0,"bdk_bitcoind_rpc"],[31,"bitcoin::blockdata::block"],[32,"bdk_chain::chain_data"],[33,"core::fmt"],[34,"bitcoin::blockdata::transaction"],[35,"alloc::vec"],[36,"bitcoincore_rpc::error"],[37,"core::result"],[38,"bitcoincore_rpc::client"],[39,"bdk_chain::local_chain"],[40,"core::option"],[41,"core::any"]],"i":[0,0,0,0,1,1,1,12,1,12,1,1,1,1,12,1,12,1,10,12,12,12,12,12,1,12,1,12,1,12,1],"f":"`````{{{d{{b{c}}}}}f{}}{{{d{{b{c}}}}}h{}}{{{d{c}}}{{d{e}}}{}{}}0{{{d{jc}}}{{d{je}}}{}{}}0`{{{d{{b{c}}}}}l{}}{{{d{{b{c}}}}{d{jn}}}A`Ab}{cc{}}0{ce{}{}}0{{{d{Ad}}}Af}{{{d{j{Ah{c}}}}}{{Bd{{B`{{An{AjAl}}}}Bb}}}Bf}{{{d{c}}Bhh}{{Ah{c}}}Bf}{{{d{j{Ah{c}}}}}{{Bd{{Bl{{b{Bj}}}}Bb}}}Bf}{{{d{j{Ah{c}}}}}{{Bd{{Bl{{b{Bn}}}}Bb}}}Bf}{c{{Bd{e}}}{}{}}000{{{d{c}}}C`{}}077","D":"Bd","p":[[5,"BlockEvent",0],[1,"reference"],[5,"BlockHash",31],[1,"u32"],[0,"mut"],[5,"BlockId",32],[5,"Formatter",33],[8,"Result",33],[10,"Debug",33],[10,"BitcoindRpcErrorExt",0],[1,"bool"],[5,"Emitter",0],[5,"Transaction",34],[1,"u64"],[1,"tuple"],[5,"Vec",35],[6,"Error",36],[6,"Result",37],[10,"RpcApi",38],[5,"CheckPoint",39],[5,"Block",31],[6,"Option",40],[5,"Header",31],[5,"TypeId",41]],"r":[],"b":[],"c":"OjAAAAAAAAA=","e":"OzAAAAEAAA0ABAAEAAAACAADAA4AAAAYAAcA"}],\ -["bdk_chain",{"t":"KKKSFSKGFFGFPPKFRFEEEFFEPPNNMNNNOOMNNNNNNENNNNNNNNNNNNNNNNNNNNNOONNNNNNNNNNNNNNNNNNNNNNNNNNNNOONNNNNONNNNNNMNNNNNNMNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNMNNNNNNNNNMNNNNNNOONNNNCONNNNNNNNNNNNNMNNNMNNONNNCCNENONNNNONNNNNNNNNNNNDNNNNNNONCNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNCNONNNNNNNNNNNNNNNNNNNNNNNNNOOOFRFKNNNMNNNNNNNNNNNNNNNNNNNNNNNOOMMOMNNNNNNNNMNNNNNNNNNNNFFSPIGPIFFNNNNNNNNNNNNNNNNNNNNNNNNNONNNNNNNNNNNNNNNNNNNNNNNONNNNNNNNNNNNNNNNNOONNNNNNNNNNNNNNNNNNNNNNNNNNNNNNONNNNNNNNNNNNNNNNNNNNNONNNNNNNOOOOFGPFIFFPFFNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNONNNNNNNNNNNNNNNNNONNNNNNNNNNNNNNNNNNNNNNONNNNNNNNNNNNNNONNNNNNNFFFFNNNNNNNNNNNOONOONNNNNNNOONNNNNNNNNOONNNNNOONNNNNNNNONNNNNNNNGFFPPFFFFNNNOONNNNNNNNNNNNNNNNNNNNNONNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNOONNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNOONNONOONNNNNNNNNNNNNNNNNN","n":["Anchor","AnchorFromBlockPosition","Append","BIP32_MAX_INDEX","BlockId","COINBASE_MATURITY","ChainOracle","ChainPosition","CombinedChangeSet","ConfirmationHeightAnchor","ConfirmationTime","ConfirmationTimeHeightAnchor","Confirmed","Confirmed","DescriptorExt","DescriptorId","Error","FullTxOut","Indexed","IndexedTxGraph","KeychainIndexed","SpkIterator","SpkTxOutIndex","TxGraph","Unconfirmed","Unconfirmed","all_spks","all_zeros","anchor_block","anchor_block","anchor_block","anchor_block","anchor_block","anchor_block","append","append","apply_changeset","as_byte_array","as_raw_hash","as_ref","as_ref","bitcoin","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","chain","chain_position","clone","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","clone_into","cloned","cmp","cmp","cmp","cmp","cmp","cmp","cmp","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","default","descriptor","descriptor_id","deserialize","deserialize","deserialize","deserialize","deserialize","deserialize","dust_value","engine","eq","eq","eq","eq","eq","eq","eq","eq","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","from","from","from","from","from_block_position","from_block_position","from_block_position","from_block_position","from_byte_array","from_engine","from_raw_hash","from_slice","from_slice_delegated","from_str","get_chain_tip","hash","hash","hash","hash","hash","hash","hash","height","index","index_of_spk","index_tx","index_txout","indexed_tx_graph","indexed_tx_graph","initial_changeset","insert_spk","into","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_empty","is_mature","is_on_coinbase","is_relevant","is_tx_relevant","is_used","keychain","local_chain","mark_used","miniscript","net_value","network","new","new_with_range","next","nth","outpoint","outpoints","outputs_in_range","partial_cmp","partial_cmp","partial_cmp","partial_cmp","partial_cmp","partial_cmp","partial_cmp","scan","scan_txout","sent_and_received","serde","serialize","serialize","serialize","serialize","serialize","serialize","spent_by","spk_at_index","spk_client","take","take","to_byte_array","to_owned","to_owned","to_owned","to_owned","to_owned","to_owned","to_owned","to_owned","to_owned","to_owned","to_raw_hash","to_string","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","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","type_id","unconfirmed","unmark_used","unused_spks","vzip","vzip","vzip","vzip","vzip","vzip","vzip","vzip","vzip","vzip","height","last_seen","time","ChangeSet","ChangeSet","IndexedTxGraph","Indexer","append","apply_block","apply_block_relevant","apply_changeset","apply_changeset","apply_update","as_ref","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","DEFAULT_LOOKAHEAD","DescriptorAlreadyAssigned","Indexed","InsertDescriptorError","KeychainAlreadyAssigned","KeychainIndexed","KeychainTxOutIndex","NoSuchKeychain","add","all_unbounded_spk_iters","append","apply_changeset","apply_changeset","borrow","borrow","borrow","borrow","borrow","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","clone","clone","clone","clone","clone","clone_into","clone_into","clone_into","clone_into","clone_into","confirmed","default","default","default","deserialize","deserialize","eq","eq","eq","eq","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","from","from","from","from","from","get_descriptor","immature","index_of_spk","index_tx","index_txout","initial_changeset","inner","insert_descriptor","into","into","into","into","into","is_empty","is_tx_relevant","is_used","keychain_outpoints","keychain_outpoints_in_range","keychains","keychains_added","last_revealed","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_owned","to_owned","to_string","to_string","to_string","total","trusted_pending","trusted_spendable","try_from","try_from","try_from","try_from","try_from","try_into","try_into","try_into","try_into","try_into","txout","txouts","txouts_in_tx","type_id","type_id","type_id","type_id","type_id","unbounded_spk_iter","unmark_used","untrusted_pending","unused_keychain_spks","unused_spks","vzip","vzip","vzip","vzip","vzip","descriptor","existing_assignment","existing_assignment","keychain","AlterCheckPointError","ApplyHeaderError","CannotConnect","CannotConnectError","ChangeSet","CheckPoint","CheckPointIter","InconsistentBlocks","LocalChain","MissingGenesisError","apply_changeset","apply_header","apply_header_connected_to","apply_update","block_id","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","disconnect_from","eq","eq","eq","eq","eq","eq","extend","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","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","insert_block","into","into","into","into","into","into","into","into_iter","into_iter","is_block_in_chain","iter","iter_checkpoints","new","next","original_hash","prev","push","range","range","tip","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_include_height","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","update_hash","vzip","vzip","vzip","vzip","vzip","vzip","vzip","FullScanRequest","FullScanResult","SyncRequest","SyncResult","borrow","borrow","borrow","borrow","borrow_mut","borrow_mut","borrow_mut","borrow_mut","chain_outpoints","chain_spks","chain_spks_for_keychain","chain_tip","chain_tip","chain_txids","chain_update","chain_update","from","from","from","from","from_chain_tip","from_chain_tip","from_keychain_txout_index","graph_update","graph_update","inspect_outpoints","inspect_spks","inspect_spks_for_all_keychains","inspect_spks_for_keychain","inspect_txids","into","into","into","into","last_active_indices","outpoints","populate_with_revealed_spks","set_outpoints","set_spks","set_spks_for_keychain","set_txids","spks","spks_by_keychain","try_from","try_from","try_from","try_from","try_into","try_into","try_into","try_into","txids","type_id","type_id","type_id","type_id","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","new","next","next","outspends","partial_cmp","partial_cmp","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":[[0,"bdk_chain"],[298,"bdk_chain::ConfirmationTime"],[301,"bdk_chain::indexed_tx_graph"],[358,"bdk_chain::keychain"],[497,"bdk_chain::keychain::InsertDescriptorError"],[501,"bdk_chain::local_chain"],[643,"bdk_chain::spk_client"],[707,"bdk_chain::tx_graph"],[868,"bdk_chain::spk_txout_index"],[869,"bitcoin::blockdata::script::owned"],[870,"alloc::collections::btree::map"],[871,"core::clone"],[872,"core::cmp"],[873,"core::fmt"],[874,"bdk_chain::descriptor_ext"],[875,"bdk_chain::tx_data_traits"],[876,"bdk_chain::chain_data"],[877,"bdk_chain::changeset"],[878,"bitcoin_hashes::sha256"],[879,"bdk_chain::spk_iter"],[880,"core::option"],[881,"miniscript::descriptor::key"],[882,"miniscript::descriptor"],[883,"core::borrow"],[884,"core::result"],[885,"serde::de"],[886,"bitcoin::blockdata::block"],[887,"bdk_chain::keychain::txout_index"],[888,"bitcoin_hashes"],[889,"bdk_chain::chain_oracle"],[890,"core::hash"],[891,"core::slice::index"],[892,"bitcoin::blockdata::script::borrowed"],[893,"bitcoin::blockdata::transaction"],[894,"bitcoin_units::amount"],[895,"core::ops::range"],[896,"alloc::collections::btree::set"],[897,"core::iter::traits::double_ended"],[898,"serde::ser"],[899,"alloc::string"],[900,"core::iter::traits::exact_size"],[901,"core::any"],[902,"core::iter::traits::collect"],[903,"core::default"],[904,"alloc::vec"],[905,"core::iter::traits::iterator"],[906,"core::marker"],[907,"core::ops::function"],[908,"core::convert"],[909,"alloc::sync"],[910,"std::collections::hash::set"]],"i":[0,0,0,0,0,0,0,0,0,0,0,0,21,22,0,0,51,0,0,0,0,0,0,0,21,22,1,8,9,10,11,12,11,12,14,16,1,8,8,8,8,0,1,21,22,10,11,12,23,8,8,24,16,1,21,22,10,11,12,23,8,24,16,16,23,1,21,22,10,11,12,23,8,24,16,1,21,22,10,11,12,23,8,24,16,21,21,22,10,11,12,23,8,11,12,9,9,21,11,12,12,1,10,11,12,16,24,31,22,10,11,12,8,16,31,8,21,22,10,11,12,23,8,16,1,21,22,10,11,12,23,8,8,8,8,16,1,21,22,22,10,10,10,11,12,23,8,8,24,16,16,16,16,47,10,11,12,8,8,8,8,8,8,51,21,22,10,11,12,8,10,10,8,1,1,1,0,16,1,1,1,21,22,10,11,12,23,8,24,16,24,51,21,22,23,14,16,23,23,1,1,1,0,0,1,0,1,16,24,24,24,24,23,1,1,21,22,10,11,12,23,8,1,1,1,0,22,10,11,12,8,16,23,1,0,14,14,8,1,21,22,10,11,12,23,8,24,16,8,8,1,21,22,10,11,12,23,8,24,16,1,21,22,10,11,12,23,8,24,16,0,1,23,1,1,1,21,22,10,11,12,23,8,24,16,22,1,1,1,21,22,10,11,12,23,8,24,16,111,112,111,0,73,0,0,43,72,72,73,72,72,72,72,72,72,72,43,72,43,43,43,72,43,43,43,72,43,72,43,43,43,72,43,72,73,73,43,73,72,72,72,72,72,72,43,43,73,72,43,43,72,43,72,43,72,43,72,43,0,0,0,81,0,0,81,0,0,0,79,80,42,80,80,80,81,42,82,79,80,81,42,82,79,80,81,42,82,79,80,81,42,82,79,79,80,42,79,42,79,81,42,82,79,80,81,81,42,82,82,79,79,80,81,42,82,79,80,79,80,80,80,80,80,80,80,81,42,82,79,42,80,80,80,80,80,42,42,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,42,79,80,80,81,42,82,79,81,82,79,79,79,79,80,81,42,82,79,80,81,42,82,79,80,80,80,80,81,42,82,79,80,80,79,80,80,80,81,42,82,79,113,113,114,114,0,0,91,0,0,0,0,91,0,0,87,87,87,87,92,94,92,87,88,93,90,91,94,92,87,88,93,90,91,92,87,88,93,90,91,92,87,88,93,90,91,87,92,87,88,93,90,91,92,92,87,88,88,93,93,90,90,91,91,94,92,87,88,93,90,91,92,87,87,87,92,87,87,92,87,87,92,92,93,87,92,87,94,92,87,88,93,90,91,94,92,87,92,87,92,94,93,92,92,92,87,87,92,87,88,93,90,91,88,93,90,91,94,92,87,88,93,90,91,90,94,92,87,88,93,90,91,94,92,87,88,93,90,91,93,94,92,87,88,93,90,91,0,0,0,0,95,115,98,116,95,115,98,116,95,95,98,95,98,95,115,116,95,115,98,116,95,98,98,115,116,95,95,98,98,95,95,115,98,116,116,95,95,95,95,98,95,95,98,95,115,98,116,95,115,98,116,95,95,115,98,116,95,115,98,116,0,0,0,103,103,0,0,0,0,75,75,78,104,78,78,75,75,75,75,75,108,109,75,104,105,103,78,108,109,75,104,105,103,78,75,105,108,108,109,109,75,104,105,78,75,104,105,78,104,105,75,78,104,78,75,75,104,105,103,78,75,75,75,75,104,105,103,103,78,108,109,75,104,105,103,78,75,75,75,75,75,75,75,75,75,75,75,108,109,75,104,105,103,78,108,109,75,78,78,104,75,75,78,75,108,109,75,104,105,78,75,104,105,78,103,75,75,75,108,109,75,104,105,103,78,75,75,108,109,75,104,105,103,78,75,104,105,75,75,104,78,78,78,108,109,75,104,105,103,78,75,108,109,75,104,105,103,78,75,75,75],"f":"``````````````````````````{{{d{{b{c}}}}}{{d{{h{cf}}}}}{jln}}{{}A`}{{{d{Ab}}}Ad}{{{d{Ad}}}Ad}{{{d{Af}}}Ad}{{{d{Ah}}}Ad}``{{{d{AjAl}}Al}An}{{{d{Aj{B`{ce}}}}{B`{ce}}}AnlAb}{{{d{Aj{b{c}}}}e}An{jln}{}}{{{d{A`}}}{{d{c}}}{}}{{{d{A`}}}{{d{Bb}}}}{{{d{A`}}}{{d{{Bf{Bd}}}}}}{{{d{A`}}}{{d{{Bh{Bd}}}}}}`{{{d{c}}}{{d{e}}}{}{}}0000000100{{{d{Ajc}}}{{d{Aje}}}{}{}}000000000``{{{d{{b{c}}}}}{{b{c}}}j}{{{d{{Bj{c}}}}}{{Bj{c}}}j}{{{d{Bl}}}Bl}>{{{d{Af}}}Af}{{{d{Ah}}}Ah}{{{d{{Bn{c}}}}}{{Bn{c}}}j}{{{d{A`}}}A`}{{{d{{C`{c}}}}}{{C`{c}}}j}{{{d{{B`{ce}}}}}{{B`{ce}}}jj}{{{d{c}}{d{Aje}}}An{}{}}000000000{{{Bj{{d{c}}}}}{{Bj{c}}}j}{{{d{{Bj{c}}}}{d{{Bj{c}}}}}Cbl}{{{d{Bl}}{d{Bl}}}Cb}{{{d{Ad}}{d{Ad}}}Cb}{{{d{Af}}{d{Af}}}Cb}{{{d{Ah}}{d{Ah}}}Cb}{{{d{{Bn{c}}}}{d{{Bn{c}}}}}Cbl}{{{d{A`}}{d{A`}}}Cb}``{{{d{Ab}}}Cd}0{{{d{{Bj{c}}}}}{{Cf{Cd}}}Ab}{{{d{Af}}}Cd}{{{d{Ah}}}Cd}`{{}{{b{c}}}{}}{{}Ad}{{}Af}{{}Ah}{{}{{B`{ce}}}{}{}}{{{d{{C`{c}}}}}{{d{c}}}{{Cl{{Cj{Ch}}}}}}{{{d{Cn}}}A`}{c{{D`{Bl}}}Db}{c{{D`{Ad}}}Db}{c{{D`{Af}}}Db}{c{{D`{Ah}}}Db}{c{{D`{A`}}}Db}{c{{D`{{B`{eg}}}}}Db{lDd}{lDd}}{{{d{Cn}}}Df}{{}c{}}{{{d{{Bj{c}}}}{d{{Bj{c}}}}}DhDj}{{{d{Bl}}{d{Bl}}}Dh}{{{d{Ad}}{d{Ad}}}Dh}{{{d{Af}}{d{Af}}}Dh}{{{d{Ah}}{d{Ah}}}Dh}{{{d{{Bn{c}}}}{d{{Bn{c}}}}}DhDj}{{{d{A`}}{d{A`}}}Dh}{{{d{{B`{ce}}}}{d{{B`{ce}}}}}DhDjDj}{{{d{{b{c}}}}{d{AjDl}}}Dnn}{{{d{{Bj{c}}}}{d{AjDl}}}Dnn}{{{d{Bl}}{d{AjDl}}}Dn}{{{d{Ad}}{d{AjDl}}}Dn}{{{d{Af}}{d{AjDl}}}Dn}{{{d{Ah}}{d{AjDl}}}Dn}{{{d{{Bn{c}}}}{d{AjDl}}}Dnn}{{{d{A`}}{d{AjDl}}}Dn}000{{{d{{B`{ce}}}}{d{AjDl}}}Dnnn}{cc{}}0{{{Bj{Ah}}}Bl}1{{{Eb{CdE`}}}Ad}{{{Eb{{d{Cd}}{d{E`}}}}}Ad}3333{BbA`}44{{{Ef{c{Ed{e}}}}}{{B`{ec}}}{}{}}{Eh{{B`{ce}}}{}{}}{{{Ed{c}}}{{B`{ce}}}{}{}}7{{{d{Ej}}AdEl}En}{{{d{Ej}}AdEl}Ad}{{{d{Ej}}AdEl}Af}{{{d{Ej}}AdEl}Ah}{cA`{}}08{{{d{{Bh{Bd}}}}}{{D`{A`F`}}}}0{{{d{Fb}}}{{D`{A`c}}}{}}{{{d{{Ff{}{{Fd{c}}}}}}}{{D`{Adc}}}n}{{{d{{Bj{c}}}}{d{Aje}}}AnFhFj}{{{d{Bl}}{d{Ajc}}}AnFj}{{{d{Ad}}{d{Ajc}}}AnFj}{{{d{Af}}{d{Ajc}}}AnFj}{{{d{Ah}}{d{Ajc}}}AnFj}{{{d{A`}}{d{Ajc}}}AnFj}``{{{d{A`}}c}{{d{e}}}{{Fl{{Bh{Bd}}}}}{}}{{{d{{b{c}}}}{d{Fn}}}{{Cf{{d{c}}}}}{jln}}{{{d{Aj{b{c}}}}{d{G`}}}e{jln}{}}{{{d{Aj{b{c}}}}Gb{d{Gd}}}e{jln}{}}``{{{d{{b{c}}}}}e{jln}{}}{{{d{Aj{b{c}}}}cf}Dh{jln}}{ce{}{}}0000000000{{{d{{Ff{}{{Fd{c}}}}}}AdAd}{{D`{{Cf{Dh}}c}}}n}{{{d{{Bj{c}}}}}Dh{}}{{{d{Bl}}}Dh}{{{d{{Bn{c}}}}Cd}DhAb}{{{d{Al}}}Dh}{{{d{{B`{ce}}}}}DhlAb}2`{{{d{{b{c}}}}{d{G`}}}Dh{jln}}0{{{d{{b{c}}}}{d{c}}}Dh{jln}}``{{{d{Aj{b{c}}}}{d{c}}}Dh{jln}}`{{{d{{b{c}}}}{d{G`}}e}Gf{jln}{{Gh{c}}}}`{c{{C`{c}}}{{Cl{{Cj{Ch}}}}}}{{ce}{{C`{c}}}{{Cl{{Cj{Ch}}}}}{{Gh{Cd}}}}{{{d{Aj{C`{c}}}}}{{Cf{e}}}{{Cl{{Cj{Ch}}}}}{}}{{{d{Aj{C`{c}}}}El}{{Cf{e}}}{{Cl{{Cj{Ch}}}}}{}}`{{{d{{b{c}}}}}{{d{{Gj{{Eb{cGb}}}}}}}{jln}}{{{d{{b{c}}}}e}{{`{{Gn{}{{Gl{{Eb{{d{c}}Gb}}}}}}}}}{jln}{{Gh{c}}}}{{{d{{Bj{c}}}}{d{{Bj{c}}}}}{{Cf{Cb}}}H`}{{{d{Bl}}{d{Bl}}}{{Cf{Cb}}}}{{{d{Ad}}{d{Ad}}}{{Cf{Cb}}}}{{{d{Af}}{d{Af}}}{{Cf{Cb}}}}{{{d{Ah}}{d{Ah}}}{{Cf{Cb}}}}{{{d{{Bn{c}}}}{d{{Bn{c}}}}}{{Cf{Cb}}}H`}{{{d{A`}}{d{A`}}}{{Cf{Cb}}}}{{{d{Aj{b{c}}}}{d{G`}}}{{Gj{c}}}{jln}}{{{d{Aj{b{c}}}}Gb{d{Gd}}}{{Cf{{d{c}}}}}{jln}}{{{d{{b{c}}}}{d{G`}}e}{{Eb{HbHb}}}{jln}{{Gh{c}}}}`{{{d{Bl}}c}D`Hd}{{{d{Ad}}c}D`Hd}{{{d{Af}}c}D`Hd}{{{d{Ah}}c}D`Hd}{{{d{A`}}c}D`Hd}{{{d{{B`{ce}}}}g}D`{lHf}{lHf}Hd}`{{{d{{b{c}}}}{d{c}}}{{Cf{{d{Fn}}}}}{jln}}`{{{d{AjAl}}}{{Cf{Al}}}}0{A`c{}}{{{d{c}}}e{}{}}000000000{A`Bb}{{{d{c}}}Hh{}}{c{{D`{e}}}{}{}}0000000000000000000`{{{d{{b{c}}}}Gb}{{Cf{{Eb{{d{c}}{d{Gd}}}}}}}{jln}}`{{{d{{b{c}}}}}{{`{{Gn{}{{Gl{{Eb{{d{c}}Gb{d{Gd}}}}}}}}Hj}}}{jln}}{{{d{{b{c}}}}Hl}{{`{{Gn{}{{Gl{{Eb{{d{c}}Gb{d{Gd}}}}}}}}}}}{jln}}{{{d{c}}}Hn{}}000000000{DfBl}{{{d{Aj{b{c}}}}{d{c}}}Dh{jln}}{{{d{{b{c}}}}e}{{`{{Gn{}{{Gl{{Eb{{d{c}}{d{Fn}}}}}}}}j}}}{jln}{{Gh{c}}}}{ce{}{}}000000000```````{{{d{Aj{Ef{ce}}}}{Ef{ce}}}AnAbAl}{{{d{Aj{I`{ce}}}}EjCd}{{Ef{c}}}{EnAb}Ib}{{{d{Aj{I`{ce}}}}{d{Ej}}Cd}{{Ef{c}}}{EnAb}Ib}{{{d{Aj{Ib{}{{Id{c}}}}}}c}An{}}{{{d{Aj{I`{ce}}}}{Ef{c}}}AnAbIb}{{{d{Aj{I`{ce}}}}{If{c}}}{{Ef{c}}}AbIb}{{{d{{I`{ce}}}}}{{d{{If{c}}}}}{}{}}{{{d{Aj{I`{ce}}}}i}{{Ef{c}}}AbIb{{Ih{}{{Gl{c}}}}}{{Ih{}{{Gl{{Eb{{d{G`}}g}}}}}}}}{{{d{Aj{I`{ce}}}}g}{{Ef{c}}}AbIb{{Ih{}{{Gl{{Eb{{d{G`}}Df}}}}}}}}{{{d{Aj{I`{ce}}}}g}{{Ef{c}}}AbIb{{Ih{}{{Gl{{Eb{G`Df}}}}}}}}{{{d{c}}}{{d{e}}}{}{}}0{{{d{Ajc}}}{{d{Aje}}}{}{}}0{{{d{{Ef{ce}}}}}{{Ef{ce}}}jj}{{{d{c}}{d{Aje}}}An{}{}}{{}{{I`{ce}}}{}Ij}{{}{{Ef{ce}}}{}Ij}{c{{D`{{Ef{eg}}}}}Db{lDd}Dd}{{{d{{Ef{ce}}}}{d{{Ef{ce}}}}}DhDjDj}{{{d{{I`{ce}}}}{d{AjDl}}}Dnnn}{{{d{{Ef{ce}}}}{d{AjDl}}}Dnnn}{cc{}}0{{{Ed{c}}}{{Ef{e{Ed{c}}}}}{}{}}{{{Il{c}}}{{Ef{ce}}}{}Ij}{{{d{{I`{ce}}}}}{{d{{If{c}}}}}{}{}}``{{{d{Aj{Ib{}{{Id{c}}}}}}{d{G`}}}c{}}{{{d{Aj{Ib{}{{Id{c}}}}}}Gb{d{Gd}}}c{}}`{{{d{{Ib{}{{Id{c}}}}}}}c{}}{{{d{{I`{ce}}}}}{{Ef{c}}}AbIb}{{{d{Aj{I`{ce}}}}Hlc}{{Ef{c}}}AbIb}{{{d{Aj{I`{ce}}}}HlDf}{{Ef{c}}}AbIb}{{{d{Aj{I`{ce}}}}G`}{{Ef{c}}}AbIb}{{{d{Aj{I`{ce}}}}GbGd}{{Ef{c}}}AbIb}{ce{}{}}0{{{d{{Ef{ce}}}}}DhAbAl}{{{d{{Ib{}{{Id{c}}}}}}{d{G`}}}Dh{}}{c{{I`{ec}}}{}{}}{{{d{{Ef{ce}}}}g}D`{lHf}HfHd}{{{d{c}}}e{}{}}{c{{D`{e}}}{}{}}000{{{d{c}}}Hn{}}077``````````{{InIn}In}{{{d{{J`{c}}}}}{{h{c{C`{{Cj{Ch}}}}}}}{jln}}{{{d{Aj{Ed{c}}}}{Ed{c}}}Anl}{{{d{Aj{J`{c}}}}e}An{jln}{}}{{{d{Aj{J`{c}}}}{Ed{c}}}An{jln}}{{{d{c}}}{{d{e}}}{}{}}0000{{{d{Ajc}}}{{d{Aje}}}{}{}}0000{{{d{{J`{c}}}}}{{J`{c}}}j}{{{d{{Jb{c}}}}}{{Jb{c}}}j}{{{d{{Ed{c}}}}}{{Ed{c}}}j}{{{d{{Jd{c}}}}}{{Jd{c}}}j}{{{d{In}}}In}{{{d{c}}{d{Aje}}}An{}{}}0000`{{}{{J`{c}}}{}}{{}{{Ed{c}}}{}}{{}In}{c{{D`{{Ed{e}}}}}Db{lDd}}{c{{D`{In}}}Db}{{{d{{Jb{c}}}}{d{{Jb{c}}}}}DhDj}{{{d{{Ed{c}}}}{d{{Ed{c}}}}}DhDj}{{{d{{Jd{c}}}}{d{{Jd{c}}}}}DhDj}{{{d{In}}{d{In}}}Dh}{{{d{{J`{c}}}}{d{AjDl}}}Dnn}{{{d{{Jb{c}}}}{d{AjDl}}}Dnn}0{{{d{{Ed{c}}}}{d{AjDl}}}Dnn}{{{d{{Jd{c}}}}{d{AjDl}}}Dnn}0{{{d{In}}{d{AjDl}}}Dn}0{cc{}}0000{{{d{{J`{c}}}}{d{c}}}{{Cf{{d{{Cj{Ch}}}}}}}{jln}}`{{{d{{J`{c}}}}{d{Fn}}}{{Cf{{d{{Eb{cCd}}}}}}}{jln}}{{{d{Aj{J`{c}}}}{d{G`}}}e{jln}{}}{{{d{Aj{J`{c}}}}Gb{d{Gd}}}e{jln}{}}{{{d{{J`{c}}}}}e{jln}{}}{{{d{{J`{c}}}}}{{d{{b{{Eb{cCd}}}}}}}{jln}}{{{d{Aj{J`{c}}}}c{Cj{Ch}}}{{D`{{Ed{c}}{Jb{c}}}}}{jln}}{ce{}{}}0000{{{d{{Ed{c}}}}}Dhl}{{{d{{J`{c}}}}{d{G`}}}Dh{jln}}{{{d{{J`{c}}}}cCd}Dh{jln}}{{{d{{J`{c}}}}{d{c}}}{{`{{Gn{}{{Gl{{Jf{Gb}}}}}}}}}{jln}}{{{d{{J`{c}}}}e}{{`{{Gn{}{{Gl{{Jh{cGb}}}}}}}}}{jln}{{Gh{c}}}}{{{d{{J`{c}}}}}{{`{{Gn{}{{Gl{{Eb{{d{c}}{d{{Cj{Ch}}}}}}}}}}Hj}}}{jln}}``{{{d{{J`{c}}}}{d{c}}}{{Cf{Cd}}}{jln}}{{{d{{J`{c}}}}}{{h{cCd}}}{jln}}10{{{d{{J`{c}}}}}Cd{jln}}{{{d{Aj{J`{c}}}}{d{c}}Cd}An{jln}}{{{d{Aj{J`{c}}}}cCd}Dh{jln}}{{{d{{J`{c}}}}{d{G`}}e}Gf{jln}{{Gh{c}}}}{Cd{{J`{c}}}{}}{{{d{{J`{c}}}}{d{c}}}{{Cf{{Eb{CdDh}}}}}{jln}}{{{d{Aj{J`{c}}}}{d{c}}}{{Cf{{Eb{{Jf{f}}{Ed{c}}}}}}}{jln}}{{{d{{J`{c}}}}}{{d{{Gj{{Jh{cGb}}}}}}}{jln}}1{{{d{Aj{J`{c}}}}{d{c}}Cd}{{Cf{{Eb{{Jj{{Jf{f}}}}{Ed{c}}}}}}}{jln}}{{{d{Aj{J`{c}}}}{d{{h{cCd}}}}}{{Ed{c}}}{jln}}{{{d{{J`{c}}}}{d{c}}}{{`{{Gn{}{{Gl{{Jf{{d{Fn}}}}}}}}}}}{jln}}{{{d{{J`{c}}}}e}{{`{{Jl{}{{Gl{{Jh{c{d{Fn}}}}}}}}}}}{jln}{{Gh{c}}}}{{{d{{J`{c}}}}{d{G`}}e}{{Eb{HbHb}}}{jln}{{Gh{c}}}}{{{d{{Ed{c}}}}e}D`{lHf}Hd}{{{d{In}}c}D`Hd}{{{d{{J`{c}}}}cCd}{{Cf{{d{Fn}}}}}{jln}}{{{d{c}}}e{}{}}0000{{{d{c}}}Hh{}}00{{{d{In}}}Hb}`0{c{{D`{e}}}{}{}}000000000{{{d{{J`{c}}}}Gb}{{Cf{{Jh{c{d{Gd}}}}}}}{jln}}{{{d{{J`{c}}}}}{{`{{Gn{}{{Gl{{Jh{c{Eb{Gb{d{Gd}}}}}}}}}}Hj}}}{jln}}{{{d{{J`{c}}}}Hl}{{`{{Gn{}{{Gl{{Jh{c{Eb{Gb{d{Gd}}}}}}}}}}}}}{jln}}{{{d{c}}}Hn{}}0000{{{d{{J`{c}}}}{d{c}}}{{Cf{{C`{{Cj{Ch}}}}}}}{jln}}{{{d{Aj{J`{c}}}}cCd}Dh{jln}}`{{{d{{J`{c}}}}{d{c}}}{{`{{Gn{}{{Gl{{Jf{{d{Fn}}}}}}}}j}}}{jln}}{{{d{{J`{c}}}}}{{`{{Gn{}{{Gl{{Jh{c{d{Fn}}}}}}}}j}}}{jln}}{ce{}{}}0000``````````````{{{d{AjJn}}{d{Eh}}}{{D`{AnK`}}}}{{{d{AjJn}}{d{Kb}}Cd}{{D`{EhKd}}}}{{{d{AjJn}}{d{Kb}}CdAd}{{D`{EhKf}}}}{{{d{AjJn}}Kh}{{D`{EhKd}}}}{{{d{Kh}}}Ad}{{{d{c}}}{{d{e}}}{}{}}000000{{{d{Ajc}}}{{d{Aje}}}{}{}}000000{{{d{Kh}}}Kh}{{{d{Jn}}}Jn}{{{d{K`}}}K`}{{{d{Kj}}}Kj}{{{d{Kd}}}Kd}{{{d{Kf}}}Kf}{{{d{c}}{d{Aje}}}An{}{}}00000{{{d{AjJn}}Ad}{{D`{EhK`}}}}{{{d{Kh}}{d{Kh}}}Dh}{{{d{Jn}}{d{Jn}}}Dh}{{{d{K`}}{d{K`}}}Dh}{{{d{Kj}}{d{Kj}}}Dh}{{{d{Kd}}{d{Kd}}}Dh}{{{d{Kf}}{d{Kf}}}Dh}{{Khc}{{D`{KhKh}}}{{Ih{}{{Gl{Ad}}}}}}{{{d{Kh}}{d{AjDl}}}Dn}{{{d{Jn}}{d{AjDl}}}Dn}{{{d{K`}}{d{AjDl}}}Dn}0{{{d{Kj}}{d{AjDl}}}Dn}0{{{d{Kd}}{d{AjDl}}}Dn}0{{{d{Kf}}{d{AjDl}}}Dn}0{cc{}}000000{c{{D`{Kh{Cf{Kh}}}}}{{Ih{}{{Gl{Ad}}}}}}{{{h{CdE`}}}{{D`{JnK`}}}}{Eh{{D`{JnK`}}}}{E`{{Eb{JnEh}}}}{{{d{Kb}}Cd}Kh}{Kh{{D`{JnK`}}}}{{{d{Jn}}}E`}{{{d{Kh}}Cd}{{Cf{Kh}}}}{{{d{Jn}}Cd}{{Cf{Kh}}}}{{{d{Jn}}}{{D`{Adc}}}{}}{{{d{Kh}}}E`}{{{d{Kh}}}Cd}`{{{d{Jn}}}Eh}{{KhAd}Kh}{{{d{AjJn}}Ad}{{D`{EhKj}}}}{ce{}{}}0000000{Khc{}}{{{d{Jn}}AdAd}{{D`{{Cf{Dh}}c}}}{}}{{{d{Kh}}}Kl}{{{d{Jn}}}Kl}{AdKh}{{{d{AjKl}}}{{Cf{c}}}{}}`{{{d{Kh}}}{{Cf{Kh}}}}{{KhAd}{{D`{KhKh}}}}{{{d{Kh}}c}{{`{{Jl{}{{Gl{Kh}}}}}}}{{Gh{Cd}}}}{{{d{Jn}}c}{{`{{Jl{}{{Gl{Kh}}}}}}}{{Gh{Cd}}}}{{{d{Jn}}}Kh}{{{d{c}}}e{}{}}00000{{{d{c}}}Hh{}}000{c{{D`{e}}}{}{}}000000`0000000{{{d{c}}}Hn{}}000000`???????````{{{d{c}}}{{d{e}}}{}{}}000{{{d{Ajc}}}{{d{Aje}}}{}{}}000{{Kne}Kn{{Hj{}{{Gl{Gb}}}}L`}{{Ih{}{{Lb{c}}{Gl{Gb}}}}}}{{Kne}Kn{{Hj{}{{Gl{f}}}}L`}{{Ih{}{{Lb{c}}{Gl{f}}}}}}{{{Ld{c}}cg}{{Ld{c}}}{lj}{{Jl{}{{Gl{{Jf{f}}}}}}L`}{{Ih{}{{Lb{e}}}}}}``{{Kne}Kn{{Hj{}{{Gl{Hl}}}}L`}{{Ih{}{{Lb{c}}{Gl{Hl}}}}}}``{cc{}}000{KhKn}{Kh{{Ld{c}}}{lj}}{{Kh{d{{J`{c}}}}}{{Ld{c}}}{nlj}}``{{Knc}Kn{{Lf{{d{Gb}}}}L`Lh}}{{Knc}Kn{{Lf{{d{Fn}}}}L`Lh}}{{{Ld{c}}e}{{Ld{c}}}{L`lj}{{Lf{cCd{d{Fn}}}}L`Lhj}}{{{Ld{c}}ce}{{Ld{c}}}{L`lj}{{Lf{Cd{d{Fn}}}}L`Lh}}{{Knc}Kn{{Lf{{d{Hl}}}}L`Lh}}{ce{}{}}000``{{Kn{d{{J`{c}}}}e}Kn{jlnL`Lh}{{Gh{c}}}}{{Kne}Kn{{Hj{}{{Gl{Gb}}}}L`}{{Ih{}{{Lb{c}}}}}}{{Kne}Kn{{Hj{}{{Gl{f}}}}L`}{{Ih{}{{Lb{c}}}}}}>{{Kne}Kn{{Hj{}{{Gl{Hl}}}}L`}{{Ih{}{{Lb{c}}}}}}``{c{{D`{e}}}{}{}}0000000`{{{d{c}}}Hn{}}0006666`````````{{{d{{If{c}}}}}{{d{{Gj{{Eb{cHl}}}}}}}{}}{{{d{{If{c}}}}}{{`{{Jl{}{{Gl{{Eb{Gb{d{Gd}}}}}}}}}}}{}}{{{d{{Il{c}}}}}{{`{{Jl{}{{Gl{Cd}}}}}}}Ab}``{{{d{Aj{Il{c}}}}{Il{c}}}Anl}{{{d{Aj{If{c}}}}{Il{c}}}An{jl}}{{{d{Aj{If{c}}}}{If{c}}}{{Il{c}}}{jl}}{{{d{{If{c}}}}}{{d{{If{c}}}}}{}}{{{d{{If{c}}}}{d{e}}Adik}InAb{{Ff{}{{Fd{Lj}}}}}j{{Ih{}{{Gl{{Eb{gGb}}}}}}}{{Lf{{d{g}}{d{Fn}}}{{Ll{Dh}}}}}}{{{d{Aj{If{c}}}}e}{{Il{c}}}{jl}{{Ih{}{{Gl{{Eb{G`Df}}}}}}}}{{{d{c}}}{{d{e}}}{}{}}000000{{{d{Ajc}}}{{d{Aje}}}{}{}}000000{{{d{{If{c}}}}{d{G`}}}{{D`{HbLn}}}{}}`{c{{Cf{Gf}}}{}}{c{{Cf{Hb}}}{}}10{{{d{{If{c}}}}}{{If{c}}}j}{{{d{{M`{ce}}}}}{{M`{ce}}}jj}{{{d{{Mb{ce}}}}}{{Mb{ce}}}jj}{{{d{{Il{c}}}}}{{Il{c}}}j}{{{d{c}}{d{Aje}}}An{}{}}000{{{d{{M`{ce}}}}{d{{M`{ce}}}}}Cbll}{{{d{{Mb{ce}}}}{d{{Mb{ce}}}}}Cbll}{{}{{If{c}}}{}}{{}{{Il{c}}}{}}{{{d{{M`{ce}}}}}{{d{g}}}{}{}{}}{c{{D`{{Il{e}}}}}Db{lDd}}{{{d{{If{c}}}}{d{G`}}}{{`{{Jl{}{{Gl{{Eb{ElHl}}}}}}}}}{}}{{{d{{If{c}}}}{d{{If{c}}}}}DhDj}{{{d{{M`{ce}}}}{d{{M`{ce}}}}}DhDjDj}{{{d{{Mb{ce}}}}{d{{Mb{ce}}}}}DhDjDj}{{{d{Ln}}{d{Ln}}}Dh}{{{d{{Il{c}}}}{d{{Il{c}}}}}DhDj}{{{d{{If{c}}}}{d{e}}Adi}{{`{{Jl{}{{Gl{{Eb{g{Bn{c}}}}}}}}}}}Ab{{Ff{}{{Fd{Lj}}}}}j{{Ih{}{{Gl{{Eb{gGb}}}}}}}}0{{{d{{If{c}}}}}{{`{{Jl{}{{Gl{{Eb{Gb{d{Gd}}}}}}}}}}}{}}{{{d{{If{c}}}}{d{AjDl}}}Dnn}{{{d{{M`{ce}}}}{d{AjDl}}}Dnnn}{{{d{{Mb{ce}}}}{d{AjDl}}}Dnnn}{{{d{Ln}}{d{AjDl}}}Dn}0{{{d{{Il{c}}}}{d{AjDl}}}Dnn}{cc{}}000000{{{d{{If{c}}}}}{{`{{Jl{}{{Gl{{M`{{Md{G`}}c}}}}}}}}}{}}{{{d{{If{c}}}}{d{e}}AdHl}{{Cf{{Bj{{d{c}}}}}}}Ab{{Ff{}{{Fd{Lj}}}}}}{{{d{{If{c}}}}{d{e}}AdGb}{{Cf{{Eb{{Bj{{d{c}}}}Hl}}}}}Ab{{Ff{}{{Fd{Lj}}}}}}{{{d{{If{c}}}}Hl}{{Cf{{Md{G`}}}}}{}}{{{d{{If{c}}}}Hl}{{Cf{{M`{{Md{G`}}c}}}}}{}}{{{d{{If{c}}}}Gb}{{Cf{{d{Gd}}}}}{}}{{{d{{If{c}}}}}{{Il{c}}}{jl}}{{{d{Aj{If{c}}}}Hlc}{{Il{c}}}{jl}}{{{d{Aj{If{c}}}}HlDf}{{Il{c}}}{jl}}{{{d{Aj{If{c}}}}e}{{Il{c}}}{jl}{{Mf{{Md{G`}}}}}}{{{d{Aj{If{c}}}}GbGd}{{Il{c}}}{jl}}{ce{}{}}00000000{{{d{{If{c}}}}}Dh{}}{{{d{{Il{c}}}}}Dhl}``{{{d{{If{c}}}}{d{e}}Ad}{{`{{Jl{}{{Gl{{Mb{{Md{G`}}c}}}}}}}}}AbFf}{{{If{c}}g}{{If{e}}}{jl}{jl}{{Lf{c}{{Ll{e}}}}}}{{{Il{c}}g}{{Il{e}}}ll{{Lf{c}{{Ll{e}}}}}}{c{{If{e}}}{{Ih{}{{Gl{G`}}}}}{jl}}{{{d{Aj{Mh{cg}}}}}{{Cf{i}}}{}{}{{Lf{El{Md{G`}}}{{Ll{{Cf{e}}}}}}}{}}{{{d{Aj{Mj{cg}}}}}{{Cf{i}}}{}{}{{Lf{ElHl}{{Ll{{Cf{e}}}}}}}{}}{{{d{{If{c}}}}Gb}{{d{{Ml{Hl}}}}}{}}{{{d{{M`{ce}}}}{d{{M`{ce}}}}}{{Cf{Cb}}}H`H`}{{{d{{Mb{ce}}}}{d{{Mb{ce}}}}}{{Cf{Cb}}}H`H`}{{{d{{Il{c}}}}e}D`{lHf}Hd}{{{d{c}}}e{}{}}000{{{d{c}}}Hh{}}{{{d{{If{c}}}}{d{e}}Adik}{{D`{In}}}AbFfj{{Ih{}{{Gl{{Eb{gGb}}}}}}}{{Lf{{d{g}}{d{Fn}}}{{Ll{Dh}}}}}}{{{d{{If{c}}}}{d{e}}Adi}{{`{{Jl{}{{Gl{{D`{{Eb{g{Bn{c}}}}}}}}}}}}}AbFfj{{Ih{}{{Gl{{Eb{gGb}}}}}}}}0{c{{D`{e}}}{}{}}000000{{{d{{If{c}}}}{d{e}}AdHl}{{D`{{Cf{{Bj{{d{c}}}}}}}}}AbFf}{{{d{{If{c}}}}{d{e}}AdGb}{{D`{{Cf{{Eb{{Bj{{d{c}}}}Hl}}}}}}}AbFf}2222222{{{d{{If{c}}}}{d{e}}Ad}{{`{{Jl{}{{Gl{{D`{{Mb{{Md{G`}}c}}}}}}}}}}}AbFf}``{{{d{{If{c}}}}Hl}{{Cf{{h{Cd{d{Gd}}}}}}}{}}{{{d{{If{c}}}}Hl}{{`{{Gn{}{{Gl{{Eb{Cd{d{{Ml{Hl}}}}}}}}}}}}}{}}`{{{d{{Il{c}}}}}{{`{{Jl{}{{Gl{{Eb{Gb{d{Gd}}}}}}}}}}}{}}``{{{d{c}}}Hn{}}000000{{{d{Aj{If{c}}}}Df}{{Il{c}}}{jl}}{ce{}{}}000000{{{d{{If{c}}}}ei}{{Mh{ci}}}{jl}{{Mf{{Md{G`}}}}}{}{{Lf{El{Md{G`}}}{{Ll{{Cf{g}}}}}}}}{{{d{{If{c}}}}{d{G`}}g}{{Mj{cg}}}{}{}{{Lf{ElHl}{{Ll{{Cf{e}}}}}}}}{{{d{{If{c}}}}Hlg}{{Mj{cg}}}{jl}{}{{Lf{ElHl}{{Ll{{Cf{e}}}}}}}}","D":"BOj","p":[[5,"SpkTxOutIndex",0,868],[1,"reference"],[5,"ScriptBuf",869],[5,"BTreeMap",870],[10,"Clone",871],[10,"Ord",872],[10,"Debug",873],[5,"DescriptorId",0,874],[10,"Anchor",0,875],[5,"BlockId",0,876],[5,"ConfirmationHeightAnchor",0,876],[5,"ConfirmationTimeHeightAnchor",0,876],[0,"mut"],[10,"Append",0,875],[1,"unit"],[5,"CombinedChangeSet",0,877],[5,"Hash",878],[1,"u8"],[1,"array"],[1,"slice"],[6,"ChainPosition",0,876],[6,"ConfirmationTime",0,876],[5,"FullTxOut",0,876],[5,"SpkIterator",0,879],[6,"Ordering",872],[1,"u32"],[6,"Option",880],[6,"DescriptorPublicKey",881],[6,"Descriptor",882],[10,"Borrow",883],[10,"DescriptorExt",0,874],[6,"Result",884],[10,"Deserializer",885],[10,"Deserialize",885],[1,"u64"],[1,"bool"],[10,"PartialEq",872],[5,"Formatter",873],[8,"Result",873],[5,"BlockHash",886],[1,"tuple"],[5,"ChangeSet",358,887],[5,"ChangeSet",301],[8,"ChangeSet",501],[5,"Block",886],[1,"usize"],[10,"AnchorFromBlockPosition",0,875],[5,"FromSliceError",888],[1,"str"],[17,"Error"],[10,"ChainOracle",0,889],[10,"Hash",890],[10,"Hasher",890],[10,"SliceIndex",891],[5,"Script",892],[5,"Transaction",893],[5,"OutPoint",893],[5,"TxOut",893],[5,"SignedAmount",894],[10,"RangeBounds",895],[5,"BTreeSet",896],[17,"Item"],[10,"DoubleEndedIterator",897],[10,"PartialOrd",872],[5,"Amount",894],[10,"Serializer",898],[10,"Serialize",898],[5,"String",899],[10,"ExactSizeIterator",900],[5,"Txid",893],[5,"TypeId",901],[5,"IndexedTxGraph",301],[10,"Indexer",301],[17,"ChangeSet"],[5,"TxGraph",707],[10,"IntoIterator",902],[10,"Default",903],[5,"ChangeSet",707],[5,"Balance",358],[5,"KeychainTxOutIndex",358,887],[6,"InsertDescriptorError",358,887],[5,"NoSuchKeychain",358,887],[8,"Indexed",358],[8,"KeychainIndexed",358],[5,"Vec",904],[10,"Iterator",905],[5,"LocalChain",501],[5,"MissingGenesisError",501],[5,"Header",886],[5,"CannotConnectError",501],[6,"ApplyHeaderError",501],[5,"CheckPoint",501],[5,"AlterCheckPointError",501],[5,"CheckPointIter",501],[5,"SyncRequest",643],[10,"Send",906],[17,"IntoIter"],[5,"FullScanRequest",643],[10,"FnMut",907],[10,"Sync",906],[6,"Infallible",908],[17,"Output"],[6,"CalculateFeeError",707],[5,"TxNode",707],[5,"CanonicalTx",707],[5,"Arc",909],[10,"Into",908],[5,"TxAncestors",707],[5,"TxDescendants",707],[5,"HashSet",910],[15,"Confirmed",298],[15,"Unconfirmed",298],[15,"DescriptorAlreadyAssigned",497],[15,"KeychainAlreadyAssigned",497],[5,"SyncResult",643],[5,"FullScanResult",643]],"r":[[0,875],[1,875],[2,875],[3,879],[4,876],[6,889],[7,876],[8,877],[9,876],[10,876],[11,876],[14,874],[15,874],[17,876],[18,358],[19,301],[20,358],[21,879],[22,868],[23,707],[359,887],[360,887],[363,887],[366,887],[367,887]],"b":[[39,"impl-AsRef%3C%5Bu8;+%3C%24hash+as+%24crate::Hash%3E::LEN%5D%3E-for-DescriptorId"],[40,"impl-AsRef%3C%5Bu8%5D%3E-for-DescriptorId"],[131,"impl-UpperHex-for-DescriptorId"],[132,"impl-Display-for-DescriptorId"],[133,"impl-Debug-for-DescriptorId"],[134,"impl-LowerHex-for-DescriptorId"],[140,"impl-From%3C(u32,+BlockHash)%3E-for-BlockId"],[141,"impl-From%3C(%26u32,+%26BlockHash)%3E-for-BlockId"],[149,"impl-From%3CChangeSet%3CA,+ChangeSet%3CK%3E%3E%3E-for-CombinedChangeSet%3CK,+A%3E"],[150,"impl-From%3CBTreeMap%3Cu32,+Option%3CBlockHash%3E%3E%3E-for-CombinedChangeSet%3CK,+A%3E"],[151,"impl-From%3CChangeSet%3CK%3E%3E-for-CombinedChangeSet%3CK,+A%3E"],[329,"impl-From%3CChangeSet%3CK%3E%3E-for-ChangeSet%3CA,+ChangeSet%3CK%3E%3E"],[330,"impl-From%3CChangeSet%3CA%3E%3E-for-ChangeSet%3CA,+IA%3E"],[371,"impl-Indexer-for-KeychainTxOutIndex%3CK%3E"],[372,"impl-KeychainTxOutIndex%3CK%3E"],[404,"impl-Debug-for-InsertDescriptorError%3CK%3E"],[405,"impl-Display-for-InsertDescriptorError%3CK%3E"],[407,"impl-Debug-for-NoSuchKeychain%3CK%3E"],[408,"impl-Display-for-NoSuchKeychain%3CK%3E"],[409,"impl-Display-for-Balance"],[410,"impl-Debug-for-Balance"],[552,"impl-Display-for-MissingGenesisError"],[553,"impl-Debug-for-MissingGenesisError"],[554,"impl-Debug-for-AlterCheckPointError"],[555,"impl-Display-for-AlterCheckPointError"],[556,"impl-Display-for-CannotConnectError"],[557,"impl-Debug-for-CannotConnectError"],[558,"impl-Display-for-ApplyHeaderError"],[559,"impl-Debug-for-ApplyHeaderError"],[773,"impl-Debug-for-CalculateFeeError"],[774,"impl-Display-for-CalculateFeeError"]],"c":"OjAAAAAAAAA=","e":"OzAAAAEAAOcBTAATAAIAGAAAABwAAAAeAAIAJAACACgAFwBCABMAVwAGAGMAAQBmAAQAbQAFAHQAFACLAAAAjQABAJMAAACWAAIAmwAEAKEAAgClAAUArQAAAK8AAQCzAAAAvwAAAMUAAADJAAAAzgAAANMAAQDYAAYA4gAGAO4ACgD6ABQAFAEJACEBCQAyAQAAOAEAADwBCwBKAQEAWgEAAF0BCQBxAQAAdAEAAHYBEwCLARAApAECAK8BAADIAQEAywEHANYBCQDjAQQA7QEEAAUCGQAgAgUAJwIJAEECAABPAgIAVQIAAFwCEABuAg0AfQIGAIgCBwCzAgcAvAIHANICAADVAgAA2AINAOgCEQD7AgQAAwMFACIDAQAlAwAALAMBAC8DBwA6AwYAQwMGAFMDBgBbAwYA"}],\ -["bdk_coin_select",{"t":"FFGGFFPIPFGPPPFGFPPSPPPPPFNNNNOONNNNNNNNNNNNNNNNNNNNNNNNNNONNNNNNNNNNNNNNNNNHNNNONONNNNOOONNNNNNNNNNNNNNNNNNNNNNNNNNNNNNONNNNNNNNNNNNNNNONNOOOONNNNONOOOOONNNNONNNNNNOOOONNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNONNNNNNNNNNNNOOON","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","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":[[0,"bdk_coin_select"],[235,"bdk_coin_select::bnb"],[236,"core::cmp"],[237,"bdk_coin_select::coin_selector"],[238,"core::iter::traits::iterator"],[239,"core::option"],[240,"core::convert"],[241,"core::result"],[242,"core::fmt"],[243,"core::time"],[244,"bitcoin::blockdata::transaction"],[245,"core::hash"],[246,"alloc::vec"],[247,"core::marker"],[248,"alloc::string"],[249,"core::any"]],"i":[0,0,0,0,0,0,41,0,22,0,0,18,18,22,0,0,0,41,41,0,18,18,11,11,11,0,2,6,7,2,16,2,7,41,2,34,22,15,16,6,17,18,7,11,12,41,2,34,22,15,16,6,17,18,7,11,12,6,6,15,16,6,17,18,7,11,12,15,16,6,17,18,7,11,12,11,0,6,6,6,12,16,16,6,15,18,11,7,7,12,12,6,15,16,6,17,17,18,18,7,11,11,12,2,41,2,34,22,22,22,15,16,6,17,18,7,11,12,16,11,15,41,2,34,22,15,16,6,17,18,7,11,12,2,34,6,15,6,16,16,16,16,16,2,15,6,34,6,11,2,2,12,2,2,6,6,6,6,7,6,6,6,6,6,6,2,16,16,16,15,16,6,17,18,7,11,12,17,18,11,41,2,34,22,15,16,6,17,18,7,11,12,41,2,34,22,15,16,6,17,18,7,11,12,41,2,34,22,15,16,6,17,18,7,11,12,6,6,15,41,2,34,22,15,16,6,17,18,7,11,12,12,15,12,41],"f":"``````````````````````````{{{f{b{d{c}}}}c}hj}{{{f{l}}}h}{{{f{n}}{f{{A`{c}}}}}{{`{{Ad{}{{Ab{{f{c}}}}}}}}}{}}{{{f{b{d{c}}}}}hj}``{{{f{n}}}{{Aj{{f{Af}}{f{Ah}}}}}}{{{f{c}}}{{f{e}}}{}{}}00000000000{{{f{bc}}}{{f{be}}}{}{}}00000000000{{{f{l}}Al}{{f{An}}}}`{{{f{An}}}An}{{{f{B`}}}B`}{{{f{l}}}l}{{{f{Bb}}}Bb}{{{f{Bd}}}Bd}{{{f{n}}}n}{{{f{Af}}}Af}{{{f{Ah}}}Ah}{{{f{c}}{f{be}}}Bf{}{}}0000000{{{f{Af}}{f{Af}}}Bh}{{cl}{{Bj{l}}}{{Bn{Bl}}}}{{{f{l}}}C`}{{{f{l}}}Cb}{{{f{bl}}Al}h}`{{{f{B`}}}C`}`3{{{f{An}}Cd}C`}{{{f{Bd}}{f{Bd}}}h}{{{f{Af}}{f{Af}}}h}```{{{f{Ah}}}Cd}{{{f{l}}}{{Cf{nBb}}}}{{{f{An}}{f{bCh}}}Cj}{{{f{B`}}{f{bCh}}}Cj}{{{f{l}}{f{bCh}}}Cj}{{{f{Bb}}{f{bCh}}}Cj}0{{{f{Bd}}{f{bCh}}}Cj}0{{{f{n}}{f{bCh}}}Cj}{{{f{Af}}{f{bCh}}}Cj}0{{{f{Ah}}{f{bCh}}}Cj}{{{f{b{d{c}}}}h}Bfj}{cc{}}00{AlBl}1{ClBl}22222222{{{f{{A`{Cn}}}}{f{Cn}}Cb}B`}{{{f{Af}}{f{bc}}}BfD`}`{ce{}{}}00000000000{{{d{c}}{f{{Db{c}}}}}{{Dd{c}}}j}1{{{f{l}}}h}`{{{f{l}}Al}h}{{{f{B`}}}Cd}````{{l{Df{{Aj{Al{f{An}}}}}}c}{{d{c}}}j}{{DhCbh}An}{{{f{{Df{An}}}}{f{B`}}}l}{{{f{b{Dd{c}}}}}{{Bj{e}}}{jDjDl}{}}`{{{f{Af}}{f{Af}}}{{Bj{Bh}}}}`````{{{f{bl}}Al}h}{{{f{bl}}}Bf}{{{f{bl}}}{{Cf{nBb}}}}{{{f{l}}}{{`{{Ad{}{{Ab{{Aj{Al{f{An}}}}}}}}}}}}`{{{f{l}}}Dh}{{{f{l}}}Al}{{{f{l}}}C`}{{{f{l}}}{{`{{Ad{}{{Ab{Al}}}}}}}}1{{{f{l}}}Cb}````{{{f{c}}}e{}{}}0000000{{{f{c}}}Dn{}}00{c{{Cf{e}}}{}{}}00000000000000000000000{{{f{c}}}E`{}}0000000000095`{ce{}{}}00000000000```{{{f{Eb}}}h}","D":"Hh","p":[[0,"mut"],[5,"Bnb",0,235],[1,"reference"],[1,"bool"],[10,"Ord",236],[5,"CoinSelector",0,237],[5,"Selection",0,237],[1,"slice"],[17,"Item"],[10,"Iterator",238],[6,"ExcessStrategyKind",0,237],[5,"ExcessStrategy",0,237],[1,"tuple"],[1,"usize"],[5,"WeightedValue",0,237],[5,"CoinSelectorOpt",0,237],[5,"SelectionError",0,237],[6,"SelectionConstraint",0,237],[1,"unit"],[6,"Ordering",236],[6,"Option",239],[6,"BnbLimit",0,235],[10,"Into",240],[1,"i64"],[1,"u32"],[1,"f32"],[6,"Result",241],[5,"Formatter",242],[8,"Result",242],[5,"Duration",243],[5,"TxOut",244],[10,"Hasher",245],[8,"DecideStrategy",0,235],[5,"BnbIter",0,235],[5,"Vec",246],[1,"u64"],[10,"Copy",247],[10,"Display",242],[5,"String",248],[5,"TypeId",249],[6,"BranchStrategy",0,235]],"r":[[0,235],[1,235],[2,235],[3,235],[4,237],[5,237],[7,235],[9,237],[10,237],[14,237],[15,237],[16,237],[25,237],[76,235]],"b":[[95,"impl-Debug-for-SelectionError"],[96,"impl-Display-for-SelectionError"],[97,"impl-Debug-for-SelectionConstraint"],[98,"impl-Display-for-SelectionConstraint"],[100,"impl-Debug-for-ExcessStrategyKind"],[101,"impl-Display-for-ExcessStrategyKind"],[107,"impl-From%3Cusize%3E-for-BnbLimit"],[109,"impl-From%3CDuration%3E-for-BnbLimit"]],"c":"OjAAAAAAAAA=","e":"OzAAAAEAAKcAGAAAAAAAAgAAAAYAAAAJAAIADgADABcAAgAcAAEAIAAAACIAKgBQAAIAVgAEAFwACwBsAAAAbgAAAHcAAQCHAAEAigABAJIADQChAAAAowAAAKYAAACqADAA3AAMAOoAAQA="}],\ +["bdk_chain",{"t":"KKKSFSKGFFGFPPKFRFEEEFFEPPNNMNNNOOMNNNNNNENNNNNNNNNNNNNNNNNNNNNOONNNNNNNNNNNNNNNNNNNNNNNNNNNNOONNNNNONNNNNNMNNNNNNMNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNMNNNNNNNNNMNNNNNNOONNNNCONNNNNNNNNNNNNMNNNMNNONNNCCNENONNNNONNNNNNNNNNNNDNNNNNNONCNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNCNONNNNNNNNNNNNNNNNNNNNNNNNNOOOFRFKNNNMNNNNNNNNNNNNNNNNNNNNNNNOOMMOMNNNNNNNNMNNNNNNNNNNNFFSPIGPIFFNNNNNNNNNNNNNNNNNNNNNNNNNONNNNNNNNNNNNNNNNNNNNNNNONNNNNNNNNNNNNNNNNOONNNNNNNNNNNNNNNNNNNNNNNNNNNNNNONNNNNNNNNNNNNNNNNNNNNONNNNNNNOOOOFGPFIFFPFFNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNONNNNNNNNNNNNNNNNNONNNNNNNNNNNNNNNNNNNNNNONNNNNNNNNNNNNNONNNNNNNFFFFNNNNNNNNNNNOONOONNNNNNNOONNNNNNNNNOONNNNNOONNNNNNNNONNNNNNNNGFFPPFFFFNNNOONNNNNNNNNNNNNNNNNNNNNONNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNOONNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNOONNONOONNNNNNNNNNNNNNNNNN","n":["Anchor","AnchorFromBlockPosition","Append","BIP32_MAX_INDEX","BlockId","COINBASE_MATURITY","ChainOracle","ChainPosition","CombinedChangeSet","ConfirmationHeightAnchor","ConfirmationTime","ConfirmationTimeHeightAnchor","Confirmed","Confirmed","DescriptorExt","DescriptorId","Error","FullTxOut","Indexed","IndexedTxGraph","KeychainIndexed","SpkIterator","SpkTxOutIndex","TxGraph","Unconfirmed","Unconfirmed","all_spks","all_zeros","anchor_block","anchor_block","anchor_block","anchor_block","anchor_block","anchor_block","append","append","apply_changeset","as_byte_array","as_raw_hash","as_ref","as_ref","bitcoin","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","chain","chain_position","clone","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","clone_into","cloned","cmp","cmp","cmp","cmp","cmp","cmp","cmp","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","default","descriptor","descriptor_id","deserialize","deserialize","deserialize","deserialize","deserialize","deserialize","dust_value","engine","eq","eq","eq","eq","eq","eq","eq","eq","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","from","from","from","from","from_block_position","from_block_position","from_block_position","from_block_position","from_byte_array","from_engine","from_raw_hash","from_slice","from_slice_delegated","from_str","get_chain_tip","hash","hash","hash","hash","hash","hash","hash","height","index","index_of_spk","index_tx","index_txout","indexed_tx_graph","indexed_tx_graph","initial_changeset","insert_spk","into","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_empty","is_mature","is_on_coinbase","is_relevant","is_tx_relevant","is_used","keychain","local_chain","mark_used","miniscript","net_value","network","new","new_with_range","next","nth","outpoint","outpoints","outputs_in_range","partial_cmp","partial_cmp","partial_cmp","partial_cmp","partial_cmp","partial_cmp","partial_cmp","scan","scan_txout","sent_and_received","serde","serialize","serialize","serialize","serialize","serialize","serialize","spent_by","spk_at_index","spk_client","take","take","to_byte_array","to_owned","to_owned","to_owned","to_owned","to_owned","to_owned","to_owned","to_owned","to_owned","to_owned","to_raw_hash","to_string","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","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","type_id","unconfirmed","unmark_used","unused_spks","vzip","vzip","vzip","vzip","vzip","vzip","vzip","vzip","vzip","vzip","height","last_seen","time","ChangeSet","ChangeSet","IndexedTxGraph","Indexer","append","apply_block","apply_block_relevant","apply_changeset","apply_changeset","apply_update","as_ref","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","DEFAULT_LOOKAHEAD","DescriptorAlreadyAssigned","Indexed","InsertDescriptorError","KeychainAlreadyAssigned","KeychainIndexed","KeychainTxOutIndex","NoSuchKeychain","add","all_unbounded_spk_iters","append","apply_changeset","apply_changeset","borrow","borrow","borrow","borrow","borrow","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","clone","clone","clone","clone","clone","clone_into","clone_into","clone_into","clone_into","clone_into","confirmed","default","default","default","deserialize","deserialize","eq","eq","eq","eq","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","from","from","from","from","from","get_descriptor","immature","index_of_spk","index_tx","index_txout","initial_changeset","inner","insert_descriptor","into","into","into","into","into","is_empty","is_tx_relevant","is_used","keychain_outpoints","keychain_outpoints_in_range","keychains","keychains_added","last_revealed","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_owned","to_owned","to_string","to_string","to_string","total","trusted_pending","trusted_spendable","try_from","try_from","try_from","try_from","try_from","try_into","try_into","try_into","try_into","try_into","txout","txouts","txouts_in_tx","type_id","type_id","type_id","type_id","type_id","unbounded_spk_iter","unmark_used","untrusted_pending","unused_keychain_spks","unused_spks","vzip","vzip","vzip","vzip","vzip","descriptor","existing_assignment","existing_assignment","keychain","AlterCheckPointError","ApplyHeaderError","CannotConnect","CannotConnectError","ChangeSet","CheckPoint","CheckPointIter","InconsistentBlocks","LocalChain","MissingGenesisError","apply_changeset","apply_header","apply_header_connected_to","apply_update","block_id","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","disconnect_from","eq","eq","eq","eq","eq","eq","extend","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","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","insert_block","into","into","into","into","into","into","into","into_iter","into_iter","is_block_in_chain","iter","iter_checkpoints","new","next","original_hash","prev","push","range","range","tip","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_include_height","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","update_hash","vzip","vzip","vzip","vzip","vzip","vzip","vzip","FullScanRequest","FullScanResult","SyncRequest","SyncResult","borrow","borrow","borrow","borrow","borrow_mut","borrow_mut","borrow_mut","borrow_mut","chain_outpoints","chain_spks","chain_spks_for_keychain","chain_tip","chain_tip","chain_txids","chain_update","chain_update","from","from","from","from","from_chain_tip","from_chain_tip","from_keychain_txout_index","graph_update","graph_update","inspect_outpoints","inspect_spks","inspect_spks_for_all_keychains","inspect_spks_for_keychain","inspect_txids","into","into","into","into","last_active_indices","outpoints","populate_with_revealed_spks","set_outpoints","set_spks","set_spks_for_keychain","set_txids","spks","spks_by_keychain","try_from","try_from","try_from","try_from","try_into","try_into","try_into","try_into","txids","type_id","type_id","type_id","type_id","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","new","next","next","outspends","partial_cmp","partial_cmp","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":[[0,"bdk_chain"],[298,"bdk_chain::ConfirmationTime"],[301,"bdk_chain::indexed_tx_graph"],[358,"bdk_chain::keychain"],[497,"bdk_chain::keychain::InsertDescriptorError"],[501,"bdk_chain::local_chain"],[643,"bdk_chain::spk_client"],[707,"bdk_chain::tx_graph"],[868,"bdk_chain::spk_txout_index"],[869,"bitcoin::blockdata::script::owned"],[870,"alloc::collections::btree::map"],[871,"core::clone"],[872,"core::cmp"],[873,"core::fmt"],[874,"bdk_chain::descriptor_ext"],[875,"bdk_chain::tx_data_traits"],[876,"bdk_chain::chain_data"],[877,"bdk_chain::changeset"],[878,"bitcoin_hashes::sha256"],[879,"bdk_chain::spk_iter"],[880,"core::option"],[881,"miniscript::descriptor::key"],[882,"miniscript::descriptor"],[883,"core::borrow"],[884,"core::result"],[885,"serde::de"],[886,"bitcoin::blockdata::block"],[887,"bdk_chain::keychain::txout_index"],[888,"bitcoin_hashes"],[889,"bdk_chain::chain_oracle"],[890,"core::hash"],[891,"core::slice::index"],[892,"bitcoin::blockdata::script::borrowed"],[893,"bitcoin::blockdata::transaction"],[894,"bitcoin_units::amount"],[895,"core::ops::range"],[896,"alloc::collections::btree::set"],[897,"core::iter::traits::double_ended"],[898,"serde::ser"],[899,"alloc::string"],[900,"core::iter::traits::exact_size"],[901,"core::any"],[902,"core::iter::traits::collect"],[903,"core::default"],[904,"alloc::vec"],[905,"core::iter::traits::iterator"],[906,"core::marker"],[907,"core::ops::function"],[908,"core::convert"],[909,"alloc::sync"],[910,"std::collections::hash::set"]],"i":[0,0,0,0,0,0,0,0,0,0,0,0,21,22,0,0,51,0,0,0,0,0,0,0,21,22,1,8,9,10,11,12,11,12,14,16,1,8,8,8,8,0,1,21,22,10,11,12,23,8,8,24,16,1,21,22,10,11,12,23,8,24,16,16,23,1,21,22,10,11,12,23,8,24,16,1,21,22,10,11,12,23,8,24,16,21,21,22,10,11,12,23,8,11,12,9,9,21,11,12,12,1,10,11,12,16,24,31,22,10,11,12,8,16,31,8,21,22,10,11,12,23,8,16,1,21,22,10,11,12,23,8,8,8,8,16,1,21,22,22,10,10,10,11,12,23,8,8,24,16,16,16,16,47,10,11,12,8,8,8,8,8,8,51,21,22,10,11,12,8,10,10,8,1,1,1,0,16,1,1,1,21,22,10,11,12,23,8,24,16,24,51,21,22,23,14,16,23,23,1,1,1,0,0,1,0,1,16,24,24,24,24,23,1,1,21,22,10,11,12,23,8,1,1,1,0,22,10,11,12,8,16,23,1,0,14,14,8,1,21,22,10,11,12,23,8,24,16,8,8,1,21,22,10,11,12,23,8,24,16,1,21,22,10,11,12,23,8,24,16,0,1,23,1,1,1,21,22,10,11,12,23,8,24,16,22,1,1,1,21,22,10,11,12,23,8,24,16,111,112,111,0,73,0,0,44,72,72,73,72,72,72,72,72,72,72,44,72,44,44,44,72,44,44,44,72,44,72,44,44,44,72,44,72,73,73,44,73,72,72,72,72,72,72,44,44,73,72,44,44,72,44,72,44,72,44,72,44,0,0,0,81,0,0,81,0,0,0,79,80,43,80,80,80,81,43,82,79,80,81,43,82,79,80,81,43,82,79,80,81,43,82,79,79,80,43,79,43,79,81,43,82,79,80,81,81,43,82,82,79,79,80,81,43,82,79,80,79,80,80,80,80,80,80,80,81,43,82,79,43,80,80,80,80,80,43,43,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,43,79,80,80,81,43,82,79,81,82,79,79,79,79,80,81,43,82,79,80,81,43,82,79,80,80,80,80,81,43,82,79,80,80,79,80,80,80,81,43,82,79,113,113,114,114,0,0,91,0,0,0,0,91,0,0,87,87,87,87,92,94,92,87,88,93,90,91,94,92,87,88,93,90,91,92,87,88,93,90,91,92,87,88,93,90,91,87,92,87,88,93,90,91,92,92,87,88,88,93,93,90,90,91,91,94,92,87,88,93,90,91,92,87,87,87,92,87,87,92,87,87,92,92,93,87,92,87,94,92,87,88,93,90,91,94,92,87,92,87,92,94,93,92,92,92,87,87,92,87,88,93,90,91,88,93,90,91,94,92,87,88,93,90,91,90,94,92,87,88,93,90,91,94,92,87,88,93,90,91,93,94,92,87,88,93,90,91,0,0,0,0,95,115,98,116,95,115,98,116,95,95,98,95,98,95,115,116,95,115,98,116,95,98,98,115,116,95,95,98,98,95,95,115,98,116,116,95,95,95,95,98,95,95,98,95,115,98,116,95,115,98,116,95,95,115,98,116,95,115,98,116,0,0,0,103,103,0,0,0,0,75,75,78,104,78,78,75,75,75,75,75,108,109,75,104,105,103,78,108,109,75,104,105,103,78,75,105,108,108,109,109,75,104,105,78,75,104,105,78,104,105,75,78,104,78,75,75,104,105,103,78,75,75,75,75,104,105,103,103,78,108,109,75,104,105,103,78,75,75,75,75,75,75,75,75,75,75,75,108,109,75,104,105,103,78,108,109,75,78,78,104,75,75,78,75,108,109,75,104,105,78,75,104,105,78,103,75,75,75,108,109,75,104,105,103,78,75,75,108,109,75,104,105,103,78,75,104,105,75,75,104,78,78,78,108,109,75,104,105,103,78,75,108,109,75,104,105,103,78,75,75,75],"f":"``````````````````````````{{{d{{b{c}}}}}{{d{{h{cf}}}}}{jln}}{{}A`}{{{d{Ab}}}Ad}{{{d{Ad}}}Ad}{{{d{Af}}}Ad}{{{d{Ah}}}Ad}``{{{d{AjAl}}Al}An}{{{d{Aj{B`{ce}}}}{B`{ce}}}AnlAb}{{{d{Aj{b{c}}}}e}An{jln}{}}{{{d{A`}}}{{d{c}}}{}}{{{d{A`}}}{{d{Bb}}}}{{{d{A`}}}{{d{{Bf{Bd}}}}}}{{{d{A`}}}{{d{{Bh{Bd}}}}}}`{{{d{c}}}{{d{e}}}{}{}}0000000200{{{d{Ajc}}}{{d{Aje}}}{}{}}000000000``{{{d{{b{c}}}}}{{b{c}}}j}{{{d{{Bj{c}}}}}{{Bj{c}}}j}{{{d{Bl}}}Bl}>{{{d{Af}}}Af}{{{d{Ah}}}Ah}{{{d{{Bn{c}}}}}{{Bn{c}}}j}{{{d{A`}}}A`}{{{d{{C`{c}}}}}{{C`{c}}}j}{{{d{{B`{ce}}}}}{{B`{ce}}}jj}{{{d{c}}{d{Aje}}}An{}{}}000000000{{{Bj{{d{c}}}}}{{Bj{c}}}j}{{{d{{Bj{c}}}}{d{{Bj{c}}}}}Cbl}{{{d{Bl}}{d{Bl}}}Cb}{{{d{Ad}}{d{Ad}}}Cb}{{{d{Af}}{d{Af}}}Cb}{{{d{Ah}}{d{Ah}}}Cb}{{{d{{Bn{c}}}}{d{{Bn{c}}}}}Cbl}{{{d{A`}}{d{A`}}}Cb}``{{{d{Ab}}}Cd}0{{{d{{Bj{c}}}}}{{Cf{Cd}}}Ab}{{{d{Af}}}Cd}{{{d{Ah}}}Cd}`{{}{{b{c}}}{}}{{}Ad}{{}Af}{{}Ah}{{}{{B`{ce}}}{}{}}{{{d{{C`{c}}}}}{{d{c}}}{{Cl{{Cj{Ch}}}}}}{{{d{Cn}}}A`}{c{{D`{Bl}}}Db}{c{{D`{Ad}}}Db}{c{{D`{Af}}}Db}{c{{D`{Ah}}}Db}{c{{D`{A`}}}Db}{c{{D`{{B`{eg}}}}}Db{lDd}{lDd}}{{{d{Cn}}}Df}{{}c{}}{{{d{{Bj{c}}}}{d{{Bj{c}}}}}DhDj}{{{d{Bl}}{d{Bl}}}Dh}{{{d{Ad}}{d{Ad}}}Dh}{{{d{Af}}{d{Af}}}Dh}{{{d{Ah}}{d{Ah}}}Dh}{{{d{{Bn{c}}}}{d{{Bn{c}}}}}DhDj}{{{d{A`}}{d{A`}}}Dh}{{{d{{B`{ce}}}}{d{{B`{ce}}}}}DhDjDj}{{{d{{b{c}}}}{d{AjDl}}}Dnn}{{{d{{Bj{c}}}}{d{AjDl}}}Dnn}{{{d{Bl}}{d{AjDl}}}Dn}{{{d{Ad}}{d{AjDl}}}Dn}{{{d{Af}}{d{AjDl}}}Dn}{{{d{Ah}}{d{AjDl}}}Dn}{{{d{{Bn{c}}}}{d{AjDl}}}Dnn}{{{d{A`}}{d{AjDl}}}Dn}000{{{d{{B`{ce}}}}{d{AjDl}}}Dnnn}{cc{}}00{{{Bj{Ah}}}Bl}{{{Eb{CdE`}}}Ad}2{{{Eb{{d{Cd}}{d{E`}}}}}Ad}333{BbA`}44{Ed{{B`{ce}}}{}{}}{{{Eh{c{Ef{e}}}}}{{B`{ec}}}{}{}}6{{{Ef{c}}}{{B`{ce}}}{}{}}{{{d{Ej}}AdEl}En}{{{d{Ej}}AdEl}Ad}{{{d{Ej}}AdEl}Af}{{{d{Ej}}AdEl}Ah}{cA`{}}08{{{d{{Bf{Bd}}}}}{{D`{A`F`}}}}0{{{d{Fb}}}{{D`{A`c}}}{}}{{{d{{Ff{}{{Fd{c}}}}}}}{{D`{Adc}}}n}{{{d{{Bj{c}}}}{d{Aje}}}AnFhFj}{{{d{Bl}}{d{Ajc}}}AnFj}{{{d{Ad}}{d{Ajc}}}AnFj}{{{d{Af}}{d{Ajc}}}AnFj}{{{d{Ah}}{d{Ajc}}}AnFj}{{{d{A`}}{d{Ajc}}}AnFj}``{{{d{A`}}c}{{d{e}}}{{Fl{{Bf{Bd}}}}}{}}{{{d{{b{c}}}}{d{Fn}}}{{Cf{{d{c}}}}}{jln}}{{{d{Aj{b{c}}}}{d{G`}}}e{jln}{}}{{{d{Aj{b{c}}}}Gb{d{Gd}}}e{jln}{}}``{{{d{{b{c}}}}}e{jln}{}}{{{d{Aj{b{c}}}}cf}Dh{jln}}{ce{}{}}0000000000{{{d{{Ff{}{{Fd{c}}}}}}AdAd}{{D`{{Cf{Dh}}c}}}n}{{{d{{Bj{c}}}}}Dh{}}{{{d{Bl}}}Dh}{{{d{{Bn{c}}}}Cd}DhAb}{{{d{Al}}}Dh}{{{d{{B`{ce}}}}}DhlAb}2`{{{d{{b{c}}}}{d{G`}}}Dh{jln}}0{{{d{{b{c}}}}{d{c}}}Dh{jln}}``{{{d{Aj{b{c}}}}{d{c}}}Dh{jln}}`{{{d{{b{c}}}}{d{G`}}e}Gf{jln}{{Gh{c}}}}`{c{{C`{c}}}{{Cl{{Cj{Ch}}}}}}{{ce}{{C`{c}}}{{Cl{{Cj{Ch}}}}}{{Gh{Cd}}}}{{{d{Aj{C`{c}}}}}{{Cf{e}}}{{Cl{{Cj{Ch}}}}}{}}{{{d{Aj{C`{c}}}}El}{{Cf{e}}}{{Cl{{Cj{Ch}}}}}{}}`{{{d{{b{c}}}}}{{d{{Gj{{Eb{cGb}}}}}}}{jln}}{{{d{{b{c}}}}e}{{`{{Gn{}{{Gl{{Eb{{d{c}}Gb}}}}}}}}}{jln}{{Gh{c}}}}{{{d{{Bj{c}}}}{d{{Bj{c}}}}}{{Cf{Cb}}}H`}{{{d{Bl}}{d{Bl}}}{{Cf{Cb}}}}{{{d{Ad}}{d{Ad}}}{{Cf{Cb}}}}{{{d{Af}}{d{Af}}}{{Cf{Cb}}}}{{{d{Ah}}{d{Ah}}}{{Cf{Cb}}}}{{{d{{Bn{c}}}}{d{{Bn{c}}}}}{{Cf{Cb}}}H`}{{{d{A`}}{d{A`}}}{{Cf{Cb}}}}{{{d{Aj{b{c}}}}{d{G`}}}{{Gj{c}}}{jln}}{{{d{Aj{b{c}}}}Gb{d{Gd}}}{{Cf{{d{c}}}}}{jln}}{{{d{{b{c}}}}{d{G`}}e}{{Eb{HbHb}}}{jln}{{Gh{c}}}}`{{{d{Bl}}c}D`Hd}{{{d{Ad}}c}D`Hd}{{{d{Af}}c}D`Hd}{{{d{Ah}}c}D`Hd}{{{d{A`}}c}D`Hd}{{{d{{B`{ce}}}}g}D`{lHf}{lHf}Hd}`{{{d{{b{c}}}}{d{c}}}{{Cf{{d{Fn}}}}}{jln}}`{{{d{AjAl}}}{{Cf{Al}}}}0{A`c{}}{{{d{c}}}e{}{}}000000000{A`Bb}{{{d{c}}}Hh{}}{c{{D`{e}}}{}{}}0000000000000000000`{{{d{{b{c}}}}Gb}{{Cf{{Eb{{d{c}}{d{Gd}}}}}}}{jln}}`{{{d{{b{c}}}}}{{`{{Gn{}{{Gl{{Eb{{d{c}}Gb{d{Gd}}}}}}}}Hj}}}{jln}}{{{d{{b{c}}}}Hl}{{`{{Gn{}{{Gl{{Eb{{d{c}}Gb{d{Gd}}}}}}}}}}}{jln}}{{{d{c}}}Hn{}}000000000{DfBl}{{{d{Aj{b{c}}}}{d{c}}}Dh{jln}}{{{d{{b{c}}}}e}{{`{{Gn{}{{Gl{{Eb{{d{c}}{d{Fn}}}}}}}}j}}}{jln}{{Gh{c}}}}{ce{}{}}000000000```````{{{d{Aj{Eh{ce}}}}{Eh{ce}}}AnAbAl}{{{d{Aj{I`{ce}}}}EjCd}{{Eh{c}}}{EnAb}Ib}{{{d{Aj{I`{ce}}}}{d{Ej}}Cd}{{Eh{c}}}{EnAb}Ib}{{{d{Aj{Ib{}{{Id{c}}}}}}c}An{}}{{{d{Aj{I`{ce}}}}{Eh{c}}}AnAbIb}{{{d{Aj{I`{ce}}}}{If{c}}}{{Eh{c}}}AbIb}{{{d{{I`{ce}}}}}{{d{{If{c}}}}}{}{}}{{{d{Aj{I`{ce}}}}i}{{Eh{c}}}AbIb{{Ih{}{{Gl{c}}}}}{{Ih{}{{Gl{{Eb{{d{G`}}g}}}}}}}}{{{d{Aj{I`{ce}}}}g}{{Eh{c}}}AbIb{{Ih{}{{Gl{{Eb{{d{G`}}Df}}}}}}}}{{{d{Aj{I`{ce}}}}g}{{Eh{c}}}AbIb{{Ih{}{{Gl{{Eb{G`Df}}}}}}}}{{{d{c}}}{{d{e}}}{}{}}0{{{d{Ajc}}}{{d{Aje}}}{}{}}0{{{d{{Eh{ce}}}}}{{Eh{ce}}}jj}{{{d{c}}{d{Aje}}}An{}{}}{{}{{I`{ce}}}{}Ij}{{}{{Eh{ce}}}{}Ij}{c{{D`{{Eh{eg}}}}}Db{lDd}Dd}{{{d{{Eh{ce}}}}{d{{Eh{ce}}}}}DhDjDj}{{{d{{I`{ce}}}}{d{AjDl}}}Dnnn}{{{d{{Eh{ce}}}}{d{AjDl}}}Dnnn}{cc{}}{{{Ef{c}}}{{Eh{e{Ef{c}}}}}{}{}}1{{{Il{c}}}{{Eh{ce}}}{}Ij}{{{d{{I`{ce}}}}}{{d{{If{c}}}}}{}{}}``{{{d{Aj{Ib{}{{Id{c}}}}}}{d{G`}}}c{}}{{{d{Aj{Ib{}{{Id{c}}}}}}Gb{d{Gd}}}c{}}`{{{d{{Ib{}{{Id{c}}}}}}}c{}}{{{d{{I`{ce}}}}}{{Eh{c}}}AbIb}{{{d{Aj{I`{ce}}}}Hlc}{{Eh{c}}}AbIb}{{{d{Aj{I`{ce}}}}HlDf}{{Eh{c}}}AbIb}{{{d{Aj{I`{ce}}}}G`}{{Eh{c}}}AbIb}{{{d{Aj{I`{ce}}}}GbGd}{{Eh{c}}}AbIb}{ce{}{}}0{{{d{{Eh{ce}}}}}DhAbAl}{{{d{{Ib{}{{Id{c}}}}}}{d{G`}}}Dh{}}{c{{I`{ec}}}{}{}}{{{d{{Eh{ce}}}}g}D`{lHf}HfHd}{{{d{c}}}e{}{}}{c{{D`{e}}}{}{}}000{{{d{c}}}Hn{}}077``````````{{InIn}In}{{{d{{J`{c}}}}}{{h{c{C`{{Cj{Ch}}}}}}}{jln}}{{{d{Aj{Ef{c}}}}{Ef{c}}}Anl}{{{d{Aj{J`{c}}}}e}An{jln}{}}{{{d{Aj{J`{c}}}}{Ef{c}}}An{jln}}{{{d{c}}}{{d{e}}}{}{}}0000{{{d{Ajc}}}{{d{Aje}}}{}{}}0000{{{d{{J`{c}}}}}{{J`{c}}}j}{{{d{{Jb{c}}}}}{{Jb{c}}}j}{{{d{{Ef{c}}}}}{{Ef{c}}}j}{{{d{{Jd{c}}}}}{{Jd{c}}}j}{{{d{In}}}In}{{{d{c}}{d{Aje}}}An{}{}}0000`{{}{{J`{c}}}{}}{{}{{Ef{c}}}{}}{{}In}{c{{D`{{Ef{e}}}}}Db{lDd}}{c{{D`{In}}}Db}{{{d{{Jb{c}}}}{d{{Jb{c}}}}}DhDj}{{{d{{Ef{c}}}}{d{{Ef{c}}}}}DhDj}{{{d{{Jd{c}}}}{d{{Jd{c}}}}}DhDj}{{{d{In}}{d{In}}}Dh}{{{d{{J`{c}}}}{d{AjDl}}}Dnn}{{{d{{Jb{c}}}}{d{AjDl}}}Dnn}0{{{d{{Ef{c}}}}{d{AjDl}}}Dnn}{{{d{{Jd{c}}}}{d{AjDl}}}Dnn}0{{{d{In}}{d{AjDl}}}Dn}0{cc{}}0000{{{d{{J`{c}}}}{d{c}}}{{Cf{{d{{Cj{Ch}}}}}}}{jln}}`{{{d{{J`{c}}}}{d{Fn}}}{{Cf{{d{{Eb{cCd}}}}}}}{jln}}{{{d{Aj{J`{c}}}}{d{G`}}}e{jln}{}}{{{d{Aj{J`{c}}}}Gb{d{Gd}}}e{jln}{}}{{{d{{J`{c}}}}}e{jln}{}}{{{d{{J`{c}}}}}{{d{{b{{Eb{cCd}}}}}}}{jln}}{{{d{Aj{J`{c}}}}c{Cj{Ch}}}{{D`{{Ef{c}}{Jb{c}}}}}{jln}}{ce{}{}}0000{{{d{{Ef{c}}}}}Dhl}{{{d{{J`{c}}}}{d{G`}}}Dh{jln}}{{{d{{J`{c}}}}cCd}Dh{jln}}{{{d{{J`{c}}}}{d{c}}}{{`{{Gn{}{{Gl{{Jf{Gb}}}}}}}}}{jln}}{{{d{{J`{c}}}}e}{{`{{Gn{}{{Gl{{Jh{cGb}}}}}}}}}{jln}{{Gh{c}}}}{{{d{{J`{c}}}}}{{`{{Gn{}{{Gl{{Eb{{d{c}}{d{{Cj{Ch}}}}}}}}}}Hj}}}{jln}}``{{{d{{J`{c}}}}{d{c}}}{{Cf{Cd}}}{jln}}{{{d{{J`{c}}}}}{{h{cCd}}}{jln}}10{{{d{{J`{c}}}}}Cd{jln}}{{{d{Aj{J`{c}}}}{d{c}}Cd}An{jln}}{{{d{Aj{J`{c}}}}cCd}Dh{jln}}{{{d{{J`{c}}}}{d{G`}}e}Gf{jln}{{Gh{c}}}}{Cd{{J`{c}}}{}}{{{d{{J`{c}}}}{d{c}}}{{Cf{{Eb{CdDh}}}}}{jln}}{{{d{Aj{J`{c}}}}{d{c}}}{{Cf{{Eb{{Jf{f}}{Ef{c}}}}}}}{jln}}{{{d{{J`{c}}}}}{{d{{Gj{{Jh{cGb}}}}}}}{jln}}1{{{d{Aj{J`{c}}}}{d{c}}Cd}{{Cf{{Eb{{Jj{{Jf{f}}}}{Ef{c}}}}}}}{jln}}{{{d{Aj{J`{c}}}}{d{{h{cCd}}}}}{{Ef{c}}}{jln}}{{{d{{J`{c}}}}{d{c}}}{{`{{Gn{}{{Gl{{Jf{{d{Fn}}}}}}}}}}}{jln}}{{{d{{J`{c}}}}e}{{`{{Jl{}{{Gl{{Jh{c{d{Fn}}}}}}}}}}}{jln}{{Gh{c}}}}{{{d{{J`{c}}}}{d{G`}}e}{{Eb{HbHb}}}{jln}{{Gh{c}}}}{{{d{{Ef{c}}}}e}D`{lHf}Hd}{{{d{In}}c}D`Hd}{{{d{{J`{c}}}}cCd}{{Cf{{d{Fn}}}}}{jln}}{{{d{c}}}e{}{}}0000{{{d{c}}}Hh{}}00{{{d{In}}}Hb}`0{c{{D`{e}}}{}{}}000000000{{{d{{J`{c}}}}Gb}{{Cf{{Jh{c{d{Gd}}}}}}}{jln}}{{{d{{J`{c}}}}}{{`{{Gn{}{{Gl{{Jh{c{Eb{Gb{d{Gd}}}}}}}}}}Hj}}}{jln}}{{{d{{J`{c}}}}Hl}{{`{{Gn{}{{Gl{{Jh{c{Eb{Gb{d{Gd}}}}}}}}}}}}}{jln}}{{{d{c}}}Hn{}}0000{{{d{{J`{c}}}}{d{c}}}{{Cf{{C`{{Cj{Ch}}}}}}}{jln}}{{{d{Aj{J`{c}}}}cCd}Dh{jln}}`{{{d{{J`{c}}}}{d{c}}}{{`{{Gn{}{{Gl{{Jf{{d{Fn}}}}}}}}j}}}{jln}}{{{d{{J`{c}}}}}{{`{{Gn{}{{Gl{{Jh{c{d{Fn}}}}}}}}j}}}{jln}}{ce{}{}}0000``````````````{{{d{AjJn}}{d{Ed}}}{{D`{AnK`}}}}{{{d{AjJn}}{d{Kb}}Cd}{{D`{EdKd}}}}{{{d{AjJn}}{d{Kb}}CdAd}{{D`{EdKf}}}}{{{d{AjJn}}Kh}{{D`{EdKd}}}}{{{d{Kh}}}Ad}{{{d{c}}}{{d{e}}}{}{}}000000{{{d{Ajc}}}{{d{Aje}}}{}{}}000000{{{d{Kh}}}Kh}{{{d{Jn}}}Jn}{{{d{K`}}}K`}{{{d{Kj}}}Kj}{{{d{Kd}}}Kd}{{{d{Kf}}}Kf}{{{d{c}}{d{Aje}}}An{}{}}00000{{{d{AjJn}}Ad}{{D`{EdK`}}}}{{{d{Kh}}{d{Kh}}}Dh}{{{d{Jn}}{d{Jn}}}Dh}{{{d{K`}}{d{K`}}}Dh}{{{d{Kj}}{d{Kj}}}Dh}{{{d{Kd}}{d{Kd}}}Dh}{{{d{Kf}}{d{Kf}}}Dh}{{Khc}{{D`{KhKh}}}{{Ih{}{{Gl{Ad}}}}}}{{{d{Kh}}{d{AjDl}}}Dn}{{{d{Jn}}{d{AjDl}}}Dn}{{{d{K`}}{d{AjDl}}}Dn}0{{{d{Kj}}{d{AjDl}}}Dn}0{{{d{Kd}}{d{AjDl}}}Dn}0{{{d{Kf}}{d{AjDl}}}Dn}0{cc{}}000000{c{{D`{Kh{Cf{Kh}}}}}{{Ih{}{{Gl{Ad}}}}}}{{{h{CdE`}}}{{D`{JnK`}}}}{Ed{{D`{JnK`}}}}{E`{{Eb{JnEd}}}}{{{d{Kb}}Cd}Kh}{Kh{{D`{JnK`}}}}{{{d{Jn}}}E`}{{{d{Kh}}Cd}{{Cf{Kh}}}}{{{d{Jn}}Cd}{{Cf{Kh}}}}{{{d{Jn}}}{{D`{Adc}}}{}}{{{d{Kh}}}E`}{{{d{Kh}}}Cd}`{{{d{Jn}}}Ed}{{KhAd}Kh}{{{d{AjJn}}Ad}{{D`{EdKj}}}}{ce{}{}}0000000{Khc{}}{{{d{Jn}}AdAd}{{D`{{Cf{Dh}}c}}}{}}{{{d{Kh}}}Kl}{{{d{Jn}}}Kl}{AdKh}{{{d{AjKl}}}{{Cf{c}}}{}}`{{{d{Kh}}}{{Cf{Kh}}}}{{KhAd}{{D`{KhKh}}}}{{{d{Kh}}c}{{`{{Jl{}{{Gl{Kh}}}}}}}{{Gh{Cd}}}}{{{d{Jn}}c}{{`{{Jl{}{{Gl{Kh}}}}}}}{{Gh{Cd}}}}{{{d{Jn}}}Kh}{{{d{c}}}e{}{}}00000{{{d{c}}}Hh{}}000{c{{D`{e}}}{}{}}000000`0000000{{{d{c}}}Hn{}}000000`???????````{{{d{c}}}{{d{e}}}{}{}}000{{{d{Ajc}}}{{d{Aje}}}{}{}}000{{Kne}Kn{{Hj{}{{Gl{Gb}}}}L`}{{Ih{}{{Lb{c}}{Gl{Gb}}}}}}{{Kne}Kn{{Hj{}{{Gl{f}}}}L`}{{Ih{}{{Lb{c}}{Gl{f}}}}}}{{{Ld{c}}cg}{{Ld{c}}}{lj}{{Jl{}{{Gl{{Jf{f}}}}}}L`}{{Ih{}{{Lb{e}}}}}}``{{Kne}Kn{{Hj{}{{Gl{Hl}}}}L`}{{Ih{}{{Lb{c}}{Gl{Hl}}}}}}``{cc{}}000{KhKn}{Kh{{Ld{c}}}{lj}}{{Kh{d{{J`{c}}}}}{{Ld{c}}}{nlj}}``{{Knc}Kn{{Lf{{d{Gb}}}}L`Lh}}{{Knc}Kn{{Lf{{d{Fn}}}}L`Lh}}{{{Ld{c}}e}{{Ld{c}}}{L`lj}{{Lf{cCd{d{Fn}}}}L`Lhj}}{{{Ld{c}}ce}{{Ld{c}}}{L`lj}{{Lf{Cd{d{Fn}}}}L`Lh}}{{Knc}Kn{{Lf{{d{Hl}}}}L`Lh}}{ce{}{}}000``{{Kn{d{{J`{c}}}}e}Kn{jlnL`Lh}{{Gh{c}}}}{{Kne}Kn{{Hj{}{{Gl{Gb}}}}L`}{{Ih{}{{Lb{c}}}}}}{{Kne}Kn{{Hj{}{{Gl{f}}}}L`}{{Ih{}{{Lb{c}}}}}}>{{Kne}Kn{{Hj{}{{Gl{Hl}}}}L`}{{Ih{}{{Lb{c}}}}}}``{c{{D`{e}}}{}{}}0000000`{{{d{c}}}Hn{}}0006666`````````{{{d{{If{c}}}}}{{d{{Gj{{Eb{cHl}}}}}}}{}}{{{d{{If{c}}}}}{{`{{Jl{}{{Gl{{Eb{Gb{d{Gd}}}}}}}}}}}{}}{{{d{{Il{c}}}}}{{`{{Jl{}{{Gl{Cd}}}}}}}Ab}``{{{d{Aj{Il{c}}}}{Il{c}}}Anl}{{{d{Aj{If{c}}}}{Il{c}}}An{jl}}{{{d{Aj{If{c}}}}{If{c}}}{{Il{c}}}{jl}}{{{d{{If{c}}}}}{{d{{If{c}}}}}{}}{{{d{{If{c}}}}{d{e}}Adik}InAb{{Ff{}{{Fd{Lj}}}}}j{{Ih{}{{Gl{{Eb{gGb}}}}}}}{{Lf{{d{g}}{d{Fn}}}{{Ll{Dh}}}}}}{{{d{Aj{If{c}}}}e}{{Il{c}}}{jl}{{Ih{}{{Gl{{Eb{G`Df}}}}}}}}{{{d{c}}}{{d{e}}}{}{}}000000{{{d{Ajc}}}{{d{Aje}}}{}{}}000000{{{d{{If{c}}}}{d{G`}}}{{D`{HbLn}}}{}}`{c{{Cf{Hb}}}{}}{c{{Cf{Gf}}}{}}10{{{d{{If{c}}}}}{{If{c}}}j}{{{d{{M`{ce}}}}}{{M`{ce}}}jj}{{{d{{Mb{ce}}}}}{{Mb{ce}}}jj}{{{d{{Il{c}}}}}{{Il{c}}}j}{{{d{c}}{d{Aje}}}An{}{}}000{{{d{{M`{ce}}}}{d{{M`{ce}}}}}Cbll}{{{d{{Mb{ce}}}}{d{{Mb{ce}}}}}Cbll}{{}{{If{c}}}{}}{{}{{Il{c}}}{}}{{{d{{M`{ce}}}}}{{d{g}}}{}{}{}}{c{{D`{{Il{e}}}}}Db{lDd}}{{{d{{If{c}}}}{d{G`}}}{{`{{Jl{}{{Gl{{Eb{ElHl}}}}}}}}}{}}{{{d{{If{c}}}}{d{{If{c}}}}}DhDj}{{{d{{M`{ce}}}}{d{{M`{ce}}}}}DhDjDj}{{{d{{Mb{ce}}}}{d{{Mb{ce}}}}}DhDjDj}{{{d{Ln}}{d{Ln}}}Dh}{{{d{{Il{c}}}}{d{{Il{c}}}}}DhDj}{{{d{{If{c}}}}{d{e}}Adi}{{`{{Jl{}{{Gl{{Eb{g{Bn{c}}}}}}}}}}}Ab{{Ff{}{{Fd{Lj}}}}}j{{Ih{}{{Gl{{Eb{gGb}}}}}}}}0{{{d{{If{c}}}}}{{`{{Jl{}{{Gl{{Eb{Gb{d{Gd}}}}}}}}}}}{}}{{{d{{If{c}}}}{d{AjDl}}}Dnn}{{{d{{M`{ce}}}}{d{AjDl}}}Dnnn}{{{d{{Mb{ce}}}}{d{AjDl}}}Dnnn}{{{d{Ln}}{d{AjDl}}}Dn}0{{{d{{Il{c}}}}{d{AjDl}}}Dnn}{cc{}}000000{{{d{{If{c}}}}}{{`{{Jl{}{{Gl{{M`{{Md{G`}}c}}}}}}}}}{}}{{{d{{If{c}}}}{d{e}}AdHl}{{Cf{{Bj{{d{c}}}}}}}Ab{{Ff{}{{Fd{Lj}}}}}}{{{d{{If{c}}}}{d{e}}AdGb}{{Cf{{Eb{{Bj{{d{c}}}}Hl}}}}}Ab{{Ff{}{{Fd{Lj}}}}}}{{{d{{If{c}}}}Hl}{{Cf{{Md{G`}}}}}{}}{{{d{{If{c}}}}Hl}{{Cf{{M`{{Md{G`}}c}}}}}{}}{{{d{{If{c}}}}Gb}{{Cf{{d{Gd}}}}}{}}{{{d{{If{c}}}}}{{Il{c}}}{jl}}{{{d{Aj{If{c}}}}Hlc}{{Il{c}}}{jl}}{{{d{Aj{If{c}}}}HlDf}{{Il{c}}}{jl}}{{{d{Aj{If{c}}}}e}{{Il{c}}}{jl}{{Mf{{Md{G`}}}}}}{{{d{Aj{If{c}}}}GbGd}{{Il{c}}}{jl}}{ce{}{}}00000000{{{d{{If{c}}}}}Dh{}}{{{d{{Il{c}}}}}Dhl}``{{{d{{If{c}}}}{d{e}}Ad}{{`{{Jl{}{{Gl{{Mb{{Md{G`}}c}}}}}}}}}AbFf}{{{If{c}}g}{{If{e}}}{jl}{jl}{{Lf{c}{{Ll{e}}}}}}{{{Il{c}}g}{{Il{e}}}ll{{Lf{c}{{Ll{e}}}}}}{c{{If{e}}}{{Ih{}{{Gl{G`}}}}}{jl}}{{{d{Aj{Mh{cg}}}}}{{Cf{i}}}{}{}{{Lf{El{Md{G`}}}{{Ll{{Cf{e}}}}}}}{}}{{{d{Aj{Mj{cg}}}}}{{Cf{i}}}{}{}{{Lf{ElHl}{{Ll{{Cf{e}}}}}}}{}}{{{d{{If{c}}}}Gb}{{d{{Ml{Hl}}}}}{}}{{{d{{M`{ce}}}}{d{{M`{ce}}}}}{{Cf{Cb}}}H`H`}{{{d{{Mb{ce}}}}{d{{Mb{ce}}}}}{{Cf{Cb}}}H`H`}{{{d{{Il{c}}}}e}D`{lHf}Hd}{{{d{c}}}e{}{}}000{{{d{c}}}Hh{}}{{{d{{If{c}}}}{d{e}}Adik}{{D`{In}}}AbFfj{{Ih{}{{Gl{{Eb{gGb}}}}}}}{{Lf{{d{g}}{d{Fn}}}{{Ll{Dh}}}}}}{{{d{{If{c}}}}{d{e}}Adi}{{`{{Jl{}{{Gl{{D`{{Eb{g{Bn{c}}}}}}}}}}}}}AbFfj{{Ih{}{{Gl{{Eb{gGb}}}}}}}}0{c{{D`{e}}}{}{}}000000{{{d{{If{c}}}}{d{e}}AdHl}{{D`{{Cf{{Bj{{d{c}}}}}}}}}AbFf}{{{d{{If{c}}}}{d{e}}AdGb}{{D`{{Cf{{Eb{{Bj{{d{c}}}}Hl}}}}}}}AbFf}2222222{{{d{{If{c}}}}{d{e}}Ad}{{`{{Jl{}{{Gl{{D`{{Mb{{Md{G`}}c}}}}}}}}}}}AbFf}``{{{d{{If{c}}}}Hl}{{Cf{{h{Cd{d{Gd}}}}}}}{}}{{{d{{If{c}}}}Hl}{{`{{Gn{}{{Gl{{Eb{Cd{d{{Ml{Hl}}}}}}}}}}}}}{}}`{{{d{{Il{c}}}}}{{`{{Jl{}{{Gl{{Eb{Gb{d{Gd}}}}}}}}}}}{}}``{{{d{c}}}Hn{}}000000{{{d{Aj{If{c}}}}Df}{{Il{c}}}{jl}}{ce{}{}}000000{{{d{{If{c}}}}ei}{{Mh{ci}}}{jl}{{Mf{{Md{G`}}}}}{}{{Lf{El{Md{G`}}}{{Ll{{Cf{g}}}}}}}}{{{d{{If{c}}}}{d{G`}}g}{{Mj{cg}}}{}{}{{Lf{ElHl}{{Ll{{Cf{e}}}}}}}}{{{d{{If{c}}}}Hlg}{{Mj{cg}}}{jl}{}{{Lf{ElHl}{{Ll{{Cf{e}}}}}}}}","D":"BOj","p":[[5,"SpkTxOutIndex",0,868],[1,"reference"],[5,"ScriptBuf",869],[5,"BTreeMap",870],[10,"Clone",871],[10,"Ord",872],[10,"Debug",873],[5,"DescriptorId",0,874],[10,"Anchor",0,875],[5,"BlockId",0,876],[5,"ConfirmationHeightAnchor",0,876],[5,"ConfirmationTimeHeightAnchor",0,876],[0,"mut"],[10,"Append",0,875],[1,"unit"],[5,"CombinedChangeSet",0,877],[5,"Hash",878],[1,"u8"],[1,"slice"],[1,"array"],[6,"ChainPosition",0,876],[6,"ConfirmationTime",0,876],[5,"FullTxOut",0,876],[5,"SpkIterator",0,879],[6,"Ordering",872],[1,"u32"],[6,"Option",880],[6,"DescriptorPublicKey",881],[6,"Descriptor",882],[10,"Borrow",883],[10,"DescriptorExt",0,874],[6,"Result",884],[10,"Deserializer",885],[10,"Deserialize",885],[1,"u64"],[1,"bool"],[10,"PartialEq",872],[5,"Formatter",873],[8,"Result",873],[5,"BlockHash",886],[1,"tuple"],[8,"ChangeSet",501],[5,"ChangeSet",358,887],[5,"ChangeSet",301],[5,"Block",886],[1,"usize"],[10,"AnchorFromBlockPosition",0,875],[5,"FromSliceError",888],[1,"str"],[17,"Error"],[10,"ChainOracle",0,889],[10,"Hash",890],[10,"Hasher",890],[10,"SliceIndex",891],[5,"Script",892],[5,"Transaction",893],[5,"OutPoint",893],[5,"TxOut",893],[5,"SignedAmount",894],[10,"RangeBounds",895],[5,"BTreeSet",896],[17,"Item"],[10,"DoubleEndedIterator",897],[10,"PartialOrd",872],[5,"Amount",894],[10,"Serializer",898],[10,"Serialize",898],[5,"String",899],[10,"ExactSizeIterator",900],[5,"Txid",893],[5,"TypeId",901],[5,"IndexedTxGraph",301],[10,"Indexer",301],[17,"ChangeSet"],[5,"TxGraph",707],[10,"IntoIterator",902],[10,"Default",903],[5,"ChangeSet",707],[5,"Balance",358],[5,"KeychainTxOutIndex",358,887],[6,"InsertDescriptorError",358,887],[5,"NoSuchKeychain",358,887],[8,"Indexed",358],[8,"KeychainIndexed",358],[5,"Vec",904],[10,"Iterator",905],[5,"LocalChain",501],[5,"MissingGenesisError",501],[5,"Header",886],[5,"CannotConnectError",501],[6,"ApplyHeaderError",501],[5,"CheckPoint",501],[5,"AlterCheckPointError",501],[5,"CheckPointIter",501],[5,"SyncRequest",643],[10,"Send",906],[17,"IntoIter"],[5,"FullScanRequest",643],[10,"FnMut",907],[10,"Sync",906],[6,"Infallible",908],[17,"Output"],[6,"CalculateFeeError",707],[5,"TxNode",707],[5,"CanonicalTx",707],[5,"Arc",909],[10,"Into",908],[5,"TxAncestors",707],[5,"TxDescendants",707],[5,"HashSet",910],[15,"Confirmed",298],[15,"Unconfirmed",298],[15,"DescriptorAlreadyAssigned",497],[15,"KeychainAlreadyAssigned",497],[5,"SyncResult",643],[5,"FullScanResult",643]],"r":[[0,875],[1,875],[2,875],[3,879],[4,876],[6,889],[7,876],[8,877],[9,876],[10,876],[11,876],[14,874],[15,874],[17,876],[18,358],[19,301],[20,358],[21,879],[22,868],[23,707],[359,887],[360,887],[363,887],[366,887],[367,887]],"b":[[39,"impl-AsRef%3C%5Bu8%5D%3E-for-DescriptorId"],[40,"impl-AsRef%3C%5Bu8;+%3C%24hash+as+%24crate::Hash%3E::LEN%5D%3E-for-DescriptorId"],[131,"impl-UpperHex-for-DescriptorId"],[132,"impl-Debug-for-DescriptorId"],[133,"impl-LowerHex-for-DescriptorId"],[134,"impl-Display-for-DescriptorId"],[140,"impl-From%3C(u32,+BlockHash)%3E-for-BlockId"],[142,"impl-From%3C(%26u32,+%26BlockHash)%3E-for-BlockId"],[149,"impl-From%3CBTreeMap%3Cu32,+Option%3CBlockHash%3E%3E%3E-for-CombinedChangeSet%3CK,+A%3E"],[150,"impl-From%3CChangeSet%3CA,+ChangeSet%3CK%3E%3E%3E-for-CombinedChangeSet%3CK,+A%3E"],[152,"impl-From%3CChangeSet%3CK%3E%3E-for-CombinedChangeSet%3CK,+A%3E"],[328,"impl-From%3CChangeSet%3CK%3E%3E-for-ChangeSet%3CA,+ChangeSet%3CK%3E%3E"],[330,"impl-From%3CChangeSet%3CA%3E%3E-for-ChangeSet%3CA,+IA%3E"],[371,"impl-Indexer-for-KeychainTxOutIndex%3CK%3E"],[372,"impl-KeychainTxOutIndex%3CK%3E"],[404,"impl-Display-for-InsertDescriptorError%3CK%3E"],[405,"impl-Debug-for-InsertDescriptorError%3CK%3E"],[407,"impl-Display-for-NoSuchKeychain%3CK%3E"],[408,"impl-Debug-for-NoSuchKeychain%3CK%3E"],[409,"impl-Debug-for-Balance"],[410,"impl-Display-for-Balance"],[552,"impl-Debug-for-MissingGenesisError"],[553,"impl-Display-for-MissingGenesisError"],[554,"impl-Display-for-AlterCheckPointError"],[555,"impl-Debug-for-AlterCheckPointError"],[556,"impl-Debug-for-CannotConnectError"],[557,"impl-Display-for-CannotConnectError"],[558,"impl-Display-for-ApplyHeaderError"],[559,"impl-Debug-for-ApplyHeaderError"],[773,"impl-Display-for-CalculateFeeError"],[774,"impl-Debug-for-CalculateFeeError"]],"c":"OjAAAAAAAAA=","e":"OzAAAAEAAOcBTgATAAIAGAAAABwAAAAeAAIAJAACACgAFwBCABMAVwAGAGMAAQBmAAQAbQAFAHQAFACMAAEAjwAAAJMAAACWAAEAmQAAAJsABAChAAIApQAFAK0AAACvAAEAswAAAL8AAADFAAAAyQAAAM4AAADTAAEA2AAGAOIABgDuAAoA+gAUABQBCQAhAQkAMgEAADgBAAA8AQsASQEAAEsBAABaAQAAXQEJAHEBAAB0AQAAdgETAIsBEACkAQIArwEAAMgBAQDLAQcA1gEJAOMBBADtAQQABQIZACACBQAnAgkAQQIAAE8CAgBVAgAAXAIQAG4CDQB9AgYAiAIHALMCBwC8AgcA0gIAANUCAADYAg0A6AIRAPsCBAADAwUAIgMBACUDAAAsAwEALwMHADoDBgBDAwYAUwMGAFsDBgA="}],\ +["bdk_coin_select",{"t":"FFGGFFPIPFGPPPFGFPPSPPPPPFNNNNOONNNNNNNNNNNNNNNNNNNNNNNNNNONNNNNNNNNNNNNNNNNHNNNONONNNNOOONNNNNNNNNNNNNNNNNNNNNNNNNNNNNNONNNNNNNNNNNNNNNONNOOOONNNNONOOOOONNNNONNNNNNOOOONNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNONNNNNNNNNNNNOOON","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","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":[[0,"bdk_coin_select"],[235,"bdk_coin_select::bnb"],[236,"core::cmp"],[237,"bdk_coin_select::coin_selector"],[238,"core::iter::traits::iterator"],[239,"core::option"],[240,"core::convert"],[241,"core::result"],[242,"core::fmt"],[243,"core::time"],[244,"bitcoin::blockdata::transaction"],[245,"core::hash"],[246,"alloc::vec"],[247,"core::marker"],[248,"alloc::string"],[249,"core::any"]],"i":[0,0,0,0,0,0,41,0,22,0,0,18,18,22,0,0,0,41,41,0,18,18,11,11,11,0,2,6,7,2,16,2,7,41,2,34,22,15,16,6,17,18,7,11,12,41,2,34,22,15,16,6,17,18,7,11,12,6,6,15,16,6,17,18,7,11,12,15,16,6,17,18,7,11,12,11,0,6,6,6,12,16,16,6,15,18,11,7,7,12,12,6,15,16,6,17,17,18,18,7,11,11,12,2,41,2,34,22,22,22,15,16,6,17,18,7,11,12,16,11,15,41,2,34,22,15,16,6,17,18,7,11,12,2,34,6,15,6,16,16,16,16,16,2,15,6,34,6,11,2,2,12,2,2,6,6,6,6,7,6,6,6,6,6,6,2,16,16,16,15,16,6,17,18,7,11,12,17,18,11,41,2,34,22,15,16,6,17,18,7,11,12,41,2,34,22,15,16,6,17,18,7,11,12,41,2,34,22,15,16,6,17,18,7,11,12,6,6,15,41,2,34,22,15,16,6,17,18,7,11,12,12,15,12,41],"f":"``````````````````````````{{{f{b{d{c}}}}c}hj}{{{f{l}}}h}{{{f{n}}{f{{A`{c}}}}}{{`{{Ad{}{{Ab{{f{c}}}}}}}}}{}}{{{f{b{d{c}}}}}hj}``{{{f{n}}}{{Aj{{f{Af}}{f{Ah}}}}}}{{{f{c}}}{{f{e}}}{}{}}00000000000{{{f{bc}}}{{f{be}}}{}{}}00000000000{{{f{l}}Al}{{f{An}}}}`{{{f{An}}}An}{{{f{B`}}}B`}{{{f{l}}}l}{{{f{Bb}}}Bb}{{{f{Bd}}}Bd}{{{f{n}}}n}{{{f{Af}}}Af}{{{f{Ah}}}Ah}{{{f{c}}{f{be}}}Bf{}{}}0000000{{{f{Af}}{f{Af}}}Bh}{{cl}{{Bj{l}}}{{Bn{Bl}}}}{{{f{l}}}C`}{{{f{l}}}Cb}{{{f{bl}}Al}h}`{{{f{B`}}}C`}`3{{{f{An}}Cd}C`}{{{f{Bd}}{f{Bd}}}h}{{{f{Af}}{f{Af}}}h}```{{{f{Ah}}}Cd}{{{f{l}}}{{Cf{nBb}}}}{{{f{An}}{f{bCh}}}Cj}{{{f{B`}}{f{bCh}}}Cj}{{{f{l}}{f{bCh}}}Cj}{{{f{Bb}}{f{bCh}}}Cj}0{{{f{Bd}}{f{bCh}}}Cj}0{{{f{n}}{f{bCh}}}Cj}{{{f{Af}}{f{bCh}}}Cj}0{{{f{Ah}}{f{bCh}}}Cj}{{{f{b{d{c}}}}h}Bfj}{cc{}}00{ClBl}{AlBl}222222222{{{f{{A`{Cn}}}}{f{Cn}}Cb}B`}{{{f{Af}}{f{bc}}}BfD`}`{ce{}{}}00000000000{{{d{c}}{f{{Db{c}}}}}{{Dd{c}}}j}1{{{f{l}}}h}`{{{f{l}}Al}h}{{{f{B`}}}Cd}````{{l{Df{{Aj{Al{f{An}}}}}}c}{{d{c}}}j}{{DhCbh}An}{{{f{{Df{An}}}}{f{B`}}}l}{{{f{b{Dd{c}}}}}{{Bj{e}}}{jDjDl}{}}`{{{f{Af}}{f{Af}}}{{Bj{Bh}}}}`````{{{f{bl}}Al}h}{{{f{bl}}}Bf}{{{f{bl}}}{{Cf{nBb}}}}{{{f{l}}}{{`{{Ad{}{{Ab{{Aj{Al{f{An}}}}}}}}}}}}`{{{f{l}}}Dh}{{{f{l}}}Al}{{{f{l}}}C`}{{{f{l}}}{{`{{Ad{}{{Ab{Al}}}}}}}}1{{{f{l}}}Cb}````{{{f{c}}}e{}{}}0000000{{{f{c}}}Dn{}}00{c{{Cf{e}}}{}{}}00000000000000000000000{{{f{c}}}E`{}}0000000000095`{ce{}{}}00000000000```{{{f{Eb}}}h}","D":"Hh","p":[[0,"mut"],[5,"Bnb",0,235],[1,"reference"],[1,"bool"],[10,"Ord",236],[5,"CoinSelector",0,237],[5,"Selection",0,237],[1,"slice"],[17,"Item"],[10,"Iterator",238],[6,"ExcessStrategyKind",0,237],[5,"ExcessStrategy",0,237],[1,"tuple"],[1,"usize"],[5,"WeightedValue",0,237],[5,"CoinSelectorOpt",0,237],[5,"SelectionError",0,237],[6,"SelectionConstraint",0,237],[1,"unit"],[6,"Ordering",236],[6,"Option",239],[6,"BnbLimit",0,235],[10,"Into",240],[1,"i64"],[1,"u32"],[1,"f32"],[6,"Result",241],[5,"Formatter",242],[8,"Result",242],[5,"Duration",243],[5,"TxOut",244],[10,"Hasher",245],[8,"DecideStrategy",0,235],[5,"BnbIter",0,235],[5,"Vec",246],[1,"u64"],[10,"Copy",247],[10,"Display",242],[5,"String",248],[5,"TypeId",249],[6,"BranchStrategy",0,235]],"r":[[0,235],[1,235],[2,235],[3,235],[4,237],[5,237],[7,235],[9,237],[10,237],[14,237],[15,237],[16,237],[25,237],[76,235]],"b":[[95,"impl-Debug-for-SelectionError"],[96,"impl-Display-for-SelectionError"],[97,"impl-Debug-for-SelectionConstraint"],[98,"impl-Display-for-SelectionConstraint"],[100,"impl-Display-for-ExcessStrategyKind"],[101,"impl-Debug-for-ExcessStrategyKind"],[107,"impl-From%3CDuration%3E-for-BnbLimit"],[108,"impl-From%3Cusize%3E-for-BnbLimit"]],"c":"OjAAAAAAAAA=","e":"OzAAAAEAAKcAFwAAAAAAAgAAAAYAAAAJAAIADgADABcAAgAcAAEAIAAAACIAKgBQAAIAVgAEAFwACwBsAAEAdwABAIcAAQCKAAEAkgANAKEAAACjAAAApgAAAKoAMADcAAwA6gABAA=="}],\ ["bdk_electrum",{"t":"FFFENNNNNNENNNNNNONNNNNNNNNNNNNNNNNNNNNNN","n":["BdkElectrumClient","ElectrumFullScanResult","ElectrumSyncResult","bdk_chain","borrow","borrow","borrow","borrow_mut","borrow_mut","borrow_mut","electrum_client","fetch_tx","fmt","from","from","from","full_scan","inner","into","into","into","new","populate_tx_cache","sync","transaction_broadcast","try_from","try_from","try_from","try_into","try_into","try_into","type_id","type_id","type_id","vzip","vzip","vzip","with_confirmation_height_anchor","with_confirmation_height_anchor","with_confirmation_time_height_anchor","with_confirmation_time_height_anchor"],"q":[[0,"bdk_electrum"],[41,"bdk_electrum::bdk_electrum_client"],[42,"bitcoin::blockdata::transaction"],[43,"alloc::sync"],[44,"electrum_client::types"],[45,"core::result"],[46,"electrum_client::api"],[47,"core::fmt"],[48,"bdk_chain::spk_client"],[49,"core::cmp"],[50,"core::clone"],[51,"bdk_chain::tx_graph"],[52,"core::convert"],[53,"core::any"],[54,"bdk_chain::chain_data"]],"i":[0,0,0,0,16,23,3,16,23,3,0,3,3,16,23,3,3,3,16,23,3,3,3,3,3,16,23,3,16,23,3,16,23,3,16,23,3,16,23,16,23],"f":"````{{{b{c}}}{{b{e}}}{}{}}00{{{b{dc}}}{{b{de}}}{}{}}00`{{{b{{f{c}}}}h}{{A`{{l{j}}n}}}Ab}{{{b{{f{c}}}}{b{dAd}}}AfAh}{cc{}}00{{{b{{f{c}}}}{Aj{e}}AlAlAn}{{A`{{B`{e}}n}}}Ab{BbBd}}`{ce{}{}}00{c{{f{c}}}Ab}{{{b{{f{c}}}}g}BfAb{}{{Bj{{Bh{e}}}}}}{{{b{{f{c}}}}BlAlAn}{{A`{Bnn}}}Ab}{{{b{{f{c}}}}{b{j}}}{{A`{hn}}}Ab}{c{{A`{e}}}{}{}}00000{{{b{c}}}C`{}}00666{{{B`{c}}}{{Cd{cCb}}}{}}{Bn{{Cf{Cb}}}}{{{B`{c}}{b{{f{e}}}}}{{A`{{Cd{cCh}}n}}}{}Ab}{{Bn{b{{f{c}}}}}{{A`{{Cf{Ch}}n}}}Ab}","D":"Bj","p":[[1,"reference"],[0,"mut"],[5,"BdkElectrumClient",0,41],[5,"Txid",42],[5,"Transaction",42],[5,"Arc",43],[6,"Error",44],[6,"Result",45],[10,"ElectrumApi",46],[5,"Formatter",47],[8,"Result",47],[10,"Debug",47],[5,"FullScanRequest",48],[1,"usize"],[1,"bool"],[5,"ElectrumFullScanResult",0,41],[10,"Ord",49],[10,"Clone",50],[1,"unit"],[5,"TxGraph",51],[10,"AsRef",52],[5,"SyncRequest",48],[5,"ElectrumSyncResult",0,41],[5,"TypeId",53],[5,"ConfirmationHeightAnchor",54],[5,"FullScanResult",48],[5,"SyncResult",48],[5,"ConfirmationTimeHeightAnchor",54]],"r":[[0,41],[1,41],[2,41]],"b":[],"c":"OjAAAAAAAAA=","e":"OzAAAAEAABQAAwAEAAcADQAAABoACwA="}],\ ["bdk_esplora",{"t":"IKKEMMMM","n":["Error","EsploraAsyncExt","EsploraExt","esplora_client","full_scan","full_scan","sync","sync"],"q":[[0,"bdk_esplora"],[8,"bdk_esplora::blocking_ext"],[9,"bdk_chain::spk_client"],[10,"core::result"],[11,"core::cmp"],[12,"core::clone"],[13,"bdk_esplora::async_ext"],[14,"core::future::future"],[15,"alloc::boxed"],[16,"core::pin"],[17,"core::marker"]],"i":[0,0,0,0,1,10,1,10],"f":"````{{{d{b}}{f{c}}hh}{{n{{j{c}}l}}}{A`Ab}}{{{d{Ad}}{f{c}}hh}{{Aj{{Ah{Af}}}}}{A`AbAl}}{{{d{b}}Anh}{{n{B`l}}}}{{{d{Ad}}Anh}{{Aj{{Ah{Af}}}}}}","D":"A`","p":[[10,"EsploraExt",0,8],[1,"reference"],[5,"FullScanRequest",9],[1,"usize"],[5,"FullScanResult",9],[8,"Error",0,8],[6,"Result",10],[10,"Ord",11],[10,"Clone",12],[10,"EsploraAsyncExt",0,13],[10,"Future",14],[5,"Box",15],[5,"Pin",16],[10,"Send",17],[5,"SyncRequest",9],[5,"SyncResult",9]],"r":[[0,8],[1,13],[2,8]],"b":[],"c":"OjAAAAAAAAA=","e":"OjAAAAEAAAAAAAAAEAAAAAQA"}],\ -["bdk_file_store",{"t":"FPFGPPPGFNNNNNNNNNNNNONNNNNNNNNNNNNNNNNNNNNNNONNNNNNNNNNNNNNNNNNNNNNNNNNNOO","n":["AggregateChangesetsError","Bincode","EntryIter","FileError","InvalidMagicBytes","Io","Io","IterError","Store","aggregate_changesets","append_changeset","borrow","borrow","borrow","borrow","borrow","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","changeset","create_new","drop","fmt","fmt","fmt","fmt","fmt","fmt","fmt","from","from","from","from","from","from","from","into","into","into","into","into","into_iter","iter_changesets","iter_error","new","next","open","open_or_create_new","to_string","to_string","to_string","try_from","try_from","try_from","try_from","try_from","try_into","try_into","try_into","try_into","try_into","type_id","type_id","type_id","type_id","type_id","vzip","vzip","vzip","vzip","vzip","expected","got"],"q":[[0,"bdk_file_store"],[73,"bdk_file_store::FileError"],[75,"bdk_file_store::store"],[76,"core::option"],[77,"core::result"],[78,"bdk_chain::tx_data_traits"],[79,"serde::ser"],[80,"serde::de"],[81,"core::marker"],[82,"std::io::error"],[83,"std::path"],[84,"core::convert"],[85,"bdk_file_store::entry_iter"],[86,"core::fmt"],[87,"std::fs"],[88,"alloc::string"],[89,"core::any"]],"i":[0,20,0,0,16,20,16,0,0,2,2,19,20,2,5,16,19,20,2,5,16,5,2,19,20,20,2,5,5,16,16,19,20,20,2,5,16,16,19,20,2,5,16,19,2,5,19,19,2,2,20,5,16,19,20,2,5,16,19,20,2,5,16,19,20,2,5,16,19,20,2,5,16,28,28],"f":"`````````{{{f{b{d{c}}}}}{{l{{h{c}}{j{c}}}}}{nA`AbAdAf}}{{{f{b{d{c}}}}{f{c}}}{{l{AhAj}}}{nA`AbAdAf}}{{{f{c}}}{{f{e}}}{}{}}0000{{{f{bc}}}{{f{be}}}{}{}}0000`{{{f{{An{Al}}}}c}{{l{{d{e}}B`}}}{{Bd{Bb}}}{nA`AbAdAf}}{{{f{b{Bf{c}}}}}Ah{}}{{{f{Bh}}{f{bBj}}}Bl}0{{{f{{d{c}}}}{f{bBj}}}Bl{AfAdBn}}{{{f{{j{c}}}}{f{bBj}}}BlBn}{{{f{{j{c}}}}{f{bBj}}}Bl{}}{{{f{B`}}{f{bBj}}}Bl}0{cc{}}{AjBh}1111{AjB`}{ce{}{}}00000{{{f{b{d{c}}}}}{{Bf{c}}}{nA`AbAdAf}}`{{C`{f{bCb}}}{{Bf{c}}}{}}{{{f{b{Bf{c}}}}}{{h{e}}}Ab{}}=={{{f{c}}}Cd{}}00{c{{l{e}}}{}{}}000000000{{{f{c}}}Cf{}}000066666``","D":"Ch","p":[[0,"mut"],[5,"Store",0,75],[1,"reference"],[6,"Option",76],[5,"AggregateChangesetsError",0,75],[6,"Result",77],[10,"Append",78],[10,"Serialize",79],[10,"DeserializeOwned",80],[10,"Send",81],[10,"Sync",81],[1,"unit"],[5,"Error",82],[1,"u8"],[1,"slice"],[6,"FileError",0],[5,"Path",83],[10,"AsRef",84],[5,"EntryIter",0,85],[6,"IterError",0,85],[5,"Formatter",86],[8,"Result",86],[10,"Debug",86],[1,"u64"],[5,"File",87],[5,"String",88],[5,"TypeId",89],[15,"InvalidMagicBytes",73]],"r":[[0,75],[2,85],[7,85],[8,75]],"b":[[24,"impl-Display-for-IterError"],[25,"impl-Debug-for-IterError"],[27,"impl-Debug-for-AggregateChangesetsError%3CC%3E"],[28,"impl-Display-for-AggregateChangesetsError%3CC%3E"],[29,"impl-Display-for-FileError"],[30,"impl-Debug-for-FileError"]],"c":"OjAAAAAAAAA=","e":"OzAAAAEAAC8ABwAMAAkAGAAHACEAAAAmAAAALAAAAC8AAQAzABgA"}],\ +["bdk_file_store",{"t":"FPFGPPPGFNNNNNNNNNNNNONNNNNNNNNNNNNNNNNNNNNNNONNNNNNNNNNNNNNNNNNNNNNNNNNNOO","n":["AggregateChangesetsError","Bincode","EntryIter","FileError","InvalidMagicBytes","Io","Io","IterError","Store","aggregate_changesets","append_changeset","borrow","borrow","borrow","borrow","borrow","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","changeset","create_new","drop","fmt","fmt","fmt","fmt","fmt","fmt","fmt","from","from","from","from","from","from","from","into","into","into","into","into","into_iter","iter_changesets","iter_error","new","next","open","open_or_create_new","to_string","to_string","to_string","try_from","try_from","try_from","try_from","try_from","try_into","try_into","try_into","try_into","try_into","type_id","type_id","type_id","type_id","type_id","vzip","vzip","vzip","vzip","vzip","expected","got"],"q":[[0,"bdk_file_store"],[73,"bdk_file_store::FileError"],[75,"bdk_file_store::store"],[76,"core::option"],[77,"core::result"],[78,"bdk_chain::tx_data_traits"],[79,"serde::ser"],[80,"serde::de"],[81,"core::marker"],[82,"std::io::error"],[83,"std::path"],[84,"core::convert"],[85,"bdk_file_store::entry_iter"],[86,"core::fmt"],[87,"std::fs"],[88,"alloc::string"],[89,"core::any"]],"i":[0,20,0,0,16,20,16,0,0,2,2,19,20,2,5,16,19,20,2,5,16,5,2,19,20,20,2,5,5,16,16,19,20,20,2,5,16,16,19,20,2,5,16,19,2,5,19,19,2,2,20,5,16,19,20,2,5,16,19,20,2,5,16,19,20,2,5,16,19,20,2,5,16,28,28],"f":"`````````{{{f{b{d{c}}}}}{{l{{h{c}}{j{c}}}}}{nA`AbAdAf}}{{{f{b{d{c}}}}{f{c}}}{{l{AhAj}}}{nA`AbAdAf}}{{{f{c}}}{{f{e}}}{}{}}0000{{{f{bc}}}{{f{be}}}{}{}}0000`{{{f{{An{Al}}}}c}{{l{{d{e}}B`}}}{{Bd{Bb}}}{nA`AbAdAf}}{{{f{b{Bf{c}}}}}Ah{}}{{{f{Bh}}{f{bBj}}}Bl}0{{{f{{d{c}}}}{f{bBj}}}Bl{AfAdBn}}{{{f{{j{c}}}}{f{bBj}}}BlBn}{{{f{{j{c}}}}{f{bBj}}}Bl{}}{{{f{B`}}{f{bBj}}}Bl}0{cc{}}0{AjBh}111{AjB`}{ce{}{}}00000{{{f{b{d{c}}}}}{{Bf{c}}}{nA`AbAdAf}}`{{C`{f{bCb}}}{{Bf{c}}}{}}{{{f{b{Bf{c}}}}}{{h{e}}}Ab{}}=={{{f{c}}}Cd{}}00{c{{l{e}}}{}{}}000000000{{{f{c}}}Cf{}}000066666``","D":"Ch","p":[[0,"mut"],[5,"Store",0,75],[1,"reference"],[6,"Option",76],[5,"AggregateChangesetsError",0,75],[6,"Result",77],[10,"Append",78],[10,"Serialize",79],[10,"DeserializeOwned",80],[10,"Send",81],[10,"Sync",81],[1,"unit"],[5,"Error",82],[1,"u8"],[1,"slice"],[6,"FileError",0],[5,"Path",83],[10,"AsRef",84],[5,"EntryIter",0,85],[6,"IterError",0,85],[5,"Formatter",86],[8,"Result",86],[10,"Debug",86],[1,"u64"],[5,"File",87],[5,"String",88],[5,"TypeId",89],[15,"InvalidMagicBytes",73]],"r":[[0,75],[2,85],[7,85],[8,75]],"b":[[24,"impl-Debug-for-IterError"],[25,"impl-Display-for-IterError"],[27,"impl-Debug-for-AggregateChangesetsError%3CC%3E"],[28,"impl-Display-for-AggregateChangesetsError%3CC%3E"],[29,"impl-Display-for-FileError"],[30,"impl-Debug-for-FileError"]],"c":"OjAAAAAAAAA=","e":"OzAAAAEAAC8ABwAMAAkAGAAHACIAAAAmAAAALAAAAC8AAQAzABgA"}],\ ["bdk_hwi",{"t":"FNNNNNNNNNNNN","n":["HWISigner","borrow","borrow_mut","fmt","from","from_device","id","into","sign_transaction","try_from","try_into","type_id","vzip"],"q":[[0,"bdk_hwi"],[13,"bdk_hwi::signer"],[14,"core::fmt"],[15,"hwi::types"],[16,"hwi::error"],[17,"core::result"],[18,"secp256k1::context::alloc_only"],[19,"secp256k1"],[20,"bdk_wallet::wallet::signer"],[21,"bitcoin::psbt"],[22,"core::any"]],"i":[0,3,3,3,3,3,3,3,3,3,3,3,3],"f":"`{{{b{c}}}{{b{e}}}{}{}}{{{b{dc}}}{{b{de}}}{}{}}{{{b{f}}{b{dh}}}j}{cc{}}{{{b{l}}n}{{Ab{fA`}}}}{{{b{f}}{b{{Af{Ad}}}}}Ah}{ce{}{}}{{{b{f}}{b{dAj}}{b{Al}}{b{{Af{Ad}}}}}{{Ab{AnB`}}}}{c{{Ab{e}}}{}{}}0{{{b{c}}}Bb{}}3","D":"j","p":[[1,"reference"],[0,"mut"],[5,"HWISigner",0,13],[5,"Formatter",14],[8,"Result",14],[5,"HWIDevice",15],[5,"HWIChain",15],[6,"Error",16],[6,"Result",17],[6,"All",18],[5,"Secp256k1",19],[6,"SignerId",20],[5,"Psbt",21],[5,"SignOptions",20],[1,"unit"],[6,"SignerError",20],[5,"TypeId",22]],"r":[[0,13]],"b":[],"c":"OjAAAAAAAAA=","e":"OzAAAAEAAAgAAwACAAIABwAAAAkABAA="}],\ -["bdk_sqlite",{"t":"GPPFNNNNNNNNNNNNNENNNNNNNNNNOO","n":["Error","Network","Sqlite","Store","borrow","borrow","borrow_mut","borrow_mut","fmt","fmt","fmt","from","from","into","into","new","read","rusqlite","to_string","try_from","try_from","try_into","try_into","type_id","type_id","vzip","vzip","write","expected","given"],"q":[[0,"bdk_sqlite"],[28,"bdk_sqlite::Error"],[30,"bdk_sqlite::store"],[31,"core::fmt"],[32,"rusqlite"],[33,"rusqlite::error"],[34,"core::result"],[35,"core::cmp"],[36,"serde::de"],[37,"serde::ser"],[38,"core::marker"],[39,"bdk_chain::tx_data_traits"],[40,"bdk_chain::changeset"],[41,"core::option"],[42,"alloc::string"],[43,"core::any"]],"i":[0,6,6,0,3,6,3,6,3,6,6,3,6,3,6,3,3,0,6,3,6,3,6,3,6,3,6,3,20,20],"f":"````{{{b{c}}}{{b{e}}}{}{}}0{{{b{dc}}}{{b{de}}}{}{}}0{{{b{{f{ce}}}}{b{dh}}}j{}{}}{{{b{l}}{b{dh}}}j}0{cc{}}0{ce{}{}}0{n{{Ab{{f{ce}}A`}}}{AdAfAhAj}{AlAfAhAj}}{{{b{d{f{ce}}}}}{{Ab{{B`{{An{ce}}}}l}}}{AdAfAhAj}{AlAfAhAj}}`{{{b{c}}}Bb{}}{c{{Ab{e}}}{}{}}000{{{b{c}}}Bd{}}055{{{b{d{f{ce}}}}{b{{An{ce}}}}}{{Ab{Bfl}}}{AdAfAhAj}{AlAfAhAj}}``","D":"Ah","p":[[1,"reference"],[0,"mut"],[5,"Store",0,30],[5,"Formatter",31],[8,"Result",31],[6,"Error",0],[5,"Connection",32],[6,"Error",33],[6,"Result",34],[10,"Ord",35],[10,"Deserialize",36],[10,"Serialize",37],[10,"Send",38],[10,"Anchor",39],[5,"CombinedChangeSet",40],[6,"Option",41],[5,"String",42],[5,"TypeId",43],[1,"unit"],[15,"Network",28]],"r":[[3,30]],"b":[[9,"impl-Display-for-Error"],[10,"impl-Debug-for-Error"]],"c":"OjAAAAAAAAA=","e":"OzAAAAEAABIAAwAFAAYAEgAJAB0AAQA="}],\ +["bdk_sqlite",{"t":"GPPFNNNNNNNNNNNNNENNNNNNNNNNOO","n":["Error","Network","Sqlite","Store","borrow","borrow","borrow_mut","borrow_mut","fmt","fmt","fmt","from","from","into","into","new","read","rusqlite","to_string","try_from","try_from","try_into","try_into","type_id","type_id","vzip","vzip","write","expected","given"],"q":[[0,"bdk_sqlite"],[28,"bdk_sqlite::Error"],[30,"bdk_sqlite::store"],[31,"core::fmt"],[32,"rusqlite"],[33,"rusqlite::error"],[34,"core::result"],[35,"core::cmp"],[36,"serde::de"],[37,"serde::ser"],[38,"core::marker"],[39,"bdk_chain::tx_data_traits"],[40,"bdk_chain::changeset"],[41,"core::option"],[42,"alloc::string"],[43,"core::any"]],"i":[0,6,6,0,3,6,3,6,3,6,6,3,6,3,6,3,3,0,6,3,6,3,6,3,6,3,6,3,20,20],"f":"````{{{b{c}}}{{b{e}}}{}{}}0{{{b{dc}}}{{b{de}}}{}{}}0{{{b{{f{ce}}}}{b{dh}}}j{}{}}{{{b{l}}{b{dh}}}j}0{cc{}}0{ce{}{}}0{n{{Ab{{f{ce}}A`}}}{AdAfAhAj}{AlAfAhAj}}{{{b{d{f{ce}}}}}{{Ab{{B`{{An{ce}}}}l}}}{AdAfAhAj}{AlAfAhAj}}`{{{b{c}}}Bb{}}{c{{Ab{e}}}{}{}}000{{{b{c}}}Bd{}}055{{{b{d{f{ce}}}}{b{{An{ce}}}}}{{Ab{Bfl}}}{AdAfAhAj}{AlAfAhAj}}``","D":"Ah","p":[[1,"reference"],[0,"mut"],[5,"Store",0,30],[5,"Formatter",31],[8,"Result",31],[6,"Error",0],[5,"Connection",32],[6,"Error",33],[6,"Result",34],[10,"Ord",35],[10,"Deserialize",36],[10,"Serialize",37],[10,"Send",38],[10,"Anchor",39],[5,"CombinedChangeSet",40],[6,"Option",41],[5,"String",42],[5,"TypeId",43],[1,"unit"],[15,"Network",28]],"r":[[3,30]],"b":[[9,"impl-Debug-for-Error"],[10,"impl-Display-for-Error"]],"c":"OjAAAAAAAAA=","e":"OzAAAAEAABIAAwAFAAYAEgAJAB0AAQA="}],\ ["bdk_testenv",{"t":"FEEEONNEOENNNNNNNNNNNNNNNNNNN","n":["TestEnv","anyhow","bitcoincore_rpc","bitcoind","bitcoind","borrow","borrow_mut","electrsd","electrsd","electrum_client","electrum_client","from","genesis_hash","into","invalidate_blocks","make_checkpoint_tip","mine_blocks","mine_empty_block","new","reorg","reorg_empty_blocks","reset_electrsd","rpc_client","send","try_from","try_into","type_id","vzip","wait_until_electrum_sees_block"],"q":[[0,"bdk_testenv"],[29,"electrum_client::api"],[30,"bitcoin::blockdata::block"],[31,"anyhow"],[32,"bdk_chain::local_chain"],[33,"bitcoin::address"],[34,"core::option"],[35,"alloc::vec"],[36,"bitcoincore_rpc::client"],[37,"bitcoin_units::amount"],[38,"bitcoin::blockdata::transaction"],[39,"core::result"],[40,"core::any"]],"i":[0,0,0,0,3,3,3,0,3,0,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3],"f":"`````{{{b{c}}}{{b{e}}}{}{}}{{{b{dc}}}{{b{de}}}{}{}}```{{{b{f}}}{{b{{`{h}}}}}}{cc{}}{{{b{f}}}{{l{j}}}}{ce{}{}}{{{b{f}}n}{{l{A`}}}}{{{b{f}}}Ab}{{{b{f}}n{Af{Ad}}}{{l{{Ah{j}}}}}}{{{b{f}}}{{l{{Aj{nj}}}}}}{{}{{l{f}}}}{{{b{f}}n}{{l{{Ah{j}}}}}}{{{b{f}}n}{{l{{Ah{{Aj{nj}}}}}}}}{f{{l{f}}}}{{{b{f}}}{{b{{`{Al}}}}}}{{{b{f}}{b{{Ad{An}}}}B`}{{l{Bb}}}}{c{{Bd{e}}}{}{}}0{{{b{c}}}Bf{}}<{{{b{f}}}{{l{A`}}}}","D":"An","p":[[1,"reference"],[0,"mut"],[5,"TestEnv",0],[10,"ElectrumApi",29],[5,"BlockHash",30],[8,"Result",31],[1,"usize"],[1,"unit"],[5,"CheckPoint",32],[5,"Address",33],[6,"Option",34],[5,"Vec",35],[1,"tuple"],[10,"RpcApi",36],[6,"NetworkChecked",33],[5,"Amount",37],[5,"Txid",38],[6,"Result",39],[5,"TypeId",40]],"r":[],"b":[],"c":"OjAAAAAAAAA=","e":"OzAAAAEAAA4ABAAAAAAAAgAIABYAAAAZAAMA"}],\ -["bdk_tmp_plan",{"t":"FKPPPPFFGGFFPPPGPPONNNNNNNNNNNNNNNNMNNNNNNNNNNNNNNNNNNOOONNNNNNNNNNNNNNNNNNNNOOOOOONNNNNNNNOONHNNNNOOOOOOONONNNNNNNNNNNNNNNNNNNNNNNNNONNNNNNNNNNNNNNNNNOOOOOOOO","n":["Assets","CanDerive","Complete","DerivationError","Incomplete","Legacy","Plan","PlanKey","PlanState","RequiredSignatures","Requirements","SatisfactionMaterial","Segwitv0","SigHashP2wpkh","SigHashTaproot","SigningError","TapKey","TapScript","asset_key","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","can_derive","clone","clone","clone","clone","clone","clone","clone","clone_into","clone_into","clone_into","clone_into","clone_into","clone_into","clone_into","default","default","default","default","derivation_hint","descriptor_key","ecdsa_sigs","expected_weight","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","from","from","from","from","from","from","from","from","from","from","from","hash160","hash160_images","hash160_preimages","hash256","hash256_images","hash256_preimages","into","into","into","into","into","into","into","into","keys","max_locktime","min_version","plan_satisfaction","required_locktime","required_sequence","requirements","requires_hash_preimages","ripemd160","ripemd160_images","ripemd160_preimages","schnorr_sigs","sha256","sha256_images","sha256_preimages","sign_with_keymap","signatures","to_owned","to_owned","to_owned","to_owned","to_owned","to_owned","to_owned","to_string","try_complete","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","txo_age","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","vzip","vzip","vzip","vzip","vzip","vzip","vzip","vzip","witness_version","final_script_sig","final_script_witness","keys","keys","leaf_hash","merkle_root","plan_key","plan_keys"],"q":[[0,"bdk_tmp_plan"],[151,"bdk_tmp_plan::PlanState"],[153,"bdk_tmp_plan::RequiredSignatures"],[159,"miniscript::descriptor::key"],[160,"bitcoin::bip32"],[161,"core::option"],[162,"bdk_tmp_plan::requirements"],[163,"core::clone"],[164,"bdk_tmp_plan::template"],[165,"core::fmt"],[166,"bitcoin::crypto::sighash"],[167,"miniscript::descriptor"],[168,"bitcoin::blockdata::locktime::absolute"],[169,"bitcoin::blockdata::transaction"],[170,"secp256k1"],[171,"core::result"],[172,"core::borrow"],[173,"secp256k1::context"],[174,"alloc::string"],[175,"core::any"],[176,"bitcoin::blockdata::script::witness_version"]],"i":[0,0,42,10,42,9,0,0,0,0,0,0,9,10,10,0,9,9,11,42,7,9,10,11,12,13,14,42,7,9,10,11,12,13,14,3,7,9,10,11,12,13,14,7,9,10,11,12,13,14,7,9,13,14,11,11,13,12,7,9,10,10,11,12,13,14,42,7,9,10,10,10,10,11,12,13,14,14,7,13,14,7,13,42,7,9,10,11,12,13,14,14,14,12,0,12,12,12,7,14,7,13,13,14,7,13,9,7,7,9,10,11,12,13,14,10,12,42,7,9,10,11,12,13,14,42,7,9,10,11,12,13,14,14,42,7,9,10,11,12,13,14,42,7,9,10,11,12,13,14,12,45,45,46,47,48,49,49,48],"f":"```````````````````{{{b{c}}}{{b{e}}}{}{}}0000000{{{b{dc}}}{{b{de}}}{}{}}0000000{{{b{f}}{b{h}}}{{l{j}}}}{{{b{{n{c}}}}}{{n{c}}}A`}{{{b{{Ab{c}}}}}{{Ab{c}}}A`}{{{b{Ad}}}Ad}{{{b{{Af{c}}}}}{{Af{c}}}A`}{{{b{{Ah{c}}}}}{{Ah{c}}}A`}{{{b{Aj}}}Aj}{{{b{{Al{c}}}}}{{Al{c}}}A`}{{{b{c}}{b{de}}}An{}{}}000000{{}{{n{c}}}{}}{{}{{Ab{c}}}{}}{{}Aj}{{}{{Al{c}}}{}}```{{{b{{Ah{c}}}}}B`A`}{{{b{{n{c}}}}{b{dBb}}}BdBf}{{{b{{Ab{c}}}}{b{dBb}}}BdBf}{{{b{Ad}}{b{dBb}}}Bd}0{{{b{{Af{c}}}}{b{dBb}}}BdBf}{{{b{{Ah{c}}}}{b{dBb}}}BdBf}{{{b{Aj}}{b{dBb}}}Bd}{{{b{{Al{c}}}}{b{dBb}}}BdBf}{cc{}}000{BhAd}{BjAd}{BlAd}3333``````{ce{}{}}0000000``{{{b{{Ah{c}}}}}{{l{Bn}}}A`}{{{b{{C`{h}}}}{b{{Al{c}}}}}{{l{{Ah{c}}}}}{fA`}}{{{b{{Ah{c}}}}}{{l{Cb}}}A`}{{{b{{Ah{c}}}}}{{l{Cd}}}A`}{{{b{{Ah{c}}}}}{{n{c}}}A`}{{{b{{n{c}}}}}Cf{}}```````{{{b{{Ab{Ch}}}}B`{b{Cj}}{b{{Cl{c}}}}{l{Cn}}{l{D`}}{b{d{Db{e}}}}{b{dAj}}{b{{Dd{g}}}}}{{Df{CfAd}}}{{Dj{Dh}}}{{Dj{Dl}}}{DnE`}}`{{{b{c}}}e{}{}}000000{{{b{c}}}Eb{}}{{{b{{Ah{c}}}}{b{Aj}}}{{Ed{c}}}A`}{c{{Df{e}}}{}{}}000000000000000`{{{b{c}}}Ef{}}0000000<<<<<<<<{{{b{{Ah{c}}}}}{{l{Eh}}}A`}````````","D":"Fl","p":[[1,"reference"],[0,"mut"],[10,"CanDerive",0],[5,"DefiniteDescriptorKey",159],[5,"DerivationPath",160],[6,"Option",161],[5,"Requirements",0,162],[10,"Clone",163],[6,"RequiredSignatures",0,162],[6,"SigningError",0,162],[5,"PlanKey",0,164],[5,"Plan",0],[5,"SatisfactionMaterial",0],[5,"Assets",0],[1,"unit"],[1,"usize"],[5,"Formatter",165],[8,"Result",165],[10,"Debug",165],[6,"P2wpkhError",166],[6,"Error",160],[6,"TaprootError",166],[1,"u32"],[6,"Descriptor",167],[6,"LockTime",168],[5,"Sequence",169],[1,"bool"],[6,"DescriptorPublicKey",159],[8,"KeyMap",167],[6,"Prevouts",166],[6,"TapSighashType",166],[6,"EcdsaSighashType",166],[5,"SighashCache",166],[5,"Secp256k1",170],[6,"Result",171],[5,"TxOut",169],[10,"Borrow",172],[5,"Transaction",169],[10,"Signing",173],[10,"Verification",173],[5,"String",174],[6,"PlanState",0],[5,"TypeId",175],[6,"WitnessVersion",176],[15,"Complete",151],[15,"Legacy",153],[15,"Segwitv0",153],[15,"TapScript",153],[15,"TapKey",153]],"r":[[7,164],[9,162],[10,162],[15,162]],"b":[[60,"impl-Display-for-SigningError"],[61,"impl-Debug-for-SigningError"],[70,"impl-From%3CP2wpkhError%3E-for-SigningError"],[71,"impl-From%3CError%3E-for-SigningError"],[72,"impl-From%3CTaprootError%3E-for-SigningError"]],"c":"OjAAAAAAAAA=","e":"OzAAAAEAAGkAEAABAAEABAABAA4AAgAUACIAOwAHAEcAAgBOAAAAUQAAAFwAAQBfAAAAYgAAAGQAAABoAAAAawAAAG0AKQCaAAEA"}],\ -["bdk_wallet",{"t":"PPEPGPFEEGEFNNDNNNNNNNNENNNNNNNNNOOCQNNNNNNNNNNQNNNNNNNNNNOOCDNONCONNNEENNNNNNNNNNNNNONNNNOHNNNNCOOOPPPIGEGIKTIKRGFPPPPEKGPPPPTIPPPPPPPPPPNNNNNNNNNNNNNNNNNENNNNNNNNNNNNNMNNMNNNNNCNNNNNNNNNNNNNNNNNNNNNNNNNNCNONMNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNMNNNNNNNNNMNNNNNNMNNNNNNNNNNNNNNNNONNNNNNNNNMNNNNCNNNNNNNNNNNMNNNCNNNNNNNNNNNNNNNNNNNONNNNNNNNNNHHPPGPPPPPPPPPPPNNNNNNNNNNNNNNNNNNPPPGPFIPPIPPPPPPPPPPPGFGPPPPPGGPPPPNNNNNNNNNNNNNNNNNNNNNNNNNNOONNNNNNNNNNNNNNNNNNNNNNNNNNNNONNNNNNNNNNONNONNNNNONNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNOOOOOOOOOOOOOOOOOOOOOOOOFFFFFFFFKIFFFFNNNNNNNNNNNNNNNNNNNNNNNNMNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNPKGGGRRKGPKKFKPPPRGIPPPPPRPFPKGPPPFFGFPIPPPHMNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNMMNNNNNNNNNNNNNNNNNNNNNNNONNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNMNNNNNNNNNNNNNNNNNNNNMNNNNNNMNNNNNNNNNNNNNNNNNNNOONHNMNNHNMNNOONNNNNNMNNNNNMNHNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNKMMMFGFPIPPPPGKGPPPPPPGGPFFNNONNNNNNNNNNNNNNNNNNNNNNNNNNNNNNOONNNNNCONNNNNNNNNCCNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNOOOONNNNNNNNNNNNMNONONNNNNNNNONNNNNNNNNNNNNNNCNNNNNNNNNNNNNNNNONNNNNNNNNNNNNNNNNNNCNNNNNNNNNNNNONNNNNNNNNHOOOOOOOOOOPPFPKFIGGPFPFNNNNNNNNNNNNNNNNNNMNNNHNNNOONNNNNNNNNNNNNNNNNNNNNONNNNNNNNNNNNNNNNNNNNNNNNNNNNNOOOOOOOGPPGPPPPPPPGPPPPPPPPPPPPPPPPPPNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNOOOOOOFIOONNNNNNNNNNNOONNNNNNPPPPPPPKPPPPPPPPPPPPPPPPFKGGGFFFPGKPPNOONONNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNMNNNNNNNNNNNNNNNNNMNNNMNONONNNNNNNNOONNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNOGGPPPGPPPPPFGPPNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNOO","n":["External","Foreign","HdKeyPaths","Internal","KeychainKind","Local","LocalOutput","SignOptions","TxBuilder","Utxo","Wallet","WeightedUtxo","as_byte","as_ref","bitcoin","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","miniscript","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","Bare","Bare","DerivedDescriptor","Descriptor","DescriptorError","DescriptorPublicKey","ExtendedDescriptor","ExtractPolicy","FALSE","HdKeyPaths","IntoWalletDescriptor","Key","Legacy","Miniscript","MultiXPub","Pkh","Pkh","Pkh","Policy","ScriptContext","Segwitv0","Sh","Sh","Sh","Single","TRUE","TapKeyOrigins","Tr","Tr","Tr","Wpkh","Wpkh","Wpkh","Wsh","Wsh","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","descriptor_id","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","ExternalAndInternalAreTheSame","HardenedDerivationXpub","Hex","InvalidDescriptorCharacter","InvalidDescriptorChecksum","InvalidHdKeyPath","Key","Miniscript","MultiPath","Pk","Policy","borrow","borrow_mut","fmt","fmt","from","from","from","from","from","from","from","from","into","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","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","n","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","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","AddressInfo","ApplyBlockError","Balance","CannotConnect","ChangeSet","ConfirmationHeightCannotBeGreaterThanTip","Descriptor","Descriptor","Descriptor","InsertTxError","IsDust","LoadError","LoadedDescriptorDoesNotMatch","LoadedGenesisDoesNotMatch","LoadedNetworkDoesNotMatch","MissingDescriptor","MissingGenesis","MissingNetwork","NewError","NewOrLoadError","UnexpectedConnectedToHash","Update","Wallet","add","add_signer","address","all_unbounded_spk_iters","apply_block","apply_block_connected_to","apply_unconfirmed_txs","apply_update","as_ref","balance","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","build_fee_bump","build_tx","calculate_fee","calculate_fee_rate","cancel_tx","chain","chain","checkpoints","clone","clone","clone_into","clone_into","coin_selection","confirmed","default","default","deref","derivation_index","derivation_of_spk","descriptor_checksum","deserialize","eq","eq","error","export","finalize_psbt","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","get_descriptor_for_keychain","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","is_dust","is_mine","keychain","keychains","last_active_indices","latest_checkpoint","list_output","list_unspent","list_unused_addresses","load_from_changeset","local_chain","mark_used","network","network","new","new_or_load","new_or_load_with_genesis_hash","new_with_genesis_hash","next_derivation_index","next_unused_address","peek_address","policies","public_descriptor","reveal_addresses_to","reveal_next_address","secp_ctx","sent_and_received","serialize","sign","signer","spk_index","staged","start_full_scan","start_sync_with_revealed_spks","take_staged","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_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","unbounded_spk_iter","unmark_used","untrusted_pending","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","got","keychain","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","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","CoinSelection","Conversion","CreateTxError","Descriptor","FeeRateTooLow","FeeRateUnavailable","FeeTooLow","IrreplaceableTransaction","LockTime","MiniscriptPsbt","MiniscriptPsbtError","MissingKeyOrigin","MissingNonWitnessUtxo","NoRecipients","NoUtxosSelected","OutputBelowDustLimit","OutputUpdate","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","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","csv","rbf","requested","required","required","required","FullyNodedExport","WalletExport","blockheight","blockheight","borrow","borrow_mut","change_descriptor","descriptor","deserialize","export_wallet","fmt","fmt","from","from_str","into","label","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","SighashP2wpkh","SighashTaproot","SignOptions","SignerCommon","SignerContext","SignerError","SignerId","SignerOrdering","SignerWrapper","SignersContainer","Tap","TapLeavesOptions","TransactionSigner","TxInputsIndexError","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","from","from","hash","id","id","id","id","ids","into","into","into","into","into","into","into","into","new","new","partial_cmp","partial_cmp","remove","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","Bip69Lexicographic","ChangeAllowed","ChangeForbidden","ChangeSpendPolicy","InvalidOutpoint","InvalidTxid","MissingUtxo","OnlyChange","Shuffle","TxBuilder","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","borrow","borrow","borrow","borrow","borrow","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","change_policy","clone","clone","clone","clone_into","clone_into","clone_into","cmp","cmp","coin_selection","current_height","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","from","from","from","from","from","hash","hash","include_output_redeem_witness_script","into","into","into","into","into","manually_selected_only","nlocktime","only_spend_change","only_witness_utxo","ordering","partial_cmp","partial_cmp","policy_path","set_recipients","sighash","sort_tx","to_owned","to_owned","to_owned","to_string","to_string","try_from","try_from","try_from","try_from","try_from","try_into","try_into","try_into","try_into","try_into","type_id","type_id","type_id","type_id","type_id","unspendable","version","vzip","vzip","vzip","vzip","vzip","foreign_utxo","input_txid"],"q":[[0,"bdk_wallet"],[97,"bdk_wallet::Utxo"],[100,"bdk_wallet::descriptor"],[352,"bdk_wallet::descriptor::checksum"],[354,"bdk_wallet::descriptor::error"],[386,"bdk_wallet::descriptor::policy"],[533,"bdk_wallet::descriptor::policy::BuildSatisfaction"],[536,"bdk_wallet::descriptor::policy::Satisfaction"],[547,"bdk_wallet::descriptor::policy::SatisfiableItem"],[557,"bdk_wallet::descriptor::template"],[693,"bdk_wallet::keys"],[992,"bdk_wallet::psbt"],[996,"bdk_wallet::wallet"],[1211,"bdk_wallet::wallet::ApplyBlockError"],[1213,"bdk_wallet::wallet::InsertTxError"],[1215,"bdk_wallet::wallet::NewOrLoadError"],[1221,"bdk_wallet::wallet::coin_selection"],[1313,"bdk_wallet::wallet::coin_selection::Error"],[1315,"bdk_wallet::wallet::coin_selection::Excess"],[1320,"bdk_wallet::wallet::error"],[1391,"bdk_wallet::wallet::error::CreateTxError"],[1397,"bdk_wallet::wallet::export"],[1420,"bdk_wallet::wallet::signer"],[1601,"bdk_wallet::wallet::signer::SignerContext"],[1602,"bdk_wallet::wallet::tx_builder"],[1717,"bdk_wallet::wallet::tx_builder::AddForeignUtxoError"],[1719,"bdk_wallet::types"],[1720,"core::cmp"],[1721,"core::result"],[1722,"serde::de"],[1723,"core::fmt"],[1724,"core::hash"],[1725,"bitcoin::blockdata::transaction"],[1726,"core::option"],[1727,"serde::ser"],[1728,"core::any"],[1729,"miniscript::descriptor"],[1730,"bitcoin::network"],[1731,"bitcoin::address"],[1732,"miniscript"],[1733,"miniscript::miniscript"],[1734,"miniscript::miniscript::decode"],[1735,"miniscript::miniscript::context"],[1736,"miniscript::iter::tree"],[1737,"miniscript::descriptor::key"],[1738,"alloc::vec"],[1739,"miniscript::miniscript::satisfy"],[1740,"miniscript::plan"],[1741,"bitcoin_hashes::sha256"],[1742,"miniscript::miniscript::hash256"],[1743,"bitcoin_hashes::ripemd160"],[1744,"bitcoin_hashes::hash160"],[1745,"core::clone"],[1746,"secp256k1"],[1747,"bitcoin::crypto::key"],[1748,"secp256k1::context"],[1749,"bdk_chain::descriptor_ext"],[1750,"miniscript::blanket_traits"],[1751,"bitcoin::blockdata::script::owned"],[1752,"miniscript::miniscript::analyzable"],[1753,"secp256k1::context::alloc_only"],[1754,"bitcoin::blockdata::script::borrowed"],[1755,"core::ops::range"],[1756,"core::ops::function"],[1757,"miniscript::descriptor::sh"],[1758,"miniscript::descriptor::bare"],[1759,"miniscript::descriptor::segwitv0"],[1760,"miniscript::descriptor::tr"],[1761,"miniscript::miniscript::types"],[1762,"miniscript::miniscript::types::extra_props"],[1763,"miniscript::expression"],[1764,"miniscript::miniscript::iter"],[1765,"miniscript::policy::semantic"],[1766,"miniscript::policy"],[1767,"bitcoin_units::weight"],[1768,"alloc::collections::btree::map"],[1769,"alloc::string"],[1770,"hex_conservative::error"],[1771,"bitcoin::bip32"],[1772,"base58ck::error"],[1773,"miniscript::descriptor::sortedmulti"],[1774,"core::str::traits"],[1775,"core::convert"],[1776,"core::default"],[1777,"bitcoin_units::amount"],[1778,"bitcoin_units::fee_rate"],[1779,"bdk_chain::keychain"],[1780,"alloc::sync"],[1781,"core::iter::traits::iterator"],[1782,"bitcoin::blockdata::block"],[1783,"bdk_chain::local_chain"],[1784,"bdk_chain::chain_data"],[1785,"core::iter::traits::collect"],[1786,"bdk_chain::tx_graph"],[1787,"bitcoin::psbt"],[1788,"bdk_chain::spk_client"],[1789,"bitcoin::psbt::map::input"],[1790,"bdk_wallet::wallet::utils"],[1791,"core::iter::traits::double_ended"],[1792,"bdk_chain::keychain::txout_index"],[1793,"bitcoin::psbt::error"],[1794,"core::marker"],[1795,"bitcoin::crypto::sighash"],[1796,"bitcoin::blockdata::script::push_bytes::primitive"],[1797,"bitcoin::blockdata::locktime::absolute"]],"i":[1,8,0,1,0,8,0,0,0,0,0,0,1,1,0,1,6,7,8,1,6,7,8,0,1,6,7,8,1,6,7,8,1,6,6,0,0,1,6,1,6,7,8,1,6,7,8,0,1,6,7,8,1,6,1,6,7,8,6,6,0,0,8,6,1,0,7,8,1,6,0,0,1,6,7,8,1,6,7,8,1,6,7,8,8,6,1,6,7,8,7,0,1,6,7,8,0,250,250,250,94,251,24,0,0,0,0,0,0,31,0,0,33,0,0,35,94,251,24,0,0,0,94,251,24,35,31,0,94,251,24,94,251,24,94,251,24,35,24,54,55,31,31,24,24,54,55,31,24,54,55,31,31,31,31,0,33,54,55,33,55,33,33,54,55,33,54,55,33,33,54,55,33,54,55,33,54,55,0,24,54,55,31,24,54,55,31,24,54,55,31,31,24,24,24,24,24,24,31,24,31,24,54,55,31,0,24,31,31,69,24,31,24,24,24,54,55,31,31,24,31,24,24,24,24,24,24,24,54,55,31,31,31,24,31,31,31,24,31,31,31,24,24,31,31,24,24,54,55,31,24,54,55,31,31,24,93,94,24,24,31,31,31,24,31,31,33,54,55,31,24,31,24,33,54,55,24,24,24,24,24,24,24,24,24,24,24,24,24,24,31,33,31,24,31,31,24,54,55,31,33,54,55,24,24,0,31,24,31,24,31,31,24,24,31,24,31,33,54,55,31,0,24,54,55,31,24,31,24,33,33,24,31,24,54,55,31,24,54,55,31,31,24,54,55,31,24,24,54,55,31,31,0,0,74,74,0,74,74,74,74,74,74,74,74,74,74,74,74,74,74,74,74,74,74,74,74,74,74,74,74,74,74,74,74,74,121,117,117,0,122,0,0,121,120,0,121,121,117,117,117,121,122,71,117,122,122,0,0,0,71,71,120,121,121,0,0,121,121,121,120,120,121,122,73,123,117,71,120,121,122,73,123,117,71,120,121,122,73,123,71,120,121,122,73,123,71,73,123,123,120,121,122,73,123,117,120,121,122,73,123,117,117,71,120,121,122,122,73,73,123,117,71,73,120,123,121,73,120,121,122,73,123,117,71,121,122,123,73,123,73,73,120,121,122,73,123,123,120,121,122,73,123,71,117,120,121,122,73,123,117,71,120,121,122,73,123,117,71,120,121,122,73,123,117,71,120,121,122,73,123,117,71,252,252,252,253,254,255,254,255,254,255,254,255,254,255,256,257,258,259,260,261,261,260,262,263,0,0,0,0,0,0,0,0,0,0,0,0,0,0,126,128,129,130,132,134,135,136,137,138,139,140,126,128,129,130,132,134,135,136,137,138,139,140,124,126,128,129,130,132,134,135,136,137,138,139,140,126,128,129,130,132,134,135,136,137,138,139,140,126,128,129,130,132,134,135,136,137,138,139,140,125,126,128,129,130,132,134,135,136,137,138,139,140,126,128,129,130,132,134,135,136,137,138,139,140,126,128,129,130,132,134,135,136,137,138,139,140,126,128,129,130,132,134,135,136,137,138,139,140,126,128,129,130,132,134,135,136,137,138,139,140,118,0,0,0,0,158,158,0,0,147,0,0,0,0,118,118,118,33,0,0,30,118,118,103,35,158,151,0,151,0,0,30,35,103,0,0,0,0,30,0,147,103,35,0,264,35,151,143,148,30,144,118,142,35,103,145,146,147,151,143,148,30,144,118,142,35,103,145,146,147,142,33,33,33,33,33,33,33,33,33,143,30,144,142,35,103,145,146,147,143,30,144,142,35,103,145,146,147,142,35,145,147,144,144,143,35,35,142,30,142,35,103,145,146,147,148,30,144,118,118,142,142,35,35,103,103,145,146,147,142,151,151,151,143,148,30,144,118,118,118,142,35,35,103,145,146,147,148,148,35,103,142,35,35,158,161,158,161,151,35,142,35,145,147,151,143,148,30,144,118,142,35,103,145,146,147,35,127,133,143,143,148,35,103,133,151,143,143,35,103,151,151,35,264,30,35,103,264,30,264,30,35,35,142,145,146,142,0,35,33,142,142,0,142,33,142,35,145,146,33,148,142,35,145,147,33,142,142,142,142,35,33,142,0,143,30,144,142,35,103,145,146,147,103,118,142,35,103,33,33,142,151,143,148,30,144,118,142,35,103,145,146,147,151,143,148,30,144,118,142,35,103,145,146,147,151,143,148,30,144,118,142,35,103,145,146,147,151,143,148,30,144,118,142,35,103,145,146,147,0,166,166,166,0,0,0,201,0,200,197,198,199,0,0,0,199,199,199,198,198,198,0,0,201,0,0,169,170,193,170,170,170,170,170,170,170,169,170,183,193,197,198,199,200,201,169,170,183,193,197,198,199,200,201,170,170,170,170,170,213,183,170,169,183,169,183,0,169,169,183,193,170,170,170,169,169,193,0,0,170,169,169,170,183,193,193,197,197,198,198,199,199,200,200,201,201,169,170,183,183,183,193,197,198,199,200,201,170,170,170,170,170,183,169,193,213,170,170,170,169,170,183,193,197,198,199,200,201,210,170,193,170,183,170,170,170,170,170,170,170,170,213,170,170,170,170,170,170,170,170,170,170,170,170,170,169,170,0,170,170,170,170,170,169,183,169,193,197,198,199,200,201,169,170,169,169,169,170,183,193,197,198,199,200,201,169,170,183,193,197,198,199,200,201,0,170,169,170,183,193,197,198,199,200,201,170,170,169,169,170,183,193,197,198,199,200,201,0,265,265,266,266,267,268,267,268,269,269,224,224,0,225,0,0,0,0,0,224,0,225,0,224,225,223,219,220,221,224,225,223,219,220,221,219,220,221,219,220,221,222,219,220,221,0,219,220,221,223,223,224,224,225,223,219,220,221,224,225,223,219,220,221,224,225,223,219,220,221,223,221,223,223,219,220,221,224,224,225,223,219,220,221,224,225,223,219,220,221,224,225,223,219,220,221,224,225,223,219,220,221,270,270,271,272,272,271,272,0,206,226,0,206,206,190,206,190,206,206,0,206,206,206,206,206,226,206,206,206,206,206,190,190,206,190,226,206,206,226,206,190,226,206,190,226,226,226,226,206,206,190,190,226,206,206,206,206,206,206,190,226,206,190,226,226,206,190,226,206,190,226,206,190,226,206,190,226,206,190,273,273,274,274,275,276,0,0,277,228,228,228,228,228,228,228,228,228,228,228,228,277,228,228,228,228,228,228,228,233,229,233,196,229,233,196,0,196,196,196,230,196,196,196,196,196,196,196,233,229,230,196,196,0,0,0,0,0,0,0,0,230,0,0,196,196,70,195,195,70,195,229,196,230,231,171,70,195,233,229,196,230,231,171,70,195,233,70,229,230,231,171,70,195,233,229,230,231,171,70,195,233,229,171,171,70,195,233,231,234,231,231,231,229,230,171,233,70,229,196,196,230,231,171,70,195,233,229,229,229,196,196,196,196,230,231,171,70,195,233,229,234,231,231,231,70,229,196,230,231,171,70,195,233,231,70,229,171,70,241,231,231,231,172,231,195,70,195,229,230,231,171,70,195,233,196,195,195,229,196,230,231,171,70,195,233,229,196,230,231,171,70,195,233,229,196,230,231,171,70,195,233,229,196,230,231,171,70,195,233,278,0,0,247,246,246,0,244,244,244,246,247,0,0,245,247,189,189,189,189,189,189,189,189,189,189,245,244,247,246,189,245,244,247,246,189,189,247,246,189,247,246,247,246,189,189,247,246,189,189,189,189,189,247,246,189,189,189,189,245,245,244,244,247,246,189,245,244,247,246,247,246,189,189,245,244,247,246,189,189,189,189,189,247,246,189,189,189,247,189,247,246,245,244,189,245,244,247,246,189,245,244,247,246,189,245,244,247,246,189,189,189,245,244,247,246,279,279],"f":"````````````{{{d{b}}}f}{{{d{b}}}{{d{{h{f}}}}}}`{{{d{c}}}{{d{e}}}{}{}}000{{{d{jc}}}{{d{je}}}{}{}}000`{{{d{b}}}b}{{{d{l}}}l}{{{d{n}}}n}{{{d{A`}}}A`}{{{d{c}}{d{je}}}Ab{}{}}000{{{d{b}}{d{b}}}Ad}````{c{{Af{b}}}Ah}{c{{Af{l}}}Ah}{{{d{b}}{d{b}}}Aj}{{{d{l}}{d{l}}}Aj}{{{d{n}}{d{n}}}Aj}{{{d{A`}}{d{A`}}}Aj}{{{d{b}}{d{jAl}}}An}{{{d{l}}{d{jAl}}}An}{{{d{n}}{d{jAl}}}An}{{{d{A`}}{d{jAl}}}An}`{cc{}}000{{{d{b}}{d{jc}}}AbB`}{{{d{l}}{d{jc}}}AbB`}{ce{}{}}000````{{{d{A`}}}Bb}`{{{d{b}}{d{b}}}{{Bd{Ad}}}}``{{{d{A`}}}{{Bd{Bf}}}}{{{d{b}}c}AfBh}{{{d{l}}c}AfBh}``{{{d{c}}}e{}{}}000{c{{Af{e}}}{}{}}0000000{{{d{A`}}}{{d{Bj}}}}`{{{d{c}}}Bl{}}000`{{}{{d{Bn}}}}::::``````````````````````````````````````````{{{d{{C`{c}}}}Cb}{{Af{CdCf}}}{ChCj}}{{}Cl}0{{{d{{Cn{ce}}}}}{{d{{D`{ce}}}}}ChDb}{{{d{{d{{Cn{ce}}}}}}}{{Dd{{d{{Cn{ce}}}}}}}ChDb}{{{d{{C`{Df}}}}Dh}{{Af{{C`{Dj}}Dl}}}}{{{d{c}}}{{d{e}}}{}{}}000{{{d{jc}}}{{d{je}}}{}{}}000{{{d{{Cn{ce}}}}}{{Dn{{d{{Cn{ce}}}}}}}ChDb}{{{d{{Cn{ce}}}}{d{g}}}{{Eb{{E`{c}}}}}{CjCh}Db{{Ed{c}}}}0`{{{d{{Cn{c{Db{}{{Ef{e}}}}}}}}}{{Af{AbEh}}}Ch{{Fj{}{{Ej{El}}{En{F`}}{Fb{Fd}}{Ff{Fh}}}}ChChChCh}}{{{d{{Cn{cFl}}}}}{{Af{AbEh}}}Ch}{{{d{{Cn{cFn}}}}}{{Af{AbEh}}}Ch}2022102102{{{d{c}}}{{Af{AbEh}}}Ch}00{{{d{{D`{c{Db{}{{Ef{e}}}}}}}}}{{Af{AbEh}}}Ch{{Fj{}{{Ej{El}}{En{F`}}{Fb{Fd}}{Ff{Fh}}}}ChChChCh}}{{{d{{D`{cFl}}}}}{{Af{AbEh}}}Ch}{{{d{{D`{cFn}}}}}{{Af{AbEh}}}Ch}{{{d{{h{{Dn{f}}}}}}}{{Af{AbEh}}}}00`{{{d{{C`{c}}}}}{{C`{c}}}{G`Ch}}{{{d{Fl}}}Fl}{{{d{Fn}}}Fn}{{{d{{Cn{ce}}}}}{{Cn{ce}}}{G`Ch}{G`Db}}{{{d{c}}{d{je}}}Ab{}{}}000{{{d{{C`{c}}}}{d{{C`{c}}}}}Ad{GbCh}}{{{d{Fl}}{d{Fl}}}Ad}{{{d{Fn}}{d{Fn}}}Ad}{{{d{{Cn{ce}}}}{d{{Cn{ce}}}}}AdChDb}{{{d{{Cn{ce}}}}}AjChDb}{{{d{{C`{Df}}}}Dh}{{Af{{C`{Dj}}Dl}}}}{{{d{{C`{Dj}}}}{d{{Gd{c}}}}}{{Af{{C`{Gf}}Dl}}}Gh}{{{d{{C`{Df}}}}{d{{Gd{c}}}}Dh}{{Af{{C`{Gf}}Dl}}}Gh}{{{d{{C`{c}}}}}GjCh}{{{d{{C`{Df}}}}}Gl}{c{{Af{{C`{e}}}}}AhGn}{c{{Af{{Cn{eg}}}}}AhGnDb}{{{d{{C`{Df}}}}}H`}{{{d{{Cn{ce}}}}}Hb{CjCh}Db}{{{d{{C`{c}}}}{d{{C`{c}}}}}Aj{HdCh}}{{{d{Fl}}{d{Fl}}}Aj}{{{d{Fn}}{d{Fn}}}Aj}{{{d{{Cn{ce}}}}{d{{Cn{ce}}}}}AjChDb}`{{{d{{C`{c}}}}}{{Af{HbCf}}}{ChCj}}`{{{d{{Cn{ce}}}}{d{Hf}}}{{Af{AbHh}}}ChDb}{{{d{Hj}}{d{Hl}}Hn{d{{Gd{I`}}}}}{{Af{{Bd{Ib}}Id}}}}{{{d{{C`{Df}}}}{d{Hl}}Hn{d{{Gd{I`}}}}}{{Af{{Bd{Ib}}Id}}}}{{{d{{Cn{Dfc}}}}{d{Hl}}Hn{d{{Gd{I`}}}}}{{Af{{Bd{Ib}}Id}}}Db}{{{d{{C`{Df}}}}{d{{Gd{c}}}}{d{If}}{Ih{Dh}}}{{Af{{Bd{{Ij{Dh{C`{Gf}}}}}}Dl}}}Gh}{{{d{{C`{c}}}}{d{jAl}}}{{Af{AbIl}}}Ch}0{{{d{Fl}}{d{jAl}}}{{Af{AbIl}}}}{{{d{Fn}}{d{jAl}}}{{Af{AbIl}}}}{{{d{{Cn{ce}}}}{d{jAl}}}{{Af{AbIl}}}ChDb}0{{{d{{C`{c}}}}e}AjCh{{J`{{d{c}}}{{In{Aj}}}}}}{{{d{{Cn{ce}}}}g}AjChDb{{J`{{d{c}}}{{In{Aj}}}}}}{{{Jb{c}}}{{C`{c}}}Ch}{{{Jd{c}}}{{C`{c}}}Ch}{cc{}}{{{Jf{c}}}{{C`{c}}}Ch}{{{Jh{c}}}{{C`{c}}}Ch}{{{Jj{c}}}{{C`{c}}}Ch}{{{Jl{c}}}{{C`{c}}}Ch}444{{{D`{ce}}}{{Af{{Cn{ce}}Cf}}}ChDb}{{{D`{ce}}JnK`}{{Cn{ce}}}ChDb}{{{d{Bn}}}{{Af{{C`{c}}Cf}}}Gn}{{{d{Bn}}}{{Af{{Cn{ce}}Cf}}}GnDb}{{{d{Bn}}{d{Hf}}}{{Af{{Cn{ce}}Cf}}}GnDb}1{{{d{Kb}}}{{Af{{C`{c}}Cf}}}Gn}{{{d{Kb}}}{{Af{{Cn{ce}}Cf}}}GnDb}{{{d{{Cn{ce}}}}Kd}{{Bd{{d{{Cn{ce}}}}}}}ChDb}{{{d{{Cn{ce}}}}Kd}{{Bd{c}}}ChDb}{{{d{{C`{c}}}}e}{{Af{{Ij{{Dn{{Dn{f}}}}Hb}}Cf}}}{ChCj}{{Kf{c}}}}0{{{d{{Cn{ce}}}}}AjChDb}0{{{d{{C`{Df}}}}}Aj}{{{d{{C`{c}}}}{d{je}}}Ab{KhCh}B`}{{{d{Fl}}{d{jc}}}AbB`}{{{d{Fn}}{d{jc}}}AbB`}{{{d{{Cn{ce}}}}{d{jg}}}AbChDbB`}{ce{}{}}000{{{Cn{ce}}}{{D`{ce}}}ChDb}{{{C`{Df}}}{{Af{{Dn{{C`{Df}}}}Cf}}}}{{Kj{d{{Gd{I`}}}}Cb}{{Af{{Ij{KlKn}}Id}}}}{{Kl{d{{Gd{I`}}}}Cb}{{Af{{Ij{KlKn}}Id}}}}99:{{{d{{Cn{ce}}}}}{{L`{ce}}}ChDb}{{{d{{Cn{ce}}}}}{{Lb{ce}}}ChDb}{{{d{{C`{c}}}}}{{Af{{Ld{c}}Cf}}}Ch}{{{d{{Cn{ce}}}}}{{Af{{Ld{c}}Cf}}}ChDb}{{{d{{Cn{ce}}}}}{{Af{AbLf}}}ChDb}{{{d{{Cn{c{Db{}{{Ef{e}}}}}}}}}{{Bd{Kd}}}Ch{{Fj{}{{Ej{El}}{En{F`}}{Fb{Fd}}{Ff{Fh}}}}ChChChCh}}{{{d{{Cn{cFl}}}}}{{Bd{Kd}}}Ch}{{{d{{Cn{cFn}}}}}{{Bd{Kd}}}Ch}{{{d{{Cn{ce}}}}}{{Af{KdCf}}}ChDb}{{{d{{C`{c}}}}}{{Af{KdCf}}}Ch}1{{{d{{C`{c}}}}}{{Af{LhCf}}}Ch}{{}{{d{Bn}}}}00{{{Cn{cLj}}}{{Af{{C`{c}}Cf}}}Ch}{c{{C`{c}}}Ch}{c{{Af{{C`{c}}Cf}}}Ch}{{{Cn{cFl}}}{{Af{{C`{c}}Cf}}}Ch}{{Kd{Dn{c}}}{{Af{{C`{c}}Cf}}}Ch}{{{Jj{c}}}{{C`{c}}}Ch}{{{Jf{c}}}{{C`{c}}}Ch}4{{{Cn{cFn}}}{{Af{{C`{c}}Cf}}}Ch}3{{c{Bd{{Ll{c}}}}}{{Af{{C`{c}}Cf}}}Ch}614`{{{d{{Cn{c{Db{}{{Ef{e}}}}}}}}}{{Af{AbCf}}}Ch{{Fj{}{{Ej{El}}{En{F`}}{Fb{Fd}}{Ff{Fh}}}}ChChChCh}}{{{d{If}}}{{Af{{Cn{c}}Cf}}}Db}{{{d{{Gd{c}}}}{d{Bn}}}{{Af{{Ij{{C`{Df}}{M`{DfLn}}}}Cf}}}Mb}1{{{d{If}}{d{Hf}}}{{Af{{Cn{c}}Cf}}}Db}{{{d{{C`{c}}}}{d{{C`{c}}}}}{{Bd{Ad}}}{MdCh}}{{{d{Fl}}{d{Fl}}}{{Bd{Ad}}}}{{{d{Fn}}{d{Fn}}}{{Bd{Ad}}}}{{{d{{Cn{ce}}}}{d{{Cn{ce}}}}}{{Bd{Ad}}}ChDb}{{{d{c}}}KdCh}00{{{C`{Dj}}{d{c}}}{{Af{Mf{C`{Dj}}}}}{{Ed{Dj}}}}0`{{{d{{Cn{ce}}}}}AjChDb}{{{d{{C`{c}}}}}{{Af{AbCf}}}Ch}{{{d{{Cn{ce}}}}}{{Af{AbHh}}}ChDb}{{{d{{C`{c}}}}{d{jMh}}e}{{Af{AbCf}}}{ChCj}{{Kf{c}}}}{{{d{{Cn{ce}}}}g}{{Af{{Dn{{Dn{f}}}}Cf}}}{CjCh}Db{{Kf{c}}}}0{{{d{{C`{c}}}}}{{Af{HbCf}}}{ChCj}}{{{d{{C`{c}}}}}Hb{ChCj}}{{{d{{Cn{ce}}}}}KdChDb}{{{d{{C`{c}}}}e}AfChBh}{{{d{{Cn{ce}}}}g}AfChDbBh}{{}Mj}00{{{d{{Cn{ce}}}}{d{{M`{Fhc}}}}}{{Cn{ce}}}ChDb}`{{{d{c}}}e{}{}}000{{{d{c}}}Ml{}}0{{{d{{C`{Df}}}}{d{{M`{DfLn}}}}}Ml}{{{d{{Cn{c{Db{}{{Ef{e}}}}}}}}}{{Af{AbCf}}}Ch{{Fj{}{{Ej{El}}{En{F`}}{Fb{Fd}}{Ff{Fh}}}}ChChChCh}}0{{{d{{C`{c}}}}{d{ji}}}{{Af{{Mn{g}}}}}ChCh{}{{N`{ceg}}}}{{{d{{Cn{ce}}}}{d{jk}}}{{Af{{Mn{i}}}}}ChDbCh{}{{N`{cgi}}}}{c{{Af{e}}}{}{}}0000000`{{{d{c}}}Bl{}}000={ce{}{}}000{{{d{{Cn{ce}}}}}AjChDb}{{{d{Bn}}}{{Af{MlId}}}}{{{d{Bn}}}{{Af{{Nb{f}}Id}}}}``````````````{{{d{c}}}{{d{e}}}{}{}}{{{d{jc}}}{{d{je}}}{}{}}{{{d{Id}}{d{jAl}}}An}0{NdId}{cc{}}{NfId}{CfId}{NhId}{NjId}{NlId}{NnId}>{{{d{c}}}Ml{}}{c{{Af{e}}}{}{}}0{{{d{c}}}Bl{}}{ce{}{}}```````````````````````````````````>>>>>>>======={{{d{O`}}}O`}{{{d{Ob}}}Ob}{{{d{Od}}}Od}{{{d{Ib}}}Ib}{{{d{Of}}}Of}{{{d{Hn}}}Hn}{{{d{c}}{d{je}}}Ab{}{}}00000``{{}Of}{{{d{O`}}{d{O`}}}Aj}{{{d{Ob}}{d{Ob}}}Aj}{{{d{Od}}{d{Od}}}Aj}{{{d{Ib}}{d{Ib}}}Aj}{{{d{Of}}{d{Of}}}Aj}{{{d{Nj}}{d{Nj}}}Aj}{{{d{O`}}{d{jAl}}}An}{{{d{Ob}}{d{jAl}}}An}{{{d{Od}}{d{jAl}}}An}{{{d{Ib}}{d{jAl}}}An}{{{d{Of}}{d{jAl}}}An}{{{d{Nj}}{d{jAl}}}An}0{{{d{Hn}}{d{jAl}}}An}{cc{}}0{AjOd}1{ObIb}2222{{{d{Ib}}{d{{M`{Ml{Dn{Kd}}}}}}}{{Af{OfNj}}}}{{{d{O`}}{d{jc}}}AbB`}{{{d{Of}}{d{jc}}}AbB`}{{{d{Ob}}}Ml}`{ce{}{}}000000{{{d{Ob}}}Aj}{{{d{Od}}}Aj}{{{d{Of}}}Aj}`{{{d{Of}}{d{Of}}}{{Bd{Ad}}}}{{{d{Ib}}}Aj}`{{{d{O`}}c}AfBh}{{{d{Ob}}c}AfBh}{{{d{Od}}c}AfBh}{{{d{Ib}}c}AfBh}{{{d{Of}}c}AfBh}`{{{d{c}}}e{}{}}00000{{{d{c}}}Ml{}}{c{{Af{e}}}{}{}}0000000000000{{{d{c}}}Bl{}}000000>>>>>>>``````````````````````````````````````{{{d{c}}}{{d{e}}}{}{}}00000000000{{{d{jc}}}{{d{je}}}{}{}}00000000000{{OhCb}{{Af{OjId}}}}{{{Ol{c}}Cb}{{Af{OjId}}}{{On{Fl}}}}{{{A@`{c}}Cb}{{Af{OjId}}}{{On{Fn}}}}{{{A@b{c}}Cb}{{Af{OjId}}}{{On{Fn}}}}{{{A@d{c}}Cb}{{Af{OjId}}}{{On{A@f}}}}{{{A@h{c}}Cb}{{Af{OjId}}}{{A@j{Fl}}}}{{{A@l{c}}Cb}{{Af{OjId}}}{{A@j{Fl}}}}{{{A@n{c}}Cb}{{Af{OjId}}}{{A@j{Fn}}}}{{{AA`{c}}Cb}{{Af{OjId}}}{{A@j{Fn}}}}{{{AAb{c}}Cb}{{Af{OjId}}}{{A@j{Fn}}}}{{{AAd{c}}Cb}{{Af{OjId}}}{{A@j{Fn}}}}{{{AAf{c}}Cb}{{Af{OjId}}}{{A@j{A@f}}}}{{{AAh{c}}Cb}{{Af{OjId}}}{{A@j{A@f}}}}{cc{}}00000000000{ce{}{}}00000000000{{Oj{d{{Gd{I`}}}}Cb}{{Af{{Ij{KlKn}}Id}}}}{{c{d{{Gd{I`}}}}Cb}{{Af{{Ij{{C`{Df}}{M`{DfLn}}}}Id}}}{}}00000000000{c{{Af{e}}}{}{}}00000000000000000000000{{{d{c}}}Bl{}}00000000000444444444444```````````````````````````````````````````{{}AAj}{{}Cl}{{DfDh}{{Af{DjDl}}}}{{{d{c}}}{{d{e}}}{}{}}00000000000{{{d{jc}}}{{d{je}}}{}{}}00000000000{{{d{{AAl{ce}}}}{d{g}}}{{Eb{{E`{c}}}}}{CjCh}Db{{Ed{c}}}}{{{d{{Cn{c{Db{}{{Ef{e}}}}}}}}}{{Af{AbEh}}}Ch{{Fj{}{{Ej{El}}{En{F`}}{Fb{Fd}}{Ff{Fh}}}}ChChChCh}}00000{{{d{c}}}{{Af{AbEh}}}Ch}{{{d{{D`{c{Db{}{{Ef{e}}}}}}}}}{{Af{AbEh}}}Ch{{Fj{}{{Ej{El}}{En{F`}}{Fb{Fd}}{Ff{Fh}}}}ChChChCh}}{{{d{{h{{Dn{f}}}}}}}{{Af{AbEh}}}}{{{d{{AAn{ce}}}}}{{AAn{ce}}}G`Db}{{{d{Cl}}}Cl}{{{d{AB`}}}AB`}{{{d{{AAl{ce}}}}}{{AAl{ce}}}{G`Ch}{G`Db}}{{{d{Df}}}Df}{{{d{Ln}}}Ln}{{{d{ABb}}}ABb}{{{d{ABd}}}ABd}{{{d{ABf}}}ABf}{{{d{c}}{d{je}}}Ab{}{}}00000000{{{d{{AAl{ce}}}}{d{{AAl{ce}}}}}Ad{GbCh}{GbDb}}{{{d{Df}}{d{Df}}}Ad}{{{d{ABb}}{d{ABb}}}Ad}{{{d{ABf}}{d{ABf}}}Ad}`{{}AB`}{{{d{{AAn{ce}}}}}{{d{g}}}{}Db{}}{{DfDh}{{Af{DjDl}}}}{c{{Af{Df}}}Ah}{{{d{{AAl{ce}}}}}Hb{CjCh}Db}{{{d{Cl}}{d{Cl}}}Aj}{{{d{{AAl{ce}}}}{d{{AAl{ce}}}}}Aj{HdCh}{HdDb}}{{{d{Df}}{d{Df}}}Aj}{{{d{Ln}}{d{Ln}}}Aj}{{{d{ABb}}{d{ABb}}}Aj}{{{d{ABd}}{d{ABd}}}Aj}{{{d{ABf}}{d{ABf}}}Aj}{{{d{{ABh{c}}}}{d{jAl}}}An{ABjDb}}{{{d{Cl}}{d{jAl}}}An}{{{d{AB`}}{d{jAl}}}An}{{{d{Nl}}{d{jAl}}}An}0{{{d{{AAl{ce}}}}{d{jAl}}}{{Af{AbIl}}}ChDb}0{{{d{Df}}{d{jAl}}}{{Af{AbIl}}}}0{{{d{Ln}}{d{jAl}}}{{Af{AbIl}}}}0{{{d{ABb}}{d{jAl}}}{{Af{AbIl}}}}{{{d{ABd}}{d{jAl}}}{{Af{AbIl}}}}{{{d{ABf}}{d{jAl}}}{{Af{AbIl}}}}{{{d{{AAl{ce}}}}g}AjChDb{{J`{{d{c}}}{{In{Aj}}}}}}{ABl{{ABn{c}}}Db}{AC`{{ABn{c}}}Db}{cc{}}0000{NfNl}1{CfNl}22{DjDf}3333{{DfAAj}{{ABh{c}}}Db}{{LnAAj}{{ABh{c}}}Db}{{{d{Bn}}}{{Af{Df}}}}{{{d{Bn}}}{{Af{Ln}}}}{{{d{Kb}}}{{Af{{AAl{ce}}Cf}}}{ACbCh}Db}{{{d{Df}}}{{Bd{ACd}}}}{{{d{Df}}}{{Dn{ACd}}}}{c{{Af{{AAn{{ACl{}{{ACf{e}}{ACh{c}}{ACj{g}}}}i}}g}}}{}{{ACn{{h{f}}}}AD`}ABjDb}{{}{{Af{{AAn{ADbc}}e}}}Db{}}{{ce}{{Af{{AAn{{ACl{}{{ACf{e}}{ACh{c}}{ACj{g}}}}i}}g}}}{}{{ACn{{h{f}}}}AD`}ABjDb}{c{{Af{{AAn{ADbe}}g}}}{}Db{}}{{{d{{ABn{c}}}}}AjDb}{{{d{Df}}}Aj}{{{d{{AAl{ce}}}}{d{jg}}}Ab{KhCh}{KhDb}B`}{{{d{Df}}{d{jc}}}AbB`}{{{d{ABb}}{d{jc}}}AbB`}{{{d{ABf}}{d{jc}}}AbB`}{ce{}{}}00000000000{DfADd}{On{{Af{{ABh{c}}Nl}}}Db}{{A@j{Bd{ADf}}ACd}{{Af{{ABh{c}}Nl}}}Db}{{{AAn{ec}}}{{Af{{ABh{c}}Nl}}}Db{{On{c}}}}{{{AAn{ec}}{Bd{ADf}}ACd}{{Af{{ABh{c}}Nl}}}Db{{A@j{c}}}}{{{ABh{c}}}{{Af{{ABh{c}}Nl}}}Db}{Df{{Af{{ABh{c}}Nl}}}Db}{Ln{{Af{{ABh{c}}Nl}}}Db}{A@j{{Af{{ABn{c}}Nl}}}Db}{{{ABn{c}}}{{Af{{ABn{c}}Nl}}}Db}{{{AAn{ec}}}{{Af{{ABn{c}}Nl}}}Db{{A@j{c}}}}{{{AAn{ce}}}c{}Db}{Df{{Dn{Df}}}}{Ln{{Dn{Ln}}}}{{{ABn{c}}Cb}{{Bd{ABl}}}Db}{{{ABn{c}}Cb{d{{Gd{e}}}}}AC`DbMb}{{{d{Df}}}Aj}{{}Aj}{{{d{Cl}}}Aj}2{{{d{Ln}}}Aj}212133{{{d{{AAl{ce}}}}}KdChDb}``{{{d{{AAl{ce}}}}}{{Af{{Ld{c}}Cf}}}ChDb}{{}AAj}{{{d{Df}}}ADh}{{{d{{Cn{c{Db{}{{Ef{e}}}}}}}}}{{Bd{Kd}}}Ch{{Fj{}{{Ej{El}}{En{F`}}{Fb{Fd}}{Ff{Fh}}}}ChChChCh}}44{{{d{AAj}}{d{AAj}}}AAj}5{{}{{d{Bn}}}}{{Kd{Dn{c}}}{{Af{{AAl{ce}}Cf}}}ChDb}{{{d{Df}}}Kd}``{{{d{{Cn{c{Db{}{{Ef{e}}}}}}}}}{{Af{AbCf}}}Ch{{Fj{}{{Ej{El}}{En{F`}}{Fb{Fd}}{Ff{Fh}}}}ChChChCh}}{{{ABh{c}}AAj}{{ABh{c}}}Db}{{{d{{AAl{ce}}}}{d{{AAl{ce}}}}}{{Bd{Ad}}}{MdCh}{MdDb}}{{{d{Df}}{d{Df}}}{{Bd{Ad}}}}{{{d{ABb}}{d{ABb}}}{{Bd{Ad}}}}{{{d{ABf}}{d{ABf}}}{{Bd{Ad}}}}{{{d{c}}}KdCh}{{{d{{AAl{ce}}}}}{{d{{h{c}}}}}ChDb}{{{d{{AAl{ce}}}}}{{Af{AbCf}}}ChDb}{{{d{{AAl{ce}}}}g}{{Af{{Dn{{Dn{f}}}}Cf}}}{CjCh}Db{{Kf{c}}}}{{{d{{AAl{ce}}}}}KdChDb}{{{d{Df}}c}AfBh}{{}Mj}{{{d{{AAl{ce}}}}}{{D`{ce}}}{CjCh}Db}{{}AAj}{{{d{c}}}e{}{}}00000000{{{d{Ln}}{d{{Gd{c}}}}}{{Af{DfADj}}}Mb}{{{d{c}}}Ml{}}000{{{d{{Cn{c{Db{}{{Ef{e}}}}}}}}}{{Af{AbCf}}}Ch{{Fj{}{{Ej{El}}{En{F`}}{Fb{Fd}}{Ff{Fh}}}}ChChChCh}}0{{{d{{AAl{ce}}}}{d{jk}}}{{Af{{AAl{ge}}{Mn{i}}}}}ChDbCh{}{{N`{cgi}}}}{c{{Af{e}}}{}{}}00000000000000000000000{{{d{c}}}Bl{}}00000000000{ce{}{}}00000000000`{{{d{ADl}}}{{Bd{ADn}}}}{{{d{ADl}}}{{Bd{AE`}}}}{{{d{ADl}}Kd}{{Bd{Bj}}}}```````````````````````{{AEbAEb}AEb}{{{d{jAEd}}bAEf{AEj{AEh}}}Ab}`{{{d{AEd}}}{{M`{b{`{{AF`{}{{AEl{{AEn{Hb}}}}}}G`}}}}}}{{{d{jAEd}}{d{AFb}}Dh}{{Af{AbAFd}}}}{{{d{jAEd}}{d{AFb}}DhAFf}{{Af{AbAFh}}}}{{{d{jAEd}}c}Ab{{AFl{}{{AEl{{Ij{{d{AFj}}H`}}}}}}}}{{{d{jAEd}}c}{{Af{AbAFd}}}{{AG`{AFn}}}}{{{d{AEd}}}{{d{{AGd{AGb}}}}}}{{{d{AEd}}}AEb}{{{d{c}}}{{d{e}}}{}{}}00000000{{{d{jc}}}{{d{je}}}{}{}}00000000{{{d{jAEd}}AGf}{{Af{{AGj{AGh}}AGl}}}}{{{d{jAEd}}}{{AGj{AGh}}}}{{{d{AEd}}{d{AFj}}}{{Af{ADnAGn}}}}{{{d{AEd}}{d{AFj}}}{{Af{AE`AGn}}}}{{{d{jAEd}}{d{AFj}}}Ab}``{{{d{AEd}}}AH`}{{{d{AEb}}}AEb}{{{d{AFn}}}AFn}{{{d{c}}{d{je}}}Ab{}{}}0``{{}AEb}{{}AFn}{{{d{AHb}}}{{d{c}}}{}}{{{d{AEd}}b}{{Bd{Dh}}}}{{{d{AEd}}{d{If}}}{{Bd{{Ij{bDh}}}}}}{{{d{AEd}}b}Ml}{c{{Af{AEb}}}Ah}{{{d{AEb}}{d{AEb}}}Aj}{{{d{AHb}}{d{AHb}}}Aj}``{{{d{AEd}}{d{jAHd}}AHf}{{Af{AjAHh}}}}{{{d{AEb}}{d{jAl}}}{{Af{AbIl}}}}0{{{d{AEd}}{d{jAl}}}An}{{{d{AFn}}{d{jAl}}}An}{{{d{AHb}}{d{jAl}}}An}0{{{d{AHj}}{d{jAl}}}An}0{{{d{AHl}}{d{jAl}}}An}0{{{d{AHn}}{d{jAl}}}An}0{{{d{AI`}}{d{jAl}}}An}0{{{d{AIb}}{d{jAl}}}An}0{cc{}}0{AIdAFn}{{{AIf{b}}}AFn}2222222{{{d{AEd}}b}{{d{Kl}}}}{{{d{AEd}}l{Bd{AIh}}Aj}{{Af{AIjAIl}}}}{{{d{AEd}}b}{{AEj{Hl}}}}{{{d{AEd}}AGf}{{Bd{{AIn{{AEj{AFj}}AGb}}}}}}{{{d{AEd}}Bb}{{Bd{l}}}}````{{{d{jAEd}}AFf}{{Af{AjAJ`}}}}{{{d{jAEd}}AFjAJb}{{Af{AjAI`}}}}{{{d{jAEd}}BbBj}Ab}{ce{}{}}00000000{{{d{AJd}}{d{If}}}Aj}{{{d{AEd}}{d{If}}}Aj}`{{{d{AEd}}}{{`{{AF`{}{{AEl{{Ij{{d{b}}{d{Kl}}}}}}}}}}}}`{{{d{AEd}}}AJf}{{{d{AEd}}}{{`{{AF`{}{{AEl{l}}}}}}}}0{{{d{AEd}}b}{{`{{AJh{}{{AEl{AHb}}}}}}}}{AJj{{Af{AEdAHl}}}}{{{d{AEd}}}{{d{AJl}}}}{{{d{jAEd}}bDh}Aj}{{{d{AEd}}}Cb}`{{ccCb}{{Af{AEdAHj}}}Kj}{{cc{Bd{AJj}}Cb}{{Af{AEdAHn}}}Kj}{{cc{Bd{AJj}}CbAJn}{{Af{AEdAHn}}}Kj}{{ccCbAJn}{{Af{AEdAHj}}}Kj}{{{d{AEd}}b}Dh}{{{d{jAEd}}b}AHb}{{{d{AEd}}bDh}AHb}{{{d{AEd}}b}{{Af{{Bd{Ib}}Id}}}}{{{d{AEd}}b}{{d{Kl}}}}{{{d{jAEd}}bDh}{{`{{AF`{}{{AEl{AHb}}}}}}}}4{{{d{AEd}}}{{d{{Gd{I`}}}}}}{{{d{AEd}}{d{AFj}}}{{Ij{ADnADn}}}}{{{d{AEb}}c}AfBh}{{{d{AEd}}{d{jAHd}}AHf}{{Af{AjAHh}}}}`{{{d{AEd}}}{{d{{AK`{b}}}}}}{{{d{AEd}}}{{Bd{{d{AJj}}}}}}{{{d{AEd}}}{{AKb{b}}}}{{{d{AEd}}}AKd}{{{d{jAEd}}}{{Bd{AJj}}}}{{{d{c}}}e{}{}}0{{{d{c}}}Ml{}}000000{{{d{AEb}}}ADn}{{{d{AEd}}}{{`{{AF`{}{{AEl{{AIn{{AEj{AFj}}AGb}}}}}}}}}}`1{c{{Af{e}}}{}{}}00000000000000000`{{{d{AEd}}}{{d{{AGd{AGb}}}}}}{{{d{c}}}Bl{}}00000000{{{d{AEd}}b}{{`{{AF`{}{{AEl{{AEn{Hb}}}}}}G`}}}}{{{d{jAEd}}bDh}Aj}`{ce{}{}}00000000{{c{Bd{c}}Cb{d{{Gd{I`}}}}}{{Af{MlId}}}Kj}```````````````````````{{{d{c}}}{{d{e}}}{}{}}00000{{{d{jc}}}{{d{je}}}{}{}}00000{{{d{AKf}}}AKf}{{{d{AKh}}}AKh}{{{d{AKj}}}AKj}{{{d{c}}{d{je}}}Ab{}{}}00{{{d{AKl}}{Dn{n}}{Dn{n}}AE`H`{d{If}}}{{Af{AKnAL`}}}}{{{d{AKf}}{Dn{n}}{Dn{n}}AE`H`{d{If}}}{{Af{AKnAL`}}}}{{{d{AKh}}{Dn{n}}{Dn{n}}AE`H`{d{If}}}{{Af{AKnAL`}}}}{{{d{AKj}}{Dn{n}}{Dn{n}}AE`H`{d{If}}}{{Af{AKnAL`}}}}{{H`AE`{d{If}}}ALb}{{}AKf}{{}AKh}{{}AKj}``{{{d{AL`}}{d{jAl}}}An}0{{{d{ALb}}{d{jAl}}}An}{{{d{AKn}}{d{jAl}}}An}{{{d{AKf}}{d{jAl}}}An}{{{d{AKh}}{d{jAl}}}An}{{{d{AKj}}{d{jAl}}}An}{cc{}}00000{ce{}{}}00000{{{d{AKn}}}H`}{H`AKj}`1{{{d{c}}}e{}{}}00{{{d{c}}}Ml{}}{c{{Af{e}}}{}{}}00000000000{{{d{c}}}Bl{}}00000666666`````````````````````````````````````{{{d{c}}}{{d{e}}}{}{}}00{{{d{jc}}}{{d{je}}}{}{}}00{{{d{ALd}}}ALd}{{{d{c}}{d{je}}}Ab{}{}}{{{d{ALd}}{d{jAl}}}An}0{{{d{AIl}}{d{jAl}}}An}0{{{d{AGl}}{d{jAl}}}An}0>{AL`AIl}{NjAIl}{ALdAIl}{ALfAIl}{cc{}}{IdAIl}1{ce{}{}}00{{{d{c}}}e{}{}}{{{d{c}}}Ml{}}00{c{{Af{e}}}{}{}}00000{{{d{c}}}Bl{}}00444``````````{{{d{c}}}{{d{e}}}{}{}}{{{d{jc}}}{{d{je}}}{}{}}{{{d{ALh}}}{{Bd{Ml}}}}{{{d{ALh}}}Ml}{c{{Af{ALh}}}Ah}{{{d{AEd}}{d{Bn}}Aj}{{Af{ALh{d{Bn}}}}}}{{{d{ALh}}{d{jAl}}}An}0={{{d{Bn}}}{{Af{ALhc}}}{}}<``{{{d{ALh}}c}AfBh};::9=`````````````````````````````````````{{{d{jHl}}ALjAEf{AEj{AEh}}}{{Bd{{AEj{AEh}}}}}}``{{{d{Hl}}{d{{Gd{I`}}}}}Kn}`::::::::99999999{{Kn{d{{C`{Df}}}}{d{{Gd{I`}}}}}Hl}{{{d{ALj}}}ALj}{{{d{ALl}}}ALl}{{{d{{ALn{c}}}}}{{ALn{c}}}{G`AM`ABjG`}}{{{d{AEf}}}AEf}{{{d{Hl}}}Hl}{{{d{AHf}}}AHf}{{{d{AMb}}}AMb}{{{d{c}}{d{je}}}Ab{}{}}000000{{{d{ALj}}{d{ALj}}}Ad}{{{d{AEf}}{d{AEf}}}Ad}{{}AEf}{{}Hl}{{}AHf}{{}AMb}{{{d{{ALn{c}}}}}{{d{e}}}{AM`ABjG`}{}}{{{d{AMd}}}{{Bd{Ln}}}}{{{d{{ALn{{AMf{ABl}}}}}}}{{Bd{Ln}}}}{{{d{{ALn{AMh}}}}}{{Bd{Ln}}}}{{{d{{ALn{{AMj{ABl}}}}}}}{{Bd{Ln}}}}{{{d{ALj}}{d{ALj}}}Aj}{{{d{ALl}}{d{ALl}}}Aj}{{{d{AEf}}{d{AEf}}}Aj}{{{d{AMb}}{d{AMb}}}Aj}{{{d{Hl}}ALj}{{Bd{{d{{AEj{AEh}}}}}}}}{{{d{ALj}}{d{jAl}}}An}{{{d{AHh}}{d{jAl}}}An}0{{{d{ALl}}{d{jAl}}}An}{{{d{{ALn{c}}}}{d{jAl}}}An{ABjAM`ABjG`}}{{{d{AEf}}{d{jAl}}}An}{{{d{Hl}}{d{jAl}}}An}{{{d{AHf}}{d{jAl}}}An}{{{d{AMb}}{d{jAl}}}An}{cc{}}{FhALj}{ADhALj}2{AMlAHh}{AMnAHh}{AN`AHh}555555{{{d{ALj}}{d{jc}}}AbB`}{{{d{AMd}}{d{{Gd{I`}}}}}ALj}{{{d{{ALn{{AMj{ABl}}}}}}{d{{Gd{I`}}}}}ALj}{{{d{{ALn{AMh}}}}{d{{Gd{I`}}}}}ALj}{{{d{{ALn{{AMf{ABl}}}}}}{d{{Gd{I`}}}}}ALj}{{{d{Hl}}}{{Dn{{d{ALj}}}}}}{ce{}{}}0000000{{cALl}{{ALn{c}}}{AM`ABjG`}}{{}Hl}{{{d{ALj}}{d{ALj}}}{{Bd{Ad}}}}{{{d{AEf}}{d{AEf}}}{{Bd{Ad}}}}{{{d{jHl}}ALjAEf}{{Bd{{AEj{AEh}}}}}}{{{d{ANb}}{d{jAHd}}Kd{d{AHf}}{d{{Gd{I`}}}}}{{Af{AbAHh}}}}{{{d{{ALn{{AMf{ABl}}}}}}{d{jAHd}}Kd{d{AHf}}{d{{Gd{I`}}}}}{{Af{AbAHh}}}}{{{d{{ALn{AMh}}}}{d{jAHd}}Kd{d{AHf}}{d{{Gd{I`}}}}}{{Af{AbAHh}}}}{{{d{{ALn{{AMj{ABl}}}}}}{d{jAHd}}Kd{d{AHf}}{d{{Gd{I`}}}}}{{Af{AbAHh}}}}{{{d{AEh}}{d{jAHd}}{d{AHf}}{d{{Gd{I`}}}}}{{Af{AbAHh}}}}{{{d{c}}{d{jAHd}}{d{AHf}}{d{{Gd{I`}}}}}{{Af{AbAHh}}}{}}`{{{d{Hl}}}{{Dn{{d{{AEj{AEh}}}}}}}}`{{{d{c}}}e{}{}}000000{{{d{c}}}Ml{}}``{c{{Af{e}}}{}{}}000000000000000{{{d{c}}}Bl{}}0000000{ce{}{}}0000000````````````````{{{d{j{AGj{c}}}}{d{e}}}{{d{j{AGj{c}}}}}{}{{ANf{ANd}}}}{{{d{j{AGj{c}}}}BbAIjKd}{{Af{{d{j{AGj{c}}}}ANh}}}{}}{{{d{j{AGj{c}}}}BbAIjKdBf}{{Af{{d{j{AGj{c}}}}ANh}}}{}}{{{d{j{AGj{c}}}}}{{d{j{AGj{c}}}}}{}}{{{d{j{AGj{c}}}}HbADn}{{d{j{AGj{c}}}}}{}}{{{d{j{AGj{c}}}}Bb}{{d{j{AGj{c}}}}}{}}{{{d{j{AGj{c}}}}Bb}{{Af{{d{j{AGj{c}}}}ANj}}}{}}{{{d{j{AGj{c}}}}{d{{h{Bb}}}}}{{Af{{d{j{AGj{c}}}}ANj}}}{}}{{{d{j{AGj{c}}}}Aj}{{d{j{AGj{c}}}}}{}}{{{d{c}}}{{d{e}}}{}{}}0000{{{d{jc}}}{{d{je}}}{}{}}0000{{{d{j{AGj{c}}}}ANl}{{d{j{AGj{c}}}}}{}}{{{d{{AGj{c}}}}}{{AGj{c}}}G`}{{{d{ANn}}}ANn}{{{d{ANl}}}ANl}{{{d{c}}{d{je}}}Ab{}{}}00{{{d{ANn}}{d{ANn}}}Ad}{{{d{ANl}}{d{ANl}}}Ad}{{{AGj{c}}e}{{AGj{e}}}{}AKl}{{{d{j{AGj{c}}}}Dh}{{d{j{AGj{c}}}}}{}}{{}ANn}{{}ANl}{{{d{j{AGj{c}}}}}{{d{j{AGj{c}}}}}{}}{{{d{j{AGj{c}}}}Hb}{{d{j{AGj{c}}}}}{}}11{{{d{j{AGj{c}}}}Bf}{{d{j{AGj{c}}}}}{}}{{{d{ANn}}{d{ANn}}}Aj}{{{d{ANl}}{d{ANl}}}Aj}{{{d{j{AGj{c}}}}ADn}{{d{j{AGj{c}}}}}{}}{{{d{j{AGj{c}}}}AE`}{{d{j{AGj{c}}}}}{}}{{{AGj{c}}}{{Af{AHdAIl}}}AKl}{{{d{{AGj{c}}}}{d{jAl}}}AnABj}{{{d{ANj}}{d{jAl}}}An}0{{{d{ANh}}{d{jAl}}}An}0{{{d{ANn}}{d{jAl}}}An}{{{d{ANl}}{d{jAl}}}An}{cc{}}0000{{{d{ANn}}{d{jc}}}AbB`}{{{d{ANl}}{d{jc}}}AbB`}?{ce{}{}}0000{{{d{j{AGj{c}}}}}{{d{j{AGj{c}}}}}{}}{{{d{j{AGj{c}}}}AO`}{{d{j{AGj{c}}}}}{}}11{{{d{j{AGj{c}}}}ANn}{{d{j{AGj{c}}}}}{}}{{{d{ANn}}{d{ANn}}}{{Bd{Ad}}}}{{{d{ANl}}{d{ANl}}}{{Bd{Ad}}}}{{{d{j{AGj{c}}}}{M`{Ml{Dn{Kd}}}}b}{{d{j{AGj{c}}}}}{}}{{{d{j{AGj{c}}}}{Dn{{Ij{HbADn}}}}}{{d{j{AGj{c}}}}}{}}{{{d{j{AGj{c}}}}AIh}{{d{j{AGj{c}}}}}{}}{{{d{ANn}}{d{jAFj}}}Ab}{{{d{c}}}e{}{}}00{{{d{c}}}Ml{}}0{c{{Af{e}}}{}{}}000000000{{{d{c}}}Bl{}}0000{{{d{j{AGj{c}}}}{Dn{Bb}}}{{d{j{AGj{c}}}}}{}}{{{d{j{AGj{c}}}}AOb}{{d{j{AGj{c}}}}}{}}?????``","D":"FGd","p":[[6,"KeychainKind",0,1719],[1,"reference"],[1,"u8"],[1,"slice"],[0,"mut"],[5,"LocalOutput",0,1719],[5,"WeightedUtxo",0,1719],[6,"Utxo",0,1719],[1,"unit"],[6,"Ordering",1720],[6,"Result",1721],[10,"Deserializer",1722],[1,"bool"],[5,"Formatter",1723],[8,"Result",1723],[10,"Hasher",1724],[5,"OutPoint",1725],[6,"Option",1726],[5,"Sequence",1725],[10,"Serializer",1727],[5,"TxOut",1725],[5,"TypeId",1728],[1,"str"],[6,"Descriptor",100,1729],[6,"Network",1730],[5,"Address",1731],[6,"Error",1732],[10,"MiniscriptKey",1732],[10,"ToPublicKey",1732],[6,"ScriptContextEnum",693],[5,"Miniscript",100,1733],[6,"Terminal",1734],[10,"ScriptContext",693,1735],[6,"Tree",1736],[6,"DescriptorPublicKey",693,1737],[1,"u32"],[5,"DefiniteDescriptorKey",1737],[6,"ConversionError",1737],[5,"Vec",1738],[6,"Placeholder",1739],[5,"Satisfaction",1739],[10,"AssetProvider",1740],[17,"Key"],[6,"ScriptContextError",1735],[17,"Sha256"],[5,"Hash",1741],[17,"Hash256"],[5,"Hash",1742],[17,"Ripemd160"],[5,"Hash",1743],[17,"Hash160"],[5,"Hash",1744],[10,"ParseableKey",1734],[6,"Legacy",100,1735],[6,"Segwitv0",100,1735],[10,"Clone",1745],[10,"Ord",1720],[5,"Secp256k1",1746],[5,"PublicKey",1747],[10,"Verification",1748],[6,"DescriptorType",1729],[5,"DescriptorId",1749],[10,"FromStrKey",1750],[1,"u64"],[5,"ScriptBuf",1751],[10,"PartialEq",1720],[5,"ExtParams",1752],[6,"AnalysisError",1752],[10,"ExtractPolicy",100],[5,"SignersContainer",1420],[6,"BuildSatisfaction",386],[6,"All",1753],[5,"Policy",386],[6,"Error",354],[5,"Script",1754],[5,"Range",1755],[1,"tuple"],[5,"Error",1723],[17,"Output"],[10,"FnMut",1756],[5,"Sh",1757],[5,"Bare",1758],[5,"Wsh",1759],[5,"Pkh",1758],[5,"Wpkh",1759],[5,"Tr",1760],[5,"Type",1761],[5,"ExtData",1762],[5,"Tree",1763],[1,"usize"],[10,"Satisfier",1739],[10,"Hash",1724],[10,"IntoWalletDescriptor",100],[8,"ExtendedDescriptor",100],[8,"KeyMap",693,1729],[5,"Iter",1764],[5,"PkIter",1764],[6,"Policy",1765],[6,"LiftError",1766],[5,"Weight",1767],[6,"BareCtx",1735],[6,"TapTree",1760],[6,"DescriptorSecretKey",693,1737],[5,"BTreeMap",1768],[10,"Signing",1748],[10,"PartialOrd",1720],[5,"Plan",1740],[5,"TxIn",1725],[6,"SigType",1735],[5,"String",1769],[6,"TranslateErr",1732],[10,"Translator",1732],[1,"array"],[6,"HexToBytesError",1770],[6,"Error",1771],[6,"Error",1772],[6,"PolicyError",386],[6,"KeyError",693],[6,"ParsePublicKeyError",1747],[6,"PkOrF",386],[6,"SatisfiableItem",386],[6,"Satisfaction",386],[5,"Condition",386],[10,"DescriptorTemplate",557],[8,"DescriptorTemplateOut",557],[5,"P2Pkh",557],[10,"IntoDescriptorKey",693],[5,"P2Wpkh_P2Sh",557],[5,"P2Wpkh",557],[5,"P2TR",557],[6,"Tap",1735],[5,"Bip44",557],[10,"DerivableKey",693],[5,"Bip44Public",557],[5,"Bip49",557],[5,"Bip49Public",557],[5,"Bip84",557],[5,"Bip84Public",557],[5,"Bip86",557],[5,"Bip86Public",557],[8,"ValidNetworks",693],[5,"SortedMultiVec",693,1773],[5,"GeneratedKey",693],[5,"PrivateKeyGenerateOptions",693],[5,"SinglePub",693,1737],[5,"SinglePriv",693,1737],[6,"SinglePubKey",693,1737],[6,"DescriptorKey",693],[10,"Debug",1723],[5,"Xpriv",1771],[6,"ExtendedKey",693],[5,"Xpub",1771],[10,"FromStr",1774],[5,"DerivationPath",1771],[17,"Entropy"],[17,"Options"],[17,"Error"],[10,"GeneratableKey",693],[10,"AsMut",1775],[10,"Default",1776],[10,"GeneratableDefaultOptions",693],[5,"Assets",1740],[8,"KeySource",1771],[5,"Fingerprint",1771],[5,"DescriptorKeyParseError",1737],[10,"PsbtUtils",992],[5,"Amount",1777],[5,"FeeRate",1778],[5,"Balance",996,1779],[5,"Wallet",996],[5,"SignerOrdering",1420],[10,"TransactionSigner",1420],[5,"Arc",1780],[17,"Item"],[8,"Indexed",1779],[10,"Iterator",1781],[5,"Block",1782],[5,"CannotConnectError",1783],[5,"BlockId",1784],[6,"ApplyHeaderError",1783],[5,"Transaction",1725],[10,"IntoIterator",1785],[5,"Update",996],[10,"Into",1775],[5,"ConfirmationTimeHeightAnchor",1784],[5,"TxGraph",1786],[5,"Txid",1725],[8,"DefaultCoinSelectionAlgorithm",1221],[5,"TxBuilder",1602],[6,"BuildFeeBumpError",1320],[6,"CalculateFeeError",1786],[5,"CheckPointIter",1783],[5,"AddressInfo",996],[5,"Psbt",1787],[5,"SignOptions",1420],[6,"SignerError",1420],[6,"NewError",996],[6,"LoadError",996],[6,"NewOrLoadError",996],[6,"InsertTxError",996],[6,"ApplyBlockError",996],[5,"SyncResult",1788],[5,"FullScanResult",1788],[5,"PsbtSighashType",1789],[5,"Input",1789],[6,"CreateTxError",1320],[5,"CanonicalTx",1786],[5,"AlterCheckPointError",1783],[6,"ConfirmationTime",1784],[10,"IsDust",996,1790],[5,"CheckPoint",1783],[10,"DoubleEndedIterator",1791],[8,"ChangeSet",996],[5,"LocalChain",1783],[5,"BlockHash",1782],[5,"KeychainTxOutIndex",1792],[5,"FullScanRequest",1788],[5,"SyncRequest",1788],[5,"LargestFirstCoinSelection",1221],[5,"OldestFirstCoinSelection",1221],[5,"BranchAndBoundCoinSelection",1221],[10,"CoinSelectionAlgorithm",1221],[5,"CoinSelectionResult",1221],[6,"Error",1221],[6,"Excess",1221],[6,"MiniscriptPsbtError",1320],[6,"Error",1793],[5,"FullyNodedExport",1397],[6,"SignerId",1420],[6,"SignerContext",1420],[5,"SignerWrapper",1420],[10,"Sized",1794],[6,"TapLeavesOptions",1420],[10,"SignerCommon",1420],[5,"DescriptorXKey",1737],[5,"PrivateKey",1747],[5,"DescriptorMultiXKey",1737],[5,"InputsIndexError",1725],[6,"TaprootError",1795],[6,"P2wpkhError",1795],[10,"InputSigner",1420],[5,"PushBytes",1796],[10,"AsRef",1775],[6,"AddForeignUtxoError",1602],[6,"AddUtxoError",1602],[6,"ChangeSpendPolicy",1602],[6,"TxOrdering",1602],[6,"LockTime",1797],[1,"i32"],[15,"Foreign",97],[8,"DerivedDescriptor",100],[15,"PsbtTimelocks",533],[15,"Complete",536],[15,"Partial",536],[15,"PartialComplete",536],[15,"Sha256Preimage",547],[15,"Hash256Preimage",547],[15,"Ripemd160Preimage",547],[15,"Hash160Preimage",547],[15,"Thresh",547],[15,"Multisig",547],[15,"AbsoluteTimelock",547],[15,"RelativeTimelock",547],[10,"ExtScriptContext",693],[15,"UnexpectedConnectedToHash",1211],[15,"ConfirmationHeightCannotBeGreaterThanTip",1213],[15,"LoadedGenesisDoesNotMatch",1215],[15,"LoadedNetworkDoesNotMatch",1215],[15,"LoadedDescriptorDoesNotMatch",1215],[15,"InsufficientFunds",1313],[15,"Change",1315],[15,"NoChange",1315],[15,"RbfSequenceCsv",1391],[15,"LockTime",1391],[15,"FeeTooLow",1391],[15,"FeeRateTooLow",1391],[8,"WalletExport",1397],[15,"Tap",1601],[15,"InvalidTxid",1717]],"r":[[2,100],[4,1719],[6,1719],[7,1420],[8,1602],[9,1719],[10,996],[11,1719],[70,996],[71,100],[104,1729],[106,1737],[113,1735],[114,1733],[119,386],[120,1735],[121,1735],[155,352],[696,1737],[697,1737],[712,1729],[722,1735],[727,1737],[728,1737],[729,1737],[730,1773],[998,1779],[1006,1790]],"b":[[193,"impl-Descriptor%3CDefiniteDescriptorKey%3E"],[194,"impl-Descriptor%3CDescriptorPublicKey%3E"],[213,"impl-Debug-for-Descriptor%3CPk%3E"],[214,"impl-Display-for-Descriptor%3CPk%3E"],[217,"impl-Debug-for-Miniscript%3CPk,+Ctx%3E"],[218,"impl-Display-for-Miniscript%3CPk,+Ctx%3E"],[221,"impl-From%3CSh%3CPk%3E%3E-for-Descriptor%3CPk%3E"],[222,"impl-From%3CBare%3CPk%3E%3E-for-Descriptor%3CPk%3E"],[224,"impl-From%3CWsh%3CPk%3E%3E-for-Descriptor%3CPk%3E"],[225,"impl-From%3CPkh%3CPk%3E%3E-for-Descriptor%3CPk%3E"],[226,"impl-From%3CWpkh%3CPk%3E%3E-for-Descriptor%3CPk%3E"],[227,"impl-From%3CTr%3CPk%3E%3E-for-Descriptor%3CPk%3E"],[370,"impl-Display-for-Error"],[371,"impl-Debug-for-Error"],[372,"impl-From%3CHexToBytesError%3E-for-Error"],[374,"impl-From%3CError%3E-for-Error"],[375,"impl-From%3CError%3E-for-Error"],[376,"impl-From%3CError%3E-for-Error"],[377,"impl-From%3CPolicyError%3E-for-Error"],[378,"impl-From%3CKeyError%3E-for-Error"],[379,"impl-From%3CParsePublicKeyError%3E-for-Error"],[461,"impl-Debug-for-PolicyError"],[462,"impl-Display-for-PolicyError"],[811,"impl-Display-for-KeyError"],[812,"impl-Debug-for-KeyError"],[813,"impl-Debug-for-SortedMultiVec%3CPk,+Ctx%3E"],[814,"impl-Display-for-SortedMultiVec%3CPk,+Ctx%3E"],[815,"impl-Debug-for-DescriptorPublicKey"],[816,"impl-Display-for-DescriptorPublicKey"],[817,"impl-Debug-for-DescriptorSecretKey"],[818,"impl-Display-for-DescriptorSecretKey"],[823,"impl-From%3CXpriv%3E-for-ExtendedKey%3CCtx%3E"],[824,"impl-From%3CXpub%3E-for-ExtendedKey%3CCtx%3E"],[830,"impl-From%3CError%3E-for-KeyError"],[832,"impl-From%3CError%3E-for-KeyError"],[872,"impl-IntoDescriptorKey%3CCtx%3E-for-GeneratedKey%3CK,+Ctx%3E"],[873,"impl-DerivableKey%3CCtx%3E-for-GeneratedKey%3CK,+Ctx%3E"],[1073,"impl-Debug-for-Balance"],[1074,"impl-Display-for-Balance"],[1077,"impl-Display-for-AddressInfo"],[1078,"impl-Debug-for-AddressInfo"],[1079,"impl-Debug-for-NewError"],[1080,"impl-Display-for-NewError"],[1081,"impl-Display-for-LoadError"],[1082,"impl-Debug-for-LoadError"],[1083,"impl-Debug-for-NewOrLoadError"],[1084,"impl-Display-for-NewOrLoadError"],[1085,"impl-Display-for-InsertTxError"],[1086,"impl-Debug-for-InsertTxError"],[1087,"impl-Display-for-ApplyBlockError"],[1088,"impl-Debug-for-ApplyBlockError"],[1091,"impl-From%3CSyncResult%3E-for-Update"],[1092,"impl-From%3CFullScanResult%3CKeychainKind%3E%3E-for-Update"],[1262,"impl-Debug-for-Error"],[1263,"impl-Display-for-Error"],[1358,"impl-Display-for-MiniscriptPsbtError"],[1359,"impl-Debug-for-MiniscriptPsbtError"],[1360,"impl-Debug-for-CreateTxError"],[1361,"impl-Display-for-CreateTxError"],[1362,"impl-Display-for-BuildFeeBumpError"],[1363,"impl-Debug-for-BuildFeeBumpError"],[1365,"impl-From%3CError%3E-for-CreateTxError"],[1366,"impl-From%3CPolicyError%3E-for-CreateTxError"],[1367,"impl-From%3CMiniscriptPsbtError%3E-for-CreateTxError"],[1368,"impl-From%3CError%3E-for-CreateTxError"],[1370,"impl-From%3CError%3E-for-CreateTxError"],[1407,"impl-Debug-for-FullyNodedExport"],[1408,"impl-Display-for-FullyNodedExport"],[1501,"impl-SignerCommon-for-SignerWrapper%3CDescriptorXKey%3CXpriv%3E%3E"],[1502,"impl-SignerCommon-for-SignerWrapper%3CPrivateKey%3E"],[1503,"impl-SignerCommon-for-SignerWrapper%3CDescriptorMultiXKey%3CXpriv%3E%3E"],[1510,"impl-Display-for-SignerError"],[1511,"impl-Debug-for-SignerError"],[1519,"impl-From%3CHash%3E-for-SignerId"],[1520,"impl-From%3CFingerprint%3E-for-SignerId"],[1522,"impl-From%3CInputsIndexError%3E-for-SignerError"],[1523,"impl-From%3CTaprootError%3E-for-SignerError"],[1524,"impl-From%3CP2wpkhError%3E-for-SignerError"],[1533,"impl-SignerCommon-for-SignerWrapper%3CDescriptorMultiXKey%3CXpriv%3E%3E"],[1534,"impl-SignerCommon-for-SignerWrapper%3CPrivateKey%3E"],[1535,"impl-SignerCommon-for-SignerWrapper%3CDescriptorXKey%3CXpriv%3E%3E"],[1551,"impl-InputSigner-for-SignerWrapper%3CDescriptorXKey%3CXpriv%3E%3E"],[1552,"impl-InputSigner-for-SignerWrapper%3CPrivateKey%3E"],[1553,"impl-InputSigner-for-SignerWrapper%3CDescriptorMultiXKey%3CXpriv%3E%3E"],[1660,"impl-Display-for-AddUtxoError"],[1661,"impl-Debug-for-AddUtxoError"],[1662,"impl-Display-for-AddForeignUtxoError"],[1663,"impl-Debug-for-AddForeignUtxoError"]],"c":"OjAAAAEAAAAAAAUAEAAAAMEAAwEPAR8DdgN3BQ==","e":"OzAAAAEAAH0DgAADAAAACAABAAsAAAAOABMAJgAJADUAAQA+AAAAQQAAAEUADwBXAAMAXQADAGoAAAB4AAAAjAABAI8AAACRAAcAnAAAAJ4AAQChAAAApAABAKcAAQCrAAEArgABALEAAQC0AAsAxQADAMoAAwDTAAEA1gAJAOEAAwDqAAAA9wADAAIBAAAIAQEADAEBABMBAQApAQMALgEBADwBAQA/AQEAQwEFAE4BBwBXAQMAXAEDAHEBBAB3AQUAfgEEAKYBGQDCAQ4A0wEAANUBAADbAQEA6gEAAO0BBADzASIAPAIXAFUCCwB5AjwA5AIXAAYDFQAdAwEAIAMAACIDFwA/AwAAQQMAAEQDAABLAwEAVgMDAGYDAABpAwQAbwMBAH8DAQCEAwAAjgMAAJMDAwCcAwAAoAMIAKoDAwCxAy8A/AMAAAQEAAAGBBEAIAQDACYEAgAsBAIAMgQPAEQEAQB9BAAAhQQIAJIEEQCmBAgAsgQIANMEEQDmBAIA6gQCAO8EBgAGBRsARwUNAFYFAwBbBQAAYAUPAHoFAQB+BQAAgAUBAIMFAACHBQUAtwUPAMgFFADeBQYA5gUIAPAFAQDzBQIA/AUAAP4FAgAMBgEAEAYCABQGAAAYBgcAIgYfAFsGCQBmBgcAcAYBAHcGAQB8BgYAiAYBAJUGAQCbBhMAsQYEAA=="}],\ +["bdk_tmp_plan",{"t":"FKPPPPFFGGFFPPPGPPONNNNNNNNNNNNNNNNMNNNNNNNNNNNNNNNNNNOOONNNNNNNNNNNNNNNNNNNNOOOOOONNNNNNNNOONHNNNNOOOOOOONONNNNNNNNNNNNNNNNNNNNNNNNNONNNNNNNNNNNNNNNNNOOOOOOOO","n":["Assets","CanDerive","Complete","DerivationError","Incomplete","Legacy","Plan","PlanKey","PlanState","RequiredSignatures","Requirements","SatisfactionMaterial","Segwitv0","SigHashP2wpkh","SigHashTaproot","SigningError","TapKey","TapScript","asset_key","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","can_derive","clone","clone","clone","clone","clone","clone","clone","clone_into","clone_into","clone_into","clone_into","clone_into","clone_into","clone_into","default","default","default","default","derivation_hint","descriptor_key","ecdsa_sigs","expected_weight","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","from","from","from","from","from","from","from","from","from","from","from","hash160","hash160_images","hash160_preimages","hash256","hash256_images","hash256_preimages","into","into","into","into","into","into","into","into","keys","max_locktime","min_version","plan_satisfaction","required_locktime","required_sequence","requirements","requires_hash_preimages","ripemd160","ripemd160_images","ripemd160_preimages","schnorr_sigs","sha256","sha256_images","sha256_preimages","sign_with_keymap","signatures","to_owned","to_owned","to_owned","to_owned","to_owned","to_owned","to_owned","to_string","try_complete","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","txo_age","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","vzip","vzip","vzip","vzip","vzip","vzip","vzip","vzip","witness_version","final_script_sig","final_script_witness","keys","keys","leaf_hash","merkle_root","plan_key","plan_keys"],"q":[[0,"bdk_tmp_plan"],[151,"bdk_tmp_plan::PlanState"],[153,"bdk_tmp_plan::RequiredSignatures"],[159,"miniscript::descriptor::key"],[160,"bitcoin::bip32"],[161,"core::option"],[162,"bdk_tmp_plan::requirements"],[163,"core::clone"],[164,"bdk_tmp_plan::template"],[165,"core::fmt"],[166,"bitcoin::crypto::sighash"],[167,"miniscript::descriptor"],[168,"bitcoin::blockdata::locktime::absolute"],[169,"bitcoin::blockdata::transaction"],[170,"secp256k1"],[171,"core::result"],[172,"core::borrow"],[173,"secp256k1::context"],[174,"alloc::string"],[175,"core::any"],[176,"bitcoin::blockdata::script::witness_version"]],"i":[0,0,42,10,42,9,0,0,0,0,0,0,9,10,10,0,9,9,11,42,7,9,10,11,12,13,14,42,7,9,10,11,12,13,14,3,7,9,10,11,12,13,14,7,9,10,11,12,13,14,7,9,13,14,11,11,13,12,7,9,10,10,11,12,13,14,42,7,9,10,10,10,10,11,12,13,14,14,7,13,14,7,13,42,7,9,10,11,12,13,14,14,14,12,0,12,12,12,7,14,7,13,13,14,7,13,9,7,7,9,10,11,12,13,14,10,12,42,7,9,10,11,12,13,14,42,7,9,10,11,12,13,14,14,42,7,9,10,11,12,13,14,42,7,9,10,11,12,13,14,12,45,45,46,47,48,49,49,48],"f":"```````````````````{{{b{c}}}{{b{e}}}{}{}}0000000{{{b{dc}}}{{b{de}}}{}{}}0000000{{{b{f}}{b{h}}}{{l{j}}}}{{{b{{n{c}}}}}{{n{c}}}A`}{{{b{{Ab{c}}}}}{{Ab{c}}}A`}{{{b{Ad}}}Ad}{{{b{{Af{c}}}}}{{Af{c}}}A`}{{{b{{Ah{c}}}}}{{Ah{c}}}A`}{{{b{Aj}}}Aj}{{{b{{Al{c}}}}}{{Al{c}}}A`}{{{b{c}}{b{de}}}An{}{}}000000{{}{{n{c}}}{}}{{}{{Ab{c}}}{}}{{}Aj}{{}{{Al{c}}}{}}```{{{b{{Ah{c}}}}}B`A`}{{{b{{n{c}}}}{b{dBb}}}BdBf}{{{b{{Ab{c}}}}{b{dBb}}}BdBf}{{{b{Ad}}{b{dBb}}}Bd}0{{{b{{Af{c}}}}{b{dBb}}}BdBf}{{{b{{Ah{c}}}}{b{dBb}}}BdBf}{{{b{Aj}}{b{dBb}}}Bd}{{{b{{Al{c}}}}{b{dBb}}}BdBf}{cc{}}000{BhAd}{BjAd}{BlAd}3333``````{ce{}{}}0000000``{{{b{{Ah{c}}}}}{{l{Bn}}}A`}{{{b{{C`{h}}}}{b{{Al{c}}}}}{{l{{Ah{c}}}}}{fA`}}{{{b{{Ah{c}}}}}{{l{Cb}}}A`}{{{b{{Ah{c}}}}}{{l{Cd}}}A`}{{{b{{Ah{c}}}}}{{n{c}}}A`}{{{b{{n{c}}}}}Cf{}}```````{{{b{{Ab{Ch}}}}B`{b{Cj}}{b{{Cl{c}}}}{l{Cn}}{l{D`}}{b{d{Db{e}}}}{b{dAj}}{b{{Dd{g}}}}}{{Df{CfAd}}}{{Dj{Dh}}}{{Dj{Dl}}}{DnE`}}`{{{b{c}}}e{}{}}000000{{{b{c}}}Eb{}}{{{b{{Ah{c}}}}{b{Aj}}}{{Ed{c}}}A`}{c{{Df{e}}}{}{}}000000000000000`{{{b{c}}}Ef{}}0000000<<<<<<<<{{{b{{Ah{c}}}}}{{l{Eh}}}A`}````````","D":"Fl","p":[[1,"reference"],[0,"mut"],[10,"CanDerive",0],[5,"DefiniteDescriptorKey",159],[5,"DerivationPath",160],[6,"Option",161],[5,"Requirements",0,162],[10,"Clone",163],[6,"RequiredSignatures",0,162],[6,"SigningError",0,162],[5,"PlanKey",0,164],[5,"Plan",0],[5,"SatisfactionMaterial",0],[5,"Assets",0],[1,"unit"],[1,"usize"],[5,"Formatter",165],[8,"Result",165],[10,"Debug",165],[6,"TaprootError",166],[6,"P2wpkhError",166],[6,"Error",160],[1,"u32"],[6,"Descriptor",167],[6,"LockTime",168],[5,"Sequence",169],[1,"bool"],[6,"DescriptorPublicKey",159],[8,"KeyMap",167],[6,"Prevouts",166],[6,"TapSighashType",166],[6,"EcdsaSighashType",166],[5,"SighashCache",166],[5,"Secp256k1",170],[6,"Result",171],[5,"TxOut",169],[10,"Borrow",172],[5,"Transaction",169],[10,"Signing",173],[10,"Verification",173],[5,"String",174],[6,"PlanState",0],[5,"TypeId",175],[6,"WitnessVersion",176],[15,"Complete",151],[15,"Legacy",153],[15,"Segwitv0",153],[15,"TapScript",153],[15,"TapKey",153]],"r":[[7,164],[9,162],[10,162],[15,162]],"b":[[60,"impl-Debug-for-SigningError"],[61,"impl-Display-for-SigningError"],[70,"impl-From%3CTaprootError%3E-for-SigningError"],[71,"impl-From%3CP2wpkhError%3E-for-SigningError"],[72,"impl-From%3CError%3E-for-SigningError"]],"c":"OjAAAAAAAAA=","e":"OzAAAAEAAGkAEAABAAEABAABAA4AAgAUACIAOwAHAEcAAgBOAAAAUQAAAFwAAQBfAAAAYgAAAGQAAABoAAAAawAAAG0AKQCaAAEA"}],\ +["bdk_wallet",{"t":"PPEPGPFEEGEFNNDNNNNNNNNENNNNNNNNNOOCQNNNNNNNNNNQNNNNNNNNNNOOCDNONCONNNEENNNNNNNNNNNNNONNNNOHNNNNCOOOPPPIGEGIKTIKRGFPPPPEKGPPPPTIPPPPPPPPPPNNNNNNNNNNNNNNNNNENNNNNNNNNNNNNMNNMNNNNNCNNNNNNNNNNNNNNNNNNNNNNNNNNCNONMNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNMNNNNNNNNNMNNNNNNMNNNNNNNNNNNNNNNNONNNNNNNNNMNNNNCNNNNNNNNNNNMNNNCNNNNNNNNNNNNNNNNNNNONNNNNNNNNNHHPPGPPPPPPPPPPPNNNNNNNNNNNNNNNNNNPPPGPFIPPIPPPPPPPPPPPGFGPPPPPGGPPPPNNNNNNNNNNNNNNNNNNNNNNNNNNOONNNNNNNNNNNNNNNNNNNNNNNNNNNNONNNNNNNNNNONNONNNNNONNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNOOOOOOOOOOOOOOOOOOOOOOOOFFFFFFFFKIFFFFNNNNNNNNNNNNNNNNNNNNNNNNMNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNPKGGGRRKGPKKFKPPPRGIPPPPPRPFPKGPPPFFGFPIPPPHMNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNMMNNNNNNNNNNNNNNNNNNNNNNNONNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNMNNNNNNNNNNNNNNNNNNNNMNNNNNNMNNNNNNNNNNNNNNNNNNNOONHNMNNHNMNNOONNNNNNMNNNNNMNHNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNKMMMFGFPIPPPPGKGPPPPPPGGPFFNNONNNNNNNNNNNNNNNNNNNNNNNNNNNNNNOONNNNNCONNNNNNNNNCCNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNOOOONNNNNNNNNNNNMNONONNNNNNNNONNNNNNNNNNNNNNNCNNNNNNNNNNNNNNNNONNNNNNNNNNNNNNNNNNNCNNNNNNNNNNNNONNNNNNNNNHOOOOOOOOOOPPFPKFIGGPFPFNNNNNNNNNNNNNNNNNNMNNNHNNNOONNNNNNNNNNNNNNNNNNNNNONNNNNNNNNNNNNNNNNNNNNNNNNNNNNOOOOOOOGPPGPPPPPPPGPPPPPPPPPPPPPPPPPPNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNOOOOOOFIOONNNNNNNNNNNOONNNNNNPPPPPPPKPPPPPPPPPPPPPPPPFKGGGFFFPGKPPNOONONNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNMNNNNNNNNNNNNNNNNNMNNNMNONONNNNNNNNOONNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNOGGPPPGPPPPPFGPPNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNOO","n":["External","Foreign","HdKeyPaths","Internal","KeychainKind","Local","LocalOutput","SignOptions","TxBuilder","Utxo","Wallet","WeightedUtxo","as_byte","as_ref","bitcoin","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","miniscript","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","Bare","Bare","DerivedDescriptor","Descriptor","DescriptorError","DescriptorPublicKey","ExtendedDescriptor","ExtractPolicy","FALSE","HdKeyPaths","IntoWalletDescriptor","Key","Legacy","Miniscript","MultiXPub","Pkh","Pkh","Pkh","Policy","ScriptContext","Segwitv0","Sh","Sh","Sh","Single","TRUE","TapKeyOrigins","Tr","Tr","Tr","Wpkh","Wpkh","Wpkh","Wsh","Wsh","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","descriptor_id","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","ExternalAndInternalAreTheSame","HardenedDerivationXpub","Hex","InvalidDescriptorCharacter","InvalidDescriptorChecksum","InvalidHdKeyPath","Key","Miniscript","MultiPath","Pk","Policy","borrow","borrow_mut","fmt","fmt","from","from","from","from","from","from","from","from","into","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","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_default_with_aux_rand","generate_with_aux_rand","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","n","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","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","AddressInfo","ApplyBlockError","Balance","CannotConnect","ChangeSet","ConfirmationHeightCannotBeGreaterThanTip","Descriptor","Descriptor","Descriptor","InsertTxError","IsDust","LoadError","LoadedDescriptorDoesNotMatch","LoadedGenesisDoesNotMatch","LoadedNetworkDoesNotMatch","MissingDescriptor","MissingGenesis","MissingNetwork","NewError","NewOrLoadError","UnexpectedConnectedToHash","Update","Wallet","add","add_signer","address","all_unbounded_spk_iters","apply_block","apply_block_connected_to","apply_unconfirmed_txs","apply_update","as_ref","balance","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","build_fee_bump","build_tx","calculate_fee","calculate_fee_rate","cancel_tx","chain","chain","checkpoints","clone","clone","clone_into","clone_into","coin_selection","confirmed","default","default","deref","derivation_index","derivation_of_spk","descriptor_checksum","deserialize","eq","eq","error","export","finalize_psbt","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","get_descriptor_for_keychain","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","is_dust","is_mine","keychain","keychains","last_active_indices","latest_checkpoint","list_output","list_unspent","list_unused_addresses","load_from_changeset","local_chain","mark_used","network","network","new","new_or_load","new_or_load_with_genesis_hash","new_with_genesis_hash","next_derivation_index","next_unused_address","peek_address","policies","public_descriptor","reveal_addresses_to","reveal_next_address","secp_ctx","sent_and_received","serialize","sign","signer","spk_index","staged","start_full_scan","start_sync_with_revealed_spks","take_staged","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_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","unbounded_spk_iter","unmark_used","untrusted_pending","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","got","keychain","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","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","CoinSelection","Conversion","CreateTxError","Descriptor","FeeRateTooLow","FeeRateUnavailable","FeeTooLow","IrreplaceableTransaction","LockTime","MiniscriptPsbt","MiniscriptPsbtError","MissingKeyOrigin","MissingNonWitnessUtxo","NoRecipients","NoUtxosSelected","OutputBelowDustLimit","OutputUpdate","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","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","csv","rbf","requested","required","required","required","FullyNodedExport","WalletExport","blockheight","blockheight","borrow","borrow_mut","change_descriptor","descriptor","deserialize","export_wallet","fmt","fmt","from","from_str","into","label","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","SighashP2wpkh","SighashTaproot","SignOptions","SignerCommon","SignerContext","SignerError","SignerId","SignerOrdering","SignerWrapper","SignersContainer","Tap","TapLeavesOptions","TransactionSigner","TxInputsIndexError","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","from","from","hash","id","id","id","id","ids","into","into","into","into","into","into","into","into","new","new","partial_cmp","partial_cmp","remove","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","Bip69Lexicographic","ChangeAllowed","ChangeForbidden","ChangeSpendPolicy","InvalidOutpoint","InvalidTxid","MissingUtxo","OnlyChange","Shuffle","TxBuilder","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","borrow","borrow","borrow","borrow","borrow","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","change_policy","clone","clone","clone","clone_into","clone_into","clone_into","cmp","cmp","coin_selection","current_height","default","default","do_not_spend_change","drain_to","drain_wallet","enable_rbf","enable_rbf_with_sequence","eq","eq","fee_absolute","fee_rate","finish","finish_with_aux_rand","fmt","fmt","fmt","fmt","fmt","fmt","fmt","from","from","from","from","from","hash","hash","include_output_redeem_witness_script","into","into","into","into","into","manually_selected_only","nlocktime","only_spend_change","only_witness_utxo","ordering","partial_cmp","partial_cmp","policy_path","set_recipients","sighash","sort_tx","sort_tx_with_aux_rand","to_owned","to_owned","to_owned","to_string","to_string","try_from","try_from","try_from","try_from","try_from","try_into","try_into","try_into","try_into","try_into","type_id","type_id","type_id","type_id","type_id","unspendable","version","vzip","vzip","vzip","vzip","vzip","foreign_utxo","input_txid"],"q":[[0,"bdk_wallet"],[97,"bdk_wallet::Utxo"],[100,"bdk_wallet::descriptor"],[352,"bdk_wallet::descriptor::checksum"],[354,"bdk_wallet::descriptor::error"],[386,"bdk_wallet::descriptor::policy"],[533,"bdk_wallet::descriptor::policy::BuildSatisfaction"],[536,"bdk_wallet::descriptor::policy::Satisfaction"],[547,"bdk_wallet::descriptor::policy::SatisfiableItem"],[557,"bdk_wallet::descriptor::template"],[693,"bdk_wallet::keys"],[994,"bdk_wallet::psbt"],[998,"bdk_wallet::wallet"],[1213,"bdk_wallet::wallet::ApplyBlockError"],[1215,"bdk_wallet::wallet::InsertTxError"],[1217,"bdk_wallet::wallet::NewOrLoadError"],[1223,"bdk_wallet::wallet::coin_selection"],[1315,"bdk_wallet::wallet::coin_selection::Error"],[1317,"bdk_wallet::wallet::coin_selection::Excess"],[1322,"bdk_wallet::wallet::error"],[1393,"bdk_wallet::wallet::error::CreateTxError"],[1399,"bdk_wallet::wallet::export"],[1422,"bdk_wallet::wallet::signer"],[1603,"bdk_wallet::wallet::signer::SignerContext"],[1604,"bdk_wallet::wallet::tx_builder"],[1721,"bdk_wallet::wallet::tx_builder::AddForeignUtxoError"],[1723,"bdk_wallet::types"],[1724,"core::cmp"],[1725,"core::result"],[1726,"serde::de"],[1727,"core::fmt"],[1728,"core::hash"],[1729,"bitcoin::blockdata::transaction"],[1730,"core::option"],[1731,"serde::ser"],[1732,"core::any"],[1733,"miniscript::descriptor"],[1734,"bitcoin::network"],[1735,"bitcoin::address"],[1736,"miniscript"],[1737,"miniscript::miniscript"],[1738,"miniscript::miniscript::decode"],[1739,"miniscript::miniscript::context"],[1740,"miniscript::iter::tree"],[1741,"miniscript::descriptor::key"],[1742,"alloc::vec"],[1743,"miniscript::miniscript::satisfy"],[1744,"miniscript::plan"],[1745,"bitcoin_hashes::sha256"],[1746,"miniscript::miniscript::hash256"],[1747,"bitcoin_hashes::ripemd160"],[1748,"bitcoin_hashes::hash160"],[1749,"core::clone"],[1750,"secp256k1"],[1751,"bitcoin::crypto::key"],[1752,"secp256k1::context"],[1753,"bdk_chain::descriptor_ext"],[1754,"miniscript::blanket_traits"],[1755,"bitcoin::blockdata::script::owned"],[1756,"miniscript::miniscript::analyzable"],[1757,"secp256k1::context::alloc_only"],[1758,"bitcoin::blockdata::script::borrowed"],[1759,"core::ops::range"],[1760,"core::ops::function"],[1761,"miniscript::descriptor::bare"],[1762,"miniscript::descriptor::segwitv0"],[1763,"miniscript::descriptor::sh"],[1764,"miniscript::descriptor::tr"],[1765,"miniscript::miniscript::types"],[1766,"miniscript::miniscript::types::extra_props"],[1767,"miniscript::expression"],[1768,"miniscript::miniscript::iter"],[1769,"miniscript::policy::semantic"],[1770,"miniscript::policy"],[1771,"bitcoin_units::weight"],[1772,"alloc::collections::btree::map"],[1773,"alloc::string"],[1774,"hex_conservative::error"],[1775,"base58ck::error"],[1776,"bitcoin::bip32"],[1777,"miniscript::descriptor::sortedmulti"],[1778,"core::str::traits"],[1779,"core::convert"],[1780,"core::default"],[1781,"rand_core"],[1782,"bitcoin_units::amount"],[1783,"bitcoin_units::fee_rate"],[1784,"bdk_chain::keychain"],[1785,"alloc::sync"],[1786,"core::iter::traits::iterator"],[1787,"bitcoin::blockdata::block"],[1788,"bdk_chain::local_chain"],[1789,"bdk_chain::chain_data"],[1790,"core::iter::traits::collect"],[1791,"bdk_chain::tx_graph"],[1792,"bitcoin::psbt"],[1793,"bdk_chain::spk_client"],[1794,"bitcoin::psbt::map::input"],[1795,"bdk_wallet::wallet::utils"],[1796,"core::iter::traits::double_ended"],[1797,"bdk_chain::keychain::txout_index"],[1798,"bitcoin::psbt::error"],[1799,"core::marker"],[1800,"bitcoin::crypto::sighash"],[1801,"bitcoin::blockdata::script::push_bytes::primitive"],[1802,"bitcoin::blockdata::locktime::absolute"]],"i":[1,8,0,1,0,8,0,0,0,0,0,0,1,1,0,1,6,7,8,1,6,7,8,0,1,6,7,8,1,6,7,8,1,6,6,0,0,1,6,1,6,7,8,1,6,7,8,0,1,6,7,8,1,6,1,6,7,8,6,6,0,0,8,6,1,0,7,8,1,6,0,0,1,6,7,8,1,6,7,8,1,6,7,8,8,6,1,6,7,8,7,0,1,6,7,8,0,252,252,252,94,253,24,0,0,0,0,0,0,31,0,0,33,0,0,35,94,253,24,0,0,0,94,253,24,35,31,0,94,253,24,94,253,24,94,253,24,35,24,54,55,31,31,24,24,54,55,31,24,54,55,31,31,31,31,0,33,54,55,33,55,33,33,54,55,33,54,55,33,33,54,55,33,54,55,33,54,55,0,24,54,55,31,24,54,55,31,24,54,55,31,31,24,24,24,24,24,24,31,24,31,24,54,55,31,0,24,31,31,69,24,31,24,24,24,54,55,31,31,24,31,24,24,24,24,24,24,24,54,55,31,31,31,24,31,31,31,24,31,31,31,24,24,31,31,24,24,54,55,31,24,54,55,31,31,24,93,94,24,24,31,31,31,24,31,31,33,54,55,31,24,31,24,33,54,55,24,24,24,24,24,24,24,24,24,24,24,24,24,24,31,33,31,24,31,31,24,54,55,31,33,54,55,24,24,0,31,24,31,24,31,31,24,24,31,24,31,33,54,55,31,0,24,54,55,31,24,31,24,33,33,24,31,24,54,55,31,24,54,55,31,31,24,54,55,31,24,24,54,55,31,31,0,0,74,74,0,74,74,74,74,74,74,74,74,74,74,74,74,74,74,74,74,74,74,74,74,74,74,74,74,74,74,74,74,74,121,115,115,0,122,0,0,121,120,0,121,121,115,115,115,121,122,71,115,122,122,0,0,0,71,71,120,121,121,0,0,121,121,121,120,120,121,122,73,123,115,71,120,121,122,73,123,115,71,120,121,122,73,123,71,120,121,122,73,123,71,73,123,123,120,121,122,73,123,115,120,121,122,73,123,115,115,71,120,121,122,122,73,73,123,115,71,73,120,123,121,73,120,121,122,73,123,115,71,121,122,123,73,123,73,73,120,121,122,73,123,123,120,121,122,73,123,71,115,120,121,122,73,123,115,71,120,121,122,73,123,115,71,120,121,122,73,123,115,71,120,121,122,73,123,115,71,254,254,254,255,256,257,256,257,256,257,256,257,256,257,258,259,260,261,262,263,263,262,264,265,0,0,0,0,0,0,0,0,0,0,0,0,0,0,126,128,129,130,132,134,135,136,137,138,139,140,126,128,129,130,132,134,135,136,137,138,139,140,124,126,128,129,130,132,134,135,136,137,138,139,140,126,128,129,130,132,134,135,136,137,138,139,140,126,128,129,130,132,134,135,136,137,138,139,140,125,126,128,129,130,132,134,135,136,137,138,139,140,126,128,129,130,132,134,135,136,137,138,139,140,126,128,129,130,132,134,135,136,137,138,139,140,126,128,129,130,132,134,135,136,137,138,139,140,126,128,129,130,132,134,135,136,137,138,139,140,118,0,0,0,0,158,158,0,0,147,0,0,0,0,118,118,118,33,0,0,30,118,118,103,35,158,151,0,151,0,0,30,35,103,0,0,0,0,30,0,147,103,35,0,266,35,151,143,148,30,144,118,142,35,103,145,146,147,151,143,148,30,144,118,142,35,103,145,146,147,142,33,33,33,33,33,33,33,33,33,143,30,144,142,35,103,145,146,147,143,30,144,142,35,103,145,146,147,142,35,145,147,144,144,143,35,35,142,30,142,35,103,145,146,147,148,30,144,118,118,142,142,35,35,103,103,145,146,147,142,151,151,151,143,148,30,144,118,118,118,142,35,35,103,145,146,147,148,148,35,103,142,35,35,158,161,161,158,158,161,151,35,142,35,145,147,151,143,148,30,144,118,142,35,103,145,146,147,35,127,133,143,143,148,35,103,133,151,143,143,35,103,151,151,35,266,30,35,103,266,30,266,30,35,35,142,145,146,142,0,35,33,142,142,0,142,33,142,35,145,146,33,148,142,35,145,147,33,142,142,142,142,35,33,142,0,143,30,144,142,35,103,145,146,147,103,118,142,35,103,33,33,142,151,143,148,30,144,118,142,35,103,145,146,147,151,143,148,30,144,118,142,35,103,145,146,147,151,143,148,30,144,118,142,35,103,145,146,147,151,143,148,30,144,118,142,35,103,145,146,147,0,168,168,168,0,0,0,203,0,202,199,200,201,0,0,0,201,201,201,200,200,200,0,0,203,0,0,171,172,195,172,172,172,172,172,172,172,171,172,185,195,199,200,201,202,203,171,172,185,195,199,200,201,202,203,172,172,172,172,172,215,185,172,171,185,171,185,0,171,171,185,195,172,172,172,171,171,195,0,0,172,171,171,172,185,195,195,199,199,200,200,201,201,202,202,203,203,171,172,185,185,185,195,199,200,201,202,203,172,172,172,172,172,185,171,195,215,172,172,172,171,172,185,195,199,200,201,202,203,212,172,195,172,185,172,172,172,172,172,172,172,172,215,172,172,172,172,172,172,172,172,172,172,172,172,172,171,172,0,172,172,172,172,172,171,185,171,195,199,200,201,202,203,171,172,171,171,171,172,185,195,199,200,201,202,203,171,172,185,195,199,200,201,202,203,0,172,171,172,185,195,199,200,201,202,203,172,172,171,171,172,185,195,199,200,201,202,203,0,267,267,268,268,269,270,269,270,271,271,226,226,0,227,0,0,0,0,0,226,0,227,0,226,227,225,221,222,223,226,227,225,221,222,223,221,222,223,221,222,223,224,221,222,223,0,221,222,223,225,225,226,226,227,225,221,222,223,226,227,225,221,222,223,226,227,225,221,222,223,225,223,225,225,221,222,223,226,226,227,225,221,222,223,226,227,225,221,222,223,226,227,225,221,222,223,226,227,225,221,222,223,272,272,273,274,274,273,274,0,208,228,0,208,208,192,208,192,208,208,0,208,208,208,208,208,228,208,208,208,208,208,192,192,208,192,228,208,208,228,208,192,228,208,192,228,228,228,228,208,208,192,192,228,208,208,208,208,208,208,192,228,208,192,228,228,208,192,228,208,192,228,208,192,228,208,192,228,208,192,275,275,276,276,277,278,0,0,279,230,230,230,230,230,230,230,230,230,230,230,230,279,230,230,230,230,230,230,230,235,231,235,198,231,235,198,0,198,198,198,232,198,198,198,198,198,198,198,235,231,232,198,198,0,0,0,0,0,0,0,0,232,0,0,198,198,70,197,197,70,197,231,198,232,233,173,70,197,235,231,198,232,233,173,70,197,235,70,231,232,233,173,70,197,235,231,232,233,173,70,197,235,231,173,173,70,197,235,233,236,233,233,233,231,232,173,235,70,231,198,198,232,233,173,70,197,235,231,231,231,198,198,198,198,232,233,173,70,197,235,231,236,233,233,233,70,231,198,232,233,173,70,197,235,233,70,231,173,70,243,233,233,233,174,233,197,70,197,231,232,233,173,70,197,235,198,197,197,231,198,232,233,173,70,197,235,231,198,232,233,173,70,197,235,231,198,232,233,173,70,197,235,231,198,232,233,173,70,197,235,280,0,0,249,248,248,0,246,246,246,248,249,0,0,247,249,191,191,191,191,191,191,191,191,191,191,247,246,249,248,191,247,246,249,248,191,191,249,248,191,249,248,249,248,191,191,249,248,191,191,191,191,191,249,248,191,191,191,191,191,247,247,246,246,249,248,191,247,246,249,248,249,248,191,191,247,246,249,248,191,191,191,191,191,249,248,191,191,191,249,249,191,249,248,247,246,191,247,246,249,248,191,247,246,249,248,191,247,246,249,248,191,191,191,247,246,249,248,281,281],"f":"````````````{{{d{b}}}f}{{{d{b}}}{{d{{h{f}}}}}}`{{{d{c}}}{{d{e}}}{}{}}000{{{d{jc}}}{{d{je}}}{}{}}000`{{{d{b}}}b}{{{d{l}}}l}{{{d{n}}}n}{{{d{A`}}}A`}{{{d{c}}{d{je}}}Ab{}{}}000{{{d{b}}{d{b}}}Ad}````{c{{Af{b}}}Ah}{c{{Af{l}}}Ah}{{{d{b}}{d{b}}}Aj}{{{d{l}}{d{l}}}Aj}{{{d{n}}{d{n}}}Aj}{{{d{A`}}{d{A`}}}Aj}{{{d{b}}{d{jAl}}}An}{{{d{l}}{d{jAl}}}An}{{{d{n}}{d{jAl}}}An}{{{d{A`}}{d{jAl}}}An}`{cc{}}000{{{d{b}}{d{jc}}}AbB`}{{{d{l}}{d{jc}}}AbB`}{ce{}{}}000````{{{d{A`}}}Bb}`{{{d{b}}{d{b}}}{{Bd{Ad}}}}``{{{d{A`}}}{{Bd{Bf}}}}{{{d{b}}c}AfBh}{{{d{l}}c}AfBh}``{{{d{c}}}e{}{}}000{c{{Af{e}}}{}{}}0000000{{{d{A`}}}{{d{Bj}}}}`{{{d{c}}}Bl{}}000`{{}{{d{Bn}}}}::::``````````````````````````````````````````{{{d{{C`{c}}}}Cb}{{Af{CdCf}}}{ChCj}}{{}Cl}0{{{d{{Cn{ce}}}}}{{d{{D`{ce}}}}}ChDb}{{{d{{d{{Cn{ce}}}}}}}{{Dd{{d{{Cn{ce}}}}}}}ChDb}{{{d{{C`{Df}}}}Dh}{{Af{{C`{Dj}}Dl}}}}{{{d{c}}}{{d{e}}}{}{}}000{{{d{jc}}}{{d{je}}}{}{}}000{{{d{{Cn{ce}}}}}{{Dn{{d{{Cn{ce}}}}}}}ChDb}{{{d{{Cn{ce}}}}{d{g}}}{{Eb{{E`{c}}}}}{CjCh}Db{{Ed{c}}}}0`{{{d{{Cn{c{Db{}{{Ef{e}}}}}}}}}{{Af{AbEh}}}Ch{{Fj{}{{Ej{El}}{En{F`}}{Fb{Fd}}{Ff{Fh}}}}ChChChCh}}{{{d{{Cn{cFl}}}}}{{Af{AbEh}}}Ch}{{{d{{Cn{cFn}}}}}{{Af{AbEh}}}Ch}2022102102{{{d{c}}}{{Af{AbEh}}}Ch}00{{{d{{D`{c{Db{}{{Ef{e}}}}}}}}}{{Af{AbEh}}}Ch{{Fj{}{{Ej{El}}{En{F`}}{Fb{Fd}}{Ff{Fh}}}}ChChChCh}}{{{d{{D`{cFl}}}}}{{Af{AbEh}}}Ch}{{{d{{D`{cFn}}}}}{{Af{AbEh}}}Ch}{{{d{{h{{Dn{f}}}}}}}{{Af{AbEh}}}}00`{{{d{{C`{c}}}}}{{C`{c}}}{G`Ch}}{{{d{Fl}}}Fl}{{{d{Fn}}}Fn}{{{d{{Cn{ce}}}}}{{Cn{ce}}}{G`Ch}{G`Db}}{{{d{c}}{d{je}}}Ab{}{}}000{{{d{{C`{c}}}}{d{{C`{c}}}}}Ad{GbCh}}{{{d{Fl}}{d{Fl}}}Ad}{{{d{Fn}}{d{Fn}}}Ad}{{{d{{Cn{ce}}}}{d{{Cn{ce}}}}}AdChDb}{{{d{{Cn{ce}}}}}AjChDb}{{{d{{C`{Df}}}}Dh}{{Af{{C`{Dj}}Dl}}}}{{{d{{C`{Df}}}}{d{{Gd{c}}}}Dh}{{Af{{C`{Gf}}Dl}}}Gh}{{{d{{C`{Dj}}}}{d{{Gd{c}}}}}{{Af{{C`{Gf}}Dl}}}Gh}{{{d{{C`{c}}}}}GjCh}{{{d{{C`{Df}}}}}Gl}{c{{Af{{C`{e}}}}}AhGn}{c{{Af{{Cn{eg}}}}}AhGnDb}{{{d{{C`{Df}}}}}H`}{{{d{{Cn{ce}}}}}Hb{CjCh}Db}{{{d{{C`{c}}}}{d{{C`{c}}}}}Aj{HdCh}}{{{d{Fl}}{d{Fl}}}Aj}{{{d{Fn}}{d{Fn}}}Aj}{{{d{{Cn{ce}}}}{d{{Cn{ce}}}}}AjChDb}`{{{d{{C`{c}}}}}{{Af{HbCf}}}{ChCj}}`{{{d{{Cn{ce}}}}{d{Hf}}}{{Af{AbHh}}}ChDb}{{{d{Hj}}{d{Hl}}Hn{d{{Gd{I`}}}}}{{Af{{Bd{Ib}}Id}}}}{{{d{{C`{Df}}}}{d{Hl}}Hn{d{{Gd{I`}}}}}{{Af{{Bd{Ib}}Id}}}}{{{d{{Cn{Dfc}}}}{d{Hl}}Hn{d{{Gd{I`}}}}}{{Af{{Bd{Ib}}Id}}}Db}{{{d{{C`{Df}}}}{d{{Gd{c}}}}{d{If}}{Ih{Dh}}}{{Af{{Bd{{Ij{Dh{C`{Gf}}}}}}Dl}}}Gh}{{{d{{C`{c}}}}{d{jAl}}}{{Af{AbIl}}}Ch}0{{{d{Fl}}{d{jAl}}}{{Af{AbIl}}}}{{{d{Fn}}{d{jAl}}}{{Af{AbIl}}}}{{{d{{Cn{ce}}}}{d{jAl}}}{{Af{AbIl}}}ChDb}0{{{d{{C`{c}}}}e}AjCh{{J`{{d{c}}}{{In{Aj}}}}}}{{{d{{Cn{ce}}}}g}AjChDb{{J`{{d{c}}}{{In{Aj}}}}}}{{{Jb{c}}}{{C`{c}}}Ch}{cc{}}{{{Jd{c}}}{{C`{c}}}Ch}{{{Jf{c}}}{{C`{c}}}Ch}{{{Jh{c}}}{{C`{c}}}Ch}{{{Jj{c}}}{{C`{c}}}Ch}{{{Jl{c}}}{{C`{c}}}Ch}555{{{D`{ce}}}{{Af{{Cn{ce}}Cf}}}ChDb}{{{D`{ce}}JnK`}{{Cn{ce}}}ChDb}{{{d{Bn}}}{{Af{{C`{c}}Cf}}}Gn}{{{d{Bn}}}{{Af{{Cn{ce}}Cf}}}GnDb}{{{d{Bn}}{d{Hf}}}{{Af{{Cn{ce}}Cf}}}GnDb}1{{{d{Kb}}}{{Af{{C`{c}}Cf}}}Gn}{{{d{Kb}}}{{Af{{Cn{ce}}Cf}}}GnDb}{{{d{{Cn{ce}}}}Kd}{{Bd{{d{{Cn{ce}}}}}}}ChDb}{{{d{{Cn{ce}}}}Kd}{{Bd{c}}}ChDb}{{{d{{C`{c}}}}e}{{Af{{Ij{{Dn{{Dn{f}}}}Hb}}Cf}}}{ChCj}{{Kf{c}}}}0{{{d{{Cn{ce}}}}}AjChDb}0{{{d{{C`{Df}}}}}Aj}{{{d{{C`{c}}}}{d{je}}}Ab{KhCh}B`}{{{d{Fl}}{d{jc}}}AbB`}{{{d{Fn}}{d{jc}}}AbB`}{{{d{{Cn{ce}}}}{d{jg}}}AbChDbB`}{ce{}{}}000{{{Cn{ce}}}{{D`{ce}}}ChDb}{{{C`{Df}}}{{Af{{Dn{{C`{Df}}}}Cf}}}}{{Kj{d{{Gd{I`}}}}Cb}{{Af{{Ij{KlKn}}Id}}}}{{Kl{d{{Gd{I`}}}}Cb}{{Af{{Ij{KlKn}}Id}}}}99:{{{d{{Cn{ce}}}}}{{L`{ce}}}ChDb}{{{d{{Cn{ce}}}}}{{Lb{ce}}}ChDb}{{{d{{C`{c}}}}}{{Af{{Ld{c}}Cf}}}Ch}{{{d{{Cn{ce}}}}}{{Af{{Ld{c}}Cf}}}ChDb}{{{d{{Cn{ce}}}}}{{Af{AbLf}}}ChDb}{{{d{{Cn{c{Db{}{{Ef{e}}}}}}}}}{{Bd{Kd}}}Ch{{Fj{}{{Ej{El}}{En{F`}}{Fb{Fd}}{Ff{Fh}}}}ChChChCh}}{{{d{{Cn{cFl}}}}}{{Bd{Kd}}}Ch}{{{d{{Cn{cFn}}}}}{{Bd{Kd}}}Ch}{{{d{{Cn{ce}}}}}{{Af{KdCf}}}ChDb}{{{d{{C`{c}}}}}{{Af{KdCf}}}Ch}1{{{d{{C`{c}}}}}{{Af{LhCf}}}Ch}{{}{{d{Bn}}}}00{{{Cn{cLj}}}{{Af{{C`{c}}Cf}}}Ch}{c{{C`{c}}}Ch}{c{{Af{{C`{c}}Cf}}}Ch}{{{Cn{cFl}}}{{Af{{C`{c}}Cf}}}Ch}{{Kd{Dn{c}}}{{Af{{C`{c}}Cf}}}Ch}{{{Jj{c}}}{{C`{c}}}Ch}{{{Jd{c}}}{{C`{c}}}Ch}4{{{Cn{cFn}}}{{Af{{C`{c}}Cf}}}Ch}3{{c{Bd{{Ll{c}}}}}{{Af{{C`{c}}Cf}}}Ch}614`{{{d{{Cn{c{Db{}{{Ef{e}}}}}}}}}{{Af{AbCf}}}Ch{{Fj{}{{Ej{El}}{En{F`}}{Fb{Fd}}{Ff{Fh}}}}ChChChCh}}{{{d{If}}}{{Af{{Cn{c}}Cf}}}Db}{{{d{{Gd{c}}}}{d{Bn}}}{{Af{{Ij{{C`{Df}}{M`{DfLn}}}}Cf}}}Mb}1{{{d{If}}{d{Hf}}}{{Af{{Cn{c}}Cf}}}Db}{{{d{{C`{c}}}}{d{{C`{c}}}}}{{Bd{Ad}}}{MdCh}}{{{d{Fl}}{d{Fl}}}{{Bd{Ad}}}}{{{d{Fn}}{d{Fn}}}{{Bd{Ad}}}}{{{d{{Cn{ce}}}}{d{{Cn{ce}}}}}{{Bd{Ad}}}ChDb}{{{d{c}}}KdCh}00{{{C`{Dj}}{d{c}}}{{Af{Mf{C`{Dj}}}}}{{Ed{Dj}}}}0`{{{d{{Cn{ce}}}}}AjChDb}{{{d{{C`{c}}}}}{{Af{AbCf}}}Ch}{{{d{{Cn{ce}}}}}{{Af{AbHh}}}ChDb}{{{d{{C`{c}}}}{d{jMh}}e}{{Af{AbCf}}}{ChCj}{{Kf{c}}}}{{{d{{Cn{ce}}}}g}{{Af{{Dn{{Dn{f}}}}Cf}}}{CjCh}Db{{Kf{c}}}}0{{{d{{C`{c}}}}}{{Af{HbCf}}}{ChCj}}{{{d{{C`{c}}}}}Hb{ChCj}}{{{d{{Cn{ce}}}}}KdChDb}{{{d{{C`{c}}}}e}AfChBh}{{{d{{Cn{ce}}}}g}AfChDbBh}{{}Mj}00{{{d{{Cn{ce}}}}{d{{M`{Fhc}}}}}{{Cn{ce}}}ChDb}`{{{d{c}}}e{}{}}000{{{d{c}}}Ml{}}0{{{d{{C`{Df}}}}{d{{M`{DfLn}}}}}Ml}{{{d{{Cn{c{Db{}{{Ef{e}}}}}}}}}{{Af{AbCf}}}Ch{{Fj{}{{Ej{El}}{En{F`}}{Fb{Fd}}{Ff{Fh}}}}ChChChCh}}0{{{d{{C`{c}}}}{d{ji}}}{{Af{{Mn{g}}}}}ChCh{}{{N`{ceg}}}}{{{d{{Cn{ce}}}}{d{jk}}}{{Af{{Mn{i}}}}}ChDbCh{}{{N`{cgi}}}}{c{{Af{e}}}{}{}}0000000`{{{d{c}}}Bl{}}000={ce{}{}}000{{{d{{Cn{ce}}}}}AjChDb}{{{d{Bn}}}{{Af{MlId}}}}{{{d{Bn}}}{{Af{{Nb{f}}Id}}}}``````````````{{{d{c}}}{{d{e}}}{}{}}{{{d{jc}}}{{d{je}}}{}{}}{{{d{Id}}{d{jAl}}}An}0{CfId}{NdId}{NfId}{cc{}}{NhId}{NjId}{NlId}{NnId}>{{{d{c}}}Ml{}}{c{{Af{e}}}{}{}}0{{{d{c}}}Bl{}}{ce{}{}}```````````````````````````````````>>>>>>>======={{{d{O`}}}O`}{{{d{Ob}}}Ob}{{{d{Od}}}Od}{{{d{Ib}}}Ib}{{{d{Of}}}Of}{{{d{Hn}}}Hn}{{{d{c}}{d{je}}}Ab{}{}}00000``{{}Of}{{{d{O`}}{d{O`}}}Aj}{{{d{Ob}}{d{Ob}}}Aj}{{{d{Od}}{d{Od}}}Aj}{{{d{Ib}}{d{Ib}}}Aj}{{{d{Of}}{d{Of}}}Aj}{{{d{Nf}}{d{Nf}}}Aj}{{{d{O`}}{d{jAl}}}An}{{{d{Ob}}{d{jAl}}}An}{{{d{Od}}{d{jAl}}}An}{{{d{Ib}}{d{jAl}}}An}{{{d{Of}}{d{jAl}}}An}{{{d{Nf}}{d{jAl}}}An}0{{{d{Hn}}{d{jAl}}}An}{cc{}}0{AjOd}11{ObIb}222{{{d{Ib}}{d{{M`{Ml{Dn{Kd}}}}}}}{{Af{OfNf}}}}{{{d{O`}}{d{jc}}}AbB`}{{{d{Of}}{d{jc}}}AbB`}{{{d{Ob}}}Ml}`{ce{}{}}000000{{{d{Ob}}}Aj}{{{d{Od}}}Aj}{{{d{Of}}}Aj}`{{{d{Of}}{d{Of}}}{{Bd{Ad}}}}{{{d{Ib}}}Aj}`{{{d{O`}}c}AfBh}{{{d{Ob}}c}AfBh}{{{d{Od}}c}AfBh}{{{d{Ib}}c}AfBh}{{{d{Of}}c}AfBh}`{{{d{c}}}e{}{}}00000{{{d{c}}}Ml{}}{c{{Af{e}}}{}{}}0000000000000{{{d{c}}}Bl{}}000000>>>>>>>``````````````````````````````````````{{{d{c}}}{{d{e}}}{}{}}00000000000{{{d{jc}}}{{d{je}}}{}{}}00000000000{{OhCb}{{Af{OjId}}}}{{{Ol{c}}Cb}{{Af{OjId}}}{{On{Fl}}}}{{{A@`{c}}Cb}{{Af{OjId}}}{{On{Fn}}}}{{{A@b{c}}Cb}{{Af{OjId}}}{{On{Fn}}}}{{{A@d{c}}Cb}{{Af{OjId}}}{{On{A@f}}}}{{{A@h{c}}Cb}{{Af{OjId}}}{{A@j{Fl}}}}{{{A@l{c}}Cb}{{Af{OjId}}}{{A@j{Fl}}}}{{{A@n{c}}Cb}{{Af{OjId}}}{{A@j{Fn}}}}{{{AA`{c}}Cb}{{Af{OjId}}}{{A@j{Fn}}}}{{{AAb{c}}Cb}{{Af{OjId}}}{{A@j{Fn}}}}{{{AAd{c}}Cb}{{Af{OjId}}}{{A@j{Fn}}}}{{{AAf{c}}Cb}{{Af{OjId}}}{{A@j{A@f}}}}{{{AAh{c}}Cb}{{Af{OjId}}}{{A@j{A@f}}}}{cc{}}00000000000{ce{}{}}00000000000{{Oj{d{{Gd{I`}}}}Cb}{{Af{{Ij{KlKn}}Id}}}}{{c{d{{Gd{I`}}}}Cb}{{Af{{Ij{{C`{Df}}{M`{DfLn}}}}Id}}}{}}00000000000{c{{Af{e}}}{}{}}00000000000000000000000{{{d{c}}}Bl{}}00000000000444444444444```````````````````````````````````````````{{}AAj}{{}Cl}{{DfDh}{{Af{DjDl}}}}{{{d{c}}}{{d{e}}}{}{}}00000000000{{{d{jc}}}{{d{je}}}{}{}}00000000000{{{d{{AAl{ce}}}}{d{g}}}{{Eb{{E`{c}}}}}{CjCh}Db{{Ed{c}}}}{{{d{{Cn{c{Db{}{{Ef{e}}}}}}}}}{{Af{AbEh}}}Ch{{Fj{}{{Ej{El}}{En{F`}}{Fb{Fd}}{Ff{Fh}}}}ChChChCh}}00000{{{d{c}}}{{Af{AbEh}}}Ch}{{{d{{D`{c{Db{}{{Ef{e}}}}}}}}}{{Af{AbEh}}}Ch{{Fj{}{{Ej{El}}{En{F`}}{Fb{Fd}}{Ff{Fh}}}}ChChChCh}}{{{d{{h{{Dn{f}}}}}}}{{Af{AbEh}}}}{{{d{{AAn{ce}}}}}{{AAn{ce}}}G`Db}{{{d{Cl}}}Cl}{{{d{AB`}}}AB`}{{{d{{AAl{ce}}}}}{{AAl{ce}}}{G`Ch}{G`Db}}{{{d{Df}}}Df}{{{d{Ln}}}Ln}{{{d{ABb}}}ABb}{{{d{ABd}}}ABd}{{{d{ABf}}}ABf}{{{d{c}}{d{je}}}Ab{}{}}00000000{{{d{{AAl{ce}}}}{d{{AAl{ce}}}}}Ad{GbCh}{GbDb}}{{{d{Df}}{d{Df}}}Ad}{{{d{ABb}}{d{ABb}}}Ad}{{{d{ABf}}{d{ABf}}}Ad}`{{}AB`}{{{d{{AAn{ce}}}}}{{d{g}}}{}Db{}}{{DfDh}{{Af{DjDl}}}}{c{{Af{Df}}}Ah}{{{d{{AAl{ce}}}}}Hb{CjCh}Db}{{{d{Cl}}{d{Cl}}}Aj}{{{d{{AAl{ce}}}}{d{{AAl{ce}}}}}Aj{HdCh}{HdDb}}{{{d{Df}}{d{Df}}}Aj}{{{d{Ln}}{d{Ln}}}Aj}{{{d{ABb}}{d{ABb}}}Aj}{{{d{ABd}}{d{ABd}}}Aj}{{{d{ABf}}{d{ABf}}}Aj}{{{d{{ABh{c}}}}{d{jAl}}}An{ABjDb}}{{{d{Cl}}{d{jAl}}}An}{{{d{AB`}}{d{jAl}}}An}{{{d{Nl}}{d{jAl}}}An}0{{{d{{AAl{ce}}}}{d{jAl}}}{{Af{AbIl}}}ChDb}0{{{d{Df}}{d{jAl}}}{{Af{AbIl}}}}0{{{d{Ln}}{d{jAl}}}{{Af{AbIl}}}}0{{{d{ABb}}{d{jAl}}}{{Af{AbIl}}}}{{{d{ABd}}{d{jAl}}}{{Af{AbIl}}}}{{{d{ABf}}{d{jAl}}}{{Af{AbIl}}}}{{{d{{AAl{ce}}}}g}AjChDb{{J`{{d{c}}}{{In{Aj}}}}}}{cc{}}{ABl{{ABn{c}}}Db}{AC`{{ABn{c}}}Db}2222{NjNl}3{CfNl}44{DjDf}5555{{DfAAj}{{ABh{c}}}Db}{{LnAAj}{{ABh{c}}}Db}{{{d{Bn}}}{{Af{Df}}}}{{{d{Bn}}}{{Af{Ln}}}}{{{d{Kb}}}{{Af{{AAl{ce}}Cf}}}{ACbCh}Db}{{{d{Df}}}{{Bd{ACd}}}}{{{d{Df}}}{{Dn{ACd}}}}{c{{Af{{AAn{{ACl{}{{ACf{e}}{ACh{c}}{ACj{g}}}}i}}g}}}{}{{ACn{{h{f}}}}AD`}ABjDb}{{}{{Af{{AAn{ADbc}}e}}}Db{}}{{{d{jc}}}{{Af{{AAn{ADbe}}g}}}{ADdADf}Db{}}{{c{d{je}}}{{Af{{AAn{{ACl{}{{ACf{g}}{ACh{c}}{ACj{i}}}}k}}i}}}{}{ADdADf}{{ACn{{h{f}}}}AD`}ABjDb}{{ce}{{Af{{AAn{{ACl{}{{ACf{e}}{ACh{c}}{ACj{g}}}}i}}g}}}{}{{ACn{{h{f}}}}AD`}ABjDb}{c{{Af{{AAn{ADbe}}g}}}{}Db{}}{{{d{{ABn{c}}}}}AjDb}{{{d{Df}}}Aj}{{{d{{AAl{ce}}}}{d{jg}}}Ab{KhCh}{KhDb}B`}{{{d{Df}}{d{jc}}}AbB`}{{{d{ABb}}{d{jc}}}AbB`}{{{d{ABf}}{d{jc}}}AbB`}{ce{}{}}00000000000{DfADh}{On{{Af{{ABh{c}}Nl}}}Db}{{A@j{Bd{ADj}}ACd}{{Af{{ABh{c}}Nl}}}Db}{{{AAn{ec}}}{{Af{{ABh{c}}Nl}}}Db{{On{c}}}}{{{AAn{ec}}{Bd{ADj}}ACd}{{Af{{ABh{c}}Nl}}}Db{{A@j{c}}}}{{{ABh{c}}}{{Af{{ABh{c}}Nl}}}Db}{Df{{Af{{ABh{c}}Nl}}}Db}{Ln{{Af{{ABh{c}}Nl}}}Db}{A@j{{Af{{ABn{c}}Nl}}}Db}{{{ABn{c}}}{{Af{{ABn{c}}Nl}}}Db}{{{AAn{ec}}}{{Af{{ABn{c}}Nl}}}Db{{A@j{c}}}}{{{AAn{ce}}}c{}Db}{Df{{Dn{Df}}}}{Ln{{Dn{Ln}}}}{{{ABn{c}}Cb}{{Bd{AC`}}}Db}{{{ABn{c}}Cb{d{{Gd{e}}}}}ABlDbMb}{{{d{Df}}}Aj}{{}Aj}{{{d{Cl}}}Aj}2{{{d{Ln}}}Aj}212133{{{d{{AAl{ce}}}}}KdChDb}``{{{d{{AAl{ce}}}}}{{Af{{Ld{c}}Cf}}}ChDb}{{}AAj}{{{d{Df}}}ADl}{{{d{{Cn{c{Db{}{{Ef{e}}}}}}}}}{{Bd{Kd}}}Ch{{Fj{}{{Ej{El}}{En{F`}}{Fb{Fd}}{Ff{Fh}}}}ChChChCh}}44{{{d{AAj}}{d{AAj}}}AAj}5{{}{{d{Bn}}}}{{Kd{Dn{c}}}{{Af{{AAl{ce}}Cf}}}ChDb}{{{d{Df}}}Kd}``{{{d{{Cn{c{Db{}{{Ef{e}}}}}}}}}{{Af{AbCf}}}Ch{{Fj{}{{Ej{El}}{En{F`}}{Fb{Fd}}{Ff{Fh}}}}ChChChCh}}{{{ABh{c}}AAj}{{ABh{c}}}Db}{{{d{{AAl{ce}}}}{d{{AAl{ce}}}}}{{Bd{Ad}}}{MdCh}{MdDb}}{{{d{Df}}{d{Df}}}{{Bd{Ad}}}}{{{d{ABb}}{d{ABb}}}{{Bd{Ad}}}}{{{d{ABf}}{d{ABf}}}{{Bd{Ad}}}}{{{d{c}}}KdCh}{{{d{{AAl{ce}}}}}{{d{{h{c}}}}}ChDb}{{{d{{AAl{ce}}}}}{{Af{AbCf}}}ChDb}{{{d{{AAl{ce}}}}g}{{Af{{Dn{{Dn{f}}}}Cf}}}{CjCh}Db{{Kf{c}}}}{{{d{{AAl{ce}}}}}KdChDb}{{{d{Df}}c}AfBh}{{}Mj}{{{d{{AAl{ce}}}}}{{D`{ce}}}{CjCh}Db}{{}AAj}{{{d{c}}}e{}{}}00000000{{{d{Ln}}{d{{Gd{c}}}}}{{Af{DfADn}}}Mb}{{{d{c}}}Ml{}}000{{{d{{Cn{c{Db{}{{Ef{e}}}}}}}}}{{Af{AbCf}}}Ch{{Fj{}{{Ej{El}}{En{F`}}{Fb{Fd}}{Ff{Fh}}}}ChChChCh}}0{{{d{{AAl{ce}}}}{d{jk}}}{{Af{{AAl{ge}}{Mn{i}}}}}ChDbCh{}{{N`{cgi}}}}{c{{Af{e}}}{}{}}00000000000000000000000{{{d{c}}}Bl{}}00000000000{ce{}{}}00000000000`{{{d{AE`}}}{{Bd{AEb}}}}{{{d{AE`}}}{{Bd{AEd}}}}{{{d{AE`}}Kd}{{Bd{Bj}}}}```````````````````````{{AEfAEf}AEf}{{{d{jAEh}}bAEj{AEn{AEl}}}Ab}`{{{d{AEh}}}{{M`{b{`{{AFd{}{{AF`{{AFb{Hb}}}}}}G`}}}}}}{{{d{jAEh}}{d{AFf}}Dh}{{Af{AbAFh}}}}{{{d{jAEh}}{d{AFf}}DhAFj}{{Af{AbAFl}}}}{{{d{jAEh}}c}Ab{{AG`{}{{AF`{{Ij{{d{AFn}}H`}}}}}}}}{{{d{jAEh}}c}{{Af{AbAFh}}}{{AGd{AGb}}}}{{{d{AEh}}}{{d{{AGh{AGf}}}}}}{{{d{AEh}}}AEf}{{{d{c}}}{{d{e}}}{}{}}00000000{{{d{jc}}}{{d{je}}}{}{}}00000000{{{d{jAEh}}AGj}{{Af{{AGn{AGl}}AH`}}}}{{{d{jAEh}}}{{AGn{AGl}}}}{{{d{AEh}}{d{AFn}}}{{Af{AEbAHb}}}}{{{d{AEh}}{d{AFn}}}{{Af{AEdAHb}}}}{{{d{jAEh}}{d{AFn}}}Ab}``{{{d{AEh}}}AHd}{{{d{AEf}}}AEf}{{{d{AGb}}}AGb}{{{d{c}}{d{je}}}Ab{}{}}0``{{}AEf}{{}AGb}{{{d{AHf}}}{{d{c}}}{}}{{{d{AEh}}b}{{Bd{Dh}}}}{{{d{AEh}}{d{If}}}{{Bd{{Ij{bDh}}}}}}{{{d{AEh}}b}Ml}{c{{Af{AEf}}}Ah}{{{d{AEf}}{d{AEf}}}Aj}{{{d{AHf}}{d{AHf}}}Aj}``{{{d{AEh}}{d{jAHh}}AHj}{{Af{AjAHl}}}}{{{d{AEf}}{d{jAl}}}{{Af{AbIl}}}}0{{{d{AEh}}{d{jAl}}}An}{{{d{AGb}}{d{jAl}}}An}{{{d{AHf}}{d{jAl}}}An}0{{{d{AHn}}{d{jAl}}}An}0{{{d{AI`}}{d{jAl}}}An}0{{{d{AIb}}{d{jAl}}}An}0{{{d{AId}}{d{jAl}}}An}0{{{d{AIf}}{d{jAl}}}An}0{cc{}}00{{{AIh{b}}}AGb}{AIjAGb}222222{{{d{AEh}}b}{{d{Kl}}}}{{{d{AEh}}l{Bd{AIl}}Aj}{{Af{AInAJ`}}}}{{{d{AEh}}b}{{AEn{Hl}}}}{{{d{AEh}}AGj}{{Bd{{AJb{{AEn{AFn}}AGf}}}}}}{{{d{AEh}}Bb}{{Bd{l}}}}````{{{d{jAEh}}AFj}{{Af{AjAJd}}}}{{{d{jAEh}}AFnAJf}{{Af{AjAId}}}}{{{d{jAEh}}BbBj}Ab}{ce{}{}}00000000{{{d{AJh}}{d{If}}}Aj}{{{d{AEh}}{d{If}}}Aj}`{{{d{AEh}}}{{`{{AFd{}{{AF`{{Ij{{d{b}}{d{Kl}}}}}}}}}}}}`{{{d{AEh}}}AJj}{{{d{AEh}}}{{`{{AFd{}{{AF`{l}}}}}}}}0{{{d{AEh}}b}{{`{{AJl{}{{AF`{AHf}}}}}}}}{AJn{{Af{AEhAI`}}}}{{{d{AEh}}}{{d{AK`}}}}{{{d{jAEh}}bDh}Aj}{{{d{AEh}}}Cb}`{{ccCb}{{Af{AEhAHn}}}Kj}{{cc{Bd{AJn}}Cb}{{Af{AEhAIb}}}Kj}{{cc{Bd{AJn}}CbAKb}{{Af{AEhAIb}}}Kj}{{ccCbAKb}{{Af{AEhAHn}}}Kj}{{{d{AEh}}b}Dh}{{{d{jAEh}}b}AHf}{{{d{AEh}}bDh}AHf}{{{d{AEh}}b}{{Af{{Bd{Ib}}Id}}}}{{{d{AEh}}b}{{d{Kl}}}}{{{d{jAEh}}bDh}{{`{{AFd{}{{AF`{AHf}}}}}}}}4{{{d{AEh}}}{{d{{Gd{I`}}}}}}{{{d{AEh}}{d{AFn}}}{{Ij{AEbAEb}}}}{{{d{AEf}}c}AfBh}{{{d{AEh}}{d{jAHh}}AHj}{{Af{AjAHl}}}}`{{{d{AEh}}}{{d{{AKd{b}}}}}}{{{d{AEh}}}{{Bd{{d{AJn}}}}}}{{{d{AEh}}}{{AKf{b}}}}{{{d{AEh}}}AKh}{{{d{jAEh}}}{{Bd{AJn}}}}{{{d{c}}}e{}{}}0{{{d{c}}}Ml{}}000000{{{d{AEf}}}AEb}{{{d{AEh}}}{{`{{AFd{}{{AF`{{AJb{{AEn{AFn}}AGf}}}}}}}}}}`1{c{{Af{e}}}{}{}}00000000000000000`{{{d{AEh}}}{{d{{AGh{AGf}}}}}}{{{d{c}}}Bl{}}00000000{{{d{AEh}}b}{{`{{AFd{}{{AF`{{AFb{Hb}}}}}}G`}}}}{{{d{jAEh}}bDh}Aj}`{ce{}{}}00000000{{c{Bd{c}}Cb{d{{Gd{I`}}}}}{{Af{MlId}}}Kj}```````````````````````{{{d{c}}}{{d{e}}}{}{}}00000{{{d{jc}}}{{d{je}}}{}{}}00000{{{d{AKj}}}AKj}{{{d{AKl}}}AKl}{{{d{AKn}}}AKn}{{{d{c}}{d{je}}}Ab{}{}}00{{{d{AL`}}{Dn{n}}{Dn{n}}AEdH`{d{If}}}{{Af{ALbALd}}}}{{{d{AKj}}{Dn{n}}{Dn{n}}AEdH`{d{If}}}{{Af{ALbALd}}}}{{{d{AKl}}{Dn{n}}{Dn{n}}AEdH`{d{If}}}{{Af{ALbALd}}}}{{{d{AKn}}{Dn{n}}{Dn{n}}AEdH`{d{If}}}{{Af{ALbALd}}}}{{H`AEd{d{If}}}ALf}{{}AKj}{{}AKl}{{}AKn}``{{{d{ALd}}{d{jAl}}}An}0{{{d{ALf}}{d{jAl}}}An}{{{d{ALb}}{d{jAl}}}An}{{{d{AKj}}{d{jAl}}}An}{{{d{AKl}}{d{jAl}}}An}{{{d{AKn}}{d{jAl}}}An}{cc{}}00000{ce{}{}}00000{{{d{ALb}}}H`}{H`AKn}`1{{{d{c}}}e{}{}}00{{{d{c}}}Ml{}}{c{{Af{e}}}{}{}}00000000000{{{d{c}}}Bl{}}00000666666`````````````````````````````````````{{{d{c}}}{{d{e}}}{}{}}00{{{d{jc}}}{{d{je}}}{}{}}00{{{d{ALh}}}ALh}{{{d{c}}{d{je}}}Ab{}{}}{{{d{ALh}}{d{jAl}}}An}0{{{d{AJ`}}{d{jAl}}}An}0{{{d{AH`}}{d{jAl}}}An}0>{IdAJ`}{ALjAJ`}{ALdAJ`}{NfAJ`}{ALhAJ`}{cc{}}0{ce{}{}}00{{{d{c}}}e{}{}}{{{d{c}}}Ml{}}00{c{{Af{e}}}{}{}}00000{{{d{c}}}Bl{}}00444``````````{{{d{c}}}{{d{e}}}{}{}}{{{d{jc}}}{{d{je}}}{}{}}{{{d{ALl}}}{{Bd{Ml}}}}{{{d{ALl}}}Ml}{c{{Af{ALl}}}Ah}{{{d{AEh}}{d{Bn}}Aj}{{Af{ALl{d{Bn}}}}}}{{{d{ALl}}{d{jAl}}}An}0<{{{d{Bn}}}{{Af{ALlc}}}{}}<``{{{d{ALl}}c}AfBh};::9=`````````````````````````````````````{{{d{jHl}}ALnAEj{AEn{AEl}}}{{Bd{{AEn{AEl}}}}}}``{{{d{Hl}}{d{{Gd{I`}}}}}Kn}`::::::::99999999{{Kn{d{{C`{Df}}}}{d{{Gd{I`}}}}}Hl}{{{d{ALn}}}ALn}{{{d{AM`}}}AM`}{{{d{{AMb{c}}}}}{{AMb{c}}}{G`AMdABjG`}}{{{d{AEj}}}AEj}{{{d{Hl}}}Hl}{{{d{AHj}}}AHj}{{{d{AMf}}}AMf}{{{d{c}}{d{je}}}Ab{}{}}000000{{{d{ALn}}{d{ALn}}}Ad}{{{d{AEj}}{d{AEj}}}Ad}{{}AEj}{{}Hl}{{}AHj}{{}AMf}{{{d{{AMb{c}}}}}{{d{e}}}{AMdABjG`}{}}{{{d{AMh}}}{{Bd{Ln}}}}{{{d{{AMb{{AMj{AC`}}}}}}}{{Bd{Ln}}}}{{{d{{AMb{AMl}}}}}{{Bd{Ln}}}}{{{d{{AMb{{AMn{AC`}}}}}}}{{Bd{Ln}}}}{{{d{ALn}}{d{ALn}}}Aj}{{{d{AM`}}{d{AM`}}}Aj}{{{d{AEj}}{d{AEj}}}Aj}{{{d{AMf}}{d{AMf}}}Aj}{{{d{Hl}}ALn}{{Bd{{d{{AEn{AEl}}}}}}}}{{{d{ALn}}{d{jAl}}}An}{{{d{AHl}}{d{jAl}}}An}0{{{d{AM`}}{d{jAl}}}An}{{{d{{AMb{c}}}}{d{jAl}}}An{ABjAMdABjG`}}{{{d{AEj}}{d{jAl}}}An}{{{d{Hl}}{d{jAl}}}An}{{{d{AHj}}{d{jAl}}}An}{{{d{AMf}}{d{jAl}}}An}{FhALn}{ADlALn}{cc{}}0{AN`AHl}{ANbAHl}{ANdAHl}333333{{{d{ALn}}{d{jc}}}AbB`}{{{d{AMh}}{d{{Gd{I`}}}}}ALn}{{{d{{AMb{{AMj{AC`}}}}}}{d{{Gd{I`}}}}}ALn}{{{d{{AMb{AMl}}}}{d{{Gd{I`}}}}}ALn}{{{d{{AMb{{AMn{AC`}}}}}}{d{{Gd{I`}}}}}ALn}{{{d{Hl}}}{{Dn{{d{ALn}}}}}}{ce{}{}}0000000{{cAM`}{{AMb{c}}}{AMdABjG`}}{{}Hl}{{{d{ALn}}{d{ALn}}}{{Bd{Ad}}}}{{{d{AEj}}{d{AEj}}}{{Bd{Ad}}}}{{{d{jHl}}ALnAEj}{{Bd{{AEn{AEl}}}}}}{{{d{ANf}}{d{jAHh}}Kd{d{AHj}}{d{{Gd{I`}}}}}{{Af{AbAHl}}}}{{{d{{AMb{{AMj{AC`}}}}}}{d{jAHh}}Kd{d{AHj}}{d{{Gd{I`}}}}}{{Af{AbAHl}}}}{{{d{{AMb{{AMn{AC`}}}}}}{d{jAHh}}Kd{d{AHj}}{d{{Gd{I`}}}}}{{Af{AbAHl}}}}{{{d{{AMb{AMl}}}}{d{jAHh}}Kd{d{AHj}}{d{{Gd{I`}}}}}{{Af{AbAHl}}}}{{{d{AEl}}{d{jAHh}}{d{AHj}}{d{{Gd{I`}}}}}{{Af{AbAHl}}}}{{{d{c}}{d{jAHh}}{d{AHj}}{d{{Gd{I`}}}}}{{Af{AbAHl}}}{}}`{{{d{Hl}}}{{Dn{{d{{AEn{AEl}}}}}}}}`{{{d{c}}}e{}{}}000000{{{d{c}}}Ml{}}``{c{{Af{e}}}{}{}}000000000000000{{{d{c}}}Bl{}}0000000{ce{}{}}0000000````````````````{{{d{j{AGn{c}}}}{d{e}}}{{d{j{AGn{c}}}}}{}{{ANj{ANh}}}}{{{d{j{AGn{c}}}}BbAInKd}{{Af{{d{j{AGn{c}}}}ANl}}}{}}{{{d{j{AGn{c}}}}BbAInKdBf}{{Af{{d{j{AGn{c}}}}ANl}}}{}}{{{d{j{AGn{c}}}}}{{d{j{AGn{c}}}}}{}}{{{d{j{AGn{c}}}}HbAEb}{{d{j{AGn{c}}}}}{}}{{{d{j{AGn{c}}}}Bb}{{d{j{AGn{c}}}}}{}}{{{d{j{AGn{c}}}}Bb}{{Af{{d{j{AGn{c}}}}ANn}}}{}}{{{d{j{AGn{c}}}}{d{{h{Bb}}}}}{{Af{{d{j{AGn{c}}}}ANn}}}{}}{{{d{j{AGn{c}}}}Aj}{{d{j{AGn{c}}}}}{}}{{{d{c}}}{{d{e}}}{}{}}0000{{{d{jc}}}{{d{je}}}{}{}}0000{{{d{j{AGn{c}}}}AO`}{{d{j{AGn{c}}}}}{}}{{{d{{AGn{c}}}}}{{AGn{c}}}G`}{{{d{AOb}}}AOb}{{{d{AO`}}}AO`}{{{d{c}}{d{je}}}Ab{}{}}00{{{d{AOb}}{d{AOb}}}Ad}{{{d{AO`}}{d{AO`}}}Ad}{{{AGn{c}}e}{{AGn{e}}}{}AL`}{{{d{j{AGn{c}}}}Dh}{{d{j{AGn{c}}}}}{}}{{}AOb}{{}AO`}{{{d{j{AGn{c}}}}}{{d{j{AGn{c}}}}}{}}{{{d{j{AGn{c}}}}Hb}{{d{j{AGn{c}}}}}{}}11{{{d{j{AGn{c}}}}Bf}{{d{j{AGn{c}}}}}{}}{{{d{AOb}}{d{AOb}}}Aj}{{{d{AO`}}{d{AO`}}}Aj}{{{d{j{AGn{c}}}}AEb}{{d{j{AGn{c}}}}}{}}{{{d{j{AGn{c}}}}AEd}{{d{j{AGn{c}}}}}{}}{{{AGn{c}}}{{Af{AHhAJ`}}}AL`}{{{AGn{c}}{d{je}}}{{Af{AHhAJ`}}}AL`ADf}{{{d{{AGn{c}}}}{d{jAl}}}AnABj}{{{d{ANn}}{d{jAl}}}An}0{{{d{ANl}}{d{jAl}}}An}0{{{d{AOb}}{d{jAl}}}An}{{{d{AO`}}{d{jAl}}}An}{cc{}}0000{{{d{AOb}}{d{jc}}}AbB`}{{{d{AO`}}{d{jc}}}AbB`}{{{d{j{AGn{c}}}}}{{d{j{AGn{c}}}}}{}}{ce{}{}}00001{{{d{j{AGn{c}}}}AOd}{{d{j{AGn{c}}}}}{}}22{{{d{j{AGn{c}}}}AOb}{{d{j{AGn{c}}}}}{}}{{{d{AOb}}{d{AOb}}}{{Bd{Ad}}}}{{{d{AO`}}{d{AO`}}}{{Bd{Ad}}}}{{{d{j{AGn{c}}}}{M`{Ml{Dn{Kd}}}}b}{{d{j{AGn{c}}}}}{}}{{{d{j{AGn{c}}}}{Dn{{Ij{HbAEb}}}}}{{d{j{AGn{c}}}}}{}}{{{d{j{AGn{c}}}}AIl}{{d{j{AGn{c}}}}}{}}{{AOb{d{jAFn}}}Ab}{{AOb{d{jAFn}}{d{jc}}}AbADf}{{{d{c}}}e{}{}}00{{{d{c}}}Ml{}}0{c{{Af{e}}}{}{}}000000000{{{d{c}}}Bl{}}0000{{{d{j{AGn{c}}}}{Dn{Bb}}}{{d{j{AGn{c}}}}}{}}{{{d{j{AGn{c}}}}AOf}{{d{j{AGn{c}}}}}{}}?????``","D":"FGl","p":[[6,"KeychainKind",0,1723],[1,"reference"],[1,"u8"],[1,"slice"],[0,"mut"],[5,"LocalOutput",0,1723],[5,"WeightedUtxo",0,1723],[6,"Utxo",0,1723],[1,"unit"],[6,"Ordering",1724],[6,"Result",1725],[10,"Deserializer",1726],[1,"bool"],[5,"Formatter",1727],[8,"Result",1727],[10,"Hasher",1728],[5,"OutPoint",1729],[6,"Option",1730],[5,"Sequence",1729],[10,"Serializer",1731],[5,"TxOut",1729],[5,"TypeId",1732],[1,"str"],[6,"Descriptor",100,1733],[6,"Network",1734],[5,"Address",1735],[6,"Error",1736],[10,"MiniscriptKey",1736],[10,"ToPublicKey",1736],[6,"ScriptContextEnum",693],[5,"Miniscript",100,1737],[6,"Terminal",1738],[10,"ScriptContext",693,1739],[6,"Tree",1740],[6,"DescriptorPublicKey",693,1741],[1,"u32"],[5,"DefiniteDescriptorKey",1741],[6,"ConversionError",1741],[5,"Vec",1742],[6,"Placeholder",1743],[5,"Satisfaction",1743],[10,"AssetProvider",1744],[17,"Key"],[6,"ScriptContextError",1739],[17,"Sha256"],[5,"Hash",1745],[17,"Hash256"],[5,"Hash",1746],[17,"Ripemd160"],[5,"Hash",1747],[17,"Hash160"],[5,"Hash",1748],[10,"ParseableKey",1738],[6,"Legacy",100,1739],[6,"Segwitv0",100,1739],[10,"Clone",1749],[10,"Ord",1724],[5,"Secp256k1",1750],[5,"PublicKey",1751],[10,"Verification",1752],[6,"DescriptorType",1733],[5,"DescriptorId",1753],[10,"FromStrKey",1754],[1,"u64"],[5,"ScriptBuf",1755],[10,"PartialEq",1724],[5,"ExtParams",1756],[6,"AnalysisError",1756],[10,"ExtractPolicy",100],[5,"SignersContainer",1422],[6,"BuildSatisfaction",386],[6,"All",1757],[5,"Policy",386],[6,"Error",354],[5,"Script",1758],[5,"Range",1759],[1,"tuple"],[5,"Error",1727],[17,"Output"],[10,"FnMut",1760],[5,"Pkh",1761],[5,"Wsh",1762],[5,"Bare",1761],[5,"Sh",1763],[5,"Wpkh",1762],[5,"Tr",1764],[5,"Type",1765],[5,"ExtData",1766],[5,"Tree",1767],[1,"usize"],[10,"Satisfier",1743],[10,"Hash",1728],[10,"IntoWalletDescriptor",100],[8,"ExtendedDescriptor",100],[8,"KeyMap",693,1733],[5,"Iter",1768],[5,"PkIter",1768],[6,"Policy",1769],[6,"LiftError",1770],[5,"Weight",1771],[6,"BareCtx",1739],[6,"TapTree",1764],[6,"DescriptorSecretKey",693,1741],[5,"BTreeMap",1772],[10,"Signing",1752],[10,"PartialOrd",1724],[5,"Plan",1744],[5,"TxIn",1729],[6,"SigType",1739],[5,"String",1773],[6,"TranslateErr",1736],[10,"Translator",1736],[1,"array"],[6,"HexToBytesError",1774],[6,"PolicyError",386],[6,"Error",1775],[6,"Error",1776],[6,"KeyError",693],[6,"ParsePublicKeyError",1751],[6,"PkOrF",386],[6,"SatisfiableItem",386],[6,"Satisfaction",386],[5,"Condition",386],[10,"DescriptorTemplate",557],[8,"DescriptorTemplateOut",557],[5,"P2Pkh",557],[10,"IntoDescriptorKey",693],[5,"P2Wpkh_P2Sh",557],[5,"P2Wpkh",557],[5,"P2TR",557],[6,"Tap",1739],[5,"Bip44",557],[10,"DerivableKey",693],[5,"Bip44Public",557],[5,"Bip49",557],[5,"Bip49Public",557],[5,"Bip84",557],[5,"Bip84Public",557],[5,"Bip86",557],[5,"Bip86Public",557],[8,"ValidNetworks",693],[5,"SortedMultiVec",693,1777],[5,"GeneratedKey",693],[5,"PrivateKeyGenerateOptions",693],[5,"SinglePub",693,1741],[5,"SinglePriv",693,1741],[6,"SinglePubKey",693,1741],[6,"DescriptorKey",693],[10,"Debug",1727],[5,"Xpub",1776],[6,"ExtendedKey",693],[5,"Xpriv",1776],[10,"FromStr",1778],[5,"DerivationPath",1776],[17,"Entropy"],[17,"Options"],[17,"Error"],[10,"GeneratableKey",693],[10,"AsMut",1779],[10,"Default",1780],[10,"GeneratableDefaultOptions",693],[10,"CryptoRng",1781],[10,"RngCore",1781],[5,"Assets",1744],[8,"KeySource",1776],[5,"Fingerprint",1776],[5,"DescriptorKeyParseError",1741],[10,"PsbtUtils",994],[5,"Amount",1782],[5,"FeeRate",1783],[5,"Balance",998,1784],[5,"Wallet",998],[5,"SignerOrdering",1422],[10,"TransactionSigner",1422],[5,"Arc",1785],[17,"Item"],[8,"Indexed",1784],[10,"Iterator",1786],[5,"Block",1787],[5,"CannotConnectError",1788],[5,"BlockId",1789],[6,"ApplyHeaderError",1788],[5,"Transaction",1729],[10,"IntoIterator",1790],[5,"Update",998],[10,"Into",1779],[5,"ConfirmationTimeHeightAnchor",1789],[5,"TxGraph",1791],[5,"Txid",1729],[8,"DefaultCoinSelectionAlgorithm",1223],[5,"TxBuilder",1604],[6,"BuildFeeBumpError",1322],[6,"CalculateFeeError",1791],[5,"CheckPointIter",1788],[5,"AddressInfo",998],[5,"Psbt",1792],[5,"SignOptions",1422],[6,"SignerError",1422],[6,"NewError",998],[6,"LoadError",998],[6,"NewOrLoadError",998],[6,"InsertTxError",998],[6,"ApplyBlockError",998],[5,"FullScanResult",1793],[5,"SyncResult",1793],[5,"PsbtSighashType",1794],[5,"Input",1794],[6,"CreateTxError",1322],[5,"CanonicalTx",1791],[5,"AlterCheckPointError",1788],[6,"ConfirmationTime",1789],[10,"IsDust",998,1795],[5,"CheckPoint",1788],[10,"DoubleEndedIterator",1796],[8,"ChangeSet",998],[5,"LocalChain",1788],[5,"BlockHash",1787],[5,"KeychainTxOutIndex",1797],[5,"FullScanRequest",1793],[5,"SyncRequest",1793],[5,"LargestFirstCoinSelection",1223],[5,"OldestFirstCoinSelection",1223],[5,"BranchAndBoundCoinSelection",1223],[10,"CoinSelectionAlgorithm",1223],[5,"CoinSelectionResult",1223],[6,"Error",1223],[6,"Excess",1223],[6,"MiniscriptPsbtError",1322],[6,"Error",1798],[5,"FullyNodedExport",1399],[6,"SignerId",1422],[6,"SignerContext",1422],[5,"SignerWrapper",1422],[10,"Sized",1799],[6,"TapLeavesOptions",1422],[10,"SignerCommon",1422],[5,"DescriptorMultiXKey",1741],[5,"PrivateKey",1751],[5,"DescriptorXKey",1741],[5,"InputsIndexError",1729],[6,"TaprootError",1800],[6,"P2wpkhError",1800],[10,"InputSigner",1422],[5,"PushBytes",1801],[10,"AsRef",1779],[6,"AddForeignUtxoError",1604],[6,"AddUtxoError",1604],[6,"ChangeSpendPolicy",1604],[6,"TxOrdering",1604],[6,"LockTime",1802],[1,"i32"],[15,"Foreign",97],[8,"DerivedDescriptor",100],[15,"PsbtTimelocks",533],[15,"Complete",536],[15,"Partial",536],[15,"PartialComplete",536],[15,"Sha256Preimage",547],[15,"Hash256Preimage",547],[15,"Ripemd160Preimage",547],[15,"Hash160Preimage",547],[15,"Thresh",547],[15,"Multisig",547],[15,"AbsoluteTimelock",547],[15,"RelativeTimelock",547],[10,"ExtScriptContext",693],[15,"UnexpectedConnectedToHash",1213],[15,"ConfirmationHeightCannotBeGreaterThanTip",1215],[15,"LoadedGenesisDoesNotMatch",1217],[15,"LoadedNetworkDoesNotMatch",1217],[15,"LoadedDescriptorDoesNotMatch",1217],[15,"InsufficientFunds",1315],[15,"Change",1317],[15,"NoChange",1317],[15,"RbfSequenceCsv",1393],[15,"LockTime",1393],[15,"FeeTooLow",1393],[15,"FeeRateTooLow",1393],[8,"WalletExport",1399],[15,"Tap",1603],[15,"InvalidTxid",1721]],"r":[[2,100],[4,1723],[6,1723],[7,1422],[8,1604],[9,1723],[10,998],[11,1723],[70,998],[71,100],[104,1733],[106,1741],[113,1739],[114,1737],[119,386],[120,1739],[121,1739],[155,352],[696,1741],[697,1741],[712,1733],[722,1739],[727,1741],[728,1741],[729,1741],[730,1777],[1000,1784],[1008,1795]],"b":[[193,"impl-Descriptor%3CDescriptorPublicKey%3E"],[194,"impl-Descriptor%3CDefiniteDescriptorKey%3E"],[213,"impl-Debug-for-Descriptor%3CPk%3E"],[214,"impl-Display-for-Descriptor%3CPk%3E"],[217,"impl-Display-for-Miniscript%3CPk,+Ctx%3E"],[218,"impl-Debug-for-Miniscript%3CPk,+Ctx%3E"],[221,"impl-From%3CPkh%3CPk%3E%3E-for-Descriptor%3CPk%3E"],[223,"impl-From%3CWsh%3CPk%3E%3E-for-Descriptor%3CPk%3E"],[224,"impl-From%3CBare%3CPk%3E%3E-for-Descriptor%3CPk%3E"],[225,"impl-From%3CSh%3CPk%3E%3E-for-Descriptor%3CPk%3E"],[226,"impl-From%3CWpkh%3CPk%3E%3E-for-Descriptor%3CPk%3E"],[227,"impl-From%3CTr%3CPk%3E%3E-for-Descriptor%3CPk%3E"],[370,"impl-Debug-for-Error"],[371,"impl-Display-for-Error"],[372,"impl-From%3CError%3E-for-Error"],[373,"impl-From%3CHexToBytesError%3E-for-Error"],[374,"impl-From%3CPolicyError%3E-for-Error"],[376,"impl-From%3CError%3E-for-Error"],[377,"impl-From%3CError%3E-for-Error"],[378,"impl-From%3CKeyError%3E-for-Error"],[379,"impl-From%3CParsePublicKeyError%3E-for-Error"],[461,"impl-Debug-for-PolicyError"],[462,"impl-Display-for-PolicyError"],[811,"impl-Display-for-KeyError"],[812,"impl-Debug-for-KeyError"],[813,"impl-Display-for-SortedMultiVec%3CPk,+Ctx%3E"],[814,"impl-Debug-for-SortedMultiVec%3CPk,+Ctx%3E"],[815,"impl-Debug-for-DescriptorPublicKey"],[816,"impl-Display-for-DescriptorPublicKey"],[817,"impl-Debug-for-DescriptorSecretKey"],[818,"impl-Display-for-DescriptorSecretKey"],[824,"impl-From%3CXpub%3E-for-ExtendedKey%3CCtx%3E"],[825,"impl-From%3CXpriv%3E-for-ExtendedKey%3CCtx%3E"],[830,"impl-From%3CError%3E-for-KeyError"],[832,"impl-From%3CError%3E-for-KeyError"],[874,"impl-IntoDescriptorKey%3CCtx%3E-for-GeneratedKey%3CK,+Ctx%3E"],[875,"impl-DerivableKey%3CCtx%3E-for-GeneratedKey%3CK,+Ctx%3E"],[1075,"impl-Debug-for-Balance"],[1076,"impl-Display-for-Balance"],[1079,"impl-Display-for-AddressInfo"],[1080,"impl-Debug-for-AddressInfo"],[1081,"impl-Display-for-NewError"],[1082,"impl-Debug-for-NewError"],[1083,"impl-Display-for-LoadError"],[1084,"impl-Debug-for-LoadError"],[1085,"impl-Display-for-NewOrLoadError"],[1086,"impl-Debug-for-NewOrLoadError"],[1087,"impl-Display-for-InsertTxError"],[1088,"impl-Debug-for-InsertTxError"],[1089,"impl-Display-for-ApplyBlockError"],[1090,"impl-Debug-for-ApplyBlockError"],[1094,"impl-From%3CFullScanResult%3CKeychainKind%3E%3E-for-Update"],[1095,"impl-From%3CSyncResult%3E-for-Update"],[1264,"impl-Debug-for-Error"],[1265,"impl-Display-for-Error"],[1360,"impl-Debug-for-MiniscriptPsbtError"],[1361,"impl-Display-for-MiniscriptPsbtError"],[1362,"impl-Display-for-CreateTxError"],[1363,"impl-Debug-for-CreateTxError"],[1364,"impl-Display-for-BuildFeeBumpError"],[1365,"impl-Debug-for-BuildFeeBumpError"],[1367,"impl-From%3CError%3E-for-CreateTxError"],[1368,"impl-From%3CError%3E-for-CreateTxError"],[1369,"impl-From%3CError%3E-for-CreateTxError"],[1370,"impl-From%3CPolicyError%3E-for-CreateTxError"],[1371,"impl-From%3CMiniscriptPsbtError%3E-for-CreateTxError"],[1409,"impl-Display-for-FullyNodedExport"],[1410,"impl-Debug-for-FullyNodedExport"],[1503,"impl-SignerCommon-for-SignerWrapper%3CDescriptorMultiXKey%3CXpriv%3E%3E"],[1504,"impl-SignerCommon-for-SignerWrapper%3CPrivateKey%3E"],[1505,"impl-SignerCommon-for-SignerWrapper%3CDescriptorXKey%3CXpriv%3E%3E"],[1512,"impl-Debug-for-SignerError"],[1513,"impl-Display-for-SignerError"],[1520,"impl-From%3CHash%3E-for-SignerId"],[1521,"impl-From%3CFingerprint%3E-for-SignerId"],[1524,"impl-From%3CInputsIndexError%3E-for-SignerError"],[1525,"impl-From%3CTaprootError%3E-for-SignerError"],[1526,"impl-From%3CP2wpkhError%3E-for-SignerError"],[1535,"impl-SignerCommon-for-SignerWrapper%3CDescriptorMultiXKey%3CXpriv%3E%3E"],[1536,"impl-SignerCommon-for-SignerWrapper%3CPrivateKey%3E"],[1537,"impl-SignerCommon-for-SignerWrapper%3CDescriptorXKey%3CXpriv%3E%3E"],[1553,"impl-InputSigner-for-SignerWrapper%3CDescriptorMultiXKey%3CXpriv%3E%3E"],[1554,"impl-InputSigner-for-SignerWrapper%3CDescriptorXKey%3CXpriv%3E%3E"],[1555,"impl-InputSigner-for-SignerWrapper%3CPrivateKey%3E"],[1663,"impl-Debug-for-AddUtxoError"],[1664,"impl-Display-for-AddUtxoError"],[1665,"impl-Display-for-AddForeignUtxoError"],[1666,"impl-Debug-for-AddForeignUtxoError"]],"c":"OjAAAAEAAAAAAAUAEAAAAMEAAwEPAR8DeAN5BQ==","e":"OzAAAAEAAH0DfwADAAAACAABAAsAAAAOABMAJgAJADUAAQA+AAAAQQAAAEUADwBXAAMAXQADAGoAAAB4AAAAjAABAI8AAACRAAcAnAAAAJ4AAQChAAAApAABAKcAAQCrAAEArgABALEAAQC0AAsAxQADAMoAAwDTAAEA1gAIAOAABADqAAAA9wADAAIBAAAIAQEADAEBABMBAQApAQMALgEBADwBAQA/AQEAQwEFAE4BBwBXAQMAXAEDAHEBBgB5AQMAfgEEAKYBGQDCAQ4A0wEAANYBAADbAQEA6gEAAO0BBADzASIAPAIXAFUCCwB5AjwA5AIXAAYDFQAdAwEAIAMAACIDFQA5AwEAPwMAAEEDAABEAwAASwMBAFgDAwBoAwAAawMEAHEDAQCBAwEAhgMAAJADAACVAwMAngMAAKIDCACsAwMAswMvAP4DAAAGBAAACAQRACIEAwAoBAIALgQCADQEDwBHBAEAfwQAAIcECACUBBEAqAQIALQECADVBBEA6AQCAOwEAgDxBAYACAUbAEkFDQBYBQQAYgUPAHwFAQCABQAAggUBAIUFAACJBQUAuQUPAMoFFADgBQYA6AUKAPUFAgD+BQAAAAYCAA4GAQASBgIAFgYAABoGBwAkBh8AXQYJAGgGBwByBgEAeQYBAH8GBgCLBgEAmAYBAJ8GEwC1BgQA"}],\ ["example_bitcoind_rpc_polling",{"t":"PSISSSGPSPFGSPPNNNNHNNNNNNNNNNONNNNNNNNNNNNNNHNOOOHNNNNNNNNNNNNNNNONNNOO","n":["Block","CHANNEL_BOUND","ChangeSet","DB_COMMIT_DELAY","DB_MAGIC","DB_PATH","Emission","Live","MEMPOOL_EMIT_DELAY","Mempool","RpcArgs","RpcCommands","STDOUT_PRINT_DELAY","Sync","Tip","augment_args","augment_args_for_update","augment_subcommands","augment_subcommands_for_update","await_flag","borrow","borrow","borrow","borrow_mut","borrow_mut","borrow_mut","clone","clone","clone_into","clone_into","fallback_height","fmt","fmt","fmt","from","from","from","from_arg_matches","from_arg_matches","from_arg_matches_mut","from_arg_matches_mut","has_subcommand","into","into","into","main","new_client","rpc_cookie","rpc_password","rpc_user","start_ctrlc_handler","to_owned","to_owned","try_from","try_from","try_from","try_into","try_into","try_into","type_id","type_id","type_id","update_from_arg_matches","update_from_arg_matches","update_from_arg_matches_mut","update_from_arg_matches_mut","url","vzip","vzip","vzip","rpc_args","rpc_args"],"q":[[0,"example_bitcoind_rpc_polling"],[70,"example_bitcoind_rpc_polling::RpcCommands"],[72,"clap::builder::command"],[73,"core::sync::atomic"],[74,"core::time"],[75,"core::fmt"],[76,"clap::parser::matches::arg_matches"],[77,"clap::error"],[78,"core::result"],[79,"anyhow"],[80,"bitcoincore_rpc::client"],[81,"alloc::sync"],[82,"core::any"]],"i":[10,0,0,0,0,0,0,8,0,10,0,0,0,8,10,7,7,8,8,0,10,7,8,10,7,8,7,8,7,8,7,10,7,8,10,7,8,7,8,7,8,8,10,7,8,0,7,7,7,7,0,7,8,10,7,8,10,7,8,10,7,8,7,8,7,8,7,10,7,8,21,22],"f":"```````````````{bb}000{{{f{d}}h}j}{{{f{c}}}{{f{e}}}{}{}}00{{{f{lc}}}{{f{le}}}{}{}}00{{{f{n}}}n}{{{f{A`}}}A`}{{{f{c}}{f{le}}}Ab{}{}}0`{{{f{Ad}}{f{lAf}}}Ah}{{{f{n}}{f{lAf}}}Ah}{{{f{A`}}{f{lAf}}}Ah}{cc{}}00{{{f{Aj}}}{{An{nAl}}}}{{{f{Aj}}}{{An{A`Al}}}}{{{f{lAj}}}{{An{nAl}}}}{{{f{lAj}}}{{An{A`Al}}}}{{{f{B`}}}j}{ce{}{}}00{{}{{Bb{Ab}}}}{{{f{n}}}{{Bb{Bd}}}}```{{}{{Bf{d}}}}{{{f{c}}}e{}{}}0{c{{An{e}}}{}{}}00000{{{f{c}}}Bh{}}00{{{f{ln}}{f{Aj}}}{{An{AbAl}}}}{{{f{lA`}}{f{Aj}}}{{An{AbAl}}}}{{{f{ln}}{f{lAj}}}{{An{AbAl}}}}{{{f{lA`}}{f{lAj}}}{{An{AbAl}}}}`:::``","D":"Bb","p":[[8,"Command",72],[5,"AtomicBool",73],[1,"reference"],[5,"Duration",74],[1,"bool"],[0,"mut"],[5,"RpcArgs",0],[6,"RpcCommands",0],[1,"unit"],[6,"Emission",0],[5,"Formatter",75],[8,"Result",75],[5,"ArgMatches",76],[5,"Error",77],[6,"Result",78],[1,"str"],[8,"Result",79],[5,"Client",80],[5,"Arc",81],[5,"TypeId",82],[15,"Sync",70],[15,"Live",70]],"r":[],"b":[],"c":"OjAAAAAAAAA=","e":"OzAAAAEAADcACgAAAAEAAwAAAAUAAgAKAAIADwAPACAAAgAmAAQALgABADMADwBEAAQA"}],\ -["example_cli",{"t":"PGFPPPGGFPPFPGIIPPPPPPPIPPPGEONNNNNNNNENNNNNNNNNNNNNNNNOOENNNNNNNNNNNOOHOONONNNNNNNNNNNNNNNNNNNNNNNNNNNNHNNNOOOOHONNNNNNNNNNOONHNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNOOOOOOOOOOO","n":["Address","AddressCmd","Args","Balance","BranchAndBound","ChainSpecific","CoinSelectionAlgo","Commands","CreateTxChange","External","Index","Init","Internal","Keychain","KeychainChangeSet","KeychainTxGraph","LargestFirst","List","List","New","NewestFirst","Next","OldestFirst","PlannedUtxo","Send","SmallestFirst","TxOut","TxOutCmd","anyhow","args","augment_args","augment_args_for_update","augment_subcommands","augment_subcommands","augment_subcommands","augment_subcommands_for_update","augment_subcommands_for_update","augment_subcommands_for_update","bdk_file_store","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_descriptor","change_keychain","clap","clone","clone","clone","clone","clone","clone_into","clone_into","clone_into","clone_into","clone_into","cmp","command","cp_limit","create_tx","db","db_path","default","descriptor","deserialize","eq","equivalent","equivalent","fmt","fmt","fmt","fmt","fmt","fmt","fmt","from","from","from","from","from","from","from","from","from_arg_matches","from_arg_matches","from_arg_matches","from_arg_matches","from_arg_matches_mut","from_arg_matches_mut","from_arg_matches_mut","from_arg_matches_mut","from_str","handle_commands","has_subcommand","has_subcommand","has_subcommand","index","index","index","index_changeset","init","init_changeset","into","into","into","into","into","into","into","into","into_app","into_app_for_update","keymap","network","partial_cmp","planned_utxos","serialize","to_owned","to_owned","to_owned","to_owned","to_owned","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","update_from_arg_matches","update_from_arg_matches","update_from_arg_matches","update_from_arg_matches","update_from_arg_matches_mut","update_from_arg_matches_mut","update_from_arg_matches_mut","update_from_arg_matches_mut","vzip","vzip","vzip","vzip","vzip","vzip","vzip","vzip","change","addr_cmd","address","chain_specific","coin_select","txout_cmd","value","confirmed","spent","unconfirmed","unspent"],"q":[[0,"example_cli"],[176,"example_cli::AddressCmd"],[177,"example_cli::Commands"],[183,"example_cli::TxOutCmd"],[187,"clap::builder::command"],[188,"core::clone"],[189,"clap::derive"],[190,"core::cmp"],[191,"miniscript::descriptor::key"],[192,"alloc::collections::btree::map"],[193,"bitcoin::address"],[194,"bitcoin::blockdata::transaction"],[195,"core::option"],[196,"anyhow"],[197,"bdk_chain::tx_data_traits"],[198,"bdk_chain::chain_oracle"],[199,"core::result"],[200,"serde::de"],[201,"core::fmt"],[202,"clap::parser::matches::arg_matches"],[203,"clap::error"],[204,"std::sync::mutex"],[205,"bdk_file_store::store"],[206,"bitcoin::network"],[207,"core::default"],[208,"serde::ser"],[209,"core::convert"],[210,"core::marker"],[211,"core::ops::function"],[212,"bdk_tmp_plan"],[213,"alloc::vec"],[214,"alloc::string"],[215,"core::any"]],"i":[4,0,0,4,8,4,0,0,0,11,9,0,11,0,0,0,8,9,10,9,8,9,8,0,4,8,4,0,0,52,34,34,4,9,10,4,9,10,0,21,52,34,4,8,9,10,11,21,52,34,4,8,9,10,11,34,21,0,4,8,9,10,11,4,8,9,10,11,11,34,34,0,52,34,8,34,11,11,11,11,4,8,8,9,10,11,11,21,52,34,4,8,9,10,11,34,4,9,10,34,4,9,10,8,0,4,9,10,14,21,52,21,0,52,21,52,34,4,8,9,10,11,34,34,52,34,11,0,11,4,8,9,10,11,8,11,21,52,34,4,8,9,10,11,21,52,34,4,8,9,10,11,21,52,34,4,8,9,10,11,34,4,9,10,34,4,9,10,21,52,34,4,8,9,10,11,60,61,62,62,62,63,62,64,64,64,64],"f":"``````````````````````````````{bb}0000000`{{{d{c}}}{{d{e}}}{}{}}0000000{{{d{fc}}}{{d{fe}}}{}{}}0000000```{{{d{{h{ce}}}}}{{h{ce}}}{jl}{jn}}{{{d{A`}}}A`}{{{d{Ab}}}Ab}{{{d{Ad}}}Ad}{{{d{Af}}}Af}{{{d{c}}{d{fe}}}Ah{}{}}0000{{{d{Af}}{d{Af}}}Aj}``{{{d{f{Al{c}}}}{d{e}}{d{{Bb{AnB`}}}}A`BdBf}{{C`{{Bn{Bh{Bl{Bj}}}}}}}CbCd}``{{}A`}`{c{{Cf{Af}}}Ch}{{{d{Af}}{d{Af}}}Cj}{{{d{c}}{d{e}}}Cj{}{}}0{{{d{{h{ce}}}}{d{fCl}}}Cn{D`l}{D`n}}{{{d{A`}}{d{fCl}}}Cn}0{{{d{Ab}}{d{fCl}}}Cn}{{{d{Ad}}{d{fCl}}}Cn}{{{d{Af}}{d{fCl}}}Cn}0{cc{}}0000000{{{d{Db}}}{{Cf{{Dd{ce}}Df}}}ln}{{{d{Db}}}{{Cf{{h{ce}}Df}}}ln}{{{d{Db}}}{{Cf{AbDf}}}}{{{d{Db}}}{{Cf{AdDf}}}}{{{d{fDb}}}{{Cf{{Dd{ce}}Df}}}ln}{{{d{fDb}}}{{Cf{{h{ce}}Df}}}ln}{{{d{fDb}}}{{Cf{AbDf}}}}{{{d{fDb}}}{{Cf{AdDf}}}}{{{d{Dh}}}{{Cf{A`c}}}{}}{{{d{{Dj{{Al{c}}}}}}{d{{Dj{{Dl{e}}}}}}{d{{Dj{g}}}}{d{{Bb{AnB`}}}}Dnk{h{mi}}}{{C`{Ah}}}Cb{E`EbEdEf{Ej{{Eh{c}}}}ElEnD`}Cdn{{Fb{i{d{Bh}}}{{F`{{C`{Ah}}}}}}}l}{{{d{Dh}}}Cj}00````{{{d{{Ff{Fd}}}}{d{Dh}}}{{C`{{Fh{ceg}}}}}ln{E`EbEfEdD`ElEn}}`{ce{}{}}0000000{{}b}0``{{{d{Af}}{d{Af}}}{{Bl{Aj}}}}{{{d{{Al{c}}}}{d{e}}{d{{Fj{g}}}}}{{Cf{{Fn{{Fl{gc}}}}}}}CbCd{jG`}}{{{d{Af}}c}CfGb}{{{d{c}}}e{}{}}0000{{{d{c}}}Gd{}}0{c{{Cf{e}}}{}{}}000000000000000{{{d{c}}}Gf{}}0000000{{{d{f{Dd{ce}}}}{d{Db}}}{{Cf{AhDf}}}ln}{{{d{f{h{ce}}}}{d{Db}}}{{Cf{AhDf}}}ln}{{{d{fAb}}{d{Db}}}{{Cf{AhDf}}}}{{{d{fAd}}{d{Db}}}{{Cf{AhDf}}}}{{{d{f{Dd{ce}}}}{d{fDb}}}{{Cf{AhDf}}}ln}{{{d{f{h{ce}}}}{d{fDb}}}{{Cf{AhDf}}}ln}{{{d{fAb}}{d{fDb}}}{{Cf{AhDf}}}}{{{d{fAd}}{d{fDb}}}{{Cf{AhDf}}}}{ce{}{}}0000000```````````","D":"E`","p":[[8,"Command",187],[1,"reference"],[0,"mut"],[6,"Commands",0],[10,"Clone",188],[10,"Subcommand",189],[10,"Args",189],[6,"CoinSelectionAlgo",0],[6,"AddressCmd",0],[6,"TxOutCmd",0],[6,"Keychain",0],[1,"unit"],[6,"Ordering",190],[8,"KeychainTxGraph",0],[6,"DescriptorPublicKey",191],[6,"DescriptorSecretKey",191],[5,"BTreeMap",192],[5,"Address",193],[1,"u64"],[5,"Transaction",194],[5,"CreateTxChange",0],[6,"Option",195],[1,"tuple"],[8,"Result",196],[10,"Anchor",197],[10,"ChainOracle",198],[6,"Result",199],[10,"Deserializer",200],[1,"bool"],[5,"Formatter",201],[8,"Result",201],[10,"Debug",201],[5,"ArgMatches",202],[5,"Args",0],[5,"Error",203],[1,"str"],[5,"Mutex",204],[5,"Store",205],[6,"Network",206],[10,"Default",207],[10,"Append",197],[10,"DeserializeOwned",200],[10,"Serialize",208],[8,"KeychainChangeSet",0],[10,"From",209],[10,"Send",210],[10,"Sync",210],[17,"Output"],[10,"FnOnce",211],[1,"u8"],[1,"slice"],[5,"Init",0],[5,"Assets",212],[8,"PlannedUtxo",0],[5,"Vec",213],[10,"CanDerive",212],[10,"Serializer",208],[5,"String",214],[5,"TypeId",215],[15,"List",176],[15,"Address",177],[15,"Send",177],[15,"TxOut",177],[15,"List",183]],"r":[],"b":[[81,"impl-Display-for-CoinSelectionAlgo"],[82,"impl-Debug-for-CoinSelectionAlgo"],[85,"impl-Display-for-Keychain"],[86,"impl-Debug-for-Keychain"]],"c":"OjAAAAAAAAA=","e":"OzAAAAEAAJMAEQAAAAAAAgABAAUABQANAAQAFQAAABcAAQAaAAAAHAABAB8AKQBKAA0AYAAMAG4AAABwAAAAewABAH4AMgCyAAAAtAACAA=="}],\ +["example_cli",{"t":"PGFPPPGGFPPFPGIIPPPPPPPIPPPGEONNNNNNNNENNNNNNNNNNNNNNNNOOENNNNNNNNNNNOOHOONONNNNNNNNNNNNNNNNNNNNNNNNNNNNHNNNOOOOHONNNNNNNNNNOONHNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNOOOOOOOOOOO","n":["Address","AddressCmd","Args","Balance","BranchAndBound","ChainSpecific","CoinSelectionAlgo","Commands","CreateTxChange","External","Index","Init","Internal","Keychain","KeychainChangeSet","KeychainTxGraph","LargestFirst","List","List","New","NewestFirst","Next","OldestFirst","PlannedUtxo","Send","SmallestFirst","TxOut","TxOutCmd","anyhow","args","augment_args","augment_args_for_update","augment_subcommands","augment_subcommands","augment_subcommands","augment_subcommands_for_update","augment_subcommands_for_update","augment_subcommands_for_update","bdk_file_store","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_descriptor","change_keychain","clap","clone","clone","clone","clone","clone","clone_into","clone_into","clone_into","clone_into","clone_into","cmp","command","cp_limit","create_tx","db","db_path","default","descriptor","deserialize","eq","equivalent","equivalent","fmt","fmt","fmt","fmt","fmt","fmt","fmt","from","from","from","from","from","from","from","from","from_arg_matches","from_arg_matches","from_arg_matches","from_arg_matches","from_arg_matches_mut","from_arg_matches_mut","from_arg_matches_mut","from_arg_matches_mut","from_str","handle_commands","has_subcommand","has_subcommand","has_subcommand","index","index","index","index_changeset","init","init_changeset","into","into","into","into","into","into","into","into","into_app","into_app_for_update","keymap","network","partial_cmp","planned_utxos","serialize","to_owned","to_owned","to_owned","to_owned","to_owned","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","update_from_arg_matches","update_from_arg_matches","update_from_arg_matches","update_from_arg_matches","update_from_arg_matches_mut","update_from_arg_matches_mut","update_from_arg_matches_mut","update_from_arg_matches_mut","vzip","vzip","vzip","vzip","vzip","vzip","vzip","vzip","change","addr_cmd","address","chain_specific","coin_select","txout_cmd","value","confirmed","spent","unconfirmed","unspent"],"q":[[0,"example_cli"],[176,"example_cli::AddressCmd"],[177,"example_cli::Commands"],[183,"example_cli::TxOutCmd"],[187,"clap::builder::command"],[188,"core::clone"],[189,"clap::derive"],[190,"core::cmp"],[191,"miniscript::descriptor::key"],[192,"alloc::collections::btree::map"],[193,"bitcoin::address"],[194,"bitcoin::blockdata::transaction"],[195,"core::option"],[196,"anyhow"],[197,"bdk_chain::tx_data_traits"],[198,"bdk_chain::chain_oracle"],[199,"core::result"],[200,"serde::de"],[201,"core::fmt"],[202,"clap::parser::matches::arg_matches"],[203,"clap::error"],[204,"std::sync::mutex"],[205,"bdk_file_store::store"],[206,"bitcoin::network"],[207,"core::default"],[208,"serde::ser"],[209,"core::convert"],[210,"core::marker"],[211,"core::ops::function"],[212,"bdk_tmp_plan"],[213,"alloc::vec"],[214,"alloc::string"],[215,"core::any"]],"i":[4,0,0,4,8,4,0,0,0,11,9,0,11,0,0,0,8,9,10,9,8,9,8,0,4,8,4,0,0,52,34,34,4,9,10,4,9,10,0,21,52,34,4,8,9,10,11,21,52,34,4,8,9,10,11,34,21,0,4,8,9,10,11,4,8,9,10,11,11,34,34,0,52,34,8,34,11,11,11,11,4,8,8,9,10,11,11,21,52,34,4,8,9,10,11,34,4,9,10,34,4,9,10,8,0,4,9,10,14,21,52,21,0,52,21,52,34,4,8,9,10,11,34,34,52,34,11,0,11,4,8,9,10,11,8,11,21,52,34,4,8,9,10,11,21,52,34,4,8,9,10,11,21,52,34,4,8,9,10,11,34,4,9,10,34,4,9,10,21,52,34,4,8,9,10,11,60,61,62,62,62,63,62,64,64,64,64],"f":"``````````````````````````````{bb}0000000`{{{d{c}}}{{d{e}}}{}{}}0000000{{{d{fc}}}{{d{fe}}}{}{}}0000000```{{{d{{h{ce}}}}}{{h{ce}}}{jl}{jn}}{{{d{A`}}}A`}{{{d{Ab}}}Ab}{{{d{Ad}}}Ad}{{{d{Af}}}Af}{{{d{c}}{d{fe}}}Ah{}{}}0000{{{d{Af}}{d{Af}}}Aj}``{{{d{f{Al{c}}}}{d{e}}{d{{Bb{AnB`}}}}A`BdBf}{{C`{{Bn{Bh{Bl{Bj}}}}}}}CbCd}``{{}A`}`{c{{Cf{Af}}}Ch}{{{d{Af}}{d{Af}}}Cj}{{{d{c}}{d{e}}}Cj{}{}}0{{{d{{h{ce}}}}{d{fCl}}}Cn{D`l}{D`n}}{{{d{A`}}{d{fCl}}}Cn}0{{{d{Ab}}{d{fCl}}}Cn}{{{d{Ad}}{d{fCl}}}Cn}{{{d{Af}}{d{fCl}}}Cn}0{cc{}}0000000{{{d{Db}}}{{Cf{{Dd{ce}}Df}}}ln}{{{d{Db}}}{{Cf{{h{ce}}Df}}}ln}{{{d{Db}}}{{Cf{AbDf}}}}{{{d{Db}}}{{Cf{AdDf}}}}{{{d{fDb}}}{{Cf{{Dd{ce}}Df}}}ln}{{{d{fDb}}}{{Cf{{h{ce}}Df}}}ln}{{{d{fDb}}}{{Cf{AbDf}}}}{{{d{fDb}}}{{Cf{AdDf}}}}{{{d{Dh}}}{{Cf{A`c}}}{}}{{{d{{Dj{{Al{c}}}}}}{d{{Dj{{Dl{e}}}}}}{d{{Dj{g}}}}{d{{Bb{AnB`}}}}Dnk{h{mi}}}{{C`{Ah}}}Cb{E`EbEdEf{Ej{{Eh{c}}}}ElEnD`}Cdn{{Fb{i{d{Bh}}}{{F`{{C`{Ah}}}}}}}l}{{{d{Dh}}}Cj}00````{{{d{{Ff{Fd}}}}{d{Dh}}}{{C`{{Fh{ceg}}}}}ln{E`EbEfEdD`ElEn}}`{ce{}{}}0000000{{}b}0``{{{d{Af}}{d{Af}}}{{Bl{Aj}}}}{{{d{{Al{c}}}}{d{e}}{d{{Fj{g}}}}}{{Cf{{Fn{{Fl{gc}}}}}}}CbCd{jG`}}{{{d{Af}}c}CfGb}{{{d{c}}}e{}{}}0000{{{d{c}}}Gd{}}0{c{{Cf{e}}}{}{}}000000000000000{{{d{c}}}Gf{}}0000000{{{d{f{Dd{ce}}}}{d{Db}}}{{Cf{AhDf}}}ln}{{{d{f{h{ce}}}}{d{Db}}}{{Cf{AhDf}}}ln}{{{d{fAb}}{d{Db}}}{{Cf{AhDf}}}}{{{d{fAd}}{d{Db}}}{{Cf{AhDf}}}}{{{d{f{Dd{ce}}}}{d{fDb}}}{{Cf{AhDf}}}ln}{{{d{f{h{ce}}}}{d{fDb}}}{{Cf{AhDf}}}ln}{{{d{fAb}}{d{fDb}}}{{Cf{AhDf}}}}{{{d{fAd}}{d{fDb}}}{{Cf{AhDf}}}}{ce{}{}}0000000```````````","D":"E`","p":[[8,"Command",187],[1,"reference"],[0,"mut"],[6,"Commands",0],[10,"Clone",188],[10,"Subcommand",189],[10,"Args",189],[6,"CoinSelectionAlgo",0],[6,"AddressCmd",0],[6,"TxOutCmd",0],[6,"Keychain",0],[1,"unit"],[6,"Ordering",190],[8,"KeychainTxGraph",0],[6,"DescriptorPublicKey",191],[6,"DescriptorSecretKey",191],[5,"BTreeMap",192],[5,"Address",193],[1,"u64"],[5,"Transaction",194],[5,"CreateTxChange",0],[6,"Option",195],[1,"tuple"],[8,"Result",196],[10,"Anchor",197],[10,"ChainOracle",198],[6,"Result",199],[10,"Deserializer",200],[1,"bool"],[5,"Formatter",201],[8,"Result",201],[10,"Debug",201],[5,"ArgMatches",202],[5,"Args",0],[5,"Error",203],[1,"str"],[5,"Mutex",204],[5,"Store",205],[6,"Network",206],[10,"Default",207],[10,"Append",197],[10,"DeserializeOwned",200],[10,"Serialize",208],[8,"KeychainChangeSet",0],[10,"From",209],[10,"Send",210],[10,"Sync",210],[17,"Output"],[10,"FnOnce",211],[1,"u8"],[1,"slice"],[5,"Init",0],[5,"Assets",212],[8,"PlannedUtxo",0],[5,"Vec",213],[10,"CanDerive",212],[10,"Serializer",208],[5,"String",214],[5,"TypeId",215],[15,"List",176],[15,"Address",177],[15,"Send",177],[15,"TxOut",177],[15,"List",183]],"r":[],"b":[[81,"impl-Debug-for-CoinSelectionAlgo"],[82,"impl-Display-for-CoinSelectionAlgo"],[85,"impl-Debug-for-Keychain"],[86,"impl-Display-for-Keychain"]],"c":"OjAAAAAAAAA=","e":"OzAAAAEAAJMAEQAAAAAAAgABAAUABQANAAQAFQAAABcAAQAaAAAAHAABAB8AKQBKAA0AYAAMAG4AAABwAAAAewABAH4AMgCyAAAAtAACAA=="}],\ ["example_electrum",{"t":"ISSFGPFPNNNNNNONNNNNNNNNNNNNNONNNNNNNNNNNNNNNNNNNHNNNNNNNNNNNNNNNNNNNNNOOOOOOOOO","n":["ChangeSet","DB_MAGIC","DB_PATH","ElectrumArgs","ElectrumCommands","Scan","ScanOptions","Sync","augment_args","augment_args","augment_args_for_update","augment_args_for_update","augment_subcommands","augment_subcommands_for_update","batch_size","borrow","borrow","borrow","borrow_mut","borrow_mut","borrow_mut","client","clone","clone","clone","clone_into","clone_into","clone_into","electrum_args","electrum_url","eq","fmt","fmt","fmt","from","from","from","from_arg_matches","from_arg_matches","from_arg_matches","from_arg_matches_mut","from_arg_matches_mut","from_arg_matches_mut","has_subcommand","into","into","into","into_app","into_app_for_update","main","to_owned","to_owned","to_owned","try_from","try_from","try_from","try_into","try_into","try_into","type_id","type_id","type_id","update_from_arg_matches","update_from_arg_matches","update_from_arg_matches","update_from_arg_matches_mut","update_from_arg_matches_mut","update_from_arg_matches_mut","vzip","vzip","vzip","all_spks","electrum_args","electrum_args","scan_options","scan_options","stop_gap","unconfirmed","unused_spks","utxos"],"q":[[0,"example_electrum"],[71,"example_electrum::ElectrumCommands"],[80,"clap::builder::command"],[81,"bitcoin::network"],[82,"electrum_client::client"],[83,"anyhow"],[84,"core::fmt"],[85,"clap::parser::matches::arg_matches"],[86,"clap::error"],[87,"core::result"],[88,"core::any"]],"i":[0,0,0,0,0,8,0,8,4,9,4,9,8,8,9,8,4,9,8,4,9,4,8,4,9,8,4,9,8,4,9,8,4,9,8,4,9,8,4,9,8,4,9,8,8,4,9,9,9,0,8,4,9,8,4,9,8,4,9,8,4,9,8,4,9,8,4,9,8,4,9,19,20,19,20,19,20,19,19,19],"f":"````````{bb}00000`{{{d{c}}}{{d{e}}}{}{}}00{{{d{fc}}}{{d{fe}}}{}{}}00{{{d{h}}j}{{n{l}}}}{{{d{A`}}}A`}{{{d{h}}}h}{{{d{Ab}}}Ab}{{{d{c}}{d{fe}}}Ad{}{}}00{{{d{A`}}}h}`{{{d{Ab}}{d{Ab}}}Af}{{{d{A`}}{d{fAh}}}Aj}{{{d{h}}{d{fAh}}}Aj}{{{d{Ab}}{d{fAh}}}Aj}{cc{}}00{{{d{Al}}}{{B`{A`An}}}}{{{d{Al}}}{{B`{hAn}}}}{{{d{Al}}}{{B`{AbAn}}}}{{{d{fAl}}}{{B`{A`An}}}}{{{d{fAl}}}{{B`{hAn}}}}{{{d{fAl}}}{{B`{AbAn}}}}{{{d{Bb}}}Af}{ce{}{}}00{{}b}0{{}{{n{Ad}}}}{{{d{c}}}e{}{}}00{c{{B`{e}}}{}{}}00000{{{d{c}}}Bd{}}00{{{d{fA`}}{d{Al}}}{{B`{AdAn}}}}{{{d{fh}}{d{Al}}}{{B`{AdAn}}}}{{{d{fAb}}{d{Al}}}{{B`{AdAn}}}}{{{d{fA`}}{d{fAl}}}{{B`{AdAn}}}}{{{d{fh}}{d{fAl}}}{{B`{AdAn}}}}{{{d{fAb}}{d{fAl}}}{{B`{AdAn}}}};;;`````````","D":"An","p":[[8,"Command",80],[1,"reference"],[0,"mut"],[5,"ElectrumArgs",0],[6,"Network",81],[5,"Client",82],[8,"Result",83],[6,"ElectrumCommands",0],[5,"ScanOptions",0],[1,"unit"],[1,"bool"],[5,"Formatter",84],[8,"Result",84],[5,"ArgMatches",85],[5,"Error",86],[6,"Result",87],[1,"str"],[5,"TypeId",88],[15,"Sync",71],[15,"Scan",71]],"r":[],"b":[],"c":"OjAAAAAAAAA=","e":"OzAAAAEAAEEACAAAAAUABwAAAAkABQAQAA0AHwADACYABgAwABcASQADAA=="}],\ ["example_esplora",{"t":"ISSFGPFPNNNNNNNNNNNNNNNNNNNNNONNNNNNNNNNNNNNNNNNHONNNNNNNNNNNNNNNNNNNNNOOOOOOOOO","n":["ChangeSet","DB_MAGIC","DB_PATH","EsploraArgs","EsploraCommands","Scan","ScanOptions","Sync","augment_args","augment_args","augment_args_for_update","augment_args_for_update","augment_subcommands","augment_subcommands_for_update","borrow","borrow","borrow","borrow_mut","borrow_mut","borrow_mut","client","clone","clone","clone","clone_into","clone_into","clone_into","eq","esplora_args","esplora_url","fmt","fmt","fmt","from","from","from","from_arg_matches","from_arg_matches","from_arg_matches","from_arg_matches_mut","from_arg_matches_mut","from_arg_matches_mut","has_subcommand","into","into","into","into_app","into_app_for_update","main","parallel_requests","to_owned","to_owned","to_owned","try_from","try_from","try_from","try_into","try_into","try_into","type_id","type_id","type_id","update_from_arg_matches","update_from_arg_matches","update_from_arg_matches","update_from_arg_matches_mut","update_from_arg_matches_mut","update_from_arg_matches_mut","vzip","vzip","vzip","all_spks","esplora_args","esplora_args","scan_options","scan_options","stop_gap","unconfirmed","unused_spks","utxos"],"q":[[0,"example_esplora"],[71,"example_esplora::EsploraCommands"],[80,"clap::builder::command"],[81,"bitcoin::network"],[82,"esplora_client::blocking"],[83,"anyhow"],[84,"core::fmt"],[85,"clap::parser::matches::arg_matches"],[86,"clap::error"],[87,"core::result"],[88,"core::any"]],"i":[0,0,0,0,0,8,0,8,4,9,4,9,8,8,8,4,9,8,4,9,4,8,4,9,8,4,9,9,8,4,8,4,9,8,4,9,8,4,9,8,4,9,8,8,4,9,9,9,0,9,8,4,9,8,4,9,8,4,9,8,4,9,8,4,9,8,4,9,8,4,9,19,20,19,20,19,20,19,19,19],"f":"````````{bb}00000{{{d{c}}}{{d{e}}}{}{}}00{{{d{fc}}}{{d{fe}}}{}{}}00{{{d{h}}j}{{n{l}}}}{{{d{A`}}}A`}{{{d{h}}}h}{{{d{Ab}}}Ab}{{{d{c}}{d{fe}}}Ad{}{}}00{{{d{Ab}}{d{Ab}}}Af}{{{d{A`}}}h}`{{{d{A`}}{d{fAh}}}Aj}{{{d{h}}{d{fAh}}}Aj}{{{d{Ab}}{d{fAh}}}Aj}{cc{}}00{{{d{Al}}}{{B`{A`An}}}}{{{d{Al}}}{{B`{hAn}}}}{{{d{Al}}}{{B`{AbAn}}}}{{{d{fAl}}}{{B`{A`An}}}}{{{d{fAl}}}{{B`{hAn}}}}{{{d{fAl}}}{{B`{AbAn}}}}{{{d{Bb}}}Af}{ce{}{}}00{{}b}0{{}{{n{Ad}}}}`{{{d{c}}}e{}{}}00{c{{B`{e}}}{}{}}00000{{{d{c}}}Bd{}}00{{{d{fA`}}{d{Al}}}{{B`{AdAn}}}}{{{d{fh}}{d{Al}}}{{B`{AdAn}}}}{{{d{fAb}}{d{Al}}}{{B`{AdAn}}}}{{{d{fA`}}{d{fAl}}}{{B`{AdAn}}}}{{{d{fh}}{d{fAl}}}{{B`{AdAn}}}}{{{d{fAb}}{d{fAl}}}{{B`{AdAn}}}};;;`````````","D":"An","p":[[8,"Command",80],[1,"reference"],[0,"mut"],[5,"EsploraArgs",0],[6,"Network",81],[5,"BlockingClient",82],[8,"Result",83],[6,"EsploraCommands",0],[5,"ScanOptions",0],[1,"unit"],[1,"bool"],[5,"Formatter",84],[8,"Result",84],[5,"ArgMatches",85],[5,"Error",86],[6,"Result",87],[1,"str"],[5,"TypeId",88],[15,"Sync",71],[15,"Scan",71]],"r":[],"b":[],"c":"OjAAAAAAAAA=","e":"OzAAAAEAAEEACAAAAAUABwAAAAkAFAAfAAIAJQAGAC8AAgAzABQASQADAA=="}],\ ["wallet_electrum_example",{"t":"SSSSH","n":["BATCH_SIZE","DB_MAGIC","SEND_AMOUNT","STOP_GAP","main"],"q":[[0,"wallet_electrum_example"],[5,"anyhow"],[6,"core::result"]],"i":[0,0,0,0,0],"f":"````{{}{{f{bd}}}}","D":"`","p":[[1,"unit"],[5,"Error",5],[6,"Result",6]],"r":[],"b":[],"c":"OjAAAAAAAAA=","e":"OzAAAAEAAAUAAQAAAAUA"}],\ diff --git a/docs-rs/bdk/nightly/latest/search.desc/bdk_wallet/bdk_wallet-desc-0-.js b/docs-rs/bdk/nightly/latest/search.desc/bdk_wallet/bdk_wallet-desc-0-.js index 1975bb8f9c..15f8a350cb 100644 --- a/docs-rs/bdk/nightly/latest/search.desc/bdk_wallet/bdk_wallet-desc-0-.js +++ b/docs-rs/bdk/nightly/latest/search.desc/bdk_wallet/bdk_wallet-desc-0-.js @@ -1 +1 @@ -searchState.loadedDescShard("bdk_wallet", 0, "BDK Wallet\nExternal keychain, used for deriving recipient addresses.\nA UTXO owned by another wallet.\nInternal keychain, used for deriving change addresses.\nTypes of keychains\nA UTXO owned by the local wallet.\nAn unspent output owned by a Wallet.\nAn unspent transaction output (UTXO).\nA Utxo with its satisfaction_weight.\nReturn KeychainKind as a byte\nThe confirmation time for transaction containing this utxo\nThe derivation index for the script pubkey in the wallet\nDescriptors\nMacro to write full descriptors with code\nMacro to write descriptor fragments with code\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nWhether this UTXO is spent or not\nType of keychain\nKey formats\nGet the location of the UTXO\nReference to a transaction output\nAdditional functions on the rust-bitcoin Psbt structure.\nThe weight of the witness data and scriptSig expressed in …\nGet the sequence number if an explicit sequence number has …\nGet the TxOut of the UTXO\nTransaction output\nThe UTXO\nGet the version of BDK at runtime\nWallet\nThe location of the output.\nThe information about the input we require to add it to a …\nThe nSequence value to set for this input.\nA raw scriptpubkey (including pay-to-pubkey) under Legacy …\nA raw scriptpubkey (including pay-to-pubkey) under Legacy …\nA raw scriptpubkey (including pay-to-pubkey) under Legacy …\nAlias for a Descriptor that contains extended derived keys\nScript descriptor\nThe descriptor pubkey, either a single pubkey or an xpub.\nAlias for a Descriptor that can contain extended keys …\nTrait implemented on Descriptors to add a method to …\nThe 0 combinator.\nAlias for the type of maps that represent derivation paths …\nTrait for types which can be converted into an …\nThe consensus key associated with the type. Must be a …\nLegacy ScriptContext To be used as P2SH scripts For …\nThe top-level miniscript abstract syntax tree (AST).\nMultiple extended public keys.\nPay-to-PubKey-Hash\nPay-to-PubKey-Hash\nPay-to-PubKey-Hash\nThe ScriptContext for Miniscript. Additional type …\nSegwitv0 ScriptContext\nPay-to-ScriptHash(includes nested wsh/wpkh/sorted multi)\nPay-to-ScriptHash(includes nested wsh/wpkh/sorted multi)\nPay-to-ScriptHash(includes nested wsh/wpkh/sorted multi)\nSingle public key.\nThe 1 combinator.\nAlias for the type of maps that represent taproot key …\nPay-to-Taproot\nPay-to-Taproot\nPay-to-Taproot\nPay-to-Witness-PubKey-Hash\nPay-to-Witness-PubKey-Hash\nPay-to-Witness-PubKey-Hash\nPay-to-Witness-ScriptHash with Segwitv0 context\nPay-to-Witness-ScriptHash with Segwitv0 context\nPay-to-Witness-ScriptHash with Segwitv0 context\nExtended public key (xpub).\nComputes the Bitcoin address of the descriptor, if one …\nGet a reference to the inner AstElem representing the root …\nReplaces all wildcards (i.e. /*) in the descriptor with a …\nEnumerates all child nodes of the current AST node (self) …\nAttempt to produce a non-malleable witness template given …\nAttempt to produce a malleable witness template given the …\nDepending on script Context, some of the Terminals might …\nDepending on script Context, some of the script resource …\nCheck the consensus + policy(if not disabled) rules that …\nConsensus rules at the Miniscript satisfaction time. It is …\nPolicy rules at the Miniscript satisfaction time. It is …\nCheck the consensus + policy(if not disabled) rules …\nEach context has slightly different rules on what Pks are …\nDepending on ScriptContext, fragments can be malleable. …\nCheck whether the given satisfaction is valid under the …\nDescriptor checksum\nWhether the given miniscript contains a raw pkh fragment\nDeprecated name for Self::at_derivation_index.\nConvert all the public keys in the descriptor to …\nConvert all the public keys in the descriptor to …\nGet the DescriptorType of Descriptor\nEncode as a Bitcoin script\nDescriptor errors\nComputes the the underlying script before any hashing is …\nAdditional information helpful for extra analysis.\nCheck whether the miniscript follows the given Extra …\nExtract the spending policy\nUtility method for deriving the descriptor at each index …\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nAdd type information(Type and Extdata) to Miniscript based …\nCreate a new Miniscript from a Terminal node and a Type …\nParse a Miniscript from string and perform sanity checks …\nAttempt to parse an Miniscripts that don’t follow the …\nAttempt to parse an insane(scripts don’t clear sanity …\nParse an expression tree into a descriptor.\nParse an expression tree into a Miniscript. As a general …\nReturns child node with given index, if any\nReturns Option::Some with cloned n’th public key from …\nReturns satisfying non-malleable witness and scriptSig to …\nReturns a possilbly mallable satisfying non-malleable …\nWhether the miniscript contains a combination of timelocks\nWhether the miniscript has repeated Pk or Pkh\nWhether or not the descriptor has any wildcards i.e. /*.\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nExtracts the AstElem representing the root of the …\nGet as many descriptors as different paths in this …\nConvert to wallet descriptor\nWhether or not the descriptor has any wildcards\nWhether this descriptor contains a key that has multiple …\nWhether the miniscript is malleable\nCreates a new Iter iterator that will iterate over all …\nCreates a new PkIter iterator that will iterate over all …\nLifting corresponds to conversion of a miniscript into a …\nDepending on script context, the size of a satifaction …\nMaximum size, in bytes, of a satisfying witness. For …\nComputes an upper bound on the weight of a satisfying …\nMaximum number of witness elements used to satisfy the …\nComputes an upper bound on the difference between a …\nLocal helper function to display error messages with …\nCreate a new bare descriptor from witness script Errors …\nCreate a new pk descriptor\nCreate a new PkH descriptor\nCreate a new sh for a given redeem script Errors when …\nCreate a new sh sortedmulti descriptor with threshold k …\nCreate a new sh wrapper for the given wpkh descriptor\nCreate a new sh wrapper for the given wsh descriptor\nCreate a new sh wrapped wpkh from Pk. Errors when …\nCreate a new sh wrapped wsh descriptor with witness script …\nCreate a new sh wrapped wsh sortedmulti descriptor from …\nCreate new tr descriptor Errors when miniscript exceeds …\nCreate a new Wpkh descriptor Will return Err if …\nCreate a new wsh descriptor from witness script Errors …\nCreate a new wsh sorted multi descriptor Errors when …\nA node in the AST.\nOther top level checks that are context specific\nAttempt to parse a Script into Miniscript representation.\nParse a descriptor that may contain secret keys\nAttempt to parse an insane(scripts don’t clear sanity …\nAttempt to parse an miniscript with extra features that …\nGet the len of public key when serialized based on context …\nReturns a plan if the provided assets are sufficient to …\nReturns a plan if the provided assets are sufficient to …\nDescriptor policy\nWhether all spend paths of miniscript require a signature\nChecks whether the descriptor is safe.\nCheck whether the underlying Miniscript is safe under the …\nAttempts to produce a non-malleable satisfying witness and …\nAttempt to produce non-malleable satisfying witness for the\nAttempt to produce a malleable satisfying witness for the …\nComputes the scriptCode of a transaction output.\nComputes the scriptpubkey of the descriptor.\nSize, in bytes of the script-pubkey. If this Miniscript is …\nThe type of signature required for satisfaction\nSubstitutes raw public keys hashes with the public keys as …\nDescriptor templates\nSerialize a descriptor to string with its secret keys\nCheck top level consensus rules.\nCheck whether the top-level is type B\nConverts a descriptor using abstract keys to one using …\nTranslates a struct from one generic to another where the …\nThe correctness and malleability type information for the …\nComputes the scriptSig that will be in place for an …\nWhether the miniscript can exceed the resource …\nCompute the checksum of a descriptor, excludes any …\nCompute the checksum bytes of a descriptor, excludes any …\nError during base58 decoding\nBIP32 error\nErrors related to the parsing and usage of descriptors\nThe provided wallet descriptors are identical\nThe descriptor contains hardened derivation steps on …\nHex decoding error\nInvalid byte found in the descriptor checksum\nThe provided descriptor doesn’t match its checksum\nInvalid HD Key path, such as having a wildcard but a …\nError thrown while working with keys\nMiniscript error\nThe descriptor contains multipath keys\nKey-related error\nError while extracting and manipulating policies\nReturns the argument unchanged.\nCalls U::from(self).\nAbsolute timeclock timestamp\nCan not add to an item that is Satisfaction::None or …\nCan not add to an item that is …\nOptions to build the satisfaction field in the policy\nCan satisfy the policy item\nAn extra condition that must be satisfied but that is out …\nType for a map of sets of Condition items keyed by each set…\nECDSA Signature for a raw public key\nAn extended key fingerprint\nType for a map of folded sets of Condition items keyed by …\nSHA256 then RIPEMD160 preimage hash\nDouble SHA256 preimage hash\nIncompatible conditions (not currently used)\nIndex out of range for an item to satisfy a …\nCan not merge CSV or timelock values unless both are less …\nMulti-signature public keys with threshold count\nCannot satisfy or contribute to the policy item\nDon’t generate satisfaction field\nNot enough items are selected to satisfy a …\nOnly a partial satisfaction of some kind of threshold …\nCan reach the threshold of some kind of threshold policy\nA unique identifier for a key\nDescriptor spending policy\nErrors that can happen while extracting and manipulating …\nAnalyze the given PSBT to check for existing signatures\nLike Psbt variant and also check for expired timelocks\nA legacy public key\nRelative timelock locktime\nRIPEMD160 preimage hash\nRepresent if and how much a policy item is satisfied by …\nAn item that needs to be satisfied\nSchnorr Signature for a raw public key\nSHA256 preimage hash\nThreshold items with threshold count\nA x-only public key\nHow the wallet’s descriptor can satisfy this policy node\nOptional CheckSequenceVerify condition\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturn the conditions that are set by the spending policy …\nReturns a unique id for the SatisfiableItem\nIdentifier for this policy node\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nReturns whether the SatisfiableItem is a leaf item\nReturns whether the Satisfaction is a leaf item\nReturns true if there are no extra conditions to verify\nType of this policy node\nReturn whether or not a specific path in the policy tree …\nHow much a given PSBT already satisfies this policy node …\nOptional timelock condition\nCurrent blockchain height\nThe highest confirmation height between the inputs CSV …\nGiven PSBT\nExtra conditions that also need to be satisfied\nExtra conditions that also need to be satisfied\nExtra conditions that also need to be satisfied\nThe items that can be satisfied by the descriptor or are …\nThe items that can be satisfied by the descriptor\nThreshold\nThreshold\nTotal number of items\nTotal number of items\nWhether the items are sorted in lexicographic order (used …\nWhether the items are sorted in lexicographic order (used …\nThe digest value\nThe digest value\nThe digest value\nThe digest value\nThe policy items\nThe raw public key or extended key fingerprint\nThe required threshold count\nThe required threshold count\nThe timelock value\nThe timelock value\nBIP44 template. Expands to pkh(key/44'/{0,1}'/0'/{0,1}/*)\nBIP44 public template. Expands to pkh(key/{0,1}/*)\nBIP49 template. Expands to …\nBIP49 public template. Expands to sh(wpkh(key/{0,1}/*))\nBIP84 template. Expands to wpkh(key/84'/{0,1}'/0'/{0,1}/*)\nBIP84 public template. Expands to wpkh(key/{0,1}/*)\nBIP86 template. Expands to tr(key/86'/{0,1}'/0'/{0,1}/*)\nBIP86 public template. Expands to tr(key/{0,1}/*)\nTrait for descriptor templates that can be built into a …\nType alias for the return type of DescriptorTemplate, …\nP2PKH template. Expands to a descriptor pkh(key)\nP2TR template. Expands to a descriptor tr(key)\nP2WPKH template. Expands to a descriptor wpkh(key)\nP2WPKH-P2SH template. Expands to a descriptor sh(wpkh(key))\nBuild the complete descriptor\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nBIP32 error\nTrait for keys that can be derived.\nContainer for public or secret keys\nThe descriptor pubkey, either a single pubkey or an xpub.\nThe descriptor secret key, either a single private key or …\nType specifying the amount of entropy required e.g. [u8;32]\nReturned error in case of failure\nTrait that adds extra useful methods to ScriptContexts\nEnum for extended keys that can be either xprv or xpub\nA bitcoin public key (compressed or uncompressed).\nTrait that allows generating a key with the default options\nTrait for keys that can be generated\nOutput of a GeneratableKey key generation\nTrait for objects that can be turned into a public or …\nThe key has an invalid checksum\nThe key is not valid for the given network\nThe key cannot exist in the given script context\nThe consensus key associated with the type. Must be a …\nErrors thrown while working with keys\nAlias type for a map of public key to secret key\nLegacy scripts\nCustom error message\nMiniscript error\nMultiple extended private keys.\nMultiple extended public keys.\nExtra options required by the generate_with_entropy\nA private extended key, aka an xprv\nOptions for generating a PrivateKey\nA public extended key, aka an xpub\nThe ScriptContext for Miniscript. Additional type …\nEnum representation of the known valid ScriptContexts\nSegwitv0 scripts\nSingle public key.\nSingle private key.\nA descriptor bitcoin::PrivateKey with optional origin …\nA descriptor SinglePubKey with optional origin information.\nSingle public key without any origin or range information.\nContents of a “sortedmulti” descriptor\nTaproot scripts\nSet of valid networks for a key\nAn xonly public key.\nExtended private key (xpriv).\nExtended public key (xpub).\nCreate a set containing mainnet, testnet, signet, and …\nReturns the ScriptContext as a ScriptContextEnum\nReplaces any wildcard (i.e. /*) in the key with a …\nAttempt to produce a witness template given the assets …\nDepending on script Context, some of the Terminals might …\nDepending on script Context, some of the script resource …\nCheck the consensus + policy(if not disabled) rules that …\nConsensus rules at the Miniscript satisfaction time. It is …\nPolicy rules at the Miniscript satisfaction time. It is …\nCheck the consensus + policy(if not disabled) rules …\nEach context has slightly different rules on what Pks are …\nDepending on ScriptContext, fragments can be malleable. …\nCheck whether the given satisfaction is valid under the …\nWhether the generated key should be “compressed” or not\nDeprecated name for Self::at_derivation_index.\nEncode as a Bitcoin script\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nCreate an instance given a public key and a set of valid …\nCreate an instance given a secret key and a set of valid …\nParse an expression tree into a SortedMultiVec\nFull path, from the master key\nReturns a vector containing the full derivation paths from …\nGenerate a key given the options with a random entropy\nGenerate a key with the default options and a random …\nGenerate a key given the extra options and the entropy\nGenerate a key with the default options and a given entropy\nReturn whether or not the key contains the private data\nWhether or not the key has a wildcard\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nTurn the key into a DescriptorKey within the requested …\nConsume self and turn it into a DescriptorKey by adding …\nConsume self and turn it into an ExtendedKey\nConsumes self and returns the key\nGet as many keys as derivation paths in this key.\nGet as many keys as derivation paths in this key.\nTransform the ExtendedKey into an Xpriv for the given …\nTransform the ExtendedKey into an Xpub for the given …\nWhether or not the key has a wildcard\nReturns whether the script context is Legacy\nReturns whether the script context is …\nWhether or not this key has multiple derivation paths.\nWhether or not this key has multiple derivation paths.\nReturns whether the script context is Segwitv0\nReturns whether the script context is …\nReturns whether the script context is Tap, aka Taproot or …\nReturns whether the script context is …\nThe threshold value for the multisig.\nThe public key.\nThe private key.\nCreate a set only containing mainnet\nThe fingerprint of the master key associated with this …\nDepending on script context, the size of a satifaction …\nMaximum size, in bytes, of a satisfying witness. In …\nMaximum number of witness elements used to satisfy the …\nCompute the intersection of two sets\nThe number of keys in the multisig.\nLocal helper function to display error messages with …\nCreate a new instance of SortedMultiVec given a list of …\nOrigin information (fingerprint and derivation path).\nOrigin information (fingerprint and derivation path).\nOther top level checks that are context specific\nOverride the computed set of valid networks\nGet the len of public key when serialized based on context …\nAccessor for the public keys in the multisig.\nutility function to sanity a sorted multi vec\nAttempt to produce a satisfying witness for the witness …\nSize, in bytes of the script-pubkey. If this Miniscript is …\nThe type of signature required for satisfaction\nCreate Terminal::Multi containing sorted pubkeys\nCreate a set containing testnet and regtest\nReturns the public version of this key.\nCheck top level consensus rules.\nCheck whether the top-level is type B\nThis will panic if fpk returns an uncompressed key when …\nTrait to add functions to extract utxos and calculate fees.\nThe total transaction fee amount, sum of input amounts …\nThe transaction’s fee rate. This value will only be …\nGet the TxOut for the specified input index, if it doesn’…\nA derived address and the index it was found at. For …\nAn error that may occur when applying a block to Wallet.\nBalance, differentiated into various categories.\nOccurs when the update chain cannot connect with original …\nThe changes made to a wallet by applying an Update.\nThe error variant that occurs when the caller attempts to …\nThere was problem with the passed-in descriptor(s).\nThere was a problem with the passed-in descriptor(s).\nThere is a problem with the passed-in descriptor.\nAn error that may occur when inserting a transaction into …\nTrait to check if a value is below the dust limit. We are …\nThe error type when loading a Wallet from a ChangeSet.\nThe loaded desccriptor does not match what was provided.\nThe loaded genesis hash does not match what was provided.\nThe loaded network type does not match what was provided.\nData loaded from persistence is missing descriptor.\nData loaded from persistence is missing genesis hash.\nData loaded from persistence is missing network type.\nThe error type when constructing a fresh Wallet.\nError type for when we try load a Wallet from persistence …\nOccurs when the connected_to hash does not match the hash …\nAn update to Wallet.\nA Bitcoin wallet\nAdd an external signer\nAddress\nGet unbounded script pubkey iterators for both Internal …\nIntroduces a block of height to the wallet, and tries to …\nApplies relevant transactions from block of height to the …\nApply relevant unconfirmed transactions to the wallet.\nApplies an update to the wallet and stages the changes …\nReturn the balance, separated into available, …\nBump the fee of a transaction previously created with this …\nStart building a transaction.\nCalculates the fee of a given transaction. Returns …\nCalculate the FeeRate for a given transaction.\nInforms the wallet that you no longer intend to broadcast …\nChanges to the LocalChain.\nUpdate for the wallet’s internal LocalChain.\nGet all the checkpoints the wallet is currently storing …\nCoin selection\nConfirmed and immediately spendable balance\nThe derivation index of this wallet. It will return None …\nFinds how the wallet derived the script pubkey spk.\nReturn the checksum of the public descriptor associated to …\nErrors that can be thrown by the Wallet\nWallet export\nFinalize a PSBT, i.e., for each input determine if …\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the descriptor used to create addresses for a …\nget the corresponding PSBT Input for a LocalUtxo\nGet the signers\nGet a single transaction from the wallet as a CanonicalTx …\nReturns the utxo owned by this wallet corresponding to …\nUpdate for the wallet’s internal TxGraph.\nAll coinbase outputs not yet matured\nChild index of this address\nChanges to IndexedTxGraph.\nAdd a new checkpoint to the wallet’s internal view of …\nAdd a transaction to the wallet’s internal view of the …\nInserts a TxOut at OutPoint into the wallet’s …\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCheck whether or not a value is below dust limit\nReturn whether or not a script is part of this wallet …\nType of keychain\nIterator over all keychains in this wallet\nContains the last active derivation indices per keychain (K…\nReturns the latest checkpoint.\nList all relevant outputs (includes both spent and …\nReturn the list of unspent outputs of this wallet\nList addresses that are revealed but unused.\nLoad Wallet from the given previously persisted ChangeSet.\nGet a reference to the inner LocalChain.\nMarks an address used of the given keychain at index.\nGet the Bitcoin network the wallet is using.\nStores the network type of the transaction data.\nInitialize an empty Wallet.\nEither loads Wallet from the given ChangeSet or …\nEither loads Wallet from a ChangeSet or initializes it if …\nInitialize an empty Wallet with a custom genesis hash.\nThe index of the next address that you would get if you …\nGet the next unused address for the given keychain, i.e. …\nPeek an address of the given keychain at index without …\nReturn the spending policies for the wallet’s descriptor\nReturn the “public” version of the wallet’s …\nReveal addresses up to and including the target index and …\nAttempt to reveal the next address of the given keychain.\nReturn the secp256k1 context used for all signing …\nCompute the tx’s sent and received Amounts.\nSign a transaction with all the wallet’s signers, in the …\nGeneralized signers\nGet a reference to the inner KeychainTxOutIndex.\nGet a reference of the staged ChangeSet that are yet to be …\nCreate a `FullScanRequest for this wallet.\nCreate a partial SyncRequest for this wallet for all …\nTake the staged ChangeSet to be persisted now (if any).\nGet the whole balance visible to the wallet.\nIterate over the transactions in the wallet.\nUnconfirmed UTXOs generated by a wallet tx\nGet sum of trusted_pending and confirmed coins.\nTransaction builder\nGet a reference to the inner TxGraph.\nGet an unbounded script pubkey iterator for the given …\nUndoes the effect of mark_used and returns whether the …\nUnconfirmed UTXOs received from an external wallet\nDeterministically generate a unique name given the …\nBlock hash of connected_to.\nExpected block hash of connected_to, as derived from block.\nThe internal chain’s tip height.\nThe introduced transaction’s confirmation height.\nThe expected genesis block hash.\nThe expected network type.\nThe block hash loaded from persistence.\nThe network type loaded from persistence.\nThe descriptor loaded from persistence.\nThe keychain of the descriptor not matching\nBranch and bound coin selection tries to avoid needing a …\nBranch and bound coin selection possible attempts with …\nBranch and bound coin selection\nIt’s possible to create spendable output from excess …\nTrait for generalized coin selection algorithms\nResult of a successful coin selection\nDefault coin selection algorithm used by TxBuilder if not …\nErrors that can be thrown by the coin_selection module\nRemaining amount after performing coin selection\nWallet’s UTXO set is not enough to cover recipient’s …\nSimple and dumb coin selection\nIt’s not possible to create spendable output from excess …\nOldestFirstCoinSelection always picks the utxo with the …\nPerform the coin selection\nDecide if change can be created\nRemaining amount after deducing fees and outgoing outputs\nTotal fee amount for the selected utxos in satoshis\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nThe total value of the inputs selected from the local …\nCreate new instance with target size for change output\nList of outputs selected for use as inputs\nThe total value of the inputs selected.\nSats available for spending\nSats needed for some transaction\nEffective amount available to create change after …\nThe calculated fee for the drain TxOut with the selected …\nThreshold to consider amount as dust for this particular …\nThe deducted change output fee\nExceeding amount of current selection over outgoing value …\nError returned from Wallet::build_fee_bump\nThere was an error with coin selection\nDescriptor key conversion error\nError returned from TxBuilder::finish\nThere was a problem with the descriptors passed in\nWhen bumping a tx the fee rate requested is lower than …\nNode doesn’t have data to estimate a fee rate\nWhen bumping a tx the absolute fee requested is lower than …\nTrying to replace a tx that has a sequence >= 0xFFFFFFFE\nRequested LockTime is less than is required to spend from …\nMiniscript PSBT error\nErrors returned by miniscript when updating inconsistent …\nIn order to use the TxBuilder::add_global_xpubs option …\nMissing non_witness_utxo on foreign utxo for given OutPoint\nCannot build a tx without recipients\nmanually_selected_only option is selected but no utxo has …\nOutput created is under the dust limit, 546 satoshis\nReturn error type for …\nThere was a problem while extracting and manipulating …\nPartially signed bitcoin transaction error\nCannot enable RBF with a Sequence >= 0xFFFFFFFE\nCannot enable RBF with Sequence given a required OP_CSV\nSpending policy is not compatible with this KeychainKind\nHappens when trying to bump a transaction that is already …\nThrown when a tx is not found in the internal database\nHappens when trying to spend an UTXO that is not in the …\nHappens when trying to spend an UTXO that is not in the …\nReturn error type for PsbtExt::update_input_with_descriptor\nRequested invalid transaction version ‘0’\nRequested transaction version 1, but at least 2 is needed …\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nRequired OP_CSV Sequence\nGiven RBF Sequence\nRequested LockTime\nRequired LockTime\nRequired fee absolute value Amount\nRequired fee rate\nStructure that contains the export of a wallet\nAlias for FullyNodedExport\nEarliest block to rescan when looking for the wallet’s …\nEarliest block to rescan when looking for the wallet’s …\nReturn the internal descriptor, if present\nReturn the external descriptor\nExport a wallet\nReturns the argument unchanged.\nCalls U::from(self).\nArbitrary label for the wallet\nArbitrary label for the wallet\nThe signer will sign all the leaves it has a key for.\nDummy identifier\nThe signer won’t sign the specified leaves.\nTo be used only by external libraries implementing …\nThe fingerprint of a BIP32 extended key\nThe signer won’t sign leaves other than the ones …\nInput index is out of range\nPSBT Input signer\nThe private key in use has the right fingerprint but …\nThe non_witness_utxo specified is invalid\nInvalid SIGHASH for the signing context in use\nLegacy context\nMiniscript PSBT error\nThe fingerprint and derivation path are missing from the …\nThe private key is missing for the required public key\nThe non_witness_utxo field of the transaction is required …\nThe witness_script field of the transaction is required to …\nThe witness_utxo field of the transaction is required to …\nThe psbt contains a non-SIGHASH_ALL sighash in one of its …\nThe signer won’t sign any leaf.\nBitcoin HASH160 (RIPEMD160 after SHA256) hash of an ECDSA …\nSegwit v0 context (BIP 143)\nError while computing the hash to sign a P2WPKH input.\nError while computing the hash to sign a Taproot input.\nOptions for a software signer\nCommon signer methods\nSigning context\nSigning error\nIdentifier of a signer in the SignersContainers. Used as a …\nDefines the order in which signers are called\nWrapper to pair a signer with its context\nContainer for multiple signers\nTaproot context (BIP 340)\nCustomize which taproot script-path leaves the signer …\nPSBT signer\nError while computing the hash, out of bounds access on …\nThe user canceled the operation\nAdds an external signer to the container for the specified …\nWhether the signer should use the sighash_type set in the …\nWhether we should grind ECDSA signature to ensure signing …\nCreate a map of public keys to secret keys\nWhether the wallet should assume a specific height has …\nBuild a new signer container from a KeyMap\nReturn the secret key for the signer\nFinds the signer with lowest ordering for a given id in …\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturn the SignerId for this signer\nReturns the list of identifiers of all the signers in the …\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCreate a wrapped signer from a signer and a context\nDefault constructor\nRemoves a signer from the container and returns it\nSign a single psbt input\nSign all the inputs of the psbt\nWhether we should try to sign a taproot transaction with …\nReturns the list of signers in the container, sorted by …\nSpecifies which Taproot script-spend leaves we should sign …\nWhether the signer should trust the witness_utxo, if the …\nWhether to try finalizing the PSBT after the inputs are …\nWhether the signer can sign for the internal key or not\nError returned from TxBuilder::add_foreign_utxo.\nError returned from TxBuilder::add_utxo and …\nBIP69 / Lexicographic\nUse both change and non-change outputs (default)\nOnly use non-change outputs (see …\nPolicy regarding the use of change outputs when creating a …\nRequested outpoint doesn’t exist in the tx (vout greater …\nForeign utxo outpoint txid does not match PSBT input txid\nForeign utxo missing witness_utxo or non_witness_utxo\nOnly use change outputs (see TxBuilder::only_spend_change)\nRandomized (default)\nA transaction builder\nOrdering of the transaction’s inputs and outputs\nHappens when trying to spend an UTXO that is not in the …\nUnchanged\nAdd data as an output, using OP_RETURN\nAdd a foreign UTXO i.e. a UTXO not owned by this wallet.\nSame as add_foreign_utxo but allows to set the nSequence …\nFill-in the PSBT_GLOBAL_XPUB field with the extended keys …\nAdd a recipient to the internal list\nAdd a utxo to the internal list of unspendable utxos\nAdd a utxo to the internal list of utxos that must be spent\nAdd the list of outpoints to the internal list of UTXOs …\nSet whether or not the dust limit is checked.\nSet a specific ChangeSpendPolicy. See …\nChoose the coin selection algorithm\nSet the current blockchain height.\nDo not spend change outputs\nSets the address to drain excess coins to.\nSpend all the available inputs. This respects filters like …\nEnable signaling RBF\nEnable signaling RBF with a specific nSequence value\nSet an absolute fee The fee_absolute method refers to the …\nSet a custom fee rate.\nFinish building the transaction.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nFill-in the psbt::Output::redeem_script and …\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nOnly spend utxos added by add_utxo.\nUse a specific nLockTime while creating the transaction\nOnly spend change outputs\nOnly Fill-in the psbt::Input::witness_utxo field when …\nChoose the ordering for inputs and outputs of the …\nSet the policy path to use while creating the transaction …\nReplace the recipients already added with a new list\nSign with a specific sig hash\nSort transaction inputs and outputs by TxOrdering variant\nReplace the internal list of unspendable utxos with a new …\nBuild a transaction with a specific version\nForeign UTXO outpoint\nPSBT input txid") \ No newline at end of file +searchState.loadedDescShard("bdk_wallet", 0, "BDK Wallet\nExternal keychain, used for deriving recipient addresses.\nA UTXO owned by another wallet.\nInternal keychain, used for deriving change addresses.\nTypes of keychains\nA UTXO owned by the local wallet.\nAn unspent output owned by a Wallet.\nAn unspent transaction output (UTXO).\nA Utxo with its satisfaction_weight.\nReturn KeychainKind as a byte\nThe confirmation time for transaction containing this utxo\nThe derivation index for the script pubkey in the wallet\nDescriptors\nMacro to write full descriptors with code\nMacro to write descriptor fragments with code\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nWhether this UTXO is spent or not\nType of keychain\nKey formats\nGet the location of the UTXO\nReference to a transaction output\nAdditional functions on the rust-bitcoin Psbt structure.\nThe weight of the witness data and scriptSig expressed in …\nGet the sequence number if an explicit sequence number has …\nGet the TxOut of the UTXO\nTransaction output\nThe UTXO\nGet the version of BDK at runtime\nWallet\nThe location of the output.\nThe information about the input we require to add it to a …\nThe nSequence value to set for this input.\nA raw scriptpubkey (including pay-to-pubkey) under Legacy …\nA raw scriptpubkey (including pay-to-pubkey) under Legacy …\nA raw scriptpubkey (including pay-to-pubkey) under Legacy …\nAlias for a Descriptor that contains extended derived keys\nScript descriptor\nThe descriptor pubkey, either a single pubkey or an xpub.\nAlias for a Descriptor that can contain extended keys …\nTrait implemented on Descriptors to add a method to …\nThe 0 combinator.\nAlias for the type of maps that represent derivation paths …\nTrait for types which can be converted into an …\nThe consensus key associated with the type. Must be a …\nLegacy ScriptContext To be used as P2SH scripts For …\nThe top-level miniscript abstract syntax tree (AST).\nMultiple extended public keys.\nPay-to-PubKey-Hash\nPay-to-PubKey-Hash\nPay-to-PubKey-Hash\nThe ScriptContext for Miniscript. Additional type …\nSegwitv0 ScriptContext\nPay-to-ScriptHash(includes nested wsh/wpkh/sorted multi)\nPay-to-ScriptHash(includes nested wsh/wpkh/sorted multi)\nPay-to-ScriptHash(includes nested wsh/wpkh/sorted multi)\nSingle public key.\nThe 1 combinator.\nAlias for the type of maps that represent taproot key …\nPay-to-Taproot\nPay-to-Taproot\nPay-to-Taproot\nPay-to-Witness-PubKey-Hash\nPay-to-Witness-PubKey-Hash\nPay-to-Witness-PubKey-Hash\nPay-to-Witness-ScriptHash with Segwitv0 context\nPay-to-Witness-ScriptHash with Segwitv0 context\nPay-to-Witness-ScriptHash with Segwitv0 context\nExtended public key (xpub).\nComputes the Bitcoin address of the descriptor, if one …\nGet a reference to the inner AstElem representing the root …\nReplaces all wildcards (i.e. /*) in the descriptor with a …\nEnumerates all child nodes of the current AST node (self) …\nAttempt to produce a non-malleable witness template given …\nAttempt to produce a malleable witness template given the …\nDepending on script Context, some of the Terminals might …\nDepending on script Context, some of the script resource …\nCheck the consensus + policy(if not disabled) rules that …\nConsensus rules at the Miniscript satisfaction time. It is …\nPolicy rules at the Miniscript satisfaction time. It is …\nCheck the consensus + policy(if not disabled) rules …\nEach context has slightly different rules on what Pks are …\nDepending on ScriptContext, fragments can be malleable. …\nCheck whether the given satisfaction is valid under the …\nDescriptor checksum\nWhether the given miniscript contains a raw pkh fragment\nDeprecated name for Self::at_derivation_index.\nConvert all the public keys in the descriptor to …\nConvert all the public keys in the descriptor to …\nGet the DescriptorType of Descriptor\nEncode as a Bitcoin script\nDescriptor errors\nComputes the the underlying script before any hashing is …\nAdditional information helpful for extra analysis.\nCheck whether the miniscript follows the given Extra …\nExtract the spending policy\nUtility method for deriving the descriptor at each index …\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nAdd type information(Type and Extdata) to Miniscript based …\nCreate a new Miniscript from a Terminal node and a Type …\nParse a Miniscript from string and perform sanity checks …\nAttempt to parse an Miniscripts that don’t follow the …\nAttempt to parse an insane(scripts don’t clear sanity …\nParse an expression tree into a descriptor.\nParse an expression tree into a Miniscript. As a general …\nReturns child node with given index, if any\nReturns Option::Some with cloned n’th public key from …\nReturns satisfying non-malleable witness and scriptSig to …\nReturns a possilbly mallable satisfying non-malleable …\nWhether the miniscript contains a combination of timelocks\nWhether the miniscript has repeated Pk or Pkh\nWhether or not the descriptor has any wildcards i.e. /*.\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nExtracts the AstElem representing the root of the …\nGet as many descriptors as different paths in this …\nConvert to wallet descriptor\nWhether or not the descriptor has any wildcards\nWhether this descriptor contains a key that has multiple …\nWhether the miniscript is malleable\nCreates a new Iter iterator that will iterate over all …\nCreates a new PkIter iterator that will iterate over all …\nLifting corresponds to conversion of a miniscript into a …\nDepending on script context, the size of a satifaction …\nMaximum size, in bytes, of a satisfying witness. For …\nComputes an upper bound on the weight of a satisfying …\nMaximum number of witness elements used to satisfy the …\nComputes an upper bound on the difference between a …\nLocal helper function to display error messages with …\nCreate a new bare descriptor from witness script Errors …\nCreate a new pk descriptor\nCreate a new PkH descriptor\nCreate a new sh for a given redeem script Errors when …\nCreate a new sh sortedmulti descriptor with threshold k …\nCreate a new sh wrapper for the given wpkh descriptor\nCreate a new sh wrapper for the given wsh descriptor\nCreate a new sh wrapped wpkh from Pk. Errors when …\nCreate a new sh wrapped wsh descriptor with witness script …\nCreate a new sh wrapped wsh sortedmulti descriptor from …\nCreate new tr descriptor Errors when miniscript exceeds …\nCreate a new Wpkh descriptor Will return Err if …\nCreate a new wsh descriptor from witness script Errors …\nCreate a new wsh sorted multi descriptor Errors when …\nA node in the AST.\nOther top level checks that are context specific\nAttempt to parse a Script into Miniscript representation.\nParse a descriptor that may contain secret keys\nAttempt to parse an insane(scripts don’t clear sanity …\nAttempt to parse an miniscript with extra features that …\nGet the len of public key when serialized based on context …\nReturns a plan if the provided assets are sufficient to …\nReturns a plan if the provided assets are sufficient to …\nDescriptor policy\nWhether all spend paths of miniscript require a signature\nChecks whether the descriptor is safe.\nCheck whether the underlying Miniscript is safe under the …\nAttempts to produce a non-malleable satisfying witness and …\nAttempt to produce non-malleable satisfying witness for the\nAttempt to produce a malleable satisfying witness for the …\nComputes the scriptCode of a transaction output.\nComputes the scriptpubkey of the descriptor.\nSize, in bytes of the script-pubkey. If this Miniscript is …\nThe type of signature required for satisfaction\nSubstitutes raw public keys hashes with the public keys as …\nDescriptor templates\nSerialize a descriptor to string with its secret keys\nCheck top level consensus rules.\nCheck whether the top-level is type B\nConverts a descriptor using abstract keys to one using …\nTranslates a struct from one generic to another where the …\nThe correctness and malleability type information for the …\nComputes the scriptSig that will be in place for an …\nWhether the miniscript can exceed the resource …\nCompute the checksum of a descriptor, excludes any …\nCompute the checksum bytes of a descriptor, excludes any …\nError during base58 decoding\nBIP32 error\nErrors related to the parsing and usage of descriptors\nThe provided wallet descriptors are identical\nThe descriptor contains hardened derivation steps on …\nHex decoding error\nInvalid byte found in the descriptor checksum\nThe provided descriptor doesn’t match its checksum\nInvalid HD Key path, such as having a wildcard but a …\nError thrown while working with keys\nMiniscript error\nThe descriptor contains multipath keys\nKey-related error\nError while extracting and manipulating policies\nReturns the argument unchanged.\nCalls U::from(self).\nAbsolute timeclock timestamp\nCan not add to an item that is Satisfaction::None or …\nCan not add to an item that is …\nOptions to build the satisfaction field in the policy\nCan satisfy the policy item\nAn extra condition that must be satisfied but that is out …\nType for a map of sets of Condition items keyed by each set…\nECDSA Signature for a raw public key\nAn extended key fingerprint\nType for a map of folded sets of Condition items keyed by …\nSHA256 then RIPEMD160 preimage hash\nDouble SHA256 preimage hash\nIncompatible conditions (not currently used)\nIndex out of range for an item to satisfy a …\nCan not merge CSV or timelock values unless both are less …\nMulti-signature public keys with threshold count\nCannot satisfy or contribute to the policy item\nDon’t generate satisfaction field\nNot enough items are selected to satisfy a …\nOnly a partial satisfaction of some kind of threshold …\nCan reach the threshold of some kind of threshold policy\nA unique identifier for a key\nDescriptor spending policy\nErrors that can happen while extracting and manipulating …\nAnalyze the given PSBT to check for existing signatures\nLike Psbt variant and also check for expired timelocks\nA legacy public key\nRelative timelock locktime\nRIPEMD160 preimage hash\nRepresent if and how much a policy item is satisfied by …\nAn item that needs to be satisfied\nSchnorr Signature for a raw public key\nSHA256 preimage hash\nThreshold items with threshold count\nA x-only public key\nHow the wallet’s descriptor can satisfy this policy node\nOptional CheckSequenceVerify condition\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturn the conditions that are set by the spending policy …\nReturns a unique id for the SatisfiableItem\nIdentifier for this policy node\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nReturns whether the SatisfiableItem is a leaf item\nReturns whether the Satisfaction is a leaf item\nReturns true if there are no extra conditions to verify\nType of this policy node\nReturn whether or not a specific path in the policy tree …\nHow much a given PSBT already satisfies this policy node …\nOptional timelock condition\nCurrent blockchain height\nThe highest confirmation height between the inputs CSV …\nGiven PSBT\nExtra conditions that also need to be satisfied\nExtra conditions that also need to be satisfied\nExtra conditions that also need to be satisfied\nThe items that can be satisfied by the descriptor or are …\nThe items that can be satisfied by the descriptor\nThreshold\nThreshold\nTotal number of items\nTotal number of items\nWhether the items are sorted in lexicographic order (used …\nWhether the items are sorted in lexicographic order (used …\nThe digest value\nThe digest value\nThe digest value\nThe digest value\nThe policy items\nThe raw public key or extended key fingerprint\nThe required threshold count\nThe required threshold count\nThe timelock value\nThe timelock value\nBIP44 template. Expands to pkh(key/44'/{0,1}'/0'/{0,1}/*)\nBIP44 public template. Expands to pkh(key/{0,1}/*)\nBIP49 template. Expands to …\nBIP49 public template. Expands to sh(wpkh(key/{0,1}/*))\nBIP84 template. Expands to wpkh(key/84'/{0,1}'/0'/{0,1}/*)\nBIP84 public template. Expands to wpkh(key/{0,1}/*)\nBIP86 template. Expands to tr(key/86'/{0,1}'/0'/{0,1}/*)\nBIP86 public template. Expands to tr(key/{0,1}/*)\nTrait for descriptor templates that can be built into a …\nType alias for the return type of DescriptorTemplate, …\nP2PKH template. Expands to a descriptor pkh(key)\nP2TR template. Expands to a descriptor tr(key)\nP2WPKH template. Expands to a descriptor wpkh(key)\nP2WPKH-P2SH template. Expands to a descriptor sh(wpkh(key))\nBuild the complete descriptor\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nBIP32 error\nTrait for keys that can be derived.\nContainer for public or secret keys\nThe descriptor pubkey, either a single pubkey or an xpub.\nThe descriptor secret key, either a single private key or …\nType specifying the amount of entropy required e.g. [u8;32]\nReturned error in case of failure\nTrait that adds extra useful methods to ScriptContexts\nEnum for extended keys that can be either xprv or xpub\nA bitcoin public key (compressed or uncompressed).\nTrait that allows generating a key with the default options\nTrait for keys that can be generated\nOutput of a GeneratableKey key generation\nTrait for objects that can be turned into a public or …\nThe key has an invalid checksum\nThe key is not valid for the given network\nThe key cannot exist in the given script context\nThe consensus key associated with the type. Must be a …\nErrors thrown while working with keys\nAlias type for a map of public key to secret key\nLegacy scripts\nCustom error message\nMiniscript error\nMultiple extended private keys.\nMultiple extended public keys.\nExtra options required by the generate_with_entropy\nA private extended key, aka an xprv\nOptions for generating a PrivateKey\nA public extended key, aka an xpub\nThe ScriptContext for Miniscript. Additional type …\nEnum representation of the known valid ScriptContexts\nSegwitv0 scripts\nSingle public key.\nSingle private key.\nA descriptor bitcoin::PrivateKey with optional origin …\nA descriptor SinglePubKey with optional origin information.\nSingle public key without any origin or range information.\nContents of a “sortedmulti” descriptor\nTaproot scripts\nSet of valid networks for a key\nAn xonly public key.\nExtended private key (xpriv).\nExtended public key (xpub).\nCreate a set containing mainnet, testnet, signet, and …\nReturns the ScriptContext as a ScriptContextEnum\nReplaces any wildcard (i.e. /*) in the key with a …\nAttempt to produce a witness template given the assets …\nDepending on script Context, some of the Terminals might …\nDepending on script Context, some of the script resource …\nCheck the consensus + policy(if not disabled) rules that …\nConsensus rules at the Miniscript satisfaction time. It is …\nPolicy rules at the Miniscript satisfaction time. It is …\nCheck the consensus + policy(if not disabled) rules …\nEach context has slightly different rules on what Pks are …\nDepending on ScriptContext, fragments can be malleable. …\nCheck whether the given satisfaction is valid under the …\nWhether the generated key should be “compressed” or not\nDeprecated name for Self::at_derivation_index.\nEncode as a Bitcoin script\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nCreate an instance given a public key and a set of valid …\nCreate an instance given a secret key and a set of valid …\nParse an expression tree into a SortedMultiVec\nFull path, from the master key\nReturns a vector containing the full derivation paths from …\nGenerate a key given the options with random entropy.\nGenerate a key with the default options and a random …\nGenerate a key with the default options and a random …\nGenerate a key given the options with random entropy.\nGenerate a key given the extra options and the entropy\nGenerate a key with the default options and a given entropy\nReturn whether or not the key contains the private data\nWhether or not the key has a wildcard\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nTurn the key into a DescriptorKey within the requested …\nConsume self and turn it into a DescriptorKey by adding …\nConsume self and turn it into an ExtendedKey\nConsumes self and returns the key\nGet as many keys as derivation paths in this key.\nGet as many keys as derivation paths in this key.\nTransform the ExtendedKey into an Xpriv for the given …\nTransform the ExtendedKey into an Xpub for the given …\nWhether or not the key has a wildcard\nReturns whether the script context is Legacy\nReturns whether the script context is …\nWhether or not this key has multiple derivation paths.\nWhether or not this key has multiple derivation paths.\nReturns whether the script context is Segwitv0\nReturns whether the script context is …\nReturns whether the script context is Tap, aka Taproot or …\nReturns whether the script context is …\nThe threshold value for the multisig.\nThe public key.\nThe private key.\nCreate a set only containing mainnet\nThe fingerprint of the master key associated with this …\nDepending on script context, the size of a satifaction …\nMaximum size, in bytes, of a satisfying witness. In …\nMaximum number of witness elements used to satisfy the …\nCompute the intersection of two sets\nThe number of keys in the multisig.\nLocal helper function to display error messages with …\nCreate a new instance of SortedMultiVec given a list of …\nOrigin information (fingerprint and derivation path).\nOrigin information (fingerprint and derivation path).\nOther top level checks that are context specific\nOverride the computed set of valid networks\nGet the len of public key when serialized based on context …\nAccessor for the public keys in the multisig.\nutility function to sanity a sorted multi vec\nAttempt to produce a satisfying witness for the witness …\nSize, in bytes of the script-pubkey. If this Miniscript is …\nThe type of signature required for satisfaction\nCreate Terminal::Multi containing sorted pubkeys\nCreate a set containing testnet and regtest\nReturns the public version of this key.\nCheck top level consensus rules.\nCheck whether the top-level is type B\nThis will panic if fpk returns an uncompressed key when …\nTrait to add functions to extract utxos and calculate fees.\nThe total transaction fee amount, sum of input amounts …\nThe transaction’s fee rate. This value will only be …\nGet the TxOut for the specified input index, if it doesn’…\nA derived address and the index it was found at. For …\nAn error that may occur when applying a block to Wallet.\nBalance, differentiated into various categories.\nOccurs when the update chain cannot connect with original …\nThe changes made to a wallet by applying an Update.\nThe error variant that occurs when the caller attempts to …\nThere was problem with the passed-in descriptor(s).\nThere was a problem with the passed-in descriptor(s).\nThere is a problem with the passed-in descriptor.\nAn error that may occur when inserting a transaction into …\nTrait to check if a value is below the dust limit. We are …\nThe error type when loading a Wallet from a ChangeSet.\nThe loaded desccriptor does not match what was provided.\nThe loaded genesis hash does not match what was provided.\nThe loaded network type does not match what was provided.\nData loaded from persistence is missing descriptor.\nData loaded from persistence is missing genesis hash.\nData loaded from persistence is missing network type.\nThe error type when constructing a fresh Wallet.\nError type for when we try load a Wallet from persistence …\nOccurs when the connected_to hash does not match the hash …\nAn update to Wallet.\nA Bitcoin wallet\nAdd an external signer\nAddress\nGet unbounded script pubkey iterators for both Internal …\nIntroduces a block of height to the wallet, and tries to …\nApplies relevant transactions from block of height to the …\nApply relevant unconfirmed transactions to the wallet.\nApplies an update to the wallet and stages the changes …\nReturn the balance, separated into available, …\nBump the fee of a transaction previously created with this …\nStart building a transaction.\nCalculates the fee of a given transaction. Returns …\nCalculate the FeeRate for a given transaction.\nInforms the wallet that you no longer intend to broadcast …\nChanges to the LocalChain.\nUpdate for the wallet’s internal LocalChain.\nGet all the checkpoints the wallet is currently storing …\nCoin selection\nConfirmed and immediately spendable balance\nThe derivation index of this wallet. It will return None …\nFinds how the wallet derived the script pubkey spk.\nReturn the checksum of the public descriptor associated to …\nErrors that can be thrown by the Wallet\nWallet export\nFinalize a PSBT, i.e., for each input determine if …\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the descriptor used to create addresses for a …\nget the corresponding PSBT Input for a LocalUtxo\nGet the signers\nGet a single transaction from the wallet as a CanonicalTx …\nReturns the utxo owned by this wallet corresponding to …\nUpdate for the wallet’s internal TxGraph.\nAll coinbase outputs not yet matured\nChild index of this address\nChanges to IndexedTxGraph.\nAdd a new checkpoint to the wallet’s internal view of …\nAdd a transaction to the wallet’s internal view of the …\nInserts a TxOut at OutPoint into the wallet’s …\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCheck whether or not a value is below dust limit\nReturn whether or not a script is part of this wallet …\nType of keychain\nIterator over all keychains in this wallet\nContains the last active derivation indices per keychain (K…\nReturns the latest checkpoint.\nList all relevant outputs (includes both spent and …\nReturn the list of unspent outputs of this wallet\nList addresses that are revealed but unused.\nLoad Wallet from the given previously persisted ChangeSet.\nGet a reference to the inner LocalChain.\nMarks an address used of the given keychain at index.\nGet the Bitcoin network the wallet is using.\nStores the network type of the transaction data.\nInitialize an empty Wallet.\nEither loads Wallet from the given ChangeSet or …\nEither loads Wallet from a ChangeSet or initializes it if …\nInitialize an empty Wallet with a custom genesis hash.\nThe index of the next address that you would get if you …\nGet the next unused address for the given keychain, i.e. …\nPeek an address of the given keychain at index without …\nReturn the spending policies for the wallet’s descriptor\nReturn the “public” version of the wallet’s …\nReveal addresses up to and including the target index and …\nAttempt to reveal the next address of the given keychain.\nReturn the secp256k1 context used for all signing …\nCompute the tx’s sent and received Amounts.\nSign a transaction with all the wallet’s signers, in the …\nGeneralized signers\nGet a reference to the inner KeychainTxOutIndex.\nGet a reference of the staged ChangeSet that are yet to be …\nCreate a `FullScanRequest for this wallet.\nCreate a partial SyncRequest for this wallet for all …\nTake the staged ChangeSet to be persisted now (if any).\nGet the whole balance visible to the wallet.\nIterate over the transactions in the wallet.\nUnconfirmed UTXOs generated by a wallet tx\nGet sum of trusted_pending and confirmed coins.\nTransaction builder\nGet a reference to the inner TxGraph.\nGet an unbounded script pubkey iterator for the given …\nUndoes the effect of mark_used and returns whether the …\nUnconfirmed UTXOs received from an external wallet\nDeterministically generate a unique name given the …\nBlock hash of connected_to.\nExpected block hash of connected_to, as derived from block.\nThe internal chain’s tip height.\nThe introduced transaction’s confirmation height.\nThe expected genesis block hash.\nThe expected network type.\nThe block hash loaded from persistence.\nThe network type loaded from persistence.\nThe descriptor loaded from persistence.\nThe keychain of the descriptor not matching\nBranch and bound coin selection tries to avoid needing a …\nBranch and bound coin selection possible attempts with …\nBranch and bound coin selection\nIt’s possible to create spendable output from excess …\nTrait for generalized coin selection algorithms\nResult of a successful coin selection\nDefault coin selection algorithm used by TxBuilder if not …\nErrors that can be thrown by the coin_selection module\nRemaining amount after performing coin selection\nWallet’s UTXO set is not enough to cover recipient’s …\nSimple and dumb coin selection\nIt’s not possible to create spendable output from excess …\nOldestFirstCoinSelection always picks the utxo with the …\nPerform the coin selection\nDecide if change can be created\nRemaining amount after deducing fees and outgoing outputs\nTotal fee amount for the selected utxos in satoshis\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nThe total value of the inputs selected from the local …\nCreate new instance with target size for change output\nList of outputs selected for use as inputs\nThe total value of the inputs selected.\nSats available for spending\nSats needed for some transaction\nEffective amount available to create change after …\nThe calculated fee for the drain TxOut with the selected …\nThreshold to consider amount as dust for this particular …\nThe deducted change output fee\nExceeding amount of current selection over outgoing value …\nError returned from Wallet::build_fee_bump\nThere was an error with coin selection\nDescriptor key conversion error\nError returned from TxBuilder::finish\nThere was a problem with the descriptors passed in\nWhen bumping a tx the fee rate requested is lower than …\nNode doesn’t have data to estimate a fee rate\nWhen bumping a tx the absolute fee requested is lower than …\nTrying to replace a tx that has a sequence >= 0xFFFFFFFE\nRequested LockTime is less than is required to spend from …\nMiniscript PSBT error\nErrors returned by miniscript when updating inconsistent …\nIn order to use the TxBuilder::add_global_xpubs option …\nMissing non_witness_utxo on foreign utxo for given OutPoint\nCannot build a tx without recipients\nmanually_selected_only option is selected but no utxo has …\nOutput created is under the dust limit, 546 satoshis\nReturn error type for …\nThere was a problem while extracting and manipulating …\nPartially signed bitcoin transaction error\nCannot enable RBF with a Sequence >= 0xFFFFFFFE\nCannot enable RBF with Sequence given a required OP_CSV\nSpending policy is not compatible with this KeychainKind\nHappens when trying to bump a transaction that is already …\nThrown when a tx is not found in the internal database\nHappens when trying to spend an UTXO that is not in the …\nHappens when trying to spend an UTXO that is not in the …\nReturn error type for PsbtExt::update_input_with_descriptor\nRequested invalid transaction version ‘0’\nRequested transaction version 1, but at least 2 is needed …\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nRequired OP_CSV Sequence\nGiven RBF Sequence\nRequested LockTime\nRequired LockTime\nRequired fee absolute value Amount\nRequired fee rate\nStructure that contains the export of a wallet\nAlias for FullyNodedExport\nEarliest block to rescan when looking for the wallet’s …\nEarliest block to rescan when looking for the wallet’s …\nReturn the internal descriptor, if present\nReturn the external descriptor\nExport a wallet\nReturns the argument unchanged.\nCalls U::from(self).\nArbitrary label for the wallet\nArbitrary label for the wallet\nThe signer will sign all the leaves it has a key for.\nDummy identifier\nThe signer won’t sign the specified leaves.\nTo be used only by external libraries implementing …\nThe fingerprint of a BIP32 extended key\nThe signer won’t sign leaves other than the ones …\nInput index is out of range\nPSBT Input signer\nThe private key in use has the right fingerprint but …\nThe non_witness_utxo specified is invalid\nInvalid SIGHASH for the signing context in use\nLegacy context\nMiniscript PSBT error\nThe fingerprint and derivation path are missing from the …\nThe private key is missing for the required public key\nThe non_witness_utxo field of the transaction is required …\nThe witness_script field of the transaction is required to …\nThe witness_utxo field of the transaction is required to …\nThe psbt contains a non-SIGHASH_ALL sighash in one of its …\nThe signer won’t sign any leaf.\nBitcoin HASH160 (RIPEMD160 after SHA256) hash of an ECDSA …\nSegwit v0 context (BIP 143)\nError while computing the hash to sign a P2WPKH input.\nError while computing the hash to sign a Taproot input.\nOptions for a software signer\nCommon signer methods\nSigning context\nSigning error\nIdentifier of a signer in the SignersContainers. Used as a …\nDefines the order in which signers are called\nWrapper to pair a signer with its context\nContainer for multiple signers\nTaproot context (BIP 340)\nCustomize which taproot script-path leaves the signer …\nPSBT signer\nError while computing the hash, out of bounds access on …\nThe user canceled the operation\nAdds an external signer to the container for the specified …\nWhether the signer should use the sighash_type set in the …\nWhether we should grind ECDSA signature to ensure signing …\nCreate a map of public keys to secret keys\nWhether the wallet should assume a specific height has …\nBuild a new signer container from a KeyMap\nReturn the secret key for the signer\nFinds the signer with lowest ordering for a given id in …\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturn the SignerId for this signer\nReturns the list of identifiers of all the signers in the …\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCreate a wrapped signer from a signer and a context\nDefault constructor\nRemoves a signer from the container and returns it\nSign a single psbt input\nSign all the inputs of the psbt\nWhether we should try to sign a taproot transaction with …\nReturns the list of signers in the container, sorted by …\nSpecifies which Taproot script-spend leaves we should sign …\nWhether the signer should trust the witness_utxo, if the …\nWhether to try finalizing the PSBT after the inputs are …\nWhether the signer can sign for the internal key or not\nError returned from TxBuilder::add_foreign_utxo.\nError returned from TxBuilder::add_utxo and …\nBIP69 / Lexicographic\nUse both change and non-change outputs (default)\nOnly use non-change outputs (see …\nPolicy regarding the use of change outputs when creating a …\nRequested outpoint doesn’t exist in the tx (vout greater …\nForeign utxo outpoint txid does not match PSBT input txid\nForeign utxo missing witness_utxo or non_witness_utxo\nOnly use change outputs (see TxBuilder::only_spend_change)\nRandomized (default)\nA transaction builder\nOrdering of the transaction’s inputs and outputs\nHappens when trying to spend an UTXO that is not in the …\nUnchanged\nAdd data as an output, using OP_RETURN\nAdd a foreign UTXO i.e. a UTXO not owned by this wallet.\nSame as add_foreign_utxo but allows to set the nSequence …\nFill-in the PSBT_GLOBAL_XPUB field with the extended keys …\nAdd a recipient to the internal list\nAdd a utxo to the internal list of unspendable utxos\nAdd a utxo to the internal list of utxos that must be spent\nAdd the list of outpoints to the internal list of UTXOs …\nSet whether or not the dust limit is checked.\nSet a specific ChangeSpendPolicy. See …\nChoose the coin selection algorithm\nSet the current blockchain height.\nDo not spend change outputs\nSets the address to drain excess coins to.\nSpend all the available inputs. This respects filters like …\nEnable signaling RBF\nEnable signaling RBF with a specific nSequence value\nSet an absolute fee The fee_absolute method refers to the …\nSet a custom fee rate.\nFinish building the transaction.\nFinish building the transaction.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nFill-in the psbt::Output::redeem_script and …\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nOnly spend utxos added by add_utxo.\nUse a specific nLockTime while creating the transaction\nOnly spend change outputs\nOnly Fill-in the psbt::Input::witness_utxo field when …\nChoose the ordering for inputs and outputs of the …\nSet the policy path to use while creating the transaction …\nReplace the recipients already added with a new list\nSign with a specific sig hash\nSort transaction inputs and outputs by TxOrdering variant.\nSort transaction inputs and outputs by TxOrdering variant.\nReplace the internal list of unspendable utxos with a new …\nBuild a transaction with a specific version\nForeign UTXO outpoint\nPSBT input txid") \ No newline at end of file diff --git a/docs-rs/bdk/nightly/latest/src/bdk_esplora/blocking_ext.rs.html b/docs-rs/bdk/nightly/latest/src/bdk_esplora/blocking_ext.rs.html index f5c655ed8f..7703fe04c9 100644 --- a/docs-rs/bdk/nightly/latest/src/bdk_esplora/blocking_ext.rs.html +++ b/docs-rs/bdk/nightly/latest/src/bdk_esplora/blocking_ext.rs.html @@ -783,10 +783,8 @@ 783 784 785 -786
    use std::collections::BTreeSet;
     use std::thread::JoinHandle;
    -use std::usize;
     
     use bdk_chain::collections::BTreeMap;
     use bdk_chain::spk_client::{FullScanRequest, FullScanResult, SyncRequest, SyncResult};
    diff --git a/docs-rs/bdk/nightly/latest/src/bdk_wallet/keys/mod.rs.html b/docs-rs/bdk/nightly/latest/src/bdk_wallet/keys/mod.rs.html
    index 131f8d5c1c..b799f8dde8 100644
    --- a/docs-rs/bdk/nightly/latest/src/bdk_wallet/keys/mod.rs.html
    +++ b/docs-rs/bdk/nightly/latest/src/bdk_wallet/keys/mod.rs.html
    @@ -1000,6 +1000,31 @@
     1000
     1001
     1002
    +1003
    +1004
    +1005
    +1006
    +1007
    +1008
    +1009
    +1010
    +1011
    +1012
    +1013
    +1014
    +1015
    +1016
    +1017
    +1018
    +1019
    +1020
    +1021
    +1022
    +1023
    +1024
    +1025
    +1026
    +1027
     
    // Bitcoin Dev Kit
     // Written in 2020 by Alekos Filini <alekos.filini@gmail.com>
     //
    @@ -1022,6 +1047,8 @@
     use core::ops::Deref;
     use core::str::FromStr;
     
    +use rand_core::{CryptoRng, RngCore};
    +
     use bitcoin::secp256k1::{self, Secp256k1, Signing};
     
     use bitcoin::bip32;
    @@ -1633,12 +1660,23 @@
             entropy: Self::Entropy,
         ) -> Result<GeneratedKey<Self, Ctx>, Self::Error>;
     
    -    /// Generate a key given the options with a random entropy
    +    /// Generate a key given the options with random entropy.
    +    ///
    +    /// Uses the thread-local random number generator.
    +    #[cfg(feature = "std")]
         fn generate(options: Self::Options) -> Result<GeneratedKey<Self, Ctx>, Self::Error> {
    -        use rand::{thread_rng, Rng};
    +        Self::generate_with_aux_rand(options, &mut bitcoin::key::rand::thread_rng())
    +    }
     
    +    /// Generate a key given the options with random entropy.
    +    ///
    +    /// Uses a provided random number generator (rng).
    +    fn generate_with_aux_rand(
    +        options: Self::Options,
    +        rng: &mut (impl CryptoRng + RngCore),
    +    ) -> Result<GeneratedKey<Self, Ctx>, Self::Error> {
             let mut entropy = Self::Entropy::default();
    -        thread_rng().fill(entropy.as_mut());
    +        rng.fill_bytes(entropy.as_mut());
             Self::generate_with_entropy(options, entropy)
         }
     }
    @@ -1659,8 +1697,20 @@
         }
     
         /// Generate a key with the default options and a random entropy
    +    ///
    +    /// Uses the thread-local random number generator.
    +    #[cfg(feature = "std")]
         fn generate_default() -> Result<GeneratedKey<Self, Ctx>, Self::Error> {
    -        Self::generate(Default::default())
    +        Self::generate_with_aux_rand(Default::default(), &mut bitcoin::key::rand::thread_rng())
    +    }
    +
    +    /// Generate a key with the default options and a random entropy
    +    ///
    +    /// Uses a provided random number generator (rng).
    +    fn generate_default_with_aux_rand(
    +        rng: &mut (impl CryptoRng + RngCore),
    +    ) -> Result<GeneratedKey<Self, Ctx>, Self::Error> {
    +        Self::generate_with_aux_rand(Default::default(), rng)
         }
     }
     
    diff --git a/docs-rs/bdk/nightly/latest/src/bdk_wallet/wallet/coin_selection.rs.html b/docs-rs/bdk/nightly/latest/src/bdk_wallet/wallet/coin_selection.rs.html
    index a23c6ca97e..0979952d03 100644
    --- a/docs-rs/bdk/nightly/latest/src/bdk_wallet/wallet/coin_selection.rs.html
    +++ b/docs-rs/bdk/nightly/latest/src/bdk_wallet/wallet/coin_selection.rs.html
    @@ -1715,8 +1715,9 @@
     
     use core::convert::TryInto;
     use core::fmt::{self, Formatter};
    -use rand::seq::SliceRandom;
    +use rand_core::RngCore;
     
    +use super::utils::shuffle_slice;
     /// Default coin selection algorithm used by [`TxBuilder`](super::tx_builder::TxBuilder) if not
     /// overridden
     pub type DefaultCoinSelectionAlgorithm = BranchAndBoundCoinSelection;
    @@ -2117,27 +2118,16 @@
                 ));
             }
     
    -        Ok(self
    -            .bnb(
    -                required_utxos.clone(),
    -                optional_utxos.clone(),
    -                curr_value,
    -                curr_available_value,
    -                target_amount,
    -                cost_of_change,
    -                drain_script,
    -                fee_rate,
    -            )
    -            .unwrap_or_else(|_| {
    -                self.single_random_draw(
    -                    required_utxos,
    -                    optional_utxos,
    -                    curr_value,
    -                    target_amount,
    -                    drain_script,
    -                    fee_rate,
    -                )
    -            }))
    +        self.bnb(
    +            required_utxos.clone(),
    +            optional_utxos.clone(),
    +            curr_value,
    +            curr_available_value,
    +            target_amount,
    +            cost_of_change,
    +            drain_script,
    +            fee_rate,
    +        )
         }
     }
     
    @@ -2264,40 +2254,6 @@
             ))
         }
     
    -    #[allow(clippy::too_many_arguments)]
    -    fn single_random_draw(
    -        &self,
    -        required_utxos: Vec<OutputGroup>,
    -        mut optional_utxos: Vec<OutputGroup>,
    -        curr_value: i64,
    -        target_amount: i64,
    -        drain_script: &Script,
    -        fee_rate: FeeRate,
    -    ) -> CoinSelectionResult {
    -        optional_utxos.shuffle(&mut rand::thread_rng());
    -        let selected_utxos = optional_utxos.into_iter().fold(
    -            (curr_value, vec![]),
    -            |(mut amount, mut utxos), utxo| {
    -                if amount >= target_amount {
    -                    (amount, utxos)
    -                } else {
    -                    amount += utxo.effective_value;
    -                    utxos.push(utxo);
    -                    (amount, utxos)
    -                }
    -            },
    -        );
    -
    -        // remaining_amount can't be negative as that would mean the
    -        // selection wasn't successful
    -        // target_amount = amount_needed + (fee_amount - vin_fees)
    -        let remaining_amount = (selected_utxos.0 - target_amount) as u64;
    -
    -        let excess = decide_change(remaining_amount, fee_rate, drain_script);
    -
    -        BranchAndBoundCoinSelection::calculate_cs_result(selected_utxos.1, required_utxos, excess)
    -    }
    -
         fn calculate_cs_result(
             mut selected_utxos: Vec<OutputGroup>,
             mut required_utxos: Vec<OutputGroup>,
    @@ -2318,6 +2274,58 @@
         }
     }
     
    +// Pull UTXOs at random until we have enough to meet the target
    +pub(crate) fn single_random_draw(
    +    required_utxos: Vec<WeightedUtxo>,
    +    optional_utxos: Vec<WeightedUtxo>,
    +    target_amount: u64,
    +    drain_script: &Script,
    +    fee_rate: FeeRate,
    +    rng: &mut impl RngCore,
    +) -> CoinSelectionResult {
    +    let target_amount = target_amount
    +        .try_into()
    +        .expect("Bitcoin amount to fit into i64");
    +
    +    let required_utxos: Vec<OutputGroup> = required_utxos
    +        .into_iter()
    +        .map(|u| OutputGroup::new(u, fee_rate))
    +        .collect();
    +
    +    let mut optional_utxos: Vec<OutputGroup> = optional_utxos
    +        .into_iter()
    +        .map(|u| OutputGroup::new(u, fee_rate))
    +        .collect();
    +
    +    let curr_value = required_utxos
    +        .iter()
    +        .fold(0, |acc, x| acc + x.effective_value);
    +
    +    shuffle_slice(&mut optional_utxos, rng);
    +
    +    let selected_utxos =
    +        optional_utxos
    +            .into_iter()
    +            .fold((curr_value, vec![]), |(mut amount, mut utxos), utxo| {
    +                if amount >= target_amount {
    +                    (amount, utxos)
    +                } else {
    +                    amount += utxo.effective_value;
    +                    utxos.push(utxo);
    +                    (amount, utxos)
    +                }
    +            });
    +
    +    // remaining_amount can't be negative as that would mean the
    +    // selection wasn't successful
    +    // target_amount = amount_needed + (fee_amount - vin_fees)
    +    let remaining_amount = (selected_utxos.0 - target_amount) as u64;
    +
    +    let excess = decide_change(remaining_amount, fee_rate, drain_script);
    +
    +    BranchAndBoundCoinSelection::calculate_cs_result(selected_utxos.1, required_utxos, excess)
    +}
    +
     /// Remove duplicate UTXOs.
     ///
     /// If a UTXO appears in both `required` and `optional`, the appearance in `required` is kept.
    @@ -2341,6 +2349,7 @@
     mod test {
         use assert_matches::assert_matches;
         use core::str::FromStr;
    +    use rand::rngs::StdRng;
     
         use bdk_chain::ConfirmationTime;
         use bitcoin::{Amount, ScriptBuf, TxIn, TxOut};
    @@ -2349,8 +2358,7 @@
         use crate::types::*;
         use crate::wallet::coin_selection::filter_duplicates;
     
    -    use rand::rngs::StdRng;
    -    use rand::seq::SliceRandom;
    +    use rand::prelude::SliceRandom;
         use rand::{Rng, RngCore, SeedableRng};
     
         // signature len (1WU) + signature and sighash (72WU)
    @@ -2691,13 +2699,12 @@
         }
     
         #[test]
    +    #[ignore = "SRD fn was moved out of BnB"]
         fn test_bnb_coin_selection_success() {
             // In this case bnb won't find a suitable match and single random draw will
             // select three outputs
             let utxos = generate_same_value_utxos(100_000, 20);
    -
             let drain_script = ScriptBuf::default();
    -
             let target_amount = 250_000 + FEE_AMOUNT;
     
             let result = BranchAndBoundCoinSelection::default()
    @@ -2737,6 +2744,7 @@
         }
     
         #[test]
    +    #[ignore = "no exact match for bnb, previously fell back to SRD"]
         fn test_bnb_coin_selection_optional_are_enough() {
             let utxos = get_test_utxos();
             let drain_script = ScriptBuf::default();
    @@ -2757,6 +2765,26 @@
             assert_eq!(result.fee_amount, 136);
         }
     
    +    #[test]
    +    fn test_single_random_draw_function_success() {
    +        let seed = [0; 32];
    +        let mut rng: StdRng = SeedableRng::from_seed(seed);
    +        let mut utxos = generate_random_utxos(&mut rng, 300);
    +        let target_amount = sum_random_utxos(&mut rng, &mut utxos) + FEE_AMOUNT;
    +        let fee_rate = FeeRate::from_sat_per_vb_unchecked(1);
    +        let drain_script = ScriptBuf::default();
    +        let result = single_random_draw(
    +            vec![],
    +            utxos,
    +            target_amount,
    +            &drain_script,
    +            fee_rate,
    +            &mut rng,
    +        );
    +        assert!(result.selected_amount() > target_amount);
    +        assert_eq!(result.fee_amount, (result.selected.len() * 68) as u64);
    +    }
    +
         #[test]
         #[ignore]
         fn test_bnb_coin_selection_required_not_enough() {
    @@ -3011,34 +3039,6 @@
             }
         }
     
    -    #[test]
    -    fn test_single_random_draw_function_success() {
    -        let seed = [0; 32];
    -        let mut rng: StdRng = SeedableRng::from_seed(seed);
    -        let mut utxos = generate_random_utxos(&mut rng, 300);
    -        let target_amount = sum_random_utxos(&mut rng, &mut utxos) + FEE_AMOUNT;
    -
    -        let fee_rate = FeeRate::from_sat_per_vb_unchecked(1);
    -        let utxos: Vec<OutputGroup> = utxos
    -            .into_iter()
    -            .map(|u| OutputGroup::new(u, fee_rate))
    -            .collect();
    -
    -        let drain_script = ScriptBuf::default();
    -
    -        let result = BranchAndBoundCoinSelection::default().single_random_draw(
    -            vec![],
    -            utxos,
    -            0,
    -            target_amount as i64,
    -            &drain_script,
    -            fee_rate,
    -        );
    -
    -        assert!(result.selected_amount() > target_amount);
    -        assert_eq!(result.fee_amount, (result.selected.len() * 68) as u64);
    -    }
    -
         #[test]
         fn test_bnb_exclude_negative_effective_value() {
             let utxos = get_test_utxos();
    diff --git a/docs-rs/bdk/nightly/latest/src/bdk_wallet/wallet/mod.rs.html b/docs-rs/bdk/nightly/latest/src/bdk_wallet/wallet/mod.rs.html
    index 0f9d72cb8b..9e55e78050 100644
    --- a/docs-rs/bdk/nightly/latest/src/bdk_wallet/wallet/mod.rs.html
    +++ b/docs-rs/bdk/nightly/latest/src/bdk_wallet/wallet/mod.rs.html
    @@ -2549,6 +2549,27 @@
     2549
     2550
     2551
    +2552
    +2553
    +2554
    +2555
    +2556
    +2557
    +2558
    +2559
    +2560
    +2561
    +2562
    +2563
    +2564
    +2565
    +2566
    +2567
    +2568
    +2569
    +2570
    +2571
    +2572
     
    // Bitcoin Dev Kit
     // Written in 2020 by Alekos Filini <alekos.filini@gmail.com>
     //
    @@ -2593,6 +2614,8 @@
     use core::fmt;
     use core::mem;
     use core::ops::Deref;
    +use rand_core::RngCore;
    +
     use descriptor::error::Error as DescriptorError;
     use miniscript::psbt::{PsbtExt, PsbtInputExt, PsbtInputSatisfier};
     
    @@ -3789,6 +3812,7 @@
             &mut self,
             coin_selection: Cs,
             params: TxParams,
    +        rng: &mut impl RngCore,
         ) -> Result<Psbt, CreateTxError> {
             let keychains: BTreeMap<_, _> = self.indexed_graph.index.keychains().collect();
             let external_descriptor = keychains.get(&KeychainKind::External).expect("must exist");
    @@ -4015,13 +4039,31 @@
             let (required_utxos, optional_utxos) =
                 coin_selection::filter_duplicates(required_utxos, optional_utxos);
     
    -        let coin_selection = coin_selection.coin_select(
    -            required_utxos,
    -            optional_utxos,
    +        let coin_selection = match coin_selection.coin_select(
    +            required_utxos.clone(),
    +            optional_utxos.clone(),
                 fee_rate,
                 outgoing.to_sat() + fee_amount,
                 &drain_script,
    -        )?;
    +        ) {
    +            Ok(res) => res,
    +            Err(e) => match e {
    +                coin_selection::Error::InsufficientFunds { .. } => {
    +                    return Err(CreateTxError::CoinSelection(e));
    +                }
    +                coin_selection::Error::BnBNoExactMatch
    +                | coin_selection::Error::BnBTotalTriesExceeded => {
    +                    coin_selection::single_random_draw(
    +                        required_utxos,
    +                        optional_utxos,
    +                        outgoing.to_sat() + fee_amount,
    +                        &drain_script,
    +                        fee_rate,
    +                        rng,
    +                    )
    +                }
    +            },
    +        };
             fee_amount += coin_selection.fee_amount;
             let excess = &coin_selection.excess;
     
    @@ -4085,7 +4127,7 @@
             };
     
             // sort input/outputs according to the chosen algorithm
    -        params.ordering.sort_tx(&mut tx);
    +        params.ordering.sort_tx_with_aux_rand(&mut tx, rng);
     
             let psbt = self.complete_transaction(tx, coin_selection.selected, params)?;
             Ok(psbt)
    diff --git a/docs-rs/bdk/nightly/latest/src/bdk_wallet/wallet/signer.rs.html b/docs-rs/bdk/nightly/latest/src/bdk_wallet/wallet/signer.rs.html
    index 871fd62773..697a101110 100644
    --- a/docs-rs/bdk/nightly/latest/src/bdk_wallet/wallet/signer.rs.html
    +++ b/docs-rs/bdk/nightly/latest/src/bdk_wallet/wallet/signer.rs.html
    @@ -1808,7 +1808,7 @@
         };
     
         let msg = &Message::from(hash);
    -    let signature = secp.sign_schnorr(msg, &keypair);
    +    let signature = secp.sign_schnorr_no_aux_rand(msg, &keypair);
         secp.verify_schnorr(&signature, msg, &XOnlyPublicKey::from_keypair(&keypair).0)
             .expect("invalid or corrupted schnorr signature");
     
    diff --git a/docs-rs/bdk/nightly/latest/src/bdk_wallet/wallet/tx_builder.rs.html b/docs-rs/bdk/nightly/latest/src/bdk_wallet/wallet/tx_builder.rs.html
    index 05103e55c8..8f4bb7789f 100644
    --- a/docs-rs/bdk/nightly/latest/src/bdk_wallet/wallet/tx_builder.rs.html
    +++ b/docs-rs/bdk/nightly/latest/src/bdk_wallet/wallet/tx_builder.rs.html
    @@ -1000,6 +1000,27 @@
     1000
     1001
     1002
    +1003
    +1004
    +1005
    +1006
    +1007
    +1008
    +1009
    +1010
    +1011
    +1012
    +1013
    +1014
    +1015
    +1016
    +1017
    +1018
    +1019
    +1020
    +1021
    +1022
    +1023
     
    // Bitcoin Dev Kit
     // Written in 2020 by Alekos Filini <alekos.filini@gmail.com>
     //
    @@ -1047,8 +1068,10 @@
     use bitcoin::psbt::{self, Psbt};
     use bitcoin::script::PushBytes;
     use bitcoin::{absolute, Amount, FeeRate, OutPoint, ScriptBuf, Sequence, Transaction, Txid};
    +use rand_core::RngCore;
     
     use super::coin_selection::CoinSelectionAlgorithm;
    +use super::utils::shuffle_slice;
     use super::{CreateTxError, Wallet};
     use crate::collections::{BTreeMap, HashSet};
     use crate::{KeychainKind, LocalOutput, Utxo, WeightedUtxo};
    @@ -1671,16 +1694,33 @@
     impl<'a, Cs: CoinSelectionAlgorithm> TxBuilder<'a, Cs> {
         /// Finish building the transaction.
         ///
    +    /// Uses the thread-local random number generator (rng).
    +    ///
         /// Returns a new [`Psbt`] per [`BIP174`].
         ///
         /// [`BIP174`]: https://github.com/bitcoin/bips/blob/master/bip-0174.mediawiki
         ///
         /// **WARNING**: To avoid change address reuse you must persist the changes resulting from one
         /// or more calls to this method before closing the wallet. See [`Wallet::reveal_next_address`].
    +    #[cfg(feature = "std")]
         pub fn finish(self) -> Result<Psbt, CreateTxError> {
    +        self.finish_with_aux_rand(&mut bitcoin::key::rand::thread_rng())
    +    }
    +
    +    /// Finish building the transaction.
    +    ///
    +    /// Uses a provided random number generator (rng).
    +    ///
    +    /// Returns a new [`Psbt`] per [`BIP174`].
    +    ///
    +    /// [`BIP174`]: https://github.com/bitcoin/bips/blob/master/bip-0174.mediawiki
    +    ///
    +    /// **WARNING**: To avoid change address reuse you must persist the changes resulting from one
    +    /// or more calls to this method before closing the wallet. See [`Wallet::reveal_next_address`].
    +    pub fn finish_with_aux_rand(self, rng: &mut impl RngCore) -> Result<Psbt, CreateTxError> {
             self.wallet
                 .borrow_mut()
    -            .create_tx(self.coin_selection, self.params)
    +            .create_tx(self.coin_selection, self.params, rng)
         }
     }
     
    @@ -1759,15 +1799,23 @@
     }
     
     impl TxOrdering {
    -    /// Sort transaction inputs and outputs by [`TxOrdering`] variant
    -    pub fn sort_tx(&self, tx: &mut Transaction) {
    +    /// Sort transaction inputs and outputs by [`TxOrdering`] variant.
    +    ///
    +    /// Uses the thread-local random number generator (rng).
    +    #[cfg(feature = "std")]
    +    pub fn sort_tx(self, tx: &mut Transaction) {
    +        self.sort_tx_with_aux_rand(tx, &mut bitcoin::key::rand::thread_rng())
    +    }
    +
    +    /// Sort transaction inputs and outputs by [`TxOrdering`] variant.
    +    ///
    +    /// Uses a provided random number generator (rng).
    +    pub fn sort_tx_with_aux_rand(self, tx: &mut Transaction, rng: &mut impl RngCore) {
             match self {
                 TxOrdering::Untouched => {}
                 TxOrdering::Shuffle => {
    -                use rand::seq::SliceRandom;
    -                let mut rng = rand::thread_rng();
    -                tx.input.shuffle(&mut rng);
    -                tx.output.shuffle(&mut rng);
    +                shuffle_slice(&mut tx.input, rng);
    +                shuffle_slice(&mut tx.output, rng);
                 }
                 TxOrdering::Bip69Lexicographic => {
                     tx.input.sort_unstable_by_key(|txin| {
    @@ -1853,12 +1901,6 @@
         use bitcoin::TxOut;
     
         use super::*;
    -
    -    #[test]
    -    fn test_output_ordering_default_shuffle() {
    -        assert_eq!(TxOrdering::default(), TxOrdering::Shuffle);
    -    }
    -
         #[test]
         fn test_output_ordering_untouched() {
             let original_tx = ordering_test_tx!();
    diff --git a/docs-rs/bdk/nightly/latest/src/bdk_wallet/wallet/utils.rs.html b/docs-rs/bdk/nightly/latest/src/bdk_wallet/wallet/utils.rs.html
    index 8d3c03d3c5..982488505a 100644
    --- a/docs-rs/bdk/nightly/latest/src/bdk_wallet/wallet/utils.rs.html
    +++ b/docs-rs/bdk/nightly/latest/src/bdk_wallet/wallet/utils.rs.html
    @@ -183,6 +183,65 @@
     183
     184
     185
    +186
    +187
    +188
    +189
    +190
    +191
    +192
    +193
    +194
    +195
    +196
    +197
    +198
    +199
    +200
    +201
    +202
    +203
    +204
    +205
    +206
    +207
    +208
    +209
    +210
    +211
    +212
    +213
    +214
    +215
    +216
    +217
    +218
    +219
    +220
    +221
    +222
    +223
    +224
    +225
    +226
    +227
    +228
    +229
    +230
    +231
    +232
    +233
    +234
    +235
    +236
    +237
    +238
    +239
    +240
    +241
    +242
    +243
    +244
     

    // Bitcoin Dev Kit
     // Written in 2020 by Alekos Filini <alekos.filini@gmail.com>
     //
    @@ -199,6 +258,8 @@
     
     use miniscript::{MiniscriptKey, Satisfier, ToPublicKey};
     
    +use rand_core::RngCore;
    +
     /// Trait to check if a value is below the dust limit.
     /// We are performing dust value calculation for a given script public key using rust-bitcoin to
     /// keep it compatible with network dust rate
    @@ -295,6 +356,19 @@
         }
     }
     
    +// The Knuth shuffling algorithm based on the original [Fisher-Yates method](https://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle)
    +pub(crate) fn shuffle_slice<T>(list: &mut [T], rng: &mut impl RngCore) {
    +    if list.is_empty() {
    +        return;
    +    }
    +    let mut current_index = list.len() - 1;
    +    while current_index > 0 {
    +        let random_index = rng.next_u32() as usize % (current_index + 1);
    +        list.swap(current_index, random_index);
    +        current_index -= 1;
    +    }
    +}
    +
     pub(crate) type SecpCtx = Secp256k1<All>;
     
     #[cfg(test)]
    @@ -303,9 +377,11 @@
         // otherwise it's time-based
         pub(crate) const SEQUENCE_LOCKTIME_TYPE_FLAG: u32 = 1 << 22;
     
    -    use super::{check_nsequence_rbf, IsDust};
    +    use super::{check_nsequence_rbf, shuffle_slice, IsDust};
         use crate::bitcoin::{Address, Network, Sequence};
    +    use alloc::vec::Vec;
         use core::str::FromStr;
    +    use rand::{rngs::StdRng, thread_rng, SeedableRng};
     
         #[test]
         fn test_is_dust() {
    @@ -367,5 +443,47 @@
             );
             assert!(result);
         }
    +
    +    #[test]
    +    #[cfg(feature = "std")]
    +    fn test_shuffle_slice_empty_vec() {
    +        let mut test: Vec<u8> = vec![];
    +        shuffle_slice(&mut test, &mut thread_rng());
    +    }
    +
    +    #[test]
    +    #[cfg(feature = "std")]
    +    fn test_shuffle_slice_single_vec() {
    +        let mut test: Vec<u8> = vec![0];
    +        shuffle_slice(&mut test, &mut thread_rng());
    +    }
    +
    +    #[test]
    +    fn test_shuffle_slice_duple_vec() {
    +        let seed = [0; 32];
    +        let mut rng: StdRng = SeedableRng::from_seed(seed);
    +        let mut test: Vec<u8> = vec![0, 1];
    +        shuffle_slice(&mut test, &mut rng);
    +        assert_eq!(test, &[0, 1]);
    +        let seed = [6; 32];
    +        let mut rng: StdRng = SeedableRng::from_seed(seed);
    +        let mut test: Vec<u8> = vec![0, 1];
    +        shuffle_slice(&mut test, &mut rng);
    +        assert_eq!(test, &[1, 0]);
    +    }
    +
    +    #[test]
    +    fn test_shuffle_slice_multi_vec() {
    +        let seed = [0; 32];
    +        let mut rng: StdRng = SeedableRng::from_seed(seed);
    +        let mut test: Vec<u8> = vec![0, 1, 2, 4, 5];
    +        shuffle_slice(&mut test, &mut rng);
    +        assert_eq!(test, &[2, 1, 0, 4, 5]);
    +        let seed = [25; 32];
    +        let mut rng: StdRng = SeedableRng::from_seed(seed);
    +        let mut test: Vec<u8> = vec![0, 1, 2, 4, 5];
    +        shuffle_slice(&mut test, &mut rng);
    +        assert_eq!(test, &[0, 4, 1, 2, 5]);
    +    }
     }
     
    \ No newline at end of file diff --git a/docs-rs/bdk/nightly/latest/type.impl/bdk_wallet/wallet/coin_selection/struct.BranchAndBoundCoinSelection.js b/docs-rs/bdk/nightly/latest/type.impl/bdk_wallet/wallet/coin_selection/struct.BranchAndBoundCoinSelection.js index 6d6ac5f00c..8d3370a70f 100644 --- a/docs-rs/bdk/nightly/latest/type.impl/bdk_wallet/wallet/coin_selection/struct.BranchAndBoundCoinSelection.js +++ b/docs-rs/bdk/nightly/latest/type.impl/bdk_wallet/wallet/coin_selection/struct.BranchAndBoundCoinSelection.js @@ -1,3 +1,3 @@ (function() {var type_impls = { -"bdk_wallet":[["
    source§

    impl BranchAndBoundCoinSelection

    source

    pub fn new(size_of_change: u64) -> Self

    Create new instance with target size for change output

    \n
    ",0,"bdk_wallet::wallet::coin_selection::DefaultCoinSelectionAlgorithm"],["
    source§

    impl Clone for BranchAndBoundCoinSelection

    source§

    fn clone(&self) -> BranchAndBoundCoinSelection

    Returns a copy of the value. Read more
    1.0.0 · source§

    fn clone_from(&mut self, source: &Self)

    Performs copy-assignment from source. Read more
    ","Clone","bdk_wallet::wallet::coin_selection::DefaultCoinSelectionAlgorithm"],["
    source§

    impl CoinSelectionAlgorithm for BranchAndBoundCoinSelection

    source§

    fn coin_select(\n &self,\n required_utxos: Vec<WeightedUtxo>,\n optional_utxos: Vec<WeightedUtxo>,\n fee_rate: FeeRate,\n target_amount: u64,\n drain_script: &Script\n) -> Result<CoinSelectionResult, Error>

    Perform the coin selection Read more
    ","CoinSelectionAlgorithm","bdk_wallet::wallet::coin_selection::DefaultCoinSelectionAlgorithm"],["
    source§

    impl Debug for BranchAndBoundCoinSelection

    source§

    fn fmt(&self, f: &mut Formatter<'_>) -> Result

    Formats the value using the given formatter. Read more
    ","Debug","bdk_wallet::wallet::coin_selection::DefaultCoinSelectionAlgorithm"],["
    source§

    impl Default for BranchAndBoundCoinSelection

    source§

    fn default() -> Self

    Returns the “default value” for a type. Read more
    ","Default","bdk_wallet::wallet::coin_selection::DefaultCoinSelectionAlgorithm"]] +"bdk_wallet":[["
    source§

    impl BranchAndBoundCoinSelection

    source

    pub fn new(size_of_change: u64) -> Self

    Create new instance with target size for change output

    \n
    ",0,"bdk_wallet::wallet::coin_selection::DefaultCoinSelectionAlgorithm"],["
    source§

    impl Clone for BranchAndBoundCoinSelection

    source§

    fn clone(&self) -> BranchAndBoundCoinSelection

    Returns a copy of the value. Read more
    1.0.0 · source§

    fn clone_from(&mut self, source: &Self)

    Performs copy-assignment from source. Read more
    ","Clone","bdk_wallet::wallet::coin_selection::DefaultCoinSelectionAlgorithm"],["
    source§

    impl CoinSelectionAlgorithm for BranchAndBoundCoinSelection

    source§

    fn coin_select(\n &self,\n required_utxos: Vec<WeightedUtxo>,\n optional_utxos: Vec<WeightedUtxo>,\n fee_rate: FeeRate,\n target_amount: u64,\n drain_script: &Script\n) -> Result<CoinSelectionResult, Error>

    Perform the coin selection Read more
    ","CoinSelectionAlgorithm","bdk_wallet::wallet::coin_selection::DefaultCoinSelectionAlgorithm"],["
    source§

    impl Debug for BranchAndBoundCoinSelection

    source§

    fn fmt(&self, f: &mut Formatter<'_>) -> Result

    Formats the value using the given formatter. Read more
    ","Debug","bdk_wallet::wallet::coin_selection::DefaultCoinSelectionAlgorithm"],["
    source§

    impl Default for BranchAndBoundCoinSelection

    source§

    fn default() -> Self

    Returns the “default value” for a type. Read more
    ","Default","bdk_wallet::wallet::coin_selection::DefaultCoinSelectionAlgorithm"]] };if (window.register_type_impls) {window.register_type_impls(type_impls);} else {window.pending_type_impls = type_impls;}})() \ No newline at end of file diff --git a/examples/index.html b/examples/index.html index 77f952c203..e0de94123f 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/about/index.html b/foundation/about/index.html index 49673e4129..59681df2cf 100644 --- a/foundation/about/index.html +++ b/foundation/about/index.html @@ -29,7 +29,7 @@ - + @@ -78,6 +78,6 @@
    - + diff --git a/foundation/grantees/index.html b/foundation/grantees/index.html index f2eb40b681..3380a7752d 100644 --- a/foundation/grantees/index.html +++ b/foundation/grantees/index.html @@ -29,7 +29,7 @@ - + @@ -82,6 +82,6 @@
    - + diff --git a/foundation/grants/index.html b/foundation/grants/index.html index 63233c0eef..425fd9805a 100644 --- a/foundation/grants/index.html +++ b/foundation/grants/index.html @@ -29,7 +29,7 @@ - + @@ -78,6 +78,6 @@
    - + diff --git a/foundation/index.html b/foundation/index.html index 443a37b9e8..8cbe1b7626 100644 --- a/foundation/index.html +++ b/foundation/index.html @@ -29,7 +29,7 @@ - + @@ -74,6 +74,6 @@
    - + diff --git a/foundation/supporters/index.html b/foundation/supporters/index.html index efbca7cdd2..db755e9cf9 100644 --- a/foundation/supporters/index.html +++ b/foundation/supporters/index.html @@ -29,7 +29,7 @@ - + @@ -113,6 +113,6 @@
    - + diff --git a/getting-started/index.html b/getting-started/index.html index a9e773e71b..e9de7f9e49 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).

    - + diff --git a/index.html b/index.html index c28ba7b8df..441d21b9b8 100644 --- a/index.html +++ b/index.html @@ -29,7 +29,7 @@ - + @@ -80,6 +80,6 @@
    - + diff --git a/sitemap.xml b/sitemap.xml index b559c9edd1..6a8cfd2e4d 100644 --- a/sitemap.xml +++ b/sitemap.xml @@ -1 +1 @@ -https://bitcoindevkit.org/2024-06-20T04:44:04.000Zdailyhttps://bitcoindevkit.org/blog/_2023-q4-update/2024-06-20T04:44:04.000Zdailyhttps://bitcoindevkit.org/blog/_2024-q1-update/2024-06-20T04:44:04.000Zdailyhttps://bitcoindevkit.org/blog/bitcoin-core-rpc-demo/2024-06-20T04:44:04.000Zdailyhttps://bitcoindevkit.org/blog/bdk-cli-basics/2024-06-20T04:44:04.000Zdailyhttps://bitcoindevkit.org/blog/bdk-cli-basics-multisig-2of3/2024-06-20T04:44:04.000Zdailyhttps://bitcoindevkit.org/blog/bdk-core-pt1/2024-06-20T04:44:04.000Zdailyhttps://bitcoindevkit.org/blog/bdk-rn-making-of/2024-06-20T04:44:04.000Zdailyhttps://bitcoindevkit.org/blog/bindings-scope/2024-06-20T04:44:04.000Zdailyhttps://bitcoindevkit.org/blog/bdk-with-tor/2024-06-20T04:44:04.000Zdailyhttps://bitcoindevkit.org/blog/compact-filters-demo/2024-06-20T04:44:04.000Zdailyhttps://bitcoindevkit.org/blog/descriptor-based-paper-wallet/2024-06-20T04:44:04.000Zdailyhttps://bitcoindevkit.org/blog/exploring-bdk-flutter/2024-06-20T04:44:04.000Zdailyhttps://bitcoindevkit.org/blog/descriptors-in-the-wild/2024-06-20T04:44:04.000Zdailyhttps://bitcoindevkit.org/blog/exploring-bdk-rn/2024-06-20T04:44:04.000Zdailyhttps://bitcoindevkit.org/blog/2021/01/fee-estimation-for-light-clients-part-1/2024-06-20T04:44:04.000Zdailyhttps://bitcoindevkit.org/blog/2021/01/fee-estimation-for-light-clients-part-2/2024-06-20T04:44:04.000Zdailyhttps://bitcoindevkit.org/blog/2021/01/fee-estimation-for-light-clients-part-3/2024-06-20T04:44:04.000Zdailyhttps://bitcoindevkit.org/blog/2021/11/first-bdk-taproot-tx-look-at-the-code-part-1/2024-06-20T04:44:04.000Zdailyhttps://bitcoindevkit.org/blog/2021/12/first-bdk-taproot-tx-look-at-the-code-part-2/2024-06-20T04:44:04.000Zdailyhttps://bitcoindevkit.org/blog/getting-started-with-rust-hwi/2024-06-20T04:44:04.000Zdailyhttps://bitcoindevkit.org/blog/2020/12/hello-world/2024-06-20T04:44:04.000Zdailyhttps://bitcoindevkit.org/blog/hidden-power-of-bitcoin/2024-06-20T04:44:04.000Zdailyhttps://bitcoindevkit.org/blog/improving-coin-selection-in-bdk/2024-06-20T04:44:04.000Zdailyhttps://bitcoindevkit.org/blog/miniscript-vulnerability/2024-06-20T04:44:04.000Zdailyhttps://bitcoindevkit.org/blog/2021/01/release-v0.3.0/2024-06-20T04:44:04.000Zdailyhttps://bitcoindevkit.org/blog/2020/12/release-v0.2.0/2024-06-20T04:44:04.000Zdailyhttps://bitcoindevkit.org/blog/2021/03/release-v0.5.0/2024-06-20T04:44:04.000Zdailyhttps://bitcoindevkit.org/blog/2021/02/release-v0.4.0/2024-06-20T04:44:04.000Zdailyhttps://bitcoindevkit.org/blog/2021/04/release-v0.6.0/2024-06-20T04:44:04.000Zdailyhttps://bitcoindevkit.org/blog/2021/05/release-v0.7.0/2024-06-20T04:44:04.000Zdailyhttps://bitcoindevkit.org/blog/2021/06/release-v0.8.0/2024-06-20T04:44:04.000Zdailyhttps://bitcoindevkit.org/blog/2021/07/release-v0.9.0/2024-06-20T04:44:04.000Zdailyhttps://bitcoindevkit.org/blog/spending-policy-demo/2024-06-20T04:44:04.000Zdailyhttps://bitcoindevkit.org/blog/using-bdk-with-hardware-wallets/2024-06-20T04:44:04.000Zdailyhttps://bitcoindevkit.org/blog/road-to-bdk-1/2024-06-20T04:44:04.000Zdailyhttps://bitcoindevkit.org/blog/why-bindings/2024-06-20T04:44:04.000Zdailyhttps://bitcoindevkit.org/adoption/all/2024-06-20T04:44:04.000Zdailyhttps://bitcoindevkit.org/adoption/custodial/2024-06-20T04:44:04.000Zdailyhttps://bitcoindevkit.org/adoption/exchange/2024-06-20T04:44:04.000Zdailyhttps://bitcoindevkit.org/adoption/desktop/2024-06-20T04:44:04.000Zdailyhttps://bitcoindevkit.org/adoption/hardware/2024-06-20T04:44:04.000Zdailyhttps://bitcoindevkit.org/adoption/infrastructure/2024-06-20T04:44:04.000Zdailyhttps://bitcoindevkit.org/adoption/mobile/2024-06-20T04:44:04.000Zdailyhttps://bitcoindevkit.org/adoption/web/2024-06-20T04:44:04.000Zdailyhttps://bitcoindevkit.org/bdk-cli/compiler/2024-06-20T04:44:04.000Zdailyhttps://bitcoindevkit.org/bdk-cli/installation/2024-06-20T04:44:04.000Zdailyhttps://bitcoindevkit.org/bdk-cli/concept/2024-06-20T04:44:04.000Zdailyhttps://bitcoindevkit.org/bdk-cli/interface/2024-06-20T04:44:04.000Zdailyhttps://bitcoindevkit.org/bdk-cli/introduction/2024-06-20T04:44:04.000Zdailyhttps://bitcoindevkit.org/bdk-cli/regtest/2024-06-20T04:44:04.000Zdailyhttps://bitcoindevkit.org/bdk-cli/playground/2024-06-20T04:44:04.000Zdailyhttps://bitcoindevkit.org/case-studies/2024-06-20T04:44:04.000Zdailyhttps://bitcoindevkit.org/foundation/about/2024-06-20T04:44:04.000Zdailyhttps://bitcoindevkit.org/examples/2024-06-20T04:44:04.000Zdailyhttps://bitcoindevkit.org/descriptors/2024-06-20T04:44:04.000Zdailyhttps://bitcoindevkit.org/foundation/grantees/2024-06-20T04:44:04.000Zdailyhttps://bitcoindevkit.org/foundation/grants/2024-06-20T04:44:04.000Zdailyhttps://bitcoindevkit.org/foundation/2024-06-20T04:44:04.000Zdailyhttps://bitcoindevkit.org/foundation/supporters/2024-06-20T04:44:04.000Zdailyhttps://bitcoindevkit.org/getting-started/2024-06-20T04:44:04.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/bindings/dailyhttps://bitcoindevkit.org/blog/tags/tor/dailyhttps://bitcoindevkit.org/blog/tags/wallet/dailyhttps://bitcoindevkit.org/blog/tags/blockchain/dailyhttps://bitcoindevkit.org/blog/tags/compact_filters/dailyhttps://bitcoindevkit.org/blog/tags/BIP157/dailyhttps://bitcoindevkit.org/blog/tags/Neutrino/dailyhttps://bitcoindevkit.org/blog/tags/guide/dailyhttps://bitcoindevkit.org/blog/tags/descriptor/dailyhttps://bitcoindevkit.org/blog/tags/paper%20wallets/dailyhttps://bitcoindevkit.org/blog/tags/bitcoin/dailyhttps://bitcoindevkit.org/blog/tags/React%20Native/dailyhttps://bitcoindevkit.org/blog/tags/Flutter/dailyhttps://bitcoindevkit.org/blog/tags/iOS/dailyhttps://bitcoindevkit.org/blog/tags/Android/dailyhttps://bitcoindevkit.org/blog/tags/mobile/dailyhttps://bitcoindevkit.org/blog/tags/bdk-rn/dailyhttps://bitcoindevkit.org/blog/tags/bdk/dailyhttps://bitcoindevkit.org/blog/tags/fee/dailyhttps://bitcoindevkit.org/blog/tags/machine%20learning/dailyhttps://bitcoindevkit.org/blog/tags/taproot/dailyhttps://bitcoindevkit.org/blog/tags/miniscript/dailyhttps://bitcoindevkit.org/blog/tags/Hardware%20Wallets/dailyhttps://bitcoindevkit.org/blog/tags/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/thunderbiscuit/dailyhttps://bitcoindevkit.org/blog/author/rorp/dailyhttps://bitcoindevkit.org/blog/author/Riccardo%20Casatta/dailyhttps://bitcoindevkit.org/blog/author/Gabriele%20Domenichini/dailyhttps://bitcoindevkit.org/blog/author/Alekos%20Filini/dailyhttps://bitcoindevkit.org/blog/author/Wszdexdrf/dailyhttps://bitcoindevkit.org/blog/author/Sandipan%20Dey/dailyhttps://bitcoindevkit.org/blog/author/C%C3%A9sar%20Alvarez%20Vallero/dailyhttps://bitcoindevkit.org/blog/page/2/dailyhttps://bitcoindevkit.org/blog/page/3/dailyhttps://bitcoindevkit.org/blog/page/4/dailyhttps://bitcoindevkit.org/blog/author/Alekos%20Filini/page/2/daily \ No newline at end of file +https://bitcoindevkit.org/2024-06-23T02:32:08.000Zdailyhttps://bitcoindevkit.org/blog/_2024-q1-update/2024-06-23T02:32:08.000Zdailyhttps://bitcoindevkit.org/blog/bdk-cli-basics-multisig-2of3/2024-06-23T02:32:08.000Zdailyhttps://bitcoindevkit.org/blog/_2023-q4-update/2024-06-23T02:32:08.000Zdailyhttps://bitcoindevkit.org/blog/bdk-cli-basics/2024-06-23T02:32:08.000Zdailyhttps://bitcoindevkit.org/blog/bitcoin-core-rpc-demo/2024-06-23T02:32:08.000Zdailyhttps://bitcoindevkit.org/blog/bdk-core-pt1/2024-06-23T02:32:08.000Zdailyhttps://bitcoindevkit.org/blog/bdk-with-tor/2024-06-23T02:32:08.000Zdailyhttps://bitcoindevkit.org/blog/bdk-rn-making-of/2024-06-23T02:32:08.000Zdailyhttps://bitcoindevkit.org/blog/bindings-scope/2024-06-23T02:32:08.000Zdailyhttps://bitcoindevkit.org/blog/exploring-bdk-rn/2024-06-23T02:32:08.000Zdailyhttps://bitcoindevkit.org/blog/descriptor-based-paper-wallet/2024-06-23T02:32:08.000Zdailyhttps://bitcoindevkit.org/blog/exploring-bdk-flutter/2024-06-23T02:32:08.000Zdailyhttps://bitcoindevkit.org/blog/descriptors-in-the-wild/2024-06-23T02:32:08.000Zdailyhttps://bitcoindevkit.org/blog/compact-filters-demo/2024-06-23T02:32:08.000Zdailyhttps://bitcoindevkit.org/blog/2021/01/fee-estimation-for-light-clients-part-1/2024-06-23T02:32:08.000Zdailyhttps://bitcoindevkit.org/blog/2021/11/first-bdk-taproot-tx-look-at-the-code-part-1/2024-06-23T02:32:08.000Zdailyhttps://bitcoindevkit.org/blog/2021/12/first-bdk-taproot-tx-look-at-the-code-part-2/2024-06-23T02:32:08.000Zdailyhttps://bitcoindevkit.org/blog/getting-started-with-rust-hwi/2024-06-23T02:32:08.000Zdailyhttps://bitcoindevkit.org/blog/2021/01/fee-estimation-for-light-clients-part-3/2024-06-23T02:32:08.000Zdailyhttps://bitcoindevkit.org/blog/2020/12/hello-world/2024-06-23T02:32:08.000Zdailyhttps://bitcoindevkit.org/blog/hidden-power-of-bitcoin/2024-06-23T02:32:08.000Zdailyhttps://bitcoindevkit.org/blog/improving-coin-selection-in-bdk/2024-06-23T02:32:08.000Zdailyhttps://bitcoindevkit.org/blog/miniscript-vulnerability/2024-06-23T02:32:08.000Zdailyhttps://bitcoindevkit.org/blog/2020/12/release-v0.2.0/2024-06-23T02:32:08.000Zdailyhttps://bitcoindevkit.org/blog/2021/01/release-v0.3.0/2024-06-23T02:32:08.000Zdailyhttps://bitcoindevkit.org/blog/2021/04/release-v0.6.0/2024-06-23T02:32:08.000Zdailyhttps://bitcoindevkit.org/blog/2021/03/release-v0.5.0/2024-06-23T02:32:08.000Zdailyhttps://bitcoindevkit.org/blog/2021/02/release-v0.4.0/2024-06-23T02:32:08.000Zdailyhttps://bitcoindevkit.org/blog/2021/05/release-v0.7.0/2024-06-23T02:32:08.000Zdailyhttps://bitcoindevkit.org/blog/2021/06/release-v0.8.0/2024-06-23T02:32:08.000Zdailyhttps://bitcoindevkit.org/blog/2021/01/fee-estimation-for-light-clients-part-2/2024-06-23T02:32:08.000Zdailyhttps://bitcoindevkit.org/blog/2021/07/release-v0.9.0/2024-06-23T02:32:08.000Zdailyhttps://bitcoindevkit.org/blog/road-to-bdk-1/2024-06-23T02:32:08.000Zdailyhttps://bitcoindevkit.org/blog/why-bindings/2024-06-23T02:32:08.000Zdailyhttps://bitcoindevkit.org/blog/spending-policy-demo/2024-06-23T02:32:08.000Zdailyhttps://bitcoindevkit.org/blog/using-bdk-with-hardware-wallets/2024-06-23T02:32:08.000Zdailyhttps://bitcoindevkit.org/adoption/all/2024-06-23T02:32:08.000Zdailyhttps://bitcoindevkit.org/adoption/custodial/2024-06-23T02:32:08.000Zdailyhttps://bitcoindevkit.org/adoption/desktop/2024-06-23T02:32:08.000Zdailyhttps://bitcoindevkit.org/adoption/exchange/2024-06-23T02:32:08.000Zdailyhttps://bitcoindevkit.org/adoption/infrastructure/2024-06-23T02:32:08.000Zdailyhttps://bitcoindevkit.org/adoption/mobile/2024-06-23T02:32:08.000Zdailyhttps://bitcoindevkit.org/adoption/hardware/2024-06-23T02:32:08.000Zdailyhttps://bitcoindevkit.org/bdk-cli/concept/2024-06-23T02:32:08.000Zdailyhttps://bitcoindevkit.org/adoption/web/2024-06-23T02:32:08.000Zdailyhttps://bitcoindevkit.org/bdk-cli/compiler/2024-06-23T02:32:08.000Zdailyhttps://bitcoindevkit.org/bdk-cli/interface/2024-06-23T02:32:08.000Zdailyhttps://bitcoindevkit.org/bdk-cli/installation/2024-06-23T02:32:08.000Zdailyhttps://bitcoindevkit.org/bdk-cli/introduction/2024-06-23T02:32:08.000Zdailyhttps://bitcoindevkit.org/bdk-cli/playground/2024-06-23T02:32:08.000Zdailyhttps://bitcoindevkit.org/bdk-cli/regtest/2024-06-23T02:32:08.000Zdailyhttps://bitcoindevkit.org/case-studies/2024-06-23T02:32:08.000Zdailyhttps://bitcoindevkit.org/descriptors/2024-06-23T02:32:08.000Zdailyhttps://bitcoindevkit.org/examples/2024-06-23T02:32:08.000Zdailyhttps://bitcoindevkit.org/foundation/about/2024-06-23T02:32:08.000Zdailyhttps://bitcoindevkit.org/foundation/grantees/2024-06-23T02:32:08.000Zdailyhttps://bitcoindevkit.org/foundation/grants/2024-06-23T02:32:08.000Zdailyhttps://bitcoindevkit.org/foundation/2024-06-23T02:32:08.000Zdailyhttps://bitcoindevkit.org/foundation/supporters/2024-06-23T02:32:08.000Zdailyhttps://bitcoindevkit.org/getting-started/2024-06-23T02:32:08.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/Bitcoin%20Core/dailyhttps://bitcoindevkit.org/blog/tags/RPC/dailyhttps://bitcoindevkit.org/blog/tags/Wallet/dailyhttps://bitcoindevkit.org/blog/tags/architecture/dailyhttps://bitcoindevkit.org/blog/tags/tor/dailyhttps://bitcoindevkit.org/blog/tags/wallet/dailyhttps://bitcoindevkit.org/blog/tags/blockchain/dailyhttps://bitcoindevkit.org/blog/tags/BDK-RN/dailyhttps://bitcoindevkit.org/blog/tags/Development/dailyhttps://bitcoindevkit.org/blog/tags/Architecture/dailyhttps://bitcoindevkit.org/blog/tags/bindings/dailyhttps://bitcoindevkit.org/blog/tags/bitcoin/dailyhttps://bitcoindevkit.org/blog/tags/React%20Native/dailyhttps://bitcoindevkit.org/blog/tags/iOS/dailyhttps://bitcoindevkit.org/blog/tags/Android/dailyhttps://bitcoindevkit.org/blog/tags/mobile/dailyhttps://bitcoindevkit.org/blog/tags/bdk-rn/dailyhttps://bitcoindevkit.org/blog/tags/bdk/dailyhttps://bitcoindevkit.org/blog/tags/guide/dailyhttps://bitcoindevkit.org/blog/tags/descriptor/dailyhttps://bitcoindevkit.org/blog/tags/paper%20wallets/dailyhttps://bitcoindevkit.org/blog/tags/Flutter/dailyhttps://bitcoindevkit.org/blog/tags/compact_filters/dailyhttps://bitcoindevkit.org/blog/tags/BIP157/dailyhttps://bitcoindevkit.org/blog/tags/Neutrino/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/waterst0ne/dailyhttps://bitcoindevkit.org/blog/author/Daniela%20Brozzoni/dailyhttps://bitcoindevkit.org/blog/author/Rajarshi%20Maitra/dailyhttps://bitcoindevkit.org/blog/author/Lloyd%20Fournier/dailyhttps://bitcoindevkit.org/blog/author/rorp/dailyhttps://bitcoindevkit.org/blog/author/Bitcoin%20Zavior/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