From: github-actions Date: Wed, 14 Dec 2022 19:32:02 +0000 (+0000) Subject: Publish autogenerated nightly docs X-Git-Url: http://internal-gitweb-vhost/script/%22https:/database/scripts/trait.EncodeBytes.html?a=commitdiff_plain;h=fb023f363f0cff20328e6c032461a188d8857c54;p=bitcoindevkit.org Publish autogenerated nightly docs --- diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/COPYRIGHT.txt b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/COPYRIGHT.txt deleted file mode 100644 index c2629a83f7..0000000000 --- a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/COPYRIGHT.txt +++ /dev/null @@ -1,50 +0,0 @@ -These documentation pages include resources by third parties. This copyright -file applies only to those resources. The following third party resources are -included, and carry their own copyright notices and license terms: - -* Fira Sans (FiraSans-Regular.woff2, FiraSans-Medium.woff2, - FiraSans-Regular.woff, FiraSans-Medium.woff): - - Copyright (c) 2014, Mozilla Foundation https://mozilla.org/ - with Reserved Font Name Fira Sans. - - Copyright (c) 2014, Telefonica S.A. - - Licensed under the SIL Open Font License, Version 1.1. - See FiraSans-LICENSE.txt. - -* rustdoc.css, main.js, and playpen.js: - - Copyright 2015 The Rust Developers. - Licensed under the Apache License, Version 2.0 (see LICENSE-APACHE.txt) or - the MIT license (LICENSE-MIT.txt) at your option. - -* normalize.css: - - Copyright (c) Nicolas Gallagher and Jonathan Neal. - Licensed under the MIT license (see LICENSE-MIT.txt). - -* Source Code Pro (SourceCodePro-Regular.ttf.woff2, - SourceCodePro-Semibold.ttf.woff2, SourceCodePro-It.ttf.woff2, - SourceCodePro-Regular.ttf.woff, SourceCodePro-Semibold.ttf.woff, - SourceCodePro-It.ttf.woff): - - Copyright 2010, 2012 Adobe Systems Incorporated (http://www.adobe.com/), - with Reserved Font Name 'Source'. All Rights Reserved. Source is a trademark - of Adobe Systems Incorporated in the United States and/or other countries. - - Licensed under the SIL Open Font License, Version 1.1. - See SourceCodePro-LICENSE.txt. - -* Source Serif 4 (SourceSerif4-Regular.ttf.woff2, SourceSerif4-Bold.ttf.woff2, - SourceSerif4-It.ttf.woff2, SourceSerif4-Regular.ttf.woff, - SourceSerif4-Bold.ttf.woff, SourceSerif4-It.ttf.woff): - - Copyright 2014-2021 Adobe (http://www.adobe.com/), with Reserved Font Name - 'Source'. All Rights Reserved. Source is a trademark of Adobe in the United - States and/or other countries. - - Licensed under the SIL Open Font License, Version 1.1. - See SourceSerif4-LICENSE.md. - -This copyright file is intended to be distributed with rustdoc output. diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/FiraSans-LICENSE.txt b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/FiraSans-LICENSE.txt deleted file mode 100644 index ff9afab064..0000000000 --- a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/FiraSans-LICENSE.txt +++ /dev/null @@ -1,94 +0,0 @@ -Digitized data copyright (c) 2012-2015, The Mozilla Foundation and Telefonica S.A. -with Reserved Font Name < Fira >, - -This Font Software is licensed under the SIL Open Font License, Version 1.1. -This license is copied below, and is also available with a FAQ at: -http://scripts.sil.org/OFL - - ------------------------------------------------------------ -SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007 ------------------------------------------------------------ - -PREAMBLE -The goals of the Open Font License (OFL) are to stimulate worldwide -development of collaborative font projects, to support the font creation -efforts of academic and linguistic communities, and to provide a free and -open framework in which fonts may be shared and improved in partnership -with others. - -The OFL allows the licensed fonts to be used, studied, modified and -redistributed freely as long as they are not sold by themselves. The -fonts, including any derivative works, can be bundled, embedded, -redistributed and/or sold with any software provided that any reserved -names are not used by derivative works. The fonts and derivatives, -however, cannot be released under any other type of license. The -requirement for fonts to remain under this license does not apply -to any document created using the fonts or their derivatives. - -DEFINITIONS -"Font Software" refers to the set of files released by the Copyright -Holder(s) under this license and clearly marked as such. This may -include source files, build scripts and documentation. - -"Reserved Font Name" refers to any names specified as such after the -copyright statement(s). - -"Original Version" refers to the collection of Font Software components as -distributed by the Copyright Holder(s). - -"Modified Version" refers to any derivative made by adding to, deleting, -or substituting -- in part or in whole -- any of the components of the -Original Version, by changing formats or by porting the Font Software to a -new environment. - -"Author" refers to any designer, engineer, programmer, technical -writer or other person who contributed to the Font Software. - -PERMISSION & CONDITIONS -Permission is hereby granted, free of charge, to any person obtaining -a copy of the Font Software, to use, study, copy, merge, embed, modify, -redistribute, and sell modified and unmodified copies of the Font -Software, subject to the following conditions: - -1) Neither the Font Software nor any of its individual components, -in Original or Modified Versions, may be sold by itself. - -2) Original or Modified Versions of the Font Software may be bundled, -redistributed and/or sold with any software, provided that each copy -contains the above copyright notice and this license. These can be -included either as stand-alone text files, human-readable headers or -in the appropriate machine-readable metadata fields within text or -binary files as long as those fields can be easily viewed by the user. - -3) No Modified Version of the Font Software may use the Reserved Font -Name(s) unless explicit written permission is granted by the corresponding -Copyright Holder. This restriction only applies to the primary font name as -presented to the users. - -4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font -Software shall not be used to promote, endorse or advertise any -Modified Version, except to acknowledge the contribution(s) of the -Copyright Holder(s) and the Author(s) or with their explicit written -permission. - -5) The Font Software, modified or unmodified, in part or in whole, -must be distributed entirely under this license, and must not be -distributed under any other license. The requirement for fonts to -remain under this license does not apply to any document created -using the Font Software. - -TERMINATION -This license becomes null and void if any of the above conditions are -not met. - -DISCLAIMER -THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT -OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE -COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, -INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL -DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM -OTHER DEALINGS IN THE FONT SOFTWARE. diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/FiraSans-Medium.woff b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/FiraSans-Medium.woff deleted file mode 100644 index 7d742c5fb7..0000000000 Binary files a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/FiraSans-Medium.woff and /dev/null differ diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/FiraSans-Medium.woff2 b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/FiraSans-Medium.woff2 deleted file mode 100644 index 7a1e5fc548..0000000000 Binary files a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/FiraSans-Medium.woff2 and /dev/null differ diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/FiraSans-Regular.woff b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/FiraSans-Regular.woff deleted file mode 100644 index d8e0363f4e..0000000000 Binary files a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/FiraSans-Regular.woff and /dev/null differ diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/FiraSans-Regular.woff2 b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/FiraSans-Regular.woff2 deleted file mode 100644 index e766e06ccb..0000000000 Binary files a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/FiraSans-Regular.woff2 and /dev/null differ diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/LICENSE-APACHE.txt b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/LICENSE-APACHE.txt deleted file mode 100644 index 16fe87b06e..0000000000 --- a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/LICENSE-APACHE.txt +++ /dev/null @@ -1,201 +0,0 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - -TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - -1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - -2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - -3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - -4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - -5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - -6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - -7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - -8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - -9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - -END OF TERMS AND CONDITIONS - -APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - -Copyright [yyyy] [name of copyright owner] - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/LICENSE-MIT.txt b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/LICENSE-MIT.txt deleted file mode 100644 index 31aa79387f..0000000000 --- a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/LICENSE-MIT.txt +++ /dev/null @@ -1,23 +0,0 @@ -Permission is hereby granted, free of charge, to any -person obtaining a copy of this software and associated -documentation files (the "Software"), to deal in the -Software without restriction, including without -limitation the rights to use, copy, modify, merge, -publish, distribute, sublicense, and/or sell copies of -the Software, and to permit persons to whom the Software -is furnished to do so, subject to the following -conditions: - -The above copyright notice and this permission notice -shall be included in all copies or substantial portions -of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF -ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED -TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A -PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT -SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY -CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR -IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -DEALINGS IN THE SOFTWARE. diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/NanumBarunGothic-LICENSE.txt b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/NanumBarunGothic-LICENSE.txt deleted file mode 100644 index 0bf46682b5..0000000000 --- a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/NanumBarunGothic-LICENSE.txt +++ /dev/null @@ -1,99 +0,0 @@ -Copyright (c) 2010, NAVER Corporation (https://www.navercorp.com/), - -with Reserved Font Name Nanum, Naver Nanum, NanumGothic, Naver NanumGothic, -NanumMyeongjo, Naver NanumMyeongjo, NanumBrush, Naver NanumBrush, NanumPen, -Naver NanumPen, Naver NanumGothicEco, NanumGothicEco, Naver NanumMyeongjoEco, -NanumMyeongjoEco, Naver NanumGothicLight, NanumGothicLight, NanumBarunGothic, -Naver NanumBarunGothic, NanumSquareRound, NanumBarunPen, MaruBuri - -This Font Software is licensed under the SIL Open Font License, Version 1.1. -This license is copied below, and is also available with a FAQ at: -http://scripts.sil.org/OFL - - ------------------------------------------------------------ -SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007 ------------------------------------------------------------ - -PREAMBLE -The goals of the Open Font License (OFL) are to stimulate worldwide -development of collaborative font projects, to support the font creation -efforts of academic and linguistic communities, and to provide a free and -open framework in which fonts may be shared and improved in partnership -with others. - -The OFL allows the licensed fonts to be used, studied, modified and -redistributed freely as long as they are not sold by themselves. The -fonts, including any derivative works, can be bundled, embedded, -redistributed and/or sold with any software provided that any reserved -names are not used by derivative works. The fonts and derivatives, -however, cannot be released under any other type of license. The -requirement for fonts to remain under this license does not apply -to any document created using the fonts or their derivatives. - -DEFINITIONS -"Font Software" refers to the set of files released by the Copyright -Holder(s) under this license and clearly marked as such. This may -include source files, build scripts and documentation. - -"Reserved Font Name" refers to any names specified as such after the -copyright statement(s). - -"Original Version" refers to the collection of Font Software components as -distributed by the Copyright Holder(s). - -"Modified Version" refers to any derivative made by adding to, deleting, -or substituting -- in part or in whole -- any of the components of the -Original Version, by changing formats or by porting the Font Software to a -new environment. - -"Author" refers to any designer, engineer, programmer, technical -writer or other person who contributed to the Font Software. - -PERMISSION & CONDITIONS -Permission is hereby granted, free of charge, to any person obtaining -a copy of the Font Software, to use, study, copy, merge, embed, modify, -redistribute, and sell modified and unmodified copies of the Font -Software, subject to the following conditions: - -1) Neither the Font Software nor any of its individual components, -in Original or Modified Versions, may be sold by itself. - -2) Original or Modified Versions of the Font Software may be bundled, -redistributed and/or sold with any software, provided that each copy -contains the above copyright notice and this license. These can be -included either as stand-alone text files, human-readable headers or -in the appropriate machine-readable metadata fields within text or -binary files as long as those fields can be easily viewed by the user. - -3) No Modified Version of the Font Software may use the Reserved Font -Name(s) unless explicit written permission is granted by the corresponding -Copyright Holder. This restriction only applies to the primary font name as -presented to the users. - -4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font -Software shall not be used to promote, endorse or advertise any -Modified Version, except to acknowledge the contribution(s) of the -Copyright Holder(s) and the Author(s) or with their explicit written -permission. - -5) The Font Software, modified or unmodified, in part or in whole, -must be distributed entirely under this license, and must not be -distributed under any other license. The requirement for fonts to -remain under this license does not apply to any document created -using the Font Software. - -TERMINATION -This license becomes null and void if any of the above conditions are -not met. - -DISCLAIMER -THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT -OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE -COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, -INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL -DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM -OTHER DEALINGS IN THE FONT SOFTWARE. diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/NanumBarunGothic.ttf.woff b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/NanumBarunGothic.ttf.woff deleted file mode 100644 index fb063e8fb7..0000000000 Binary files a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/NanumBarunGothic.ttf.woff and /dev/null differ diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/NanumBarunGothic.ttf.woff2 b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/NanumBarunGothic.ttf.woff2 deleted file mode 100644 index 1866ad4bce..0000000000 Binary files a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/NanumBarunGothic.ttf.woff2 and /dev/null differ diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/SourceCodePro-It.ttf.woff b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/SourceCodePro-It.ttf.woff deleted file mode 100644 index 8d68f2febd..0000000000 Binary files a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/SourceCodePro-It.ttf.woff and /dev/null differ diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/SourceCodePro-It.ttf.woff2 b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/SourceCodePro-It.ttf.woff2 deleted file mode 100644 index 462c34efcd..0000000000 Binary files a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/SourceCodePro-It.ttf.woff2 and /dev/null differ diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/SourceCodePro-LICENSE.txt b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/SourceCodePro-LICENSE.txt deleted file mode 100644 index 07542572e3..0000000000 --- a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/SourceCodePro-LICENSE.txt +++ /dev/null @@ -1,93 +0,0 @@ -Copyright 2010, 2012 Adobe Systems Incorporated (http://www.adobe.com/), with Reserved Font Name 'Source'. All Rights Reserved. Source is a trademark of Adobe Systems Incorporated in the United States and/or other countries. - -This Font Software is licensed under the SIL Open Font License, Version 1.1. - -This license is copied below, and is also available with a FAQ at: http://scripts.sil.org/OFL - - ------------------------------------------------------------ -SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007 ------------------------------------------------------------ - -PREAMBLE -The goals of the Open Font License (OFL) are to stimulate worldwide -development of collaborative font projects, to support the font creation -efforts of academic and linguistic communities, and to provide a free and -open framework in which fonts may be shared and improved in partnership -with others. - -The OFL allows the licensed fonts to be used, studied, modified and -redistributed freely as long as they are not sold by themselves. The -fonts, including any derivative works, can be bundled, embedded, -redistributed and/or sold with any software provided that any reserved -names are not used by derivative works. The fonts and derivatives, -however, cannot be released under any other type of license. The -requirement for fonts to remain under this license does not apply -to any document created using the fonts or their derivatives. - -DEFINITIONS -"Font Software" refers to the set of files released by the Copyright -Holder(s) under this license and clearly marked as such. This may -include source files, build scripts and documentation. - -"Reserved Font Name" refers to any names specified as such after the -copyright statement(s). - -"Original Version" refers to the collection of Font Software components as -distributed by the Copyright Holder(s). - -"Modified Version" refers to any derivative made by adding to, deleting, -or substituting -- in part or in whole -- any of the components of the -Original Version, by changing formats or by porting the Font Software to a -new environment. - -"Author" refers to any designer, engineer, programmer, technical -writer or other person who contributed to the Font Software. - -PERMISSION & CONDITIONS -Permission is hereby granted, free of charge, to any person obtaining -a copy of the Font Software, to use, study, copy, merge, embed, modify, -redistribute, and sell modified and unmodified copies of the Font -Software, subject to the following conditions: - -1) Neither the Font Software nor any of its individual components, -in Original or Modified Versions, may be sold by itself. - -2) Original or Modified Versions of the Font Software may be bundled, -redistributed and/or sold with any software, provided that each copy -contains the above copyright notice and this license. These can be -included either as stand-alone text files, human-readable headers or -in the appropriate machine-readable metadata fields within text or -binary files as long as those fields can be easily viewed by the user. - -3) No Modified Version of the Font Software may use the Reserved Font -Name(s) unless explicit written permission is granted by the corresponding -Copyright Holder. This restriction only applies to the primary font name as -presented to the users. - -4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font -Software shall not be used to promote, endorse or advertise any -Modified Version, except to acknowledge the contribution(s) of the -Copyright Holder(s) and the Author(s) or with their explicit written -permission. - -5) The Font Software, modified or unmodified, in part or in whole, -must be distributed entirely under this license, and must not be -distributed under any other license. The requirement for fonts to -remain under this license does not apply to any document created -using the Font Software. - -TERMINATION -This license becomes null and void if any of the above conditions are -not met. - -DISCLAIMER -THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT -OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE -COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, -INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL -DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM -OTHER DEALINGS IN THE FONT SOFTWARE. diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/SourceCodePro-Regular.ttf.woff b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/SourceCodePro-Regular.ttf.woff deleted file mode 100644 index 7be076e1fc..0000000000 Binary files a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/SourceCodePro-Regular.ttf.woff and /dev/null differ diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/SourceCodePro-Regular.ttf.woff2 b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/SourceCodePro-Regular.ttf.woff2 deleted file mode 100644 index 10b558e0b6..0000000000 Binary files a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/SourceCodePro-Regular.ttf.woff2 and /dev/null differ diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/SourceCodePro-Semibold.ttf.woff b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/SourceCodePro-Semibold.ttf.woff deleted file mode 100644 index 61bc67b802..0000000000 Binary files a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/SourceCodePro-Semibold.ttf.woff and /dev/null differ diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/SourceCodePro-Semibold.ttf.woff2 b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/SourceCodePro-Semibold.ttf.woff2 deleted file mode 100644 index 5ec64eef0e..0000000000 Binary files a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/SourceCodePro-Semibold.ttf.woff2 and /dev/null differ diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/SourceSerif4-Bold.ttf.woff b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/SourceSerif4-Bold.ttf.woff deleted file mode 100644 index 8ad41888e6..0000000000 Binary files a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/SourceSerif4-Bold.ttf.woff and /dev/null differ diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/SourceSerif4-Bold.ttf.woff2 b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/SourceSerif4-Bold.ttf.woff2 deleted file mode 100644 index db57d21455..0000000000 Binary files a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/SourceSerif4-Bold.ttf.woff2 and /dev/null differ diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/SourceSerif4-It.ttf.woff b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/SourceSerif4-It.ttf.woff deleted file mode 100644 index 2a34b5c42a..0000000000 Binary files a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/SourceSerif4-It.ttf.woff and /dev/null differ diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/SourceSerif4-It.ttf.woff2 b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/SourceSerif4-It.ttf.woff2 deleted file mode 100644 index 1cbc021a3a..0000000000 Binary files a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/SourceSerif4-It.ttf.woff2 and /dev/null differ diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/SourceSerif4-LICENSE.md b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/SourceSerif4-LICENSE.md deleted file mode 100644 index 68ea189240..0000000000 --- a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/SourceSerif4-LICENSE.md +++ /dev/null @@ -1,93 +0,0 @@ -Copyright 2014-2021 Adobe (http://www.adobe.com/), with Reserved Font Name 'Source'. All Rights Reserved. Source is a trademark of Adobe in the United States and/or other countries. - -This Font Software is licensed under the SIL Open Font License, Version 1.1. - -This license is copied below, and is also available with a FAQ at: http://scripts.sil.org/OFL - - ------------------------------------------------------------ -SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007 ------------------------------------------------------------ - -PREAMBLE -The goals of the Open Font License (OFL) are to stimulate worldwide -development of collaborative font projects, to support the font creation -efforts of academic and linguistic communities, and to provide a free and -open framework in which fonts may be shared and improved in partnership -with others. - -The OFL allows the licensed fonts to be used, studied, modified and -redistributed freely as long as they are not sold by themselves. The -fonts, including any derivative works, can be bundled, embedded, -redistributed and/or sold with any software provided that any reserved -names are not used by derivative works. The fonts and derivatives, -however, cannot be released under any other type of license. The -requirement for fonts to remain under this license does not apply -to any document created using the fonts or their derivatives. - -DEFINITIONS -"Font Software" refers to the set of files released by the Copyright -Holder(s) under this license and clearly marked as such. This may -include source files, build scripts and documentation. - -"Reserved Font Name" refers to any names specified as such after the -copyright statement(s). - -"Original Version" refers to the collection of Font Software components as -distributed by the Copyright Holder(s). - -"Modified Version" refers to any derivative made by adding to, deleting, -or substituting -- in part or in whole -- any of the components of the -Original Version, by changing formats or by porting the Font Software to a -new environment. - -"Author" refers to any designer, engineer, programmer, technical -writer or other person who contributed to the Font Software. - -PERMISSION & CONDITIONS -Permission is hereby granted, free of charge, to any person obtaining -a copy of the Font Software, to use, study, copy, merge, embed, modify, -redistribute, and sell modified and unmodified copies of the Font -Software, subject to the following conditions: - -1) Neither the Font Software nor any of its individual components, -in Original or Modified Versions, may be sold by itself. - -2) Original or Modified Versions of the Font Software may be bundled, -redistributed and/or sold with any software, provided that each copy -contains the above copyright notice and this license. These can be -included either as stand-alone text files, human-readable headers or -in the appropriate machine-readable metadata fields within text or -binary files as long as those fields can be easily viewed by the user. - -3) No Modified Version of the Font Software may use the Reserved Font -Name(s) unless explicit written permission is granted by the corresponding -Copyright Holder. This restriction only applies to the primary font name as -presented to the users. - -4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font -Software shall not be used to promote, endorse or advertise any -Modified Version, except to acknowledge the contribution(s) of the -Copyright Holder(s) and the Author(s) or with their explicit written -permission. - -5) The Font Software, modified or unmodified, in part or in whole, -must be distributed entirely under this license, and must not be -distributed under any other license. The requirement for fonts to -remain under this license does not apply to any document created -using the Font Software. - -TERMINATION -This license becomes null and void if any of the above conditions are -not met. - -DISCLAIMER -THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT -OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE -COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, -INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL -DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM -OTHER DEALINGS IN THE FONT SOFTWARE. diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/SourceSerif4-Regular.ttf.woff b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/SourceSerif4-Regular.ttf.woff deleted file mode 100644 index 45a5521ab0..0000000000 Binary files a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/SourceSerif4-Regular.ttf.woff and /dev/null differ diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/SourceSerif4-Regular.ttf.woff2 b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/SourceSerif4-Regular.ttf.woff2 deleted file mode 100644 index 2db73fe2b4..0000000000 Binary files a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/SourceSerif4-Regular.ttf.woff2 and /dev/null differ diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/ayu.css b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/ayu.css deleted file mode 100644 index d31f43f1a1..0000000000 --- a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/ayu.css +++ /dev/null @@ -1 +0,0 @@ - body{background-color:#0f1419;color:#c5c5c5;}h1,h2,h3,h4{color:white;}h1.fqn{border-bottom-color:#5c6773;}h1.fqn a{color:#fff;}h2,h3,h4{border-bottom-color:#5c6773;}h4{border:none;}.in-band{background-color:#0f1419;}.invisible{background:rgba(0,0,0,0);}.docblock code{color:#ffb454;}.code-header{color:#e6e1cf;}.docblock pre>code,pre>code{color:#e6e1cf;}span code{color:#e6e1cf;}.docblock a>code{color:#39AFD7 !important;}.docblock code,.docblock-short code{background-color:#191f26;}pre,.rustdoc.source .example-wrap{color:#e6e1cf;background-color:#191f26;}.sidebar,.mobile-topbar,.sidebar-menu-toggle{background-color:#14191f;}.rust-logo{filter:drop-shadow(1px 0 0px #fff) drop-shadow(0 1px 0 #fff) drop-shadow(-1px 0 0 #fff) drop-shadow(0 -1px 0 #fff);}*{scrollbar-color:#5c6773 #24292f;}.sidebar{scrollbar-color:#5c6773 #24292f;}::-webkit-scrollbar-track{background-color:transparent;}::-webkit-scrollbar-thumb{background-color:#5c6773;}.sidebar::-webkit-scrollbar-track{background-color:transparent;}.sidebar::-webkit-scrollbar-thumb{background-color:#5c6773;}.sidebar .current{background-color:transparent;color:#ffb44c;}.source .sidebar{background-color:#14191f;}.sidebar-elems .location{color:#ff7733;}.sidebar-elems .location a{color:#fff;}.block a:hover{background:transparent;color:#ffb44c;}.line-numbers span{color:#5c6773;}.line-numbers .line-highlighted{color:#708090;background-color:rgba(255,236,164,0.06);padding-right:4px;border-right:1px solid #ffb44c;}.docblock h1,.docblock h2,.docblock h3,.docblock h4,.docblock h5,.docblock h6{border-bottom-color:#5c6773;}.docblock table td,.docblock table th{border-color:#5c6773;}.content .method .where,.content .fn .where,.content .where.fmt-newline{color:#c5c5c5;}.search-results a:hover{background-color:#777;}.search-results a:focus{color:#000 !important;background-color:#c6afb3;}.search-results a{color:#0096cf;}.search-results a div.desc{color:#c5c5c5;}.content .item-info::before{color:#ccc;}.content span.foreigntype,.content a.foreigntype{color:#ffa0a5;}.content span.union,.content a.union{color:#ffa0a5;}.content span.constant,.content a.constant,.content span.static,.content a.static{color:#39AFD7;}.content span.primitive,.content a.primitive{color:#ffa0a5;}.content span.traitalias,.content a.traitalias{color:#39AFD7;}.content span.keyword,.content a.keyword{color:#39AFD7;}.content span.externcrate,.content span.mod,.content a.mod{color:#39AFD7;}.content span.struct,.content a.struct{color:#ffa0a5;}.content span.enum,.content a.enum{color:#ffa0a5;}.content span.trait,.content a.trait{color:#39AFD7;}.content span.type,.content a.type{color:#39AFD7;}.content span.type,.content a.type,.block a.current.type{color:#39AFD7;}.content span.associatedtype,.content a.associatedtype,.block a.current.associatedtype{color:#39AFD7;}.content span.fn,.content a.fn,.content span.method,.content a.method,.content span.tymethod,.content a.tymethod,.content .fnname{color:#fdd687;}.content span.attr,.content a.attr,.content span.derive,.content a.derive,.content span.macro,.content a.macro{color:#a37acc;}.sidebar a{color:#53b1db;}.sidebar a.current.type{color:#53b1db;}.sidebar a.current.associatedtype{color:#53b1db;}pre.rust .comment{color:#788797;}pre.rust .doccomment{color:#a1ac88;}nav.main .current{border-top-color:#5c6773;border-bottom-color:#5c6773;}nav.main .separator{border:1px solid #5c6773;}a{color:#39AFD7;}a#toggle-all-docs,a.anchor,.small-section-header a,#source-sidebar a,pre.rust a,.sidebar h2 a,.sidebar h3 a,.in-band a{color:#c5c5c5;}.search-results a{color:#0096cf;}body.source .example-wrap pre.rust a{background:#333;}details.rustdoc-toggle>summary.hideme>span,details.rustdoc-toggle>summary::before,details.undocumented>summary::before{color:#999;}details.rustdoc-toggle>summary::before,details.undocumented>summary::before{filter:invert(100%);}#crate-search,.search-input{background-color:#141920;border-color:#424c57;color:#c5c5c5;}.search-input{color:#ffffff;}.module-item .stab,.import-item .stab{color:#000;}.stab.unstable,.stab.deprecated,.stab.portability{color:#c5c5c5;background:#314559 !important;border-style:none !important;border-radius:4px;padding:3px 6px 3px 6px;}.stab.portability>code{color:#e6e1cf;background:none;}#help>div{background:#14191f;box-shadow:0px 6px 20px 0px black;border:none;border-radius:4px;}#help span.bottom,#help span.top{border-color:#5c6773;}.rightside,.out-of-band{color:grey;}.result-name .primitive>i,.result-name .keyword>i{color:#788797;}.line-numbers :target{background-color:transparent;}pre.rust .number,pre.rust .string{color:#b8cc52;}pre.rust .kw,pre.rust .kw-2,pre.rust .prelude-ty,pre.rust .bool-val,pre.rust .prelude-val,pre.rust .op,pre.rust .lifetime{color:#ff7733;}pre.rust .macro,pre.rust .macro-nonterminal{color:#a37acc;}pre.rust .question-mark{color:#ff9011;}pre.rust .self{color:#36a3d9;font-style:italic;}pre.rust .attribute{color:#e6e1cf;}pre.rust .attribute .ident,pre.rust .attribute .op{color:#e6e1cf;}.example-wrap>pre.line-number{color:#5c67736e;border:none;}a.test-arrow{font-size:100%;color:#788797;border-radius:4px;background-color:rgba(57,175,215,0.09);}a.test-arrow:hover{background-color:rgba(57,175,215,0.368);color:#c5c5c5;}.toggle-label,.code-attribute{color:#999;}:target{background:rgba(255,236,164,0.06);border-right:3px solid rgba(255,180,76,0.85);}pre.compile_fail{border-left:2px solid rgba(255,0,0,.4);}pre.compile_fail:hover,.information:hover+pre.compile_fail{border-left:2px solid #f00;}pre.should_panic{border-left:2px solid rgba(255,0,0,.4);}pre.should_panic:hover,.information:hover+pre.should_panic{border-left:2px solid #f00;}pre.ignore{border-left:2px solid rgba(255,142,0,.6);}pre.ignore:hover,.information:hover+pre.ignore{border-left:2px solid #ff9200;}.tooltip.compile_fail{color:rgba(255,0,0,.5);}.information>.compile_fail:hover{color:#f00;}.tooltip.should_panic{color:rgba(255,0,0,.5);}.information>.should_panic:hover{color:#f00;}.tooltip.ignore{color:rgba(255,142,0,.6);}.information>.ignore:hover{color:#ff9200;}.search-failed a{color:#39AFD7;}.tooltip::after{background-color:#314559;color:#c5c5c5;border:1px solid #5c6773;}.tooltip::before{border-color:transparent #314559 transparent transparent;}.notable-traits-tooltiptext{background-color:#314559;border-color:#5c6773;}.notable-traits-tooltiptext .notable{border-bottom-color:#5c6773;}#titles>button.selected{background-color:#141920 !important;border-bottom:1px solid #ffb44c !important;border-top:none;}#titles>button:not(.selected){background-color:transparent !important;border:none;}#titles>button:hover{border-bottom:1px solid rgba(242,151,24,0.3);}#titles>button>div.count{color:#888;}.search-input:focus{}.content span.attr,.content a.attr,.block a.current.attr,.content span.derive,.content a.derive,.block a.current.derive,.content span.macro,.content a.macro,.block a.current.macro{}.content span.struct,.content a.struct,.block a.current.struct{}#titles>button:hover,#titles>button.selected{}.content span.typedef,.content a.typedef,.block a.current.typedef{}.content span.union,.content a.union,.block a.current.union{}pre.rust .lifetime{}.stab.unstable{}h2,h3:not(.impl):not(.method):not(.type):not(.tymethod),h4:not(.method):not(.type):not(.tymethod){}.content span.enum,.content a.enum,.block a.current.enum{}.content span.constant,.content a.constant,.block a.current.constant,.content span.static,.content a.static,.block a.current.static{}.content span.keyword,.content a.keyword,.block a.current.keyword{}pre.rust .comment{}.content span.traitalias,.content a.traitalias,.block a.current.traitalias{}.content span.fn,.content a.fn,.block a.current.fn,.content span.method,.content a.method,.block a.current.method,.content span.tymethod,.content a.tymethod,.block a.current.tymethod,.content .fnname{}pre.rust .kw{}pre.rust .self,pre.rust .bool-val,pre.rust .prelude-val,pre.rust .attribute,pre.rust .attribute .ident{}.content span.foreigntype,.content a.foreigntype,.block a.current.foreigntype{}pre.rust .doccomment{}.stab.deprecated{}.content a.attr,.content a.derive,.content a.macro{}.stab.portability{}.content span.primitive,.content a.primitive,.block a.current.primitive{}.content span.externcrate,.content span.mod,.content a.mod,.block a.current.mod{}pre.rust .kw-2,pre.rust .prelude-ty{}.content span.trait,.content a.trait,.block a.current.trait{}.search-results a:focus span{}a.result-trait:focus{}a.result-traitalias:focus{}a.result-mod:focus,a.result-externcrate:focus{}a.result-mod:focus{}a.result-externcrate:focus{}a.result-enum:focus{}a.result-struct:focus{}a.result-union:focus{}a.result-fn:focus,a.result-method:focus,a.result-tymethod:focus{}a.result-type:focus{}a.result-associatedtype:focus{}a.result-foreigntype:focus{}a.result-attr:focus,a.result-derive:focus,a.result-macro:focus{}a.result-constant:focus,a.result-static:focus{}a.result-primitive:focus{}a.result-keyword:focus{}.sidebar a.current.enum{}.sidebar a.current.struct{}.sidebar a.current.foreigntype{}.sidebar a.current.attr,.sidebar a.current.derive,.sidebar a.current.macro{}.sidebar a.current.union{}.sidebar a.current.constant .sidebar a.current.static{}.sidebar a.current.primitive{}.sidebar a.current.externcrate .sidebar a.current.mod{}.sidebar a.current.trait{}.sidebar a.current.traitalias{}.sidebar a.current.fn,.sidebar a.current.method,.sidebar a.current.tymethod{}.sidebar a.current.keyword{}@media (max-width:700px){.sidebar-menu{background-color:#14191f;border-bottom-color:#5c6773;border-right-color:#5c6773;}.sidebar-elems{background-color:#14191f;border-right-color:#5c6773;}#sidebar-filler{background-color:#14191f;border-bottom-color:#5c6773;}}kbd{color:#c5c5c5;background-color:#314559;border-color:#5c6773;border-bottom-color:#5c6773;box-shadow-color:#c6cbd1;}#theme-picker,#settings-menu,#help-button{border-color:#5c6773;background-color:#0f1419;color:#fff;}#theme-picker>img,#settings-menu>img{filter:invert(100);}#copy-path{color:#fff;}#copy-path>img{filter:invert(70%);}#copy-path:hover>img{filter:invert(100%);}#theme-picker:hover,#theme-picker:focus,#settings-menu:hover,#settings-menu:focus,#help-button:hover,#help-button:focus{border-color:#e0e0e0;}#theme-choices{border-color:#5c6773;background-color:#0f1419;}#theme-choices>button:not(:first-child){border-top-color:#5c6773;}#theme-choices>button:hover,#theme-choices>button:focus{background-color:rgba(110,110,110,0.33);}@media (max-width:700px){#theme-picker{background:#0f1419;}}.search-results .result-name span.alias{color:#c5c5c5;}.search-results .result-name span.grey{color:#999;}#sidebar-toggle{background-color:#14191f;}#sidebar-toggle:hover{background-color:rgba(70,70,70,0.33);}#source-sidebar{background-color:#14191f;}#source-sidebar>.title{color:#fff;border-bottom-color:#5c6773;}div.files>a:hover,div.name:hover{background-color:#14191f;color:#ffb44c;}div.files>.selected{background-color:#14191f;color:#ffb44c;}.setting-line>.title{border-bottom-color:#5c6773;}input:checked+.slider{background-color:#ffb454 !important;}.scraped-example .example-wrap .rust span.highlight{background:rgb(91,59,1);}.scraped-example .example-wrap .rust span.highlight.focus{background:rgb(124,75,15);}.scraped-example:not(.expanded) .code-wrapper:before{background:linear-gradient(to bottom,rgba(15,20,25,1),rgba(15,20,25,0));}.scraped-example:not(.expanded) .code-wrapper:after{background:linear-gradient(to top,rgba(15,20,25,1),rgba(15,20,25,0));}.toggle-line-inner{background:#616161;}.toggle-line:hover .toggle-line-inner{background:##898989;} \ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/all.html b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/all.html index d9c9e296cd..28de033bbc 100644 --- a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/all.html +++ b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/all.html @@ -1,9 +1,2 @@ -List of all items in this crate - -

List of all items

Structs

Enums

Traits

Macros

Functions

Typedefs

- \ No newline at end of file +List of all items in this crate

List of all items

Structs

Enums

Traits

Macros

Functions

Type Definitions

\ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/blockchain/any/enum.AnyBlockchain.html b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/blockchain/any/enum.AnyBlockchain.html index f7d9965e99..8de2ff7aae 100644 --- a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/blockchain/any/enum.AnyBlockchain.html +++ b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/blockchain/any/enum.AnyBlockchain.html @@ -1,12 +1,5 @@ -AnyBlockchain in bdk::blockchain::any - Rust - -
pub enum AnyBlockchain {
+AnyBlockchain in bdk::blockchain::any - Rust
pub enum AnyBlockchain {
     Electrum(Box<ElectrumBlockchain>),
     Esplora(Box<EsploraBlockchain>),
     CompactFilters(Box<CompactFiltersBlockchain>),
@@ -14,38 +7,12 @@
 }
Expand description

Type that can contain any of the Blockchain types defined by the library

It allows switching backend at runtime

See this module’s documentation for a usage example.

-

Variants

Electrum(Box<ElectrumBlockchain>)

This is supported on crate feature electrum only.

Electrum client

-

Esplora(Box<EsploraBlockchain>)

This is supported on crate feature esplora only.

Esplora client

-

CompactFilters(Box<CompactFiltersBlockchain>)

This is supported on crate feature compact_filters only.

Compact filters client

-

Rpc(Box<RpcBlockchain>)

This is supported on crate feature rpc only.

RPC client

-

Trait Implementations

Return the set of Capability supported by this backend

-

Broadcast a transaction

-

Estimate the fee rate required to confirm a transaction in a given target of blocks

-

Type that contains the configuration

-

Create a new instance given a configuration

-

Performs the conversion.

-

Performs the conversion.

-

Performs the conversion.

-

Performs the conversion.

-

fetch block hash given its height

-

Return the current height

-

Fetch a transaction given its txid

-

If not overridden, it defaults to calling Self::wallet_setup internally. Read more

-

Setup the backend and populate the internal database for the first time Read more

-

Auto Trait Implementations

Blanket Implementations

Gets the TypeId of self. Read more

-

Immutably borrows from an owned value. Read more

-

Mutably borrows from an owned value. Read more

-

Performs the conversion.

-

Performs the conversion.

-

The alignment of pointer.

-

The type for initializers.

-

Initializes a with the given initializer. Read more

-

Dereferences the given pointer. Read more

-

Mutably dereferences the given pointer. Read more

-

Drops the object pointed to by the given pointer. Read more

-

The type returned in the event of a conversion error.

-

Performs the conversion.

-

The type returned in the event of a conversion error.

-

Performs the conversion.

-
- \ No newline at end of file +

Variants§

§

Electrum(Box<ElectrumBlockchain>)

Available on crate feature electrum only.

Electrum client

+
§

Esplora(Box<EsploraBlockchain>)

Available on crate feature esplora only.

Esplora client

+
§

CompactFilters(Box<CompactFiltersBlockchain>)

Available on crate feature compact_filters only.

Compact filters client

+
§

Rpc(Box<RpcBlockchain>)

Available on crate feature rpc only.

RPC client

+

Trait Implementations§

Return the set of Capability supported by this backend
Broadcast a transaction
Estimate the fee rate required to confirm a transaction in a given target of blocks
Type that contains the configuration
Create a new instance given a configuration
Converts to this type from the input type.
Converts to this type from the input type.
Converts to this type from the input type.
Converts to this type from the input type.
fetch block hash given its height
Return the current height
Fetch a transaction given its txid
If not overridden, it defaults to calling Self::wallet_setup internally. Read more
Setup the backend and populate the internal database for the first time Read more

Auto Trait Implementations§

Blanket Implementations§

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

Returns the argument unchanged.

+

Calls U::from(self).

+

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

+
The alignment of pointer.
The type for initializers.
Initializes a with the given initializer. Read more
Dereferences the given pointer. Read more
Mutably dereferences the given pointer. Read more
Drops the object pointed to by the given pointer. Read more
The type returned in the event of a conversion error.
Performs the conversion.
The type returned in the event of a conversion error.
Performs the conversion.
\ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/blockchain/any/enum.AnyBlockchainConfig.html b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/blockchain/any/enum.AnyBlockchainConfig.html index b0814ca547..5512c5f067 100644 --- a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/blockchain/any/enum.AnyBlockchainConfig.html +++ b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/blockchain/any/enum.AnyBlockchainConfig.html @@ -1,12 +1,5 @@ -AnyBlockchainConfig in bdk::blockchain::any - Rust - -
pub enum AnyBlockchainConfig {
+AnyBlockchainConfig in bdk::blockchain::any - Rust
pub enum AnyBlockchainConfig {
     Electrum(ElectrumBlockchainConfig),
     Esplora(EsploraBlockchainConfig),
     CompactFilters(CompactFiltersBlockchainConfig),
@@ -17,8 +10,8 @@ instance. Wallets that plan to offer users the ability to switch blockchain back
 will find this particularly useful.

This type can be serialized from a JSON object like:

-
use bdk::blockchain::{electrum::ElectrumBlockchainConfig, AnyBlockchainConfig};
-let config: AnyBlockchainConfig = serde_json::from_str(
+
use bdk::blockchain::{electrum::ElectrumBlockchainConfig, AnyBlockchainConfig};
+let config: AnyBlockchainConfig = serde_json::from_str(
     r#"{
    "type" : "electrum",
    "url" : "ssl://electrum.blockstream.info:50002",
@@ -26,50 +19,25 @@ will find this particularly useful.

"stop_gap": 20 }"#
, ) -.unwrap(); +.unwrap(); assert_eq!( - config, - AnyBlockchainConfig::Electrum(ElectrumBlockchainConfig { - url: "ssl://electrum.blockstream.info:50002".into(), - retry: 2, - socks5: None, - timeout: None, - stop_gap: 20, + config, + AnyBlockchainConfig::Electrum(ElectrumBlockchainConfig { + url: "ssl://electrum.blockstream.info:50002".into(), + retry: 2, + socks5: None, + timeout: None, + stop_gap: 20, }) );
-

Variants

Electrum(ElectrumBlockchainConfig)

This is supported on crate feature electrum only.

Electrum client

-

Esplora(EsploraBlockchainConfig)

This is supported on crate feature esplora only.

Esplora client

-

CompactFilters(CompactFiltersBlockchainConfig)

This is supported on crate feature compact_filters only.

Compact filters client

-

Rpc(RpcConfig)

This is supported on crate feature rpc only.

RPC client configuration

-

Trait Implementations

Returns a copy of the value. Read more

-

Performs copy-assignment from source. Read more

-

Formats the value using the given formatter. Read more

-

Deserialize this value from the given Serde deserializer. Read more

-

Performs the conversion.

-

Performs the conversion.

-

Performs the conversion.

-

Performs the conversion.

-

This method tests for self and other values to be equal, and is used -by ==. Read more

-

This method tests for !=.

-

Serialize this value into the given Serde serializer. Read more

-

Auto Trait Implementations

Blanket Implementations

Gets the TypeId of self. Read more

-

Immutably borrows from an owned value. Read more

-

Mutably borrows from an owned value. Read more

-

Performs the conversion.

-

Performs the conversion.

-

The alignment of pointer.

-

The type for initializers.

-

Initializes a with the given initializer. Read more

-

Dereferences the given pointer. Read more

-

Mutably dereferences the given pointer. Read more

-

Drops the object pointed to by the given pointer. Read more

-

The resulting type after obtaining ownership.

-

Creates owned data from borrowed data, usually by cloning. Read more

-
🔬 This is a nightly-only experimental API. (toowned_clone_into)

Uses borrowed data to replace owned data, usually by cloning. Read more

-

The type returned in the event of a conversion error.

-

Performs the conversion.

-

The type returned in the event of a conversion error.

-

Performs the conversion.

-
- \ No newline at end of file +

Variants§

§

Electrum(ElectrumBlockchainConfig)

Available on crate feature electrum only.

Electrum client

+
§

Esplora(EsploraBlockchainConfig)

Available on crate feature esplora only.

Esplora client

+
§

CompactFilters(CompactFiltersBlockchainConfig)

Available on crate feature compact_filters only.

Compact filters client

+
§

Rpc(RpcConfig)

Available on crate feature rpc only.

RPC client configuration

+

Trait Implementations§

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

Auto Trait Implementations§

Blanket Implementations§

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

Returns the argument unchanged.

+

Calls U::from(self).

+

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

+
The alignment of pointer.
The type for initializers.
Initializes a with the given initializer. Read more
Dereferences the given pointer. Read more
Mutably dereferences the given pointer. Read more
Drops the object pointed to by the given pointer. Read more
The resulting type after obtaining ownership.
Creates owned data from borrowed data, usually by cloning. Read more
Uses borrowed data to replace owned data, usually by cloning. Read more
The type returned in the event of a conversion error.
Performs the conversion.
The type returned in the event of a conversion error.
Performs the conversion.
\ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/blockchain/any/index.html b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/blockchain/any/index.html index 7e979e273c..1632cf77fa 100644 --- a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/blockchain/any/index.html +++ b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/blockchain/any/index.html @@ -1,23 +1,12 @@ -bdk::blockchain::any - Rust - -
-

Module bdk::blockchain::any

source · []
Expand description

Runtime-checked blockchain types

+bdk::blockchain::any - Rust

Module bdk::blockchain::any

source ·
Expand description

Runtime-checked blockchain types

This module provides the implementation of AnyBlockchain which allows switching the inner Blockchain type at runtime.

-

Example

+

Example

When paired with the use of ConfigurableBlockchain, it allows creating any blockchain type supported using a single line of code:

-
let config = serde_json::from_str("...")?;
-let blockchain = AnyBlockchain::from_config(&config)?;
-let height = blockchain.get_height();
-

Enums

-

Type that can contain any of the Blockchain types defined by the library

-

Type that can contain any of the blockchain configurations defined by the library

-
- \ No newline at end of file +
let config = serde_json::from_str("...")?;
+let blockchain = AnyBlockchain::from_config(&config)?;
+let height = blockchain.get_height();
+

Enums

Type that can contain any of the Blockchain types defined by the library
Type that can contain any of the blockchain configurations defined by the library
\ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/blockchain/any/sidebar-items.js b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/blockchain/any/sidebar-items.js index 14144cf693..a478f31365 100644 --- a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/blockchain/any/sidebar-items.js +++ b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/blockchain/any/sidebar-items.js @@ -1 +1 @@ -initSidebarItems({"enum":[["AnyBlockchain","Type that can contain any of the [`Blockchain`] types defined by the library"],["AnyBlockchainConfig","Type that can contain any of the blockchain configurations defined by the library"]]}); \ No newline at end of file +window.SIDEBAR_ITEMS = {"enum":[["AnyBlockchain","Type that can contain any of the [`Blockchain`] types defined by the library"],["AnyBlockchainConfig","Type that can contain any of the blockchain configurations defined by the library"]]}; \ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/blockchain/compact_filters/enum.CompactFiltersError.html b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/blockchain/compact_filters/enum.CompactFiltersError.html index 5b8b6c39fd..6f17b98720 100644 --- a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/blockchain/compact_filters/enum.CompactFiltersError.html +++ b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/blockchain/compact_filters/enum.CompactFiltersError.html @@ -1,12 +1,5 @@ -CompactFiltersError in bdk::blockchain::compact_filters - Rust - -
pub enum CompactFiltersError {
+CompactFiltersError in bdk::blockchain::compact_filters - Rust
pub enum CompactFiltersError {
 
Show 16 variants InvalidResponse, InvalidHeaders, InvalidFilterHeader, @@ -23,50 +16,26 @@ Bip158(Error), Time(SystemTimeError), Global(Box<Error>), -
}
This is supported on crate feature compact_filters only.
Expand description

An error that can occur during sync with a CompactFiltersBlockchain

-

Variants

InvalidResponse

A peer sent an invalid or unexpected response

-

InvalidHeaders

The headers returned are invalid

-

InvalidFilterHeader

The compact filter headers returned are invalid

-

InvalidFilter

The compact filter returned is invalid

-

MissingBlock

The peer is missing a block in the valid chain

-

BlockHashNotFound

Block hash at specified height not found

-

DataCorruption

The data stored in the block filters storage are corrupted

-

NotConnected

A peer is not connected

-

Timeout

A peer took too long to reply to one of our messages

-

PeerBloomDisabled

The peer doesn’t advertise the BLOOM service flag

-

NoPeers

No peers have been specified

-

Db(Error)

Internal database error

-

Io(Error)

Internal I/O error

-

Bip158(Error)

Invalid BIP158 filter

-

Time(SystemTimeError)

Internal system time error

-

Global(Box<Error>)

Wrapper for crate::error::Error

-

Trait Implementations

Formats the value using the given formatter. Read more

-

Formats the value using the given formatter. Read more

-

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

-
🔬 This is a nightly-only experimental API. (backtrace)

Returns a stack backtrace, if available, of where this error occurred. Read more

-
👎 Deprecated since 1.42.0:

use the Display impl or to_string()

-
👎 Deprecated since 1.33.0:

replaced by Error::source, which can support downcasting

-

Performs the conversion.

-

Performs the conversion.

-

Performs the conversion.

-

Performs the conversion.

-

Performs the conversion.

-

Performs the conversion.

-

Auto Trait Implementations

Blanket Implementations

Gets the TypeId of self. Read more

-

Immutably borrows from an owned value. Read more

-

Mutably borrows from an owned value. Read more

-

Performs the conversion.

-

Performs the conversion.

-

The alignment of pointer.

-

The type for initializers.

-

Initializes a with the given initializer. Read more

-

Dereferences the given pointer. Read more

-

Mutably dereferences the given pointer. Read more

-

Drops the object pointed to by the given pointer. Read more

-

Converts the given value to a String. Read more

-

The type returned in the event of a conversion error.

-

Performs the conversion.

-

The type returned in the event of a conversion error.

-

Performs the conversion.

-
- \ No newline at end of file +}
Available on crate feature compact_filters only.
Expand description

An error that can occur during sync with a CompactFiltersBlockchain

+

Variants§

§

InvalidResponse

A peer sent an invalid or unexpected response

+
§

InvalidHeaders

The headers returned are invalid

+
§

InvalidFilterHeader

The compact filter headers returned are invalid

+
§

InvalidFilter

The compact filter returned is invalid

+
§

MissingBlock

The peer is missing a block in the valid chain

+
§

BlockHashNotFound

Block hash at specified height not found

+
§

DataCorruption

The data stored in the block filters storage are corrupted

+
§

NotConnected

A peer is not connected

+
§

Timeout

A peer took too long to reply to one of our messages

+
§

PeerBloomDisabled

The peer doesn’t advertise the BLOOM service flag

+
§

NoPeers

No peers have been specified

+
§

Db(Error)

Internal database error

+
§

Io(Error)

Internal I/O error

+
§

Bip158(Error)

Invalid BIP158 filter

+
§

Time(SystemTimeError)

Internal system time error

+
§

Global(Box<Error>)

Wrapper for crate::error::Error

+

Trait Implementations§

Formats the value using the given formatter. Read more
Formats the value using the given formatter. Read more
The lower-level source of this error, if any. Read more
👎Deprecated since 1.42.0: use the Display impl or to_string()
👎Deprecated since 1.33.0: replaced by Error::source, which can support downcasting
🔬This is a nightly-only experimental API. (error_generic_member_access)
Provides type based access to context intended for error reports. Read more
Converts to this type from the input type.
Converts to this type from the input type.
Converts to this type from the input type.
Converts to this type from the input type.
Converts to this type from the input type.
Converts to this type from the input type.

Auto Trait Implementations§

Blanket Implementations§

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

Returns the argument unchanged.

+

Calls U::from(self).

+

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

+
The alignment of pointer.
The type for initializers.
Initializes a with the given initializer. Read more
Dereferences the given pointer. Read more
Mutably dereferences the given pointer. Read more
Drops the object pointed to by the given pointer. Read more
🔬This is a nightly-only experimental API. (provide_any)
Data providers should implement this method to provide all values they are able to +provide by using demand. Read more
Converts the given value to a String. Read more
The type returned in the event of a conversion error.
Performs the conversion.
The type returned in the event of a conversion error.
Performs the conversion.
\ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/blockchain/compact_filters/index.html b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/blockchain/compact_filters/index.html index bf60870ba0..b36d1e0e97 100644 --- a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/blockchain/compact_filters/index.html +++ b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/blockchain/compact_filters/index.html @@ -1,12 +1,5 @@ -bdk::blockchain::compact_filters - Rust - -
This is supported on crate feature compact_filters only.
Expand description

Compact Filters

+bdk::blockchain::compact_filters - Rust
Available on crate feature compact_filters only.
Expand description

Compact Filters

This module contains a multithreaded implementation of an Blockchain backend that uses BIP157 (aka “Neutrino”) to populate the wallet’s database by downloading compact filters from the P2P network.

@@ -18,27 +11,18 @@ messages received by different peers. Thus, it’s recommended to use this modul connecting to a single peer at a time, optionally by opening multiple connections if it’s desirable to use multiple threads at once to sync in parallel.

This is an EXPERIMENTAL feature, API and other major changes are expected.

-

Example

-
let num_threads = 4;
+

Example

+
let num_threads = 4;
 
-let mempool = Arc::new(Mempool::default());
-let peers = (0..num_threads)
-    .map(|_| {
-        Peer::connect(
+let mempool = Arc::new(Mempool::default());
+let peers = (0..num_threads)
+    .map(|_| {
+        Peer::connect(
             "btcd-mainnet.lightning.computer:8333",
-            Arc::clone(&mempool),
-            Network::Bitcoin,
+            Arc::clone(&mempool),
+            Network::Bitcoin,
         )
     })
-    .collect::<Result<_, _>>()?;
-let blockchain = CompactFiltersBlockchain::new(peers, "./wallet-filters", Some(500_000))?;
-

Structs

-

Data to connect to a Bitcoin P2P peer

-

Structure implementing the required blockchain traits

-

Container for unconfirmed, but valid Bitcoin transactions

-

A Bitcoin peer

-

Enums

-

An error that can occur during sync with a CompactFiltersBlockchain

-
- \ No newline at end of file + .collect::<Result<_, _>>()?; +let blockchain = CompactFiltersBlockchain::new(peers, "./wallet-filters", Some(500_000))?;
+

Structs

Data to connect to a Bitcoin P2P peer
Structure implementing the required blockchain traits
Container for unconfirmed, but valid Bitcoin transactions
A Bitcoin peer

Enums

An error that can occur during sync with a CompactFiltersBlockchain
\ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/blockchain/compact_filters/sidebar-items.js b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/blockchain/compact_filters/sidebar-items.js index 187af79563..82f3cc2ddd 100644 --- a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/blockchain/compact_filters/sidebar-items.js +++ b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/blockchain/compact_filters/sidebar-items.js @@ -1 +1 @@ -initSidebarItems({"enum":[["CompactFiltersError","An error that can occur during sync with a [`CompactFiltersBlockchain`]"]],"struct":[["BitcoinPeerConfig","Data to connect to a Bitcoin P2P peer"],["CompactFiltersBlockchain","Structure implementing the required blockchain traits"],["CompactFiltersBlockchainConfig","Configuration for a [`CompactFiltersBlockchain`]"],["Mempool","Container for unconfirmed, but valid Bitcoin transactions"],["Peer","A Bitcoin peer"]]}); \ No newline at end of file +window.SIDEBAR_ITEMS = {"enum":[["CompactFiltersError","An error that can occur during sync with a [`CompactFiltersBlockchain`]"]],"struct":[["BitcoinPeerConfig","Data to connect to a Bitcoin P2P peer"],["CompactFiltersBlockchain","Structure implementing the required blockchain traits"],["CompactFiltersBlockchainConfig","Configuration for a [`CompactFiltersBlockchain`]"],["Mempool","Container for unconfirmed, but valid Bitcoin transactions"],["Peer","A Bitcoin peer"]]}; \ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/blockchain/compact_filters/struct.BitcoinPeerConfig.html b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/blockchain/compact_filters/struct.BitcoinPeerConfig.html index cb295ba566..5206f230dd 100644 --- a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/blockchain/compact_filters/struct.BitcoinPeerConfig.html +++ b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/blockchain/compact_filters/struct.BitcoinPeerConfig.html @@ -1,44 +1,16 @@ -BitcoinPeerConfig in bdk::blockchain::compact_filters - Rust - -
pub struct BitcoinPeerConfig {
+BitcoinPeerConfig in bdk::blockchain::compact_filters - Rust
pub struct BitcoinPeerConfig {
     pub address: String,
     pub socks5: Option<String>,
-    pub socks5_credentials: Option<(String, String)>,
-}
This is supported on crate feature compact_filters only.
Expand description

Data to connect to a Bitcoin P2P peer

-

Fields

address: String

Peer address such as 127.0.0.1:18333

-
socks5: Option<String>

Optional socks5 proxy

-
socks5_credentials: Option<(String, String)>

Optional socks5 proxy credentials

-

Trait Implementations

Returns a copy of the value. Read more

-

Performs copy-assignment from source. Read more

-

Formats the value using the given formatter. Read more

-

Deserialize this value from the given Serde deserializer. Read more

-

This method tests for self and other values to be equal, and is used -by ==. Read more

-

This method tests for !=.

-

Serialize this value into the given Serde serializer. Read more

-

Auto Trait Implementations

Blanket Implementations

Gets the TypeId of self. Read more

-

Immutably borrows from an owned value. Read more

-

Mutably borrows from an owned value. Read more

-

Performs the conversion.

-

Performs the conversion.

-

The alignment of pointer.

-

The type for initializers.

-

Initializes a with the given initializer. Read more

-

Dereferences the given pointer. Read more

-

Mutably dereferences the given pointer. Read more

-

Drops the object pointed to by the given pointer. Read more

-

The resulting type after obtaining ownership.

-

Creates owned data from borrowed data, usually by cloning. Read more

-
🔬 This is a nightly-only experimental API. (toowned_clone_into)

Uses borrowed data to replace owned data, usually by cloning. Read more

-

The type returned in the event of a conversion error.

-

Performs the conversion.

-

The type returned in the event of a conversion error.

-

Performs the conversion.

-
- \ No newline at end of file + pub socks5_credentials: Option<(String, String)>, +}
Available on crate feature compact_filters only.
Expand description

Data to connect to a Bitcoin P2P peer

+

Fields§

§address: String

Peer address such as 127.0.0.1:18333

+
§socks5: Option<String>

Optional socks5 proxy

+
§socks5_credentials: Option<(String, String)>

Optional socks5 proxy credentials

+

Trait Implementations§

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

Auto Trait Implementations§

Blanket Implementations§

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

Returns the argument unchanged.

+

Calls U::from(self).

+

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

+
The alignment of pointer.
The type for initializers.
Initializes a with the given initializer. Read more
Dereferences the given pointer. Read more
Mutably dereferences the given pointer. Read more
Drops the object pointed to by the given pointer. Read more
The resulting type after obtaining ownership.
Creates owned data from borrowed data, usually by cloning. Read more
Uses borrowed data to replace owned data, usually by cloning. Read more
The type returned in the event of a conversion error.
Performs the conversion.
The type returned in the event of a conversion error.
Performs the conversion.
\ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/blockchain/compact_filters/struct.CompactFiltersBlockchain.html b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/blockchain/compact_filters/struct.CompactFiltersBlockchain.html index c9a699ccc4..4de0638533 100644 --- a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/blockchain/compact_filters/struct.CompactFiltersBlockchain.html +++ b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/blockchain/compact_filters/struct.CompactFiltersBlockchain.html @@ -1,47 +1,16 @@ -CompactFiltersBlockchain in bdk::blockchain::compact_filters - Rust - -
pub struct CompactFiltersBlockchain { /* private fields */ }
This is supported on crate feature compact_filters only.
Expand description

Structure implementing the required blockchain traits

-

Example

+CompactFiltersBlockchain in bdk::blockchain::compact_filters - Rust
pub struct CompactFiltersBlockchain { /* private fields */ }
Available on crate feature compact_filters only.
Expand description

Structure implementing the required blockchain traits

+

Example

See the blockchain::compact_filters module for a usage example.

-

Implementations

Construct a new instance given a list of peers, a path to store headers and block +

Implementations§

Construct a new instance given a list of peers, a path to store headers and block filters downloaded during the sync and optionally a number of blocks to ignore starting from the genesis while scanning for the wallet’s outputs.

For each Peer specified a new thread will be spawned to download and verify the filters in parallel. It’s currently recommended to only connect to a single peer to avoid inconsistencies in the data returned, optionally with multiple connections in parallel to speed-up the sync process.

-

Trait Implementations

Return the set of Capability supported by this backend

-

Broadcast a transaction

-

Estimate the fee rate required to confirm a transaction in a given target of blocks

-

Type that contains the configuration

-

Create a new instance given a configuration

-

Formats the value using the given formatter. Read more

-

Performs the conversion.

-

fetch block hash given its height

-

Return the current height

-

Fetch a transaction given its txid

-

Setup the backend and populate the internal database for the first time Read more

-

If not overridden, it defaults to calling Self::wallet_setup internally. Read more

-

Auto Trait Implementations

Blanket Implementations

Gets the TypeId of self. Read more

-

Immutably borrows from an owned value. Read more

-

Mutably borrows from an owned value. Read more

-

Performs the conversion.

-

Performs the conversion.

-

The alignment of pointer.

-

The type for initializers.

-

Initializes a with the given initializer. Read more

-

Dereferences the given pointer. Read more

-

Mutably dereferences the given pointer. Read more

-

Drops the object pointed to by the given pointer. Read more

-

The type returned in the event of a conversion error.

-

Performs the conversion.

-

The type returned in the event of a conversion error.

-

Performs the conversion.

-
- \ No newline at end of file +

Trait Implementations§

Return the set of Capability supported by this backend
Broadcast a transaction
Estimate the fee rate required to confirm a transaction in a given target of blocks
Type that contains the configuration
Create a new instance given a configuration
Formats the value using the given formatter. Read more
Converts to this type from the input type.
fetch block hash given its height
Return the current height
Fetch a transaction given its txid
Setup the backend and populate the internal database for the first time Read more
If not overridden, it defaults to calling Self::wallet_setup internally. Read more

Auto Trait Implementations§

Blanket Implementations§

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

Returns the argument unchanged.

+

Calls U::from(self).

+

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

+
The alignment of pointer.
The type for initializers.
Initializes a with the given initializer. Read more
Dereferences the given pointer. Read more
Mutably dereferences the given pointer. Read more
Drops the object pointed to by the given pointer. Read more
The type returned in the event of a conversion error.
Performs the conversion.
The type returned in the event of a conversion error.
Performs the conversion.
\ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/blockchain/compact_filters/struct.CompactFiltersBlockchainConfig.html b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/blockchain/compact_filters/struct.CompactFiltersBlockchainConfig.html index 780a395917..44bf24d64d 100644 --- a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/blockchain/compact_filters/struct.CompactFiltersBlockchainConfig.html +++ b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/blockchain/compact_filters/struct.CompactFiltersBlockchainConfig.html @@ -1,47 +1,18 @@ -CompactFiltersBlockchainConfig in bdk::blockchain::compact_filters - Rust - -
pub struct CompactFiltersBlockchainConfig {
+CompactFiltersBlockchainConfig in bdk::blockchain::compact_filters - Rust
pub struct CompactFiltersBlockchainConfig {
     pub peers: Vec<BitcoinPeerConfig>,
     pub network: Network,
     pub storage_dir: String,
     pub skip_blocks: Option<usize>,
-}
This is supported on crate feature compact_filters only.
Expand description

Configuration for a CompactFiltersBlockchain

-

Fields

peers: Vec<BitcoinPeerConfig>

List of peers to try to connect to for asking headers and filters

-
network: Network

Network used

-
storage_dir: String

Storage dir to save partially downloaded headers and full blocks. Should be a separate directory per descriptor. Consider using crate::wallet::wallet_name_from_descriptor for this.

-
skip_blocks: Option<usize>

Optionally skip initial skip_blocks blocks (default: 0)

-

Trait Implementations

Returns a copy of the value. Read more

-

Performs copy-assignment from source. Read more

-

Formats the value using the given formatter. Read more

-

Deserialize this value from the given Serde deserializer. Read more

-

Performs the conversion.

-

This method tests for self and other values to be equal, and is used -by ==. Read more

-

This method tests for !=.

-

Serialize this value into the given Serde serializer. Read more

-

Auto Trait Implementations

Blanket Implementations

Gets the TypeId of self. Read more

-

Immutably borrows from an owned value. Read more

-

Mutably borrows from an owned value. Read more

-

Performs the conversion.

-

Performs the conversion.

-

The alignment of pointer.

-

The type for initializers.

-

Initializes a with the given initializer. Read more

-

Dereferences the given pointer. Read more

-

Mutably dereferences the given pointer. Read more

-

Drops the object pointed to by the given pointer. Read more

-

The resulting type after obtaining ownership.

-

Creates owned data from borrowed data, usually by cloning. Read more

-
🔬 This is a nightly-only experimental API. (toowned_clone_into)

Uses borrowed data to replace owned data, usually by cloning. Read more

-

The type returned in the event of a conversion error.

-

Performs the conversion.

-

The type returned in the event of a conversion error.

-

Performs the conversion.

-
- \ No newline at end of file +}
Available on crate feature compact_filters only.
Expand description

Configuration for a CompactFiltersBlockchain

+

Fields§

§peers: Vec<BitcoinPeerConfig>

List of peers to try to connect to for asking headers and filters

+
§network: Network

Network used

+
§storage_dir: String

Storage dir to save partially downloaded headers and full blocks. Should be a separate directory per descriptor. Consider using crate::wallet::wallet_name_from_descriptor for this.

+
§skip_blocks: Option<usize>

Optionally skip initial skip_blocks blocks (default: 0)

+

Trait Implementations§

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

Auto Trait Implementations§

Blanket Implementations§

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

Returns the argument unchanged.

+

Calls U::from(self).

+

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

+
The alignment of pointer.
The type for initializers.
Initializes a with the given initializer. Read more
Dereferences the given pointer. Read more
Mutably dereferences the given pointer. Read more
Drops the object pointed to by the given pointer. Read more
The resulting type after obtaining ownership.
Creates owned data from borrowed data, usually by cloning. Read more
Uses borrowed data to replace owned data, usually by cloning. Read more
The type returned in the event of a conversion error.
Performs the conversion.
The type returned in the event of a conversion error.
Performs the conversion.
\ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/blockchain/compact_filters/struct.Mempool.html b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/blockchain/compact_filters/struct.Mempool.html index ff3433d9a3..1211d91519 100644 --- a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/blockchain/compact_filters/struct.Mempool.html +++ b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/blockchain/compact_filters/struct.Mempool.html @@ -1,37 +1,16 @@ -Mempool in bdk::blockchain::compact_filters - Rust - -
pub struct Mempool(_);
This is supported on crate feature compact_filters only.
Expand description

Container for unconfirmed, but valid Bitcoin transactions

+Mempool in bdk::blockchain::compact_filters - Rust
pub struct Mempool(_);
Available on crate feature compact_filters only.
Expand description

Container for unconfirmed, but valid Bitcoin transactions

It is normally shared between Peers with the use of Arc, so that transactions are not duplicated in memory.

-

Implementations

Create a new empty mempool

-

Add a transaction to the mempool

+

Implementations§

Create a new empty mempool

+

Add a transaction to the mempool

Note that this doesn’t propagate the transaction to other peers. To do that, broadcast should be used.

-

Look-up a transaction in the mempool given an [Inventory] request

-

Return whether or not the mempool contains a transaction with a given txid

-

Return the list of transactions contained in the mempool

-

Trait Implementations

Formats the value using the given formatter. Read more

-

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

-

Auto Trait Implementations

Blanket Implementations

Gets the TypeId of self. Read more

-

Immutably borrows from an owned value. Read more

-

Mutably borrows from an owned value. Read more

-

Performs the conversion.

-

Performs the conversion.

-

The alignment of pointer.

-

The type for initializers.

-

Initializes a with the given initializer. Read more

-

Dereferences the given pointer. Read more

-

Mutably dereferences the given pointer. Read more

-

Drops the object pointed to by the given pointer. Read more

-

The type returned in the event of a conversion error.

-

Performs the conversion.

-

The type returned in the event of a conversion error.

-

Performs the conversion.

-
- \ No newline at end of file +

Look-up a transaction in the mempool given an [Inventory] request

+

Return whether or not the mempool contains a transaction with a given txid

+

Return the list of transactions contained in the mempool

+

Trait Implementations§

Formats the value using the given formatter. Read more
Returns the “default value” for a type. Read more

Auto Trait Implementations§

Blanket Implementations§

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

Returns the argument unchanged.

+

Calls U::from(self).

+

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

+
The alignment of pointer.
The type for initializers.
Initializes a with the given initializer. Read more
Dereferences the given pointer. Read more
Mutably dereferences the given pointer. Read more
Drops the object pointed to by the given pointer. Read more
The type returned in the event of a conversion error.
Performs the conversion.
The type returned in the event of a conversion error.
Performs the conversion.
\ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/blockchain/compact_filters/struct.Peer.html b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/blockchain/compact_filters/struct.Peer.html index 43f20d69ba..53e44a36f0 100644 --- a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/blockchain/compact_filters/struct.Peer.html +++ b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/blockchain/compact_filters/struct.Peer.html @@ -1,40 +1,20 @@ -Peer in bdk::blockchain::compact_filters - Rust - -
pub struct Peer { /* private fields */ }
This is supported on crate feature compact_filters only.
Expand description

A Bitcoin peer

-

Implementations

Connect to a peer over a plaintext TCP connection

+Peer in bdk::blockchain::compact_filters - Rust
pub struct Peer { /* private fields */ }
Available on crate feature compact_filters only.
Expand description

A Bitcoin peer

+

Implementations§

Connect to a peer over a plaintext TCP connection

This function internally spawns a new thread that will monitor incoming messages from the peer, and optionally reply to some of them transparently, like pings

-

Connect to a peer through a SOCKS5 proxy, optionally by using some credentials, specified +

Connect to a peer through a SOCKS5 proxy, optionally by using some credentials, specified as a tuple of (username, password)

This function internally spawns a new thread that will monitor incoming messages from the peer, and optionally reply to some of them transparently, like pings

-

Return the [VersionMessage] sent by the peer

-

Return the Bitcoin [Network] in use

-

Return the mempool used by this peer

-

Return whether or not the peer is still connected

-

Send a raw Bitcoin message to the peer

-

Waits for a specific incoming Bitcoin message, optionally with a timeout

-

Trait Implementations

Formats the value using the given formatter. Read more

-

Auto Trait Implementations

Blanket Implementations

Gets the TypeId of self. Read more

-

Immutably borrows from an owned value. Read more

-

Mutably borrows from an owned value. Read more

-

Performs the conversion.

-

Performs the conversion.

-

The alignment of pointer.

-

The type for initializers.

-

Initializes a with the given initializer. Read more

-

Dereferences the given pointer. Read more

-

Mutably dereferences the given pointer. Read more

-

Drops the object pointed to by the given pointer. Read more

-

The type returned in the event of a conversion error.

-

Performs the conversion.

-

The type returned in the event of a conversion error.

-

Performs the conversion.

-
- \ No newline at end of file +

Return the [VersionMessage] sent by the peer

+

Return the Bitcoin [Network] in use

+

Return the mempool used by this peer

+

Return whether or not the peer is still connected

+

Send a raw Bitcoin message to the peer

+

Waits for a specific incoming Bitcoin message, optionally with a timeout

+

Trait Implementations§

Formats the value using the given formatter. Read more

Auto Trait Implementations§

Blanket Implementations§

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

Returns the argument unchanged.

+

Calls U::from(self).

+

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

+
The alignment of pointer.
The type for initializers.
Initializes a with the given initializer. Read more
Dereferences the given pointer. Read more
Mutably dereferences the given pointer. Read more
Drops the object pointed to by the given pointer. Read more
The type returned in the event of a conversion error.
Performs the conversion.
The type returned in the event of a conversion error.
Performs the conversion.
\ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/blockchain/electrum/index.html b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/blockchain/electrum/index.html index b1e4d899ac..d19af4894d 100644 --- a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/blockchain/electrum/index.html +++ b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/blockchain/electrum/index.html @@ -1,20 +1,9 @@ -bdk::blockchain::electrum - Rust - -
This is supported on crate feature electrum only.
Expand description

Electrum

+bdk::blockchain::electrum - Rust

Module bdk::blockchain::electrum

source ·
Available on crate feature electrum only.
Expand description

Electrum

This module defines a Blockchain struct that wraps an [electrum_client::Client] and implements the logic required to populate the wallet’s database by querying the inner client.

-

Example

-
let client = electrum_client::Client::new("ssl://electrum.blockstream.info:50002")?;
-let blockchain = ElectrumBlockchain::from(client);
-

Structs

-

Wrapper over an Electrum Client that implements the required blockchain traits

-
- \ No newline at end of file +

Example

+
let client = electrum_client::Client::new("ssl://electrum.blockstream.info:50002")?;
+let blockchain = ElectrumBlockchain::from(client);
+

Structs

Wrapper over an Electrum Client that implements the required blockchain traits
\ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/blockchain/electrum/sidebar-items.js b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/blockchain/electrum/sidebar-items.js index 1bd5458912..fc07f94fa7 100644 --- a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/blockchain/electrum/sidebar-items.js +++ b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/blockchain/electrum/sidebar-items.js @@ -1 +1 @@ -initSidebarItems({"struct":[["ElectrumBlockchain","Wrapper over an Electrum Client that implements the required blockchain traits"],["ElectrumBlockchainConfig","Configuration for an [`ElectrumBlockchain`]"]]}); \ No newline at end of file +window.SIDEBAR_ITEMS = {"struct":[["ElectrumBlockchain","Wrapper over an Electrum Client that implements the required blockchain traits"],["ElectrumBlockchainConfig","Configuration for an [`ElectrumBlockchain`]"]]}; \ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/blockchain/electrum/struct.ElectrumBlockchain.html b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/blockchain/electrum/struct.ElectrumBlockchain.html index 1c3f5b6573..3a05322ff2 100644 --- a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/blockchain/electrum/struct.ElectrumBlockchain.html +++ b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/blockchain/electrum/struct.ElectrumBlockchain.html @@ -1,42 +1,9 @@ -ElectrumBlockchain in bdk::blockchain::electrum - Rust - -
pub struct ElectrumBlockchain { /* private fields */ }
This is supported on crate feature electrum only.
Expand description

Wrapper over an Electrum Client that implements the required blockchain traits

-

Example

+ElectrumBlockchain in bdk::blockchain::electrum - Rust
pub struct ElectrumBlockchain { /* private fields */ }
Available on crate feature electrum only.
Expand description

Wrapper over an Electrum Client that implements the required blockchain traits

+

Example

See the blockchain::electrum module for a usage example.

-

Trait Implementations

Return the set of Capability supported by this backend

-

Broadcast a transaction

-

Estimate the fee rate required to confirm a transaction in a given target of blocks

-

Type that contains the configuration

-

Create a new instance given a configuration

-

The resulting type after dereferencing.

-

Dereferences the value.

-

Performs the conversion.

-

Performs the conversion.

-

fetch block hash given its height

-

Return the current height

-

Fetch a transaction given its txid

-

Setup the backend and populate the internal database for the first time Read more

-

If not overridden, it defaults to calling Self::wallet_setup internally. Read more

-

Auto Trait Implementations

Blanket Implementations

Gets the TypeId of self. Read more

-

Immutably borrows from an owned value. Read more

-

Mutably borrows from an owned value. Read more

-

Performs the conversion.

-

Performs the conversion.

-

The alignment of pointer.

-

The type for initializers.

-

Initializes a with the given initializer. Read more

-

Dereferences the given pointer. Read more

-

Mutably dereferences the given pointer. Read more

-

Drops the object pointed to by the given pointer. Read more

-

The type returned in the event of a conversion error.

-

Performs the conversion.

-

The type returned in the event of a conversion error.

-

Performs the conversion.

-
- \ No newline at end of file +

Trait Implementations§

Return the set of Capability supported by this backend
Broadcast a transaction
Estimate the fee rate required to confirm a transaction in a given target of blocks
Type that contains the configuration
Create a new instance given a configuration
The resulting type after dereferencing.
Dereferences the value.
Converts to this type from the input type.
Converts to this type from the input type.
fetch block hash given its height
Return the current height
Fetch a transaction given its txid
Setup the backend and populate the internal database for the first time Read more
If not overridden, it defaults to calling Self::wallet_setup internally. Read more

Auto Trait Implementations§

Blanket Implementations§

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

Returns the argument unchanged.

+

Calls U::from(self).

+

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

+
The alignment of pointer.
The type for initializers.
Initializes a with the given initializer. Read more
Dereferences the given pointer. Read more
Mutably dereferences the given pointer. Read more
Drops the object pointed to by the given pointer. Read more
The type returned in the event of a conversion error.
Performs the conversion.
The type returned in the event of a conversion error.
Performs the conversion.
\ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/blockchain/electrum/struct.ElectrumBlockchainConfig.html b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/blockchain/electrum/struct.ElectrumBlockchainConfig.html index 5a281fb1ba..d318ae928f 100644 --- a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/blockchain/electrum/struct.ElectrumBlockchainConfig.html +++ b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/blockchain/electrum/struct.ElectrumBlockchainConfig.html @@ -1,50 +1,21 @@ -ElectrumBlockchainConfig in bdk::blockchain::electrum - Rust - -
pub struct ElectrumBlockchainConfig {
+ElectrumBlockchainConfig in bdk::blockchain::electrum - Rust
pub struct ElectrumBlockchainConfig {
     pub url: String,
     pub socks5: Option<String>,
     pub retry: u8,
     pub timeout: Option<u8>,
     pub stop_gap: usize,
-}
This is supported on crate feature electrum only.
Expand description

Configuration for an ElectrumBlockchain

-

Fields

url: String

URL of the Electrum server (such as ElectrumX, Esplora, BWT) may start with ssl:// or tcp:// and include a port

+}
Available on crate feature electrum only.
Expand description

Configuration for an ElectrumBlockchain

+

Fields§

§url: String

URL of the Electrum server (such as ElectrumX, Esplora, BWT) may start with ssl:// or tcp:// and include a port

eg. ssl://electrum.blockstream.info:60002

-
socks5: Option<String>

URL of the socks5 proxy server or a Tor service

-
retry: u8

Request retry count

-
timeout: Option<u8>

Request timeout (seconds)

-
stop_gap: usize

Stop searching addresses for transactions after finding an unused gap of this length

-

Trait Implementations

Returns a copy of the value. Read more

-

Performs copy-assignment from source. Read more

-

Formats the value using the given formatter. Read more

-

Deserialize this value from the given Serde deserializer. Read more

-

Performs the conversion.

-

This method tests for self and other values to be equal, and is used -by ==. Read more

-

This method tests for !=.

-

Serialize this value into the given Serde serializer. Read more

-

Auto Trait Implementations

Blanket Implementations

Gets the TypeId of self. Read more

-

Immutably borrows from an owned value. Read more

-

Mutably borrows from an owned value. Read more

-

Performs the conversion.

-

Performs the conversion.

-

The alignment of pointer.

-

The type for initializers.

-

Initializes a with the given initializer. Read more

-

Dereferences the given pointer. Read more

-

Mutably dereferences the given pointer. Read more

-

Drops the object pointed to by the given pointer. Read more

-

The resulting type after obtaining ownership.

-

Creates owned data from borrowed data, usually by cloning. Read more

-
🔬 This is a nightly-only experimental API. (toowned_clone_into)

Uses borrowed data to replace owned data, usually by cloning. Read more

-

The type returned in the event of a conversion error.

-

Performs the conversion.

-

The type returned in the event of a conversion error.

-

Performs the conversion.

-
- \ No newline at end of file +§socks5: Option<String>

URL of the socks5 proxy server or a Tor service

+
§retry: u8

Request retry count

+
§timeout: Option<u8>

Request timeout (seconds)

+
§stop_gap: usize

Stop searching addresses for transactions after finding an unused gap of this length

+

Trait Implementations§

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

Auto Trait Implementations§

Blanket Implementations§

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

Returns the argument unchanged.

+

Calls U::from(self).

+

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

+
The alignment of pointer.
The type for initializers.
Initializes a with the given initializer. Read more
Dereferences the given pointer. Read more
Mutably dereferences the given pointer. Read more
Drops the object pointed to by the given pointer. Read more
The resulting type after obtaining ownership.
Creates owned data from borrowed data, usually by cloning. Read more
Uses borrowed data to replace owned data, usually by cloning. Read more
The type returned in the event of a conversion error.
Performs the conversion.
The type returned in the event of a conversion error.
Performs the conversion.
\ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/blockchain/enum.Capability.html b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/blockchain/enum.Capability.html index fc4930f246..8f011eb6ab 100644 --- a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/blockchain/enum.Capability.html +++ b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/blockchain/enum.Capability.html @@ -1,44 +1,16 @@ -Capability in bdk::blockchain - Rust - -
pub enum Capability {
+Capability in bdk::blockchain - Rust

Enum bdk::blockchain::Capability

source ·
pub enum Capability {
     FullHistory,
     GetAnyTx,
     AccurateFees,
 }
Expand description

Capabilities that can be supported by a Blockchain backend

-

Variants

FullHistory

Can recover the full history of a wallet and not only the set of currently spendable UTXOs

-

GetAnyTx

Can fetch any historical transaction given its txid

-

AccurateFees

Can compute accurate fees for the transactions found during sync

-

Trait Implementations

Returns a copy of the value. Read more

-

Performs copy-assignment from source. Read more

-

Formats the value using the given formatter. Read more

-

Feeds this value into the given Hasher. Read more

-

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

-

This method tests for self and other values to be equal, and is used -by ==. Read more

-

This method tests for !=.

-

Auto Trait Implementations

Blanket Implementations

Gets the TypeId of self. Read more

-

Immutably borrows from an owned value. Read more

-

Mutably borrows from an owned value. Read more

-

Performs the conversion.

-

Performs the conversion.

-

The alignment of pointer.

-

The type for initializers.

-

Initializes a with the given initializer. Read more

-

Dereferences the given pointer. Read more

-

Mutably dereferences the given pointer. Read more

-

Drops the object pointed to by the given pointer. Read more

-

The resulting type after obtaining ownership.

-

Creates owned data from borrowed data, usually by cloning. Read more

-
🔬 This is a nightly-only experimental API. (toowned_clone_into)

Uses borrowed data to replace owned data, usually by cloning. Read more

-

The type returned in the event of a conversion error.

-

Performs the conversion.

-

The type returned in the event of a conversion error.

-

Performs the conversion.

-
- \ No newline at end of file +

Variants§

§

FullHistory

Can recover the full history of a wallet and not only the set of currently spendable UTXOs

+
§

GetAnyTx

Can fetch any historical transaction given its txid

+
§

AccurateFees

Can compute accurate fees for the transactions found during sync

+

Trait Implementations§

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

Auto Trait Implementations§

Blanket Implementations§

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

Returns the argument unchanged.

+

Calls U::from(self).

+

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

+
The alignment of pointer.
The type for initializers.
Initializes a with the given initializer. Read more
Dereferences the given pointer. Read more
Mutably dereferences the given pointer. Read more
Drops the object pointed to by the given pointer. Read more
The resulting type after obtaining ownership.
Creates owned data from borrowed data, usually by cloning. Read more
Uses borrowed data to replace owned data, usually by cloning. Read more
The type returned in the event of a conversion error.
Performs the conversion.
The type returned in the event of a conversion error.
Performs the conversion.
\ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/blockchain/esplora/enum.EsploraError.html b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/blockchain/esplora/enum.EsploraError.html index 92e9f6e2ce..22b13fe1f0 100644 --- a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/blockchain/esplora/enum.EsploraError.html +++ b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/blockchain/esplora/enum.EsploraError.html @@ -1,12 +1,5 @@ -EsploraError in bdk::blockchain::esplora - Rust - -
pub enum EsploraError {
+EsploraError in bdk::blockchain::esplora - Rust
pub enum EsploraError {
     Ureq(Error),
     UreqTransport(Transport),
     HttpResponse(u16),
@@ -18,46 +11,21 @@
     TransactionNotFound(Txid),
     HeaderHeightNotFound(u32),
     HeaderHashNotFound(BlockHash),
-}
This is supported on crate feature esplora only.
Expand description

Errors that can happen during a sync with Esplora

-

Variants

Ureq(Error)

Error during ureq HTTP request

-

UreqTransport(Transport)

Transport error during the ureq HTTP call

-

HttpResponse(u16)

HTTP response error

-

Io(Error)

IO error during ureq response read

-

NoHeader

No header found in ureq response

-

Parsing(ParseIntError)

Invalid number returned

-

BitcoinEncoding(Error)

Invalid Bitcoin data returned

-

Hex(Error)

Invalid Hex data returned

-

TransactionNotFound(Txid)

Transaction not found

-

HeaderHeightNotFound(u32)

Header height not found

-

HeaderHashNotFound(BlockHash)

Header hash not found

-

Trait Implementations

Formats the value using the given formatter. Read more

-

Formats the value using the given formatter. Read more

-

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

-
🔬 This is a nightly-only experimental API. (backtrace)

Returns a stack backtrace, if available, of where this error occurred. Read more

-
👎 Deprecated since 1.42.0:

use the Display impl or to_string()

-
👎 Deprecated since 1.33.0:

replaced by Error::source, which can support downcasting

-

Performs the conversion.

-

Performs the conversion.

-

Performs the conversion.

-

Performs the conversion.

-

Performs the conversion.

-

Performs the conversion.

-

Performs the conversion.

-

Auto Trait Implementations

Blanket Implementations

Gets the TypeId of self. Read more

-

Immutably borrows from an owned value. Read more

-

Mutably borrows from an owned value. Read more

-

Performs the conversion.

-

Performs the conversion.

-

The alignment of pointer.

-

The type for initializers.

-

Initializes a with the given initializer. Read more

-

Dereferences the given pointer. Read more

-

Mutably dereferences the given pointer. Read more

-

Drops the object pointed to by the given pointer. Read more

-

Converts the given value to a String. Read more

-

The type returned in the event of a conversion error.

-

Performs the conversion.

-

The type returned in the event of a conversion error.

-

Performs the conversion.

-
- \ No newline at end of file +}
Available on crate feature esplora only.
Expand description

Errors that can happen during a sync with Esplora

+

Variants§

§

Ureq(Error)

Error during ureq HTTP request

+
§

UreqTransport(Transport)

Transport error during the ureq HTTP call

+
§

HttpResponse(u16)

HTTP response error

+
§

Io(Error)

IO error during ureq response read

+
§

NoHeader

No header found in ureq response

+
§

Parsing(ParseIntError)

Invalid number returned

+
§

BitcoinEncoding(Error)

Invalid Bitcoin data returned

+
§

Hex(Error)

Invalid Hex data returned

+
§

TransactionNotFound(Txid)

Transaction not found

+
§

HeaderHeightNotFound(u32)

Header height not found

+
§

HeaderHashNotFound(BlockHash)

Header hash not found

+

Trait Implementations§

Formats the value using the given formatter. Read more
Formats the value using the given formatter. Read more
The lower-level source of this error, if any. Read more
👎Deprecated since 1.42.0: use the Display impl or to_string()
👎Deprecated since 1.33.0: replaced by Error::source, which can support downcasting
🔬This is a nightly-only experimental API. (error_generic_member_access)
Provides type based access to context intended for error reports. Read more
Converts to this type from the input type.
Converts to this type from the input type.
Converts to this type from the input type.
Converts to this type from the input type.
Converts to this type from the input type.
Converts to this type from the input type.
Converts to this type from the input type.

Auto Trait Implementations§

Blanket Implementations§

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

Returns the argument unchanged.

+

Calls U::from(self).

+

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

+
The alignment of pointer.
The type for initializers.
Initializes a with the given initializer. Read more
Dereferences the given pointer. Read more
Mutably dereferences the given pointer. Read more
Drops the object pointed to by the given pointer. Read more
🔬This is a nightly-only experimental API. (provide_any)
Data providers should implement this method to provide all values they are able to +provide by using demand. Read more
Converts the given value to a String. Read more
The type returned in the event of a conversion error.
Performs the conversion.
The type returned in the event of a conversion error.
Performs the conversion.
\ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/blockchain/esplora/index.html b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/blockchain/esplora/index.html index 0131ee26aa..71e42768bd 100644 --- a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/blockchain/esplora/index.html +++ b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/blockchain/esplora/index.html @@ -1,25 +1,12 @@ -bdk::blockchain::esplora - Rust - -
This is supported on crate feature esplora only.
Expand description

Esplora

+bdk::blockchain::esplora - Rust

Module bdk::blockchain::esplora

source ·
Available on crate feature esplora only.
Expand description

Esplora

This module defines a EsploraBlockchain struct that can query an Esplora backend populate the wallet’s database by:

-

Example

-
let blockchain = EsploraBlockchain::new("https://blockstream.info/testnet/api", 20);
+

Example

+
let blockchain = EsploraBlockchain::new("https://blockstream.info/testnet/api", 20);

Esplora blockchain can use either ureq or reqwest for the HTTP client depending on your needs (blocking or async respectively).

Please note, to configure the Esplora HTTP client correctly use one of: Blocking: –features=‘use-esplora-blocking’ Async: –features=‘async-interface,use-esplora-async’ –no-default-features

-

Structs

-

Structure that implements the logic to sync with Esplora

-

Enums

-

Errors that can happen during a sync with Esplora

-
- \ No newline at end of file +

Structs

Structure that implements the logic to sync with Esplora

Enums

Errors that can happen during a sync with Esplora
\ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/blockchain/esplora/sidebar-items.js b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/blockchain/esplora/sidebar-items.js index 963e464da0..387fca4052 100644 --- a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/blockchain/esplora/sidebar-items.js +++ b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/blockchain/esplora/sidebar-items.js @@ -1 +1 @@ -initSidebarItems({"enum":[["EsploraError","Errors that can happen during a sync with `Esplora`"]],"struct":[["EsploraBlockchain","Structure that implements the logic to sync with Esplora"],["EsploraBlockchainConfig","Configuration for an [`EsploraBlockchain`]"]]}); \ No newline at end of file +window.SIDEBAR_ITEMS = {"enum":[["EsploraError","Errors that can happen during a sync with `Esplora`"]],"struct":[["EsploraBlockchain","Structure that implements the logic to sync with Esplora"],["EsploraBlockchainConfig","Configuration for an [`EsploraBlockchain`]"]]}; \ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/blockchain/esplora/struct.EsploraBlockchain.html b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/blockchain/esplora/struct.EsploraBlockchain.html index 9d4c0a83fb..e3b5cd6e91 100644 --- a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/blockchain/esplora/struct.EsploraBlockchain.html +++ b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/blockchain/esplora/struct.EsploraBlockchain.html @@ -1,64 +1,30 @@ -EsploraBlockchain in bdk::blockchain::esplora - Rust - -
pub struct EsploraBlockchain { /* private fields */ }
This is supported on crate feature esplora only.
Expand description

Structure that implements the logic to sync with Esplora

-

Example

+EsploraBlockchain in bdk::blockchain::esplora - Rust
pub struct EsploraBlockchain { /* private fields */ }
Available on crate feature esplora only.
Expand description

Structure that implements the logic to sync with Esplora

+

Example

See the blockchain::esplora module for a usage example.

-

Implementations

Create a new instance of the client from a base URL and the stop_gap.

-

Build a new instance given a client

-

Set the number of parallel requests the client can make.

-

Methods from Deref<Target = BlockingClient>

Get a [Transaction] option given its [Txid]

-

Get a [Transaction] given its [Txid].

-

Get a [Txid] of a transaction given its index in a block with a given hash.

-

Get the status of a [Transaction] given its [Txid].

-
👎 Deprecated since 0.1.2:

Deprecated to improve alignment with Esplora API. Users should use get_block_hash and get_header_by_hash methods directly.

-

Get a [BlockHeader] given a particular block height.

-

Get a [BlockHeader] given a particular block hash.

-

Get the [BlockStatus] given a particular [BlockHash].

-

Get a merkle inclusion proof for a [Transaction] with the given [Txid].

-

Get the spending status of an output given a [Txid] and the output index.

-

Broadcast a [Transaction] to Esplora

-

Get the height of the current blockchain tip.

-

Get the [BlockHash] of the current blockchain tip.

-

Get the [BlockHash] of a specific block height

-

Get an map where the key is the confirmation target (in number of blocks) +

Implementations§

Create a new instance of the client from a base URL and the stop_gap.

+

Build a new instance given a client

+

Set the number of parallel requests the client can make.

+

Methods from Deref<Target = BlockingClient>§

Get a [Transaction] option given its [Txid]

+

Get a [Transaction] given its [Txid].

+

Get a [Txid] of a transaction given its index in a block with a given hash.

+

Get the status of a [Transaction] given its [Txid].

+
👎Deprecated since 0.1.2: Deprecated to improve alignment with Esplora API. Users should use get_block_hash and get_header_by_hash methods directly.

Get a [BlockHeader] given a particular block height.

+

Get a [BlockHeader] given a particular block hash.

+

Get the [BlockStatus] given a particular [BlockHash].

+

Get a merkle inclusion proof for a [Transaction] with the given [Txid].

+

Get the spending status of an output given a [Txid] and the output index.

+

Broadcast a [Transaction] to Esplora

+

Get the height of the current blockchain tip.

+

Get the [BlockHash] of the current blockchain tip.

+

Get the [BlockHash] of a specific block height

+

Get an map where the key is the confirmation target (in number of blocks) and the value is the estimated feerate (in sat/vB).

-

Get confirmed transaction history for the specified address/scripthash, +

Get confirmed transaction history for the specified address/scripthash, sorted with newest first. Returns 25 transactions per page. More can be requested by specifying the last txid seen by the previous query.

-

Trait Implementations

Return the set of Capability supported by this backend

-

Broadcast a transaction

-

Estimate the fee rate required to confirm a transaction in a given target of blocks

-

Type that contains the configuration

-

Create a new instance given a configuration

-

Formats the value using the given formatter. Read more

-

The resulting type after dereferencing.

-

Dereferences the value.

-

Performs the conversion.

-

fetch block hash given its height

-

Return the current height

-

Fetch a transaction given its txid

-

Setup the backend and populate the internal database for the first time Read more

-

If not overridden, it defaults to calling Self::wallet_setup internally. Read more

-

Auto Trait Implementations

Blanket Implementations

Gets the TypeId of self. Read more

-

Immutably borrows from an owned value. Read more

-

Mutably borrows from an owned value. Read more

-

Performs the conversion.

-

Performs the conversion.

-

The alignment of pointer.

-

The type for initializers.

-

Initializes a with the given initializer. Read more

-

Dereferences the given pointer. Read more

-

Mutably dereferences the given pointer. Read more

-

Drops the object pointed to by the given pointer. Read more

-

The type returned in the event of a conversion error.

-

Performs the conversion.

-

The type returned in the event of a conversion error.

-

Performs the conversion.

-
- \ No newline at end of file +

Trait Implementations§

Return the set of Capability supported by this backend
Broadcast a transaction
Estimate the fee rate required to confirm a transaction in a given target of blocks
Type that contains the configuration
Create a new instance given a configuration
Formats the value using the given formatter. Read more
The resulting type after dereferencing.
Dereferences the value.
Converts to this type from the input type.
fetch block hash given its height
Return the current height
Fetch a transaction given its txid
Setup the backend and populate the internal database for the first time Read more
If not overridden, it defaults to calling Self::wallet_setup internally. Read more

Auto Trait Implementations§

Blanket Implementations§

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

Returns the argument unchanged.

+

Calls U::from(self).

+

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

+
The alignment of pointer.
The type for initializers.
Initializes a with the given initializer. Read more
Dereferences the given pointer. Read more
Mutably dereferences the given pointer. Read more
Drops the object pointed to by the given pointer. Read more
The type returned in the event of a conversion error.
Performs the conversion.
The type returned in the event of a conversion error.
Performs the conversion.
\ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/blockchain/esplora/struct.EsploraBlockchainConfig.html b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/blockchain/esplora/struct.EsploraBlockchainConfig.html index 2fe21f086c..50322a572e 100644 --- a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/blockchain/esplora/struct.EsploraBlockchainConfig.html +++ b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/blockchain/esplora/struct.EsploraBlockchainConfig.html @@ -1,57 +1,28 @@ -EsploraBlockchainConfig in bdk::blockchain::esplora - Rust - -
pub struct EsploraBlockchainConfig {
+EsploraBlockchainConfig in bdk::blockchain::esplora - Rust
pub struct EsploraBlockchainConfig {
     pub base_url: String,
     pub proxy: Option<String>,
     pub concurrency: Option<u8>,
     pub stop_gap: usize,
     pub timeout: Option<u64>,
-}
This is supported on crate feature esplora only.
Expand description

Configuration for an EsploraBlockchain

-

Fields

base_url: String

Base URL of the esplora service

+}
Available on crate feature esplora only.
Expand description

Configuration for an EsploraBlockchain

+

Fields§

§base_url: String

Base URL of the esplora service

eg. https://blockstream.info/api/

-
proxy: Option<String>

Optional URL of the proxy to use to make requests to the Esplora server

+
§proxy: Option<String>

Optional URL of the proxy to use to make requests to the Esplora server

The string should be formatted as: <protocol>://<user>:<password>@host:<port>.

Note that the format of this value and the supported protocols change slightly between the sync version of esplora (using ureq) and the async version (using reqwest). For more details check with the documentation of the two crates. Both of them are compiled with the socks feature enabled.

The proxy is ignored when targeting wasm32.

-
concurrency: Option<u8>

Number of parallel requests sent to the esplora service (default: 4)

-
stop_gap: usize

Stop searching addresses for transactions after finding an unused gap of this length.

-
timeout: Option<u64>

Socket timeout.

-

Implementations

create a config with default values given the base url and stop gap

-

Trait Implementations

Returns a copy of the value. Read more

-

Performs copy-assignment from source. Read more

-

Formats the value using the given formatter. Read more

-

Deserialize this value from the given Serde deserializer. Read more

-

Performs the conversion.

-

This method tests for self and other values to be equal, and is used -by ==. Read more

-

This method tests for !=.

-

Serialize this value into the given Serde serializer. Read more

-

Auto Trait Implementations

Blanket Implementations

Gets the TypeId of self. Read more

-

Immutably borrows from an owned value. Read more

-

Mutably borrows from an owned value. Read more

-

Performs the conversion.

-

Performs the conversion.

-

The alignment of pointer.

-

The type for initializers.

-

Initializes a with the given initializer. Read more

-

Dereferences the given pointer. Read more

-

Mutably dereferences the given pointer. Read more

-

Drops the object pointed to by the given pointer. Read more

-

The resulting type after obtaining ownership.

-

Creates owned data from borrowed data, usually by cloning. Read more

-
🔬 This is a nightly-only experimental API. (toowned_clone_into)

Uses borrowed data to replace owned data, usually by cloning. Read more

-

The type returned in the event of a conversion error.

-

Performs the conversion.

-

The type returned in the event of a conversion error.

-

Performs the conversion.

-
- \ No newline at end of file +§concurrency: Option<u8>

Number of parallel requests sent to the esplora service (default: 4)

+
§stop_gap: usize

Stop searching addresses for transactions after finding an unused gap of this length.

+
§timeout: Option<u64>

Socket timeout.

+

Implementations§

create a config with default values given the base url and stop gap

+

Trait Implementations§

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

Auto Trait Implementations§

Blanket Implementations§

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

Returns the argument unchanged.

+

Calls U::from(self).

+

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

+
The alignment of pointer.
The type for initializers.
Initializes a with the given initializer. Read more
Dereferences the given pointer. Read more
Mutably dereferences the given pointer. Read more
Drops the object pointed to by the given pointer. Read more
The resulting type after obtaining ownership.
Creates owned data from borrowed data, usually by cloning. Read more
Uses borrowed data to replace owned data, usually by cloning. Read more
The type returned in the event of a conversion error.
Performs the conversion.
The type returned in the event of a conversion error.
Performs the conversion.
\ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/blockchain/fn.log_progress.html b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/blockchain/fn.log_progress.html index df43158902..3761884943 100644 --- a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/blockchain/fn.log_progress.html +++ b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/blockchain/fn.log_progress.html @@ -1,11 +1,3 @@ -log_progress in bdk::blockchain - Rust - -
pub fn log_progress() -> LogProgress
Expand description

Create a new instance of LogProgress

-
- \ No newline at end of file +log_progress in bdk::blockchain - Rust

Function bdk::blockchain::log_progress

source ·
pub fn log_progress() -> LogProgress
Expand description

Create a new instance of LogProgress

+
\ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/blockchain/fn.noop_progress.html b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/blockchain/fn.noop_progress.html index e9d846da6e..2ae5b6972c 100644 --- a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/blockchain/fn.noop_progress.html +++ b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/blockchain/fn.noop_progress.html @@ -1,11 +1,3 @@ -noop_progress in bdk::blockchain - Rust - -
pub fn noop_progress() -> NoopProgress
Expand description

Create a new instance of NoopProgress

-
- \ No newline at end of file +noop_progress in bdk::blockchain - Rust

Function bdk::blockchain::noop_progress

source ·
pub fn noop_progress() -> NoopProgress
Expand description

Create a new instance of NoopProgress

+
\ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/blockchain/fn.progress.html b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/blockchain/fn.progress.html index ec0b8b0ede..6681e8fe0a 100644 --- a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/blockchain/fn.progress.html +++ b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/blockchain/fn.progress.html @@ -1,11 +1,3 @@ -progress in bdk::blockchain - Rust - -
-

Function bdk::blockchain::progress

source · []
pub fn progress() -> (Sender<ProgressData>, Receiver<ProgressData>)
Expand description

Shortcut to create a channel (pair of Sender and Receiver) that can transport ProgressData

-
- \ No newline at end of file +progress in bdk::blockchain - Rust

Function bdk::blockchain::progress

source ·
pub fn progress() -> (Sender<ProgressData>, Receiver<ProgressData>)
Expand description

Shortcut to create a channel (pair of Sender and Receiver) that can transport ProgressData

+
\ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/blockchain/index.html b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/blockchain/index.html index 080b1d25db..5e2cc4eab0 100644 --- a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/blockchain/index.html +++ b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/blockchain/index.html @@ -1,45 +1,8 @@ -bdk::blockchain - Rust - -
-

Module bdk::blockchain

source · []
Expand description

Blockchain backends

+bdk::blockchain - Rust

Module bdk::blockchain

source ·
Expand description

Blockchain backends

This module provides the implementation of a few commonly-used backends like Electrum, Esplora and Compact Filters/Neutrino, along with a generalized trait Blockchain that can be implemented to build customized backends.

-

Re-exports

-
pub use any::AnyBlockchain;
pub use any::AnyBlockchainConfig;
pub use self::electrum::ElectrumBlockchain;
pub use self::electrum::ElectrumBlockchainConfig;
pub use self::rpc::RpcBlockchain;
pub use self::rpc::RpcConfig;
pub use self::compact_filters::CompactFiltersBlockchain;

Modules

-

Runtime-checked blockchain types

-
compact_filterscompact_filters

Compact Filters

-
electrumelectrum

Electrum

-
esploraesplora

Esplora

-
rpcrpc

Rpc Blockchain

-

Structs

-

Structure that implements the logic to sync with Esplora

-

Type that implements Progress and logs at level INFO every update received

-

Type that implements Progress and drops every update received

-

Enums

-

Capabilities that can be supported by a Blockchain backend

-

Traits

-

Trait that defines the actions that must be supported by a blockchain backend

-

Trait for a factory of blockchains that share the underlying connection or configuration

-

Trait for Blockchain types that can be created given a configuration

-

Trait for getting block hash by block height

-

Trait for getting the current height of the blockchain.

-

Trait for getting a transaction by txid

-

Trait for types that can receive and process progress updates during WalletSync::wallet_sync and -WalletSync::wallet_setup

-

Trait for blockchains that don’t contain any state

-

Trait for blockchains that can sync by updating the database directly.

-

Functions

-

Create a new instance of LogProgress

-

Create a new instance of NoopProgress

-

Shortcut to create a channel (pair of Sender and Receiver) that can transport ProgressData

-

Type Definitions

-

Data sent with a progress update over a channel

-
- \ No newline at end of file +

Re-exports

pub use any::AnyBlockchain;
pub use any::AnyBlockchainConfig;
pub use self::electrum::ElectrumBlockchain;
pub use self::electrum::ElectrumBlockchainConfig;
pub use self::rpc::RpcBlockchain;
pub use self::rpc::RpcConfig;
pub use self::compact_filters::CompactFiltersBlockchain;

Modules

Runtime-checked blockchain types
compact_filterscompact_filters
Compact Filters
electrumelectrum
Electrum
esploraesplora
Esplora
rpcrpc
Rpc Blockchain

Structs

Structure that implements the logic to sync with Esplora
Type that implements Progress and logs at level INFO every update received
Type that implements Progress and drops every update received

Enums

Capabilities that can be supported by a Blockchain backend

Traits

Trait that defines the actions that must be supported by a blockchain backend
Trait for a factory of blockchains that share the underlying connection or configuration
Trait for Blockchain types that can be created given a configuration
Trait for getting block hash by block height
Trait for getting the current height of the blockchain.
Trait for getting a transaction by txid
Trait for types that can receive and process progress updates during WalletSync::wallet_sync and +WalletSync::wallet_setup
Trait for blockchains that don’t contain any state
Trait for blockchains that can sync by updating the database directly.

Functions

Create a new instance of LogProgress
Create a new instance of NoopProgress
Shortcut to create a channel (pair of Sender and Receiver) that can transport ProgressData

Type Definitions

Data sent with a progress update over a channel
\ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/blockchain/rpc/enum.Auth.html b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/blockchain/rpc/enum.Auth.html index 7269b91ab1..011b51d5c9 100644 --- a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/blockchain/rpc/enum.Auth.html +++ b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/blockchain/rpc/enum.Auth.html @@ -1,12 +1,5 @@ -Auth in bdk::blockchain::rpc - Rust - -
pub enum Auth {
+Auth in bdk::blockchain::rpc - Rust

Enum bdk::blockchain::rpc::Auth

source ·
pub enum Auth {
     None,
     UserPass {
         username: String,
@@ -15,54 +8,21 @@
     Cookie {
         file: PathBuf,
     },
-}
This is supported on crate feature rpc only.
Expand description

This struct is equivalent to [bitcoincore_rpc::Auth] but it implements serde::Serialize +}

Available on crate feature rpc only.
Expand description

This struct is equivalent to [bitcoincore_rpc::Auth] but it implements serde::Serialize To be removed once upstream equivalent is implementing Serialize (json serialization format should be the same), see rust-bitcoincore-rpc/pull/181

-

Variants

None

None authentication

-

UserPass

Fields

username: String

Username

-
password: String

Password

+

Variants§

§

None

None authentication

+
§

UserPass

Fields

§username: String

Username

+
§password: String

Password

Authentication with username and password, usually Auth::Cookie should be preferred

-

Cookie

Fields

file: PathBuf

Cookie file

+
§

Cookie

Fields

§file: PathBuf

Cookie file

Authentication with a cookie file

-

Trait Implementations

Returns a copy of the value. Read more

-

Performs copy-assignment from source. Read more

-

Formats the value using the given formatter. Read more

-

Deserialize this value from the given Serde deserializer. Read more

-

Performs the conversion.

-

Feeds this value into the given Hasher. Read more

-

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

-

This method returns an Ordering between self and other. Read more

-

Compares and returns the maximum of two values. Read more

-

Compares and returns the minimum of two values. Read more

-

Restrict a value to a certain interval. Read more

-

This method tests for self and other values to be equal, and is used -by ==. Read more

-

This method tests for !=.

-

This method returns an ordering between self and other values if one exists. Read more

-

This method tests less than (for self and other) and is used by the < operator. Read more

-

This method tests less than or equal to (for self and other) and is used by the <= -operator. Read more

-

This method tests greater than (for self and other) and is used by the > operator. Read more

-

This method tests greater than or equal to (for self and other) and is used by the >= -operator. Read more

-

Serialize this value into the given Serde serializer. Read more

-

Auto Trait Implementations

Blanket Implementations

Gets the TypeId of self. Read more

-

Immutably borrows from an owned value. Read more

-

Mutably borrows from an owned value. Read more

-

Performs the conversion.

-

Performs the conversion.

-

The alignment of pointer.

-

The type for initializers.

-

Initializes a with the given initializer. Read more

-

Dereferences the given pointer. Read more

-

Mutably dereferences the given pointer. Read more

-

Drops the object pointed to by the given pointer. Read more

-

The resulting type after obtaining ownership.

-

Creates owned data from borrowed data, usually by cloning. Read more

-
🔬 This is a nightly-only experimental API. (toowned_clone_into)

Uses borrowed data to replace owned data, usually by cloning. Read more

-

The type returned in the event of a conversion error.

-

Performs the conversion.

-

The type returned in the event of a conversion error.

-

Performs the conversion.

-
- \ No newline at end of file +

Trait Implementations§

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

Auto Trait Implementations§

Blanket Implementations§

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

Returns the argument unchanged.

+

Calls U::from(self).

+

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

+
The alignment of pointer.
The type for initializers.
Initializes a with the given initializer. Read more
Dereferences the given pointer. Read more
Mutably dereferences the given pointer. Read more
Drops the object pointed to by the given pointer. Read more
The resulting type after obtaining ownership.
Creates owned data from borrowed data, usually by cloning. Read more
Uses borrowed data to replace owned data, usually by cloning. Read more
The type returned in the event of a conversion error.
Performs the conversion.
The type returned in the event of a conversion error.
Performs the conversion.
\ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/blockchain/rpc/index.html b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/blockchain/rpc/index.html index b46c724a56..cdd0509971 100644 --- a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/blockchain/rpc/index.html +++ b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/blockchain/rpc/index.html @@ -1,33 +1,18 @@ -bdk::blockchain::rpc - Rust - -
-

Module bdk::blockchain::rpc

source · []
This is supported on crate feature rpc only.
Expand description

Rpc Blockchain

+bdk::blockchain::rpc - Rust

Module bdk::blockchain::rpc

source ·
Available on crate feature rpc only.
Expand description

Rpc Blockchain

Backend that gets blockchain data from Bitcoin Core RPC

This is an EXPERIMENTAL feature, API and other major changes are expected.

-

Example

-
let config = RpcConfig {
-    url: "127.0.0.1:18332".to_string(),
-    auth: Auth::Cookie {
-        file: "/home/user/.bitcoin/.cookie".into(),
+

Example

+
let config = RpcConfig {
+    url: "127.0.0.1:18332".to_string(),
+    auth: Auth::Cookie {
+        file: "/home/user/.bitcoin/.cookie".into(),
     },
-    network: bdk::bitcoin::Network::Testnet,
-    wallet_name: "wallet_name".to_string(),
-    sync_params: None,
+    network: bdk::bitcoin::Network::Testnet,
+    wallet_name: "wallet_name".to_string(),
+    sync_params: None,
 };
-let blockchain = RpcBlockchain::from_config(&config);
-

Structs

-

The main struct for RPC backend implementing the crate::blockchain::Blockchain trait

-

Factory of RpcBlockchain instances, implements BlockchainFactory

-

RpcBlockchain configuration options

-

Sync parameters for Bitcoin Core RPC.

-

Enums

-

This struct is equivalent to [bitcoincore_rpc::Auth] but it implements serde::Serialize +let blockchain = RpcBlockchain::from_config(&config);

+

Structs

The main struct for RPC backend implementing the crate::blockchain::Blockchain trait
Factory of RpcBlockchain instances, implements BlockchainFactory
RpcBlockchain configuration options
Sync parameters for Bitcoin Core RPC.

Enums

This struct is equivalent to [bitcoincore_rpc::Auth] but it implements serde::Serialize To be removed once upstream equivalent is implementing Serialize (json serialization format -should be the same), see rust-bitcoincore-rpc/pull/181

-
- \ No newline at end of file +should be the same), see rust-bitcoincore-rpc/pull/181
\ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/blockchain/rpc/sidebar-items.js b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/blockchain/rpc/sidebar-items.js index 0cf4ae23a5..8e01f942a8 100644 --- a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/blockchain/rpc/sidebar-items.js +++ b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/blockchain/rpc/sidebar-items.js @@ -1 +1 @@ -initSidebarItems({"enum":[["Auth","This struct is equivalent to [bitcoincore_rpc::Auth] but it implements [serde::Serialize] To be removed once upstream equivalent is implementing Serialize (json serialization format should be the same), see rust-bitcoincore-rpc/pull/181"]],"struct":[["RpcBlockchain","The main struct for RPC backend implementing the [crate::blockchain::Blockchain] trait"],["RpcBlockchainFactory","Factory of [`RpcBlockchain`] instances, implements [`BlockchainFactory`]"],["RpcConfig","RpcBlockchain configuration options"],["RpcSyncParams","Sync parameters for Bitcoin Core RPC."]]}); \ No newline at end of file +window.SIDEBAR_ITEMS = {"enum":[["Auth","This struct is equivalent to [bitcoincore_rpc::Auth] but it implements [serde::Serialize] To be removed once upstream equivalent is implementing Serialize (json serialization format should be the same), see rust-bitcoincore-rpc/pull/181"]],"struct":[["RpcBlockchain","The main struct for RPC backend implementing the [crate::blockchain::Blockchain] trait"],["RpcBlockchainFactory","Factory of [`RpcBlockchain`] instances, implements [`BlockchainFactory`]"],["RpcConfig","RpcBlockchain configuration options"],["RpcSyncParams","Sync parameters for Bitcoin Core RPC."]]}; \ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/blockchain/rpc/struct.RpcBlockchain.html b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/blockchain/rpc/struct.RpcBlockchain.html index 19a02ec75a..bc55a6b0c5 100644 --- a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/blockchain/rpc/struct.RpcBlockchain.html +++ b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/blockchain/rpc/struct.RpcBlockchain.html @@ -1,42 +1,10 @@ -RpcBlockchain in bdk::blockchain::rpc - Rust - -
pub struct RpcBlockchain { /* private fields */ }
This is supported on crate feature rpc only.
Expand description

The main struct for RPC backend implementing the crate::blockchain::Blockchain trait

-

Methods from Deref<Target = Client>

Get the underlying JSONRPC client.

-

Trait Implementations

Return the set of Capability supported by this backend

-

Broadcast a transaction

-

Estimate the fee rate required to confirm a transaction in a given target of blocks

-

Returns RpcBlockchain backend creating an RPC client to a specific wallet named as the descriptor’s checksum +RpcBlockchain in bdk::blockchain::rpc - Rust

Struct bdk::blockchain::rpc::RpcBlockchain

source ·
pub struct RpcBlockchain { /* private fields */ }
Available on crate feature rpc only.
Expand description

The main struct for RPC backend implementing the crate::blockchain::Blockchain trait

+

Methods from Deref<Target = Client>§

Get the underlying JSONRPC client.

+

Trait Implementations§

Return the set of Capability supported by this backend
Broadcast a transaction
Estimate the fee rate required to confirm a transaction in a given target of blocks

Returns RpcBlockchain backend creating an RPC client to a specific wallet named as the descriptor’s checksum if it’s the first time it creates the wallet in the node and upon return is granted the wallet is loaded

-

Type that contains the configuration

-

Formats the value using the given formatter. Read more

-

The resulting type after dereferencing.

-

Dereferences the value.

-

Performs the conversion.

-

fetch block hash given its height

-

Return the current height

-

Fetch a transaction given its txid

-

Setup the backend and populate the internal database for the first time Read more

-

If not overridden, it defaults to calling Self::wallet_setup internally. Read more

-

Auto Trait Implementations

Blanket Implementations

Gets the TypeId of self. Read more

-

Immutably borrows from an owned value. Read more

-

Mutably borrows from an owned value. Read more

-

Performs the conversion.

-

Performs the conversion.

-

The alignment of pointer.

-

The type for initializers.

-

Initializes a with the given initializer. Read more

-

Dereferences the given pointer. Read more

-

Mutably dereferences the given pointer. Read more

-

Drops the object pointed to by the given pointer. Read more

-

The type returned in the event of a conversion error.

-

Performs the conversion.

-

The type returned in the event of a conversion error.

-

Performs the conversion.

-
- \ No newline at end of file +
Type that contains the configuration
Formats the value using the given formatter. Read more
The resulting type after dereferencing.
Dereferences the value.
Converts to this type from the input type.
fetch block hash given its height
Return the current height
Fetch a transaction given its txid
Setup the backend and populate the internal database for the first time Read more
If not overridden, it defaults to calling Self::wallet_setup internally. Read more

Auto Trait Implementations§

Blanket Implementations§

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

Returns the argument unchanged.

+

Calls U::from(self).

+

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

+
The alignment of pointer.
The type for initializers.
Initializes a with the given initializer. Read more
Dereferences the given pointer. Read more
Mutably dereferences the given pointer. Read more
Drops the object pointed to by the given pointer. Read more
The type returned in the event of a conversion error.
Performs the conversion.
The type returned in the event of a conversion error.
Performs the conversion.
\ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/blockchain/rpc/struct.RpcBlockchainFactory.html b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/blockchain/rpc/struct.RpcBlockchainFactory.html index d717ea53f9..60ce920e12 100644 --- a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/blockchain/rpc/struct.RpcBlockchainFactory.html +++ b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/blockchain/rpc/struct.RpcBlockchainFactory.html @@ -1,63 +1,34 @@ -RpcBlockchainFactory in bdk::blockchain::rpc - Rust - -
pub struct RpcBlockchainFactory {
+RpcBlockchainFactory in bdk::blockchain::rpc - Rust
pub struct RpcBlockchainFactory {
     pub url: String,
     pub auth: Auth,
     pub network: Network,
     pub wallet_name_prefix: Option<String>,
     pub default_skip_blocks: u32,
     pub sync_params: Option<RpcSyncParams>,
-}
This is supported on crate feature rpc only.
Expand description

Factory of RpcBlockchain instances, implements BlockchainFactory

+}
Available on crate feature rpc only.
Expand description

Factory of RpcBlockchain instances, implements BlockchainFactory

Internally caches the node url and authentication params and allows getting many different RpcBlockchain objects for different wallet names and with different rescan heights.

-

Example

-
let factory = RpcBlockchainFactory {
-    url: "http://127.0.0.1:18332".to_string(),
-    auth: Auth::Cookie {
-        file: "/home/user/.bitcoin/.cookie".into(),
+

Example

+
let factory = RpcBlockchainFactory {
+    url: "http://127.0.0.1:18332".to_string(),
+    auth: Auth::Cookie {
+        file: "/home/user/.bitcoin/.cookie".into(),
     },
-    network: Network::Testnet,
-    wallet_name_prefix: Some("prefix-".to_string()),
-    default_skip_blocks: 100_000,
-    sync_params: None,
+    network: Network::Testnet,
+    wallet_name_prefix: Some("prefix-".to_string()),
+    default_skip_blocks: 100_000,
+    sync_params: None,
 };
-let main_wallet_blockchain = factory.build("main_wallet", Some(200_000))?;
-

Fields

url: String

The bitcoin node url

-
auth: Auth

The bitcoin node authentication mechanism

-
network: Network

The network we are using (it will be checked the bitcoin node network matches this)

-
wallet_name_prefix: Option<String>

The optional prefix used to build the full wallet name for blockchains

-
default_skip_blocks: u32

Default number of blocks to skip which will be inherited by blockchain unless overridden

-
sync_params: Option<RpcSyncParams>

Sync parameters

-

Trait Implementations

The type returned when building a blockchain from this factory

-

Build a new blockchain for the given descriptor wallet_name Read more

-

Build a new blockchain for a given wallet Read more

-
This is supported on neither WebAssembly nor crate feature async-interface.

Use BlockchainFactory::build_for_wallet to get a blockchain, then sync the wallet Read more

-

Returns a copy of the value. Read more

-

Performs copy-assignment from source. Read more

-

Formats the value using the given formatter. Read more

-

Auto Trait Implementations

Blanket Implementations

Gets the TypeId of self. Read more

-

Immutably borrows from an owned value. Read more

-

Mutably borrows from an owned value. Read more

-

Performs the conversion.

-

Performs the conversion.

-

The alignment of pointer.

-

The type for initializers.

-

Initializes a with the given initializer. Read more

-

Dereferences the given pointer. Read more

-

Mutably dereferences the given pointer. Read more

-

Drops the object pointed to by the given pointer. Read more

-

The resulting type after obtaining ownership.

-

Creates owned data from borrowed data, usually by cloning. Read more

-
🔬 This is a nightly-only experimental API. (toowned_clone_into)

Uses borrowed data to replace owned data, usually by cloning. Read more

-

The type returned in the event of a conversion error.

-

Performs the conversion.

-

The type returned in the event of a conversion error.

-

Performs the conversion.

-
- \ No newline at end of file +let main_wallet_blockchain = factory.build("main_wallet", Some(200_000))?; +

Fields§

§url: String

The bitcoin node url

+
§auth: Auth

The bitcoin node authentication mechanism

+
§network: Network

The network we are using (it will be checked the bitcoin node network matches this)

+
§wallet_name_prefix: Option<String>

The optional prefix used to build the full wallet name for blockchains

+
§default_skip_blocks: u32

Default number of blocks to skip which will be inherited by blockchain unless overridden

+
§sync_params: Option<RpcSyncParams>

Sync parameters

+

Trait Implementations§

The type returned when building a blockchain from this factory
Build a new blockchain for the given descriptor wallet_name Read more
Build a new blockchain for a given wallet Read more
Available on neither WebAssembly nor crate feature async-interface.
Use BlockchainFactory::build_for_wallet to get a blockchain, then sync the wallet Read more
Returns a copy of the value. Read more
Performs copy-assignment from source. Read more
Formats the value using the given formatter. Read more

Auto Trait Implementations§

Blanket Implementations§

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

Returns the argument unchanged.

+

Calls U::from(self).

+

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

+
The alignment of pointer.
The type for initializers.
Initializes a with the given initializer. Read more
Dereferences the given pointer. Read more
Mutably dereferences the given pointer. Read more
Drops the object pointed to by the given pointer. Read more
The resulting type after obtaining ownership.
Creates owned data from borrowed data, usually by cloning. Read more
Uses borrowed data to replace owned data, usually by cloning. Read more
The type returned in the event of a conversion error.
Performs the conversion.
The type returned in the event of a conversion error.
Performs the conversion.
\ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/blockchain/rpc/struct.RpcConfig.html b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/blockchain/rpc/struct.RpcConfig.html index 03e2bb19c9..dee6048575 100644 --- a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/blockchain/rpc/struct.RpcConfig.html +++ b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/blockchain/rpc/struct.RpcConfig.html @@ -1,49 +1,20 @@ -RpcConfig in bdk::blockchain::rpc - Rust - -
pub struct RpcConfig {
+RpcConfig in bdk::blockchain::rpc - Rust

Struct bdk::blockchain::rpc::RpcConfig

source ·
pub struct RpcConfig {
     pub url: String,
     pub auth: Auth,
     pub network: Network,
     pub wallet_name: String,
     pub sync_params: Option<RpcSyncParams>,
-}
This is supported on crate feature rpc only.
Expand description

RpcBlockchain configuration options

-

Fields

url: String

The bitcoin node url

-
auth: Auth

The bitcoin node authentication mechanism

-
network: Network

The network we are using (it will be checked the bitcoin node network matches this)

-
wallet_name: String

The wallet name in the bitcoin node, consider using crate::wallet::wallet_name_from_descriptor for this

-
sync_params: Option<RpcSyncParams>

Sync parameters

-

Trait Implementations

Returns a copy of the value. Read more

-

Performs copy-assignment from source. Read more

-

Formats the value using the given formatter. Read more

-

Deserialize this value from the given Serde deserializer. Read more

-

Performs the conversion.

-

This method tests for self and other values to be equal, and is used -by ==. Read more

-

This method tests for !=.

-

Serialize this value into the given Serde serializer. Read more

-

Auto Trait Implementations

Blanket Implementations

Gets the TypeId of self. Read more

-

Immutably borrows from an owned value. Read more

-

Mutably borrows from an owned value. Read more

-

Performs the conversion.

-

Performs the conversion.

-

The alignment of pointer.

-

The type for initializers.

-

Initializes a with the given initializer. Read more

-

Dereferences the given pointer. Read more

-

Mutably dereferences the given pointer. Read more

-

Drops the object pointed to by the given pointer. Read more

-

The resulting type after obtaining ownership.

-

Creates owned data from borrowed data, usually by cloning. Read more

-
🔬 This is a nightly-only experimental API. (toowned_clone_into)

Uses borrowed data to replace owned data, usually by cloning. Read more

-

The type returned in the event of a conversion error.

-

Performs the conversion.

-

The type returned in the event of a conversion error.

-

Performs the conversion.

-
- \ No newline at end of file +}
Available on crate feature rpc only.
Expand description

RpcBlockchain configuration options

+

Fields§

§url: String

The bitcoin node url

+
§auth: Auth

The bitcoin node authentication mechanism

+
§network: Network

The network we are using (it will be checked the bitcoin node network matches this)

+
§wallet_name: String

The wallet name in the bitcoin node, consider using crate::wallet::wallet_name_from_descriptor for this

+
§sync_params: Option<RpcSyncParams>

Sync parameters

+

Trait Implementations§

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

Auto Trait Implementations§

Blanket Implementations§

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

Returns the argument unchanged.

+

Calls U::from(self).

+

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

+
The alignment of pointer.
The type for initializers.
Initializes a with the given initializer. Read more
Dereferences the given pointer. Read more
Mutably dereferences the given pointer. Read more
Drops the object pointed to by the given pointer. Read more
The resulting type after obtaining ownership.
Creates owned data from borrowed data, usually by cloning. Read more
Uses borrowed data to replace owned data, usually by cloning. Read more
The type returned in the event of a conversion error.
Performs the conversion.
The type returned in the event of a conversion error.
Performs the conversion.
\ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/blockchain/rpc/struct.RpcSyncParams.html b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/blockchain/rpc/struct.RpcSyncParams.html index 2e85cf03b5..cbd0b68645 100644 --- a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/blockchain/rpc/struct.RpcSyncParams.html +++ b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/blockchain/rpc/struct.RpcSyncParams.html @@ -1,50 +1,21 @@ -RpcSyncParams in bdk::blockchain::rpc - Rust - -
pub struct RpcSyncParams {
+RpcSyncParams in bdk::blockchain::rpc - Rust

Struct bdk::blockchain::rpc::RpcSyncParams

source ·
pub struct RpcSyncParams {
     pub start_script_count: usize,
     pub start_time: u64,
     pub force_start_time: bool,
     pub poll_rate_sec: u64,
-}
This is supported on crate feature rpc only.
Expand description

Sync parameters for Bitcoin Core RPC.

+}
Available on crate feature rpc only.
Expand description

Sync parameters for Bitcoin Core RPC.

In general, BDK tries to sync scriptPubKeys cached in crate::database::Database with scriptPubKeys imported in the Bitcoin Core Wallet. These parameters are used for determining how the importdescriptors RPC calls are to be made.

-

Fields

start_script_count: usize

The minimum number of scripts to scan for on initial sync.

-
start_time: u64

Time in unix seconds in which initial sync will start scanning from (0 to start from genesis).

-
force_start_time: bool

Forces every sync to use start_time as import timestamp.

-
poll_rate_sec: u64

RPC poll rate (in seconds) to get state updates.

-

Trait Implementations

Returns a copy of the value. Read more

-

Performs copy-assignment from source. Read more

-

Formats the value using the given formatter. Read more

-

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

-

Deserialize this value from the given Serde deserializer. Read more

-

This method tests for self and other values to be equal, and is used -by ==. Read more

-

This method tests for !=.

-

Serialize this value into the given Serde serializer. Read more

-

Auto Trait Implementations

Blanket Implementations

Gets the TypeId of self. Read more

-

Immutably borrows from an owned value. Read more

-

Mutably borrows from an owned value. Read more

-

Performs the conversion.

-

Performs the conversion.

-

The alignment of pointer.

-

The type for initializers.

-

Initializes a with the given initializer. Read more

-

Dereferences the given pointer. Read more

-

Mutably dereferences the given pointer. Read more

-

Drops the object pointed to by the given pointer. Read more

-

The resulting type after obtaining ownership.

-

Creates owned data from borrowed data, usually by cloning. Read more

-
🔬 This is a nightly-only experimental API. (toowned_clone_into)

Uses borrowed data to replace owned data, usually by cloning. Read more

-

The type returned in the event of a conversion error.

-

Performs the conversion.

-

The type returned in the event of a conversion error.

-

Performs the conversion.

-
- \ No newline at end of file +

Fields§

§start_script_count: usize

The minimum number of scripts to scan for on initial sync.

+
§start_time: u64

Time in unix seconds in which initial sync will start scanning from (0 to start from genesis).

+
§force_start_time: bool

Forces every sync to use start_time as import timestamp.

+
§poll_rate_sec: u64

RPC poll rate (in seconds) to get state updates.

+

Trait Implementations§

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

Auto Trait Implementations§

Blanket Implementations§

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

Returns the argument unchanged.

+

Calls U::from(self).

+

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

+
The alignment of pointer.
The type for initializers.
Initializes a with the given initializer. Read more
Dereferences the given pointer. Read more
Mutably dereferences the given pointer. Read more
Drops the object pointed to by the given pointer. Read more
The resulting type after obtaining ownership.
Creates owned data from borrowed data, usually by cloning. Read more
Uses borrowed data to replace owned data, usually by cloning. Read more
The type returned in the event of a conversion error.
Performs the conversion.
The type returned in the event of a conversion error.
Performs the conversion.
\ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/blockchain/sidebar-items.js b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/blockchain/sidebar-items.js index a11daf6513..50df514818 100644 --- a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/blockchain/sidebar-items.js +++ b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/blockchain/sidebar-items.js @@ -1 +1 @@ -initSidebarItems({"enum":[["Capability","Capabilities that can be supported by a [`Blockchain`] backend"]],"fn":[["log_progress","Create a new instance of [`LogProgress`]"],["noop_progress","Create a new instance of [`NoopProgress`]"],["progress","Shortcut to create a [`channel`] (pair of [`Sender`] and [`Receiver`]) that can transport [`ProgressData`]"]],"mod":[["any","Runtime-checked blockchain types"],["compact_filters","Compact Filters"],["electrum","Electrum"],["esplora","Esplora"],["rpc","Rpc Blockchain"]],"struct":[["EsploraBlockchain","Structure that implements the logic to sync with Esplora"],["LogProgress","Type that implements [`Progress`] and logs at level `INFO` every update received"],["NoopProgress","Type that implements [`Progress`] and drops every update received"]],"trait":[["Blockchain","Trait that defines the actions that must be supported by a blockchain backend"],["BlockchainFactory","Trait for a factory of blockchains that share the underlying connection or configuration"],["ConfigurableBlockchain","Trait for [`Blockchain`] types that can be created given a configuration"],["GetBlockHash","Trait for getting block hash by block height"],["GetHeight","Trait for getting the current height of the blockchain."],["GetTx","Trait for getting a transaction by txid"],["Progress","Trait for types that can receive and process progress updates during [`WalletSync::wallet_sync`] and [`WalletSync::wallet_setup`]"],["StatelessBlockchain","Trait for blockchains that don’t contain any state"],["WalletSync","Trait for blockchains that can sync by updating the database directly."]],"type":[["ProgressData","Data sent with a progress update over a [`channel`]"]]}); \ No newline at end of file +window.SIDEBAR_ITEMS = {"enum":[["Capability","Capabilities that can be supported by a [`Blockchain`] backend"]],"fn":[["log_progress","Create a new instance of [`LogProgress`]"],["noop_progress","Create a new instance of [`NoopProgress`]"],["progress","Shortcut to create a [`channel`] (pair of [`Sender`] and [`Receiver`]) that can transport [`ProgressData`]"]],"mod":[["any","Runtime-checked blockchain types"],["compact_filters","Compact Filters"],["electrum","Electrum"],["esplora","Esplora"],["rpc","Rpc Blockchain"]],"struct":[["EsploraBlockchain","Structure that implements the logic to sync with Esplora"],["LogProgress","Type that implements [`Progress`] and logs at level `INFO` every update received"],["NoopProgress","Type that implements [`Progress`] and drops every update received"]],"trait":[["Blockchain","Trait that defines the actions that must be supported by a blockchain backend"],["BlockchainFactory","Trait for a factory of blockchains that share the underlying connection or configuration"],["ConfigurableBlockchain","Trait for [`Blockchain`] types that can be created given a configuration"],["GetBlockHash","Trait for getting block hash by block height"],["GetHeight","Trait for getting the current height of the blockchain."],["GetTx","Trait for getting a transaction by txid"],["Progress","Trait for types that can receive and process progress updates during [`WalletSync::wallet_sync`] and [`WalletSync::wallet_setup`]"],["StatelessBlockchain","Trait for blockchains that don’t contain any state"],["WalletSync","Trait for blockchains that can sync by updating the database directly."]],"type":[["ProgressData","Data sent with a progress update over a [`channel`]"]]}; \ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/blockchain/struct.EsploraBlockchain.html b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/blockchain/struct.EsploraBlockchain.html index 1024626bab..beb00dfe59 100644 --- a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/blockchain/struct.EsploraBlockchain.html +++ b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/blockchain/struct.EsploraBlockchain.html @@ -1,64 +1,30 @@ -EsploraBlockchain in bdk::blockchain - Rust - -
pub struct EsploraBlockchain { /* private fields */ }
Expand description

Structure that implements the logic to sync with Esplora

-

Example

+EsploraBlockchain in bdk::blockchain - Rust
pub struct EsploraBlockchain { /* private fields */ }
Available on crate feature esplora only.
Expand description

Structure that implements the logic to sync with Esplora

+

Example

See the blockchain::esplora module for a usage example.

-

Implementations

This is supported on crate feature esplora only.

Create a new instance of the client from a base URL and the stop_gap.

-
This is supported on crate feature esplora only.

Build a new instance given a client

-
This is supported on crate feature esplora only.

Set the number of parallel requests the client can make.

-

Methods from Deref<Target = BlockingClient>

Get a [Transaction] option given its [Txid]

-

Get a [Transaction] given its [Txid].

-

Get a [Txid] of a transaction given its index in a block with a given hash.

-

Get the status of a [Transaction] given its [Txid].

-
👎 Deprecated since 0.1.2:

Deprecated to improve alignment with Esplora API. Users should use get_block_hash and get_header_by_hash methods directly.

-

Get a [BlockHeader] given a particular block height.

-

Get a [BlockHeader] given a particular block hash.

-

Get the [BlockStatus] given a particular [BlockHash].

-

Get a merkle inclusion proof for a [Transaction] with the given [Txid].

-

Get the spending status of an output given a [Txid] and the output index.

-

Broadcast a [Transaction] to Esplora

-

Get the height of the current blockchain tip.

-

Get the [BlockHash] of the current blockchain tip.

-

Get the [BlockHash] of a specific block height

-

Get an map where the key is the confirmation target (in number of blocks) +

Implementations§

Create a new instance of the client from a base URL and the stop_gap.

+

Build a new instance given a client

+

Set the number of parallel requests the client can make.

+

Methods from Deref<Target = BlockingClient>§

Get a [Transaction] option given its [Txid]

+

Get a [Transaction] given its [Txid].

+

Get a [Txid] of a transaction given its index in a block with a given hash.

+

Get the status of a [Transaction] given its [Txid].

+
👎Deprecated since 0.1.2: Deprecated to improve alignment with Esplora API. Users should use get_block_hash and get_header_by_hash methods directly.

Get a [BlockHeader] given a particular block height.

+

Get a [BlockHeader] given a particular block hash.

+

Get the [BlockStatus] given a particular [BlockHash].

+

Get a merkle inclusion proof for a [Transaction] with the given [Txid].

+

Get the spending status of an output given a [Txid] and the output index.

+

Broadcast a [Transaction] to Esplora

+

Get the height of the current blockchain tip.

+

Get the [BlockHash] of the current blockchain tip.

+

Get the [BlockHash] of a specific block height

+

Get an map where the key is the confirmation target (in number of blocks) and the value is the estimated feerate (in sat/vB).

-

Get confirmed transaction history for the specified address/scripthash, +

Get confirmed transaction history for the specified address/scripthash, sorted with newest first. Returns 25 transactions per page. More can be requested by specifying the last txid seen by the previous query.

-

Trait Implementations

Return the set of Capability supported by this backend

-

Broadcast a transaction

-

Estimate the fee rate required to confirm a transaction in a given target of blocks

-

Type that contains the configuration

-

Create a new instance given a configuration

-

Formats the value using the given formatter. Read more

-

The resulting type after dereferencing.

-

Dereferences the value.

-

Performs the conversion.

-

fetch block hash given its height

-

Return the current height

-

Fetch a transaction given its txid

-

Setup the backend and populate the internal database for the first time Read more

-

If not overridden, it defaults to calling Self::wallet_setup internally. Read more

-

Auto Trait Implementations

Blanket Implementations

Gets the TypeId of self. Read more

-

Immutably borrows from an owned value. Read more

-

Mutably borrows from an owned value. Read more

-

Performs the conversion.

-

Performs the conversion.

-

The alignment of pointer.

-

The type for initializers.

-

Initializes a with the given initializer. Read more

-

Dereferences the given pointer. Read more

-

Mutably dereferences the given pointer. Read more

-

Drops the object pointed to by the given pointer. Read more

-

The type returned in the event of a conversion error.

-

Performs the conversion.

-

The type returned in the event of a conversion error.

-

Performs the conversion.

-
- \ No newline at end of file +

Trait Implementations§

Return the set of Capability supported by this backend
Broadcast a transaction
Estimate the fee rate required to confirm a transaction in a given target of blocks
Type that contains the configuration
Create a new instance given a configuration
Formats the value using the given formatter. Read more
The resulting type after dereferencing.
Dereferences the value.
Converts to this type from the input type.
fetch block hash given its height
Return the current height
Fetch a transaction given its txid
Setup the backend and populate the internal database for the first time Read more
If not overridden, it defaults to calling Self::wallet_setup internally. Read more

Auto Trait Implementations§

Blanket Implementations§

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

Returns the argument unchanged.

+

Calls U::from(self).

+

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

+
The alignment of pointer.
The type for initializers.
Initializes a with the given initializer. Read more
Dereferences the given pointer. Read more
Mutably dereferences the given pointer. Read more
Drops the object pointed to by the given pointer. Read more
The type returned in the event of a conversion error.
Performs the conversion.
The type returned in the event of a conversion error.
Performs the conversion.
\ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/blockchain/struct.LogProgress.html b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/blockchain/struct.LogProgress.html index 1af6bebd76..f2dd46d216 100644 --- a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/blockchain/struct.LogProgress.html +++ b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/blockchain/struct.LogProgress.html @@ -1,34 +1,7 @@ -LogProgress in bdk::blockchain - Rust - -
pub struct LogProgress;
Expand description

Type that implements Progress and logs at level INFO every update received

-

Trait Implementations

Returns a copy of the value. Read more

-

Performs copy-assignment from source. Read more

-

Formats the value using the given formatter. Read more

-

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

-

Send a new progress update Read more

-

Auto Trait Implementations

Blanket Implementations

Gets the TypeId of self. Read more

-

Immutably borrows from an owned value. Read more

-

Mutably borrows from an owned value. Read more

-

Performs the conversion.

-

Performs the conversion.

-

The alignment of pointer.

-

The type for initializers.

-

Initializes a with the given initializer. Read more

-

Dereferences the given pointer. Read more

-

Mutably dereferences the given pointer. Read more

-

Drops the object pointed to by the given pointer. Read more

-

The resulting type after obtaining ownership.

-

Creates owned data from borrowed data, usually by cloning. Read more

-
🔬 This is a nightly-only experimental API. (toowned_clone_into)

Uses borrowed data to replace owned data, usually by cloning. Read more

-

The type returned in the event of a conversion error.

-

Performs the conversion.

-

The type returned in the event of a conversion error.

-

Performs the conversion.

-
- \ No newline at end of file +LogProgress in bdk::blockchain - Rust

Struct bdk::blockchain::LogProgress

source ·
pub struct LogProgress;
Expand description

Type that implements Progress and logs at level INFO every update received

+

Trait Implementations§

Returns a copy of the value. Read more
Performs copy-assignment from source. Read more
Formats the value using the given formatter. Read more
Returns the “default value” for a type. Read more
Send a new progress update Read more

Auto Trait Implementations§

Blanket Implementations§

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

Returns the argument unchanged.

+

Calls U::from(self).

+

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

+
The alignment of pointer.
The type for initializers.
Initializes a with the given initializer. Read more
Dereferences the given pointer. Read more
Mutably dereferences the given pointer. Read more
Drops the object pointed to by the given pointer. Read more
The resulting type after obtaining ownership.
Creates owned data from borrowed data, usually by cloning. Read more
Uses borrowed data to replace owned data, usually by cloning. Read more
The type returned in the event of a conversion error.
Performs the conversion.
The type returned in the event of a conversion error.
Performs the conversion.
\ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/blockchain/struct.NoopProgress.html b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/blockchain/struct.NoopProgress.html index 48f543feed..aa8da44e4e 100644 --- a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/blockchain/struct.NoopProgress.html +++ b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/blockchain/struct.NoopProgress.html @@ -1,34 +1,7 @@ -NoopProgress in bdk::blockchain - Rust - -
pub struct NoopProgress;
Expand description

Type that implements Progress and drops every update received

-

Trait Implementations

Returns a copy of the value. Read more

-

Performs copy-assignment from source. Read more

-

Formats the value using the given formatter. Read more

-

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

-

Send a new progress update Read more

-

Auto Trait Implementations

Blanket Implementations

Gets the TypeId of self. Read more

-

Immutably borrows from an owned value. Read more

-

Mutably borrows from an owned value. Read more

-

Performs the conversion.

-

Performs the conversion.

-

The alignment of pointer.

-

The type for initializers.

-

Initializes a with the given initializer. Read more

-

Dereferences the given pointer. Read more

-

Mutably dereferences the given pointer. Read more

-

Drops the object pointed to by the given pointer. Read more

-

The resulting type after obtaining ownership.

-

Creates owned data from borrowed data, usually by cloning. Read more

-
🔬 This is a nightly-only experimental API. (toowned_clone_into)

Uses borrowed data to replace owned data, usually by cloning. Read more

-

The type returned in the event of a conversion error.

-

Performs the conversion.

-

The type returned in the event of a conversion error.

-

Performs the conversion.

-
- \ No newline at end of file +NoopProgress in bdk::blockchain - Rust

Struct bdk::blockchain::NoopProgress

source ·
pub struct NoopProgress;
Expand description

Type that implements Progress and drops every update received

+

Trait Implementations§

Returns a copy of the value. Read more
Performs copy-assignment from source. Read more
Formats the value using the given formatter. Read more
Returns the “default value” for a type. Read more
Send a new progress update Read more

Auto Trait Implementations§

Blanket Implementations§

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

Returns the argument unchanged.

+

Calls U::from(self).

+

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

+
The alignment of pointer.
The type for initializers.
Initializes a with the given initializer. Read more
Dereferences the given pointer. Read more
Mutably dereferences the given pointer. Read more
Drops the object pointed to by the given pointer. Read more
The resulting type after obtaining ownership.
Creates owned data from borrowed data, usually by cloning. Read more
Uses borrowed data to replace owned data, usually by cloning. Read more
The type returned in the event of a conversion error.
Performs the conversion.
The type returned in the event of a conversion error.
Performs the conversion.
\ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/blockchain/trait.Blockchain.html b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/blockchain/trait.Blockchain.html index bce37063c1..a581155910 100644 --- a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/blockchain/trait.Blockchain.html +++ b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/blockchain/trait.Blockchain.html @@ -1,18 +1,10 @@ -Blockchain in bdk::blockchain - Rust - -
pub trait Blockchain: WalletSync + GetHeight + GetTx + GetBlockHash {
-    fn get_capabilities(&self) -> HashSet<Capability>;
-
fn broadcast(&self, tx: &Transaction) -> Result<(), Error>; -
fn estimate_fee(&self, target: usize) -> Result<FeeRate, Error>; +Blockchain in bdk::blockchain - Rust

Trait bdk::blockchain::Blockchain

source ·
pub trait Blockchain: WalletSync + GetHeight + GetTx + GetBlockHash {
+    fn get_capabilities(&self) -> HashSet<Capability>;
+    fn broadcast(&self, tx: &Transaction) -> Result<(), Error>;
+    fn estimate_fee(&self, target: usize) -> Result<FeeRate, Error>;
 }
Expand description

Trait that defines the actions that must be supported by a blockchain backend

-

Required methods

Return the set of Capability supported by this backend

-

Broadcast a transaction

-

Estimate the fee rate required to confirm a transaction in a given target of blocks

-

Implementations on Foreign Types

Implementors

- \ No newline at end of file +

Required Methods§

Return the set of Capability supported by this backend

+

Broadcast a transaction

+

Estimate the fee rate required to confirm a transaction in a given target of blocks

+

Implementations on Foreign Types§

Implementors§

\ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/blockchain/trait.BlockchainFactory.html b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/blockchain/trait.BlockchainFactory.html index c68429d891..173d2ba533 100644 --- a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/blockchain/trait.BlockchainFactory.html +++ b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/blockchain/trait.BlockchainFactory.html @@ -1,45 +1,38 @@ -BlockchainFactory in bdk::blockchain - Rust - -
pub trait BlockchainFactory {
+BlockchainFactory in bdk::blockchain - Rust
pub trait BlockchainFactory {
     type Inner: Blockchain;
-    fn build(
        &self,
        wallet_name: &str,
        override_skip_blocks: Option<u32>
    ) -> Result<Self::Inner, Error>; - fn build_for_wallet<D: BatchDatabase>(
        &self,
        wallet: &Wallet<D>,
        override_skip_blocks: Option<u32>
    ) -> Result<Self::Inner, Error> { ... } -
fn sync_wallet<D: BatchDatabase>(
        &self,
        wallet: &Wallet<D>,
        override_skip_blocks: Option<u32>,
        sync_options: SyncOptions
    ) -> Result<(), Error> { ... } + fn build(
        &self,
        wallet_name: &str,
        override_skip_blocks: Option<u32>
    ) -> Result<Self::Inner, Error>; + + fn build_for_wallet<D: BatchDatabase>(
        &self,
        wallet: &Wallet<D>,
        override_skip_blocks: Option<u32>
    ) -> Result<Self::Inner, Error> { ... } + fn sync_wallet<D: BatchDatabase>(
        &self,
        wallet: &Wallet<D>,
        override_skip_blocks: Option<u32>,
        sync_options: SyncOptions
    ) -> Result<(), Error> { ... } }
Expand description

Trait for a factory of blockchains that share the underlying connection or configuration

-

Example

+

Example

This example shows how to sync multiple walles and return the sum of their balances

-
fn sum_of_balances<B: BlockchainFactory>(blockchain_factory: B, wallets: &[Wallet<MemoryDatabase>]) -> Result<Balance, Error> {
-    Ok(wallets
-        .iter()
-        .map(|w| -> Result<_, Error> {
-            blockchain_factory.sync_wallet(&w, None, SyncOptions::default())?;
-            w.get_balance()
+
fn sum_of_balances<B: BlockchainFactory>(blockchain_factory: B, wallets: &[Wallet<MemoryDatabase>]) -> Result<Balance, Error> {
+    Ok(wallets
+        .iter()
+        .map(|w| -> Result<_, Error> {
+            blockchain_factory.sync_wallet(&w, None, SyncOptions::default())?;
+            w.get_balance()
         })
-        .collect::<Result<Vec<_>, _>>()?
-        .into_iter()
-        .sum())
+        .collect::<Result<Vec<_>, _>>()?
+        .into_iter()
+        .sum())
 }
-

Associated Types

The type returned when building a blockchain from this factory

-

Required methods

Build a new blockchain for the given descriptor wallet_name

+

Required Associated Types§

The type returned when building a blockchain from this factory

+

Required Methods§

Build a new blockchain for the given descriptor wallet_name

If override_skip_blocks is None, the returned blockchain will inherit the number of blocks from the factory. Since it’s not possible to override the value to None, set it to Some(0) to rescan from the genesis.

-

Provided methods

Build a new blockchain for a given wallet

+

Provided Methods§

Build a new blockchain for a given wallet

Internally uses wallet_name_from_descriptor to derive the name, and then calls BlockchainFactory::build to create the blockchain instance.

-
This is supported on neither WebAssembly nor crate feature async-interface.

Use BlockchainFactory::build_for_wallet to get a blockchain, then sync the wallet

+
Available on neither WebAssembly nor crate feature async-interface.

Use BlockchainFactory::build_for_wallet to get a blockchain, then sync the wallet

This can be used when a new blockchain would only be used to sync a wallet and then immediately dropped. Keep in mind that specific blockchain factories may perform slow operations to build a blockchain for a given wallet, so if a wallet needs to be synced often it’s recommended to use BlockchainFactory::build_for_wallet to reuse the same blockchain multiple times.

-

Implementations on Foreign Types

Implementors

- \ No newline at end of file +

Implementations on Foreign Types§

Implementors§

\ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/blockchain/trait.ConfigurableBlockchain.html b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/blockchain/trait.ConfigurableBlockchain.html index a6d6dbc7d9..3b2fb3a6c9 100644 --- a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/blockchain/trait.ConfigurableBlockchain.html +++ b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/blockchain/trait.ConfigurableBlockchain.html @@ -1,16 +1,9 @@ -ConfigurableBlockchain in bdk::blockchain - Rust - -
pub trait ConfigurableBlockchain: Blockchain + Sized {
+ConfigurableBlockchain in bdk::blockchain - Rust
pub trait ConfigurableBlockchain: Blockchain + Sized {
     type Config: Debug;
-    fn from_config(config: &Self::Config) -> Result<Self, Error>;
+
+    fn from_config(config: &Self::Config) -> Result<Self, Error>;
 }
Expand description

Trait for Blockchain types that can be created given a configuration

-

Associated Types

Type that contains the configuration

-

Required methods

Create a new instance given a configuration

-

Implementors

- \ No newline at end of file +

Required Associated Types§

Type that contains the configuration

+

Required Methods§

Create a new instance given a configuration

+

Implementors§

\ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/blockchain/trait.GetBlockHash.html b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/blockchain/trait.GetBlockHash.html index d0947f198d..1306d03c0f 100644 --- a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/blockchain/trait.GetBlockHash.html +++ b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/blockchain/trait.GetBlockHash.html @@ -1,14 +1,6 @@ -GetBlockHash in bdk::blockchain - Rust - -
pub trait GetBlockHash {
-    fn get_block_hash(&self, height: u64) -> Result<BlockHash, Error>;
+GetBlockHash in bdk::blockchain - Rust

Trait bdk::blockchain::GetBlockHash

source ·
pub trait GetBlockHash {
+    fn get_block_hash(&self, height: u64) -> Result<BlockHash, Error>;
 }
Expand description

Trait for getting block hash by block height

-

Required methods

fetch block hash given its height

-

Implementations on Foreign Types

Implementors

- \ No newline at end of file +

Required Methods§

fetch block hash given its height

+

Implementations on Foreign Types§

Implementors§

\ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/blockchain/trait.GetHeight.html b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/blockchain/trait.GetHeight.html index 6b8d4ef8d9..c9ea6f3357 100644 --- a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/blockchain/trait.GetHeight.html +++ b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/blockchain/trait.GetHeight.html @@ -1,14 +1,6 @@ -GetHeight in bdk::blockchain - Rust - -
pub trait GetHeight {
-    fn get_height(&self) -> Result<u32, Error>;
+GetHeight in bdk::blockchain - Rust

Trait bdk::blockchain::GetHeight

source ·
pub trait GetHeight {
+    fn get_height(&self) -> Result<u32, Error>;
 }
Expand description

Trait for getting the current height of the blockchain.

-

Required methods

Return the current height

-

Implementations on Foreign Types

Implementors

- \ No newline at end of file +

Required Methods§

Return the current height

+

Implementations on Foreign Types§

Implementors§

\ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/blockchain/trait.GetTx.html b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/blockchain/trait.GetTx.html index 77d63c1c3c..108ada4c14 100644 --- a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/blockchain/trait.GetTx.html +++ b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/blockchain/trait.GetTx.html @@ -1,14 +1,6 @@ -GetTx in bdk::blockchain - Rust - -
pub trait GetTx {
-    fn get_tx(&self, txid: &Txid) -> Result<Option<Transaction>, Error>;
+GetTx in bdk::blockchain - Rust

Trait bdk::blockchain::GetTx

source ·
pub trait GetTx {
+    fn get_tx(&self, txid: &Txid) -> Result<Option<Transaction>, Error>;
 }
Expand description

Trait for getting a transaction by txid

-

Required methods

Fetch a transaction given its txid

-

Implementations on Foreign Types

Implementors

- \ No newline at end of file +

Required Methods§

Fetch a transaction given its txid

+

Implementations on Foreign Types§

Implementors§

\ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/blockchain/trait.Progress.html b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/blockchain/trait.Progress.html index 0e34e9ff10..ba1c6fbf61 100644 --- a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/blockchain/trait.Progress.html +++ b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/blockchain/trait.Progress.html @@ -1,17 +1,9 @@ -Progress in bdk::blockchain - Rust - -
pub trait Progress: Send + 'static + Debug {
-    fn update(
        &self,
        progress: f32,
        message: Option<String>
    ) -> Result<(), Error>; +Progress in bdk::blockchain - Rust

Trait bdk::blockchain::Progress

source ·
pub trait Progress: Send + 'static + Debug {
+    fn update(&self, progress: f32, message: Option<String>) -> Result<(), Error>;
 }
Expand description

Trait for types that can receive and process progress updates during WalletSync::wallet_sync and WalletSync::wallet_setup

-

Required methods

Send a new progress update

+

Required Methods§

Send a new progress update

The progress value should be in the range 0.0 - 100.0, and the message value is an optional text message that can be displayed to the user.

-

Implementations on Foreign Types

Implementors

- \ No newline at end of file +

Implementations on Foreign Types§

Implementors§

\ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/blockchain/trait.StatelessBlockchain.html b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/blockchain/trait.StatelessBlockchain.html index 087c747120..43ea038d99 100644 --- a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/blockchain/trait.StatelessBlockchain.html +++ b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/blockchain/trait.StatelessBlockchain.html @@ -1,14 +1,6 @@ -StatelessBlockchain in bdk::blockchain - Rust - -
pub trait StatelessBlockchain: Blockchain { }
Expand description

Trait for blockchains that don’t contain any state

+StatelessBlockchain in bdk::blockchain - Rust
pub trait StatelessBlockchain: Blockchain { }
Expand description

Trait for blockchains that don’t contain any state

Statless blockchains can be used to sync multiple wallets with different descriptors.

BlockchainFactory is automatically implemented for Arc<T> where T is a stateless blockchain.

-

Implementors

- \ No newline at end of file +

Implementors§

\ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/blockchain/trait.WalletSync.html b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/blockchain/trait.WalletSync.html index 378ebd0308..89207b7566 100644 --- a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/blockchain/trait.WalletSync.html +++ b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/blockchain/trait.WalletSync.html @@ -1,17 +1,10 @@ -WalletSync in bdk::blockchain - Rust - -
pub trait WalletSync {
-    fn wallet_setup<D: BatchDatabase>(
        &self,
        database: &mut D,
        progress_update: Box<dyn Progress>
    ) -> Result<(), Error>; +WalletSync in bdk::blockchain - Rust

Trait bdk::blockchain::WalletSync

source ·
pub trait WalletSync {
+    fn wallet_setup<D: BatchDatabase>(
        &self,
        database: &mut D,
        progress_update: Box<dyn Progress>
    ) -> Result<(), Error>; - fn wallet_sync<D: BatchDatabase>(
        &self,
        database: &mut D,
        progress_update: Box<dyn Progress>
    ) -> Result<(), Error> { ... } + fn wallet_sync<D: BatchDatabase>(
        &self,
        database: &mut D,
        progress_update: Box<dyn Progress>
    ) -> Result<(), Error> { ... } }
Expand description

Trait for blockchains that can sync by updating the database directly.

-

Required methods

Setup the backend and populate the internal database for the first time

+

Required Methods§

Setup the backend and populate the internal database for the first time

This method is the equivalent of Self::wallet_sync, but it’s guaranteed to only be called once, at the first Wallet::sync.

The rationale behind the distinction between sync and setup is that some custom backends @@ -19,7 +12,7 @@ might need to perform specific actions only the first time they are synced.

For types that do not have that distinction, only this method can be implemented, since WalletSync::wallet_sync defaults to calling this internally if not overridden. Populate the internal database with transactions and UTXOs

-

Provided methods

If not overridden, it defaults to calling Self::wallet_setup internally.

+

Provided Methods§

If not overridden, it defaults to calling Self::wallet_setup internally.

This method should implement the logic required to iterate over the list of the wallet’s script_pubkeys using Database::iter_script_pubkeys and look for relevant transactions in the blockchain to populate the database with BatchOperations::set_tx and @@ -28,5 +21,4 @@ in the blockchain to populate the database with BatchOperations::del_utxo.

The progress_update object can be used to give the caller updates about the progress by using Progress::update.

-

Implementations on Foreign Types

Implementors

- \ No newline at end of file +

Implementations on Foreign Types§

Implementors§

\ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/blockchain/type.ProgressData.html b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/blockchain/type.ProgressData.html index b5eb038739..7547300c5d 100644 --- a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/blockchain/type.ProgressData.html +++ b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/blockchain/type.ProgressData.html @@ -1,11 +1,3 @@ -ProgressData in bdk::blockchain - Rust - -
-

Type Definition bdk::blockchain::ProgressData

source · []
pub type ProgressData = (f32, Option<String>);
Expand description

Data sent with a progress update over a channel

-
- \ No newline at end of file +ProgressData in bdk::blockchain - Rust

Type Definition bdk::blockchain::ProgressData

source ·
pub type ProgressData = (f32, Option<String>);
Expand description

Data sent with a progress update over a channel

+
\ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/database/any/enum.AnyBatch.html b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/database/any/enum.AnyBatch.html index f738dc8fc4..c71e8870d2 100644 --- a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/database/any/enum.AnyBatch.html +++ b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/database/any/enum.AnyBatch.html @@ -1,50 +1,15 @@ -AnyBatch in bdk::database::any - Rust - -
pub enum AnyBatch {
+AnyBatch in bdk::database::any - Rust

Enum bdk::database::any::AnyBatch

source ·
pub enum AnyBatch {
     Memory(<MemoryDatabase as BatchDatabase>::Batch),
     Sled(<Tree as BatchDatabase>::Batch),
     Sqlite(<SqliteDatabase as BatchDatabase>::Batch),
 }
Expand description

Type that contains any of the BatchDatabase::Batch types defined by the library

-

Variants

Memory(<MemoryDatabase as BatchDatabase>::Batch)

In-memory ephemeral database

-

Sled(<Tree as BatchDatabase>::Batch)

This is supported on crate feature key-value-db only.

Simple key-value embedded database based on [sled]

-

Sqlite(<SqliteDatabase as BatchDatabase>::Batch)

This is supported on crate feature sqlite only.

Sqlite embedded database using [rusqlite]

-

Trait Implementations

Store a script_pubkey along with its keychain and child number.

-

Store a LocalUtxo

-

Store a raw transaction

-

Store the metadata of a transaction

-

Store the last derivation index for a given keychain.

-

Store the sync time

-

Delete a script_pubkey given the keychain and its child number.

-

Delete the data related to a specific script_pubkey, meaning the keychain and the child -number. Read more

-

Delete a LocalUtxo given its [OutPoint]

-

Delete a raw transaction given its [Txid]

-

Delete the metadata of a transaction and optionally the raw transaction itself

-

Delete the last derivation index for a keychain.

-

Reset the sync time to None Read more

-

Performs the conversion.

-

Performs the conversion.

-

Performs the conversion.

-

Auto Trait Implementations

Blanket Implementations

Gets the TypeId of self. Read more

-

Immutably borrows from an owned value. Read more

-

Mutably borrows from an owned value. Read more

-

Performs the conversion.

-

Performs the conversion.

-

The alignment of pointer.

-

The type for initializers.

-

Initializes a with the given initializer. Read more

-

Dereferences the given pointer. Read more

-

Mutably dereferences the given pointer. Read more

-

Drops the object pointed to by the given pointer. Read more

-

The type returned in the event of a conversion error.

-

Performs the conversion.

-

The type returned in the event of a conversion error.

-

Performs the conversion.

-
- \ No newline at end of file +

Variants§

§

Memory(<MemoryDatabase as BatchDatabase>::Batch)

In-memory ephemeral database

+
§

Sled(<Tree as BatchDatabase>::Batch)

Available on crate feature key-value-db only.

Simple key-value embedded database based on [sled]

+
§

Sqlite(<SqliteDatabase as BatchDatabase>::Batch)

Available on crate feature sqlite only.

Sqlite embedded database using [rusqlite]

+

Trait Implementations§

Store a script_pubkey along with its keychain and child number.
Store a LocalUtxo
Store a raw transaction
Store the metadata of a transaction
Store the last derivation index for a given keychain.
Store the sync time
Delete a script_pubkey given the keychain and its child number.
Delete the data related to a specific script_pubkey, meaning the keychain and the child +number. Read more
Delete a LocalUtxo given its [OutPoint]
Delete a raw transaction given its [Txid]
Delete the metadata of a transaction and optionally the raw transaction itself
Delete the last derivation index for a keychain.
Reset the sync time to None Read more
Converts to this type from the input type.
Converts to this type from the input type.
Converts to this type from the input type.

Auto Trait Implementations§

Blanket Implementations§

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

Returns the argument unchanged.

+

Calls U::from(self).

+

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

+
The alignment of pointer.
The type for initializers.
Initializes a with the given initializer. Read more
Dereferences the given pointer. Read more
Mutably dereferences the given pointer. Read more
Drops the object pointed to by the given pointer. Read more
The type returned in the event of a conversion error.
Performs the conversion.
The type returned in the event of a conversion error.
Performs the conversion.
\ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/database/any/enum.AnyDatabase.html b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/database/any/enum.AnyDatabase.html index 24c19c6929..e63e401b80 100644 --- a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/database/any/enum.AnyDatabase.html +++ b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/database/any/enum.AnyDatabase.html @@ -1,71 +1,17 @@ -AnyDatabase in bdk::database::any - Rust - -
pub enum AnyDatabase {
+AnyDatabase in bdk::database::any - Rust

Enum bdk::database::any::AnyDatabase

source ·
pub enum AnyDatabase {
     Memory(MemoryDatabase),
     Sled(Tree),
     Sqlite(SqliteDatabase),
 }
Expand description

Type that can contain any of the Database types defined by the library

It allows switching database type at runtime.

See this module’s documentation for a usage example.

-

Variants

Memory(MemoryDatabase)

In-memory ephemeral database

-

Sled(Tree)

This is supported on crate feature key-value-db only.

Simple key-value embedded database based on [sled]

-

Sqlite(SqliteDatabase)

This is supported on crate feature sqlite only.

Sqlite embedded database using [rusqlite]

-

Trait Implementations

Container for the operations

-

Create a new batch container

-

Consume and apply a batch of operations

-

Store a script_pubkey along with its keychain and child number.

-

Store a LocalUtxo

-

Store a raw transaction

-

Store the metadata of a transaction

-

Store the last derivation index for a given keychain.

-

Store the sync time

-

Delete a script_pubkey given the keychain and its child number.

-

Delete the data related to a specific script_pubkey, meaning the keychain and the child -number. Read more

-

Delete a LocalUtxo given its [OutPoint]

-

Delete a raw transaction given its [Txid]

-

Delete the metadata of a transaction and optionally the raw transaction itself

-

Delete the last derivation index for a keychain.

-

Reset the sync time to None Read more

-

Type that contains the configuration

-

Create a new instance given a configuration

-

Read and checks the descriptor checksum for a given keychain. Read more

-

Return the list of script_pubkeys

-

Return the list of LocalUtxos

-

Return the list of raw transactions

-

Return the list of transactions metadata

-

Fetch a script_pubkey given the child number of a keychain.

-

Fetch the keychain and child number of a given script_pubkey

-

Fetch a LocalUtxo given its [OutPoint]

-

Fetch a raw transaction given its [Txid]

-

Fetch the transaction metadata and optionally also the raw transaction

-

Return the last derivation index for a keychain.

-

Return the sync time, if present

-

Increment the last derivation index for a keychain and return it Read more

-

Formats the value using the given formatter. Read more

-

Performs the conversion.

-

Performs the conversion.

-

Performs the conversion.

-

Auto Trait Implementations

Blanket Implementations

Gets the TypeId of self. Read more

-

Immutably borrows from an owned value. Read more

-

Mutably borrows from an owned value. Read more

-

Performs the conversion.

-

Performs the conversion.

-

The alignment of pointer.

-

The type for initializers.

-

Initializes a with the given initializer. Read more

-

Dereferences the given pointer. Read more

-

Mutably dereferences the given pointer. Read more

-

Drops the object pointed to by the given pointer. Read more

-

The type returned in the event of a conversion error.

-

Performs the conversion.

-

The type returned in the event of a conversion error.

-

Performs the conversion.

-
- \ No newline at end of file +

Variants§

§

Memory(MemoryDatabase)

In-memory ephemeral database

+
§

Sled(Tree)

Available on crate feature key-value-db only.

Simple key-value embedded database based on [sled]

+
§

Sqlite(SqliteDatabase)

Available on crate feature sqlite only.

Sqlite embedded database using [rusqlite]

+

Trait Implementations§

Container for the operations
Create a new batch container
Consume and apply a batch of operations
Store a script_pubkey along with its keychain and child number.
Store a LocalUtxo
Store a raw transaction
Store the metadata of a transaction
Store the last derivation index for a given keychain.
Store the sync time
Delete a script_pubkey given the keychain and its child number.
Delete the data related to a specific script_pubkey, meaning the keychain and the child +number. Read more
Delete a LocalUtxo given its [OutPoint]
Delete a raw transaction given its [Txid]
Delete the metadata of a transaction and optionally the raw transaction itself
Delete the last derivation index for a keychain.
Reset the sync time to None Read more
Type that contains the configuration
Create a new instance given a configuration
Read and checks the descriptor checksum for a given keychain. Read more
Return the list of script_pubkeys
Return the list of LocalUtxos
Return the list of raw transactions
Return the list of transactions metadata
Fetch a script_pubkey given the child number of a keychain.
Fetch the keychain and child number of a given script_pubkey
Fetch a LocalUtxo given its [OutPoint]
Fetch a raw transaction given its [Txid]
Fetch the transaction metadata and optionally also the raw transaction
Return the last derivation index for a keychain.
Return the sync time, if present
Increment the last derivation index for a keychain and return it Read more
Formats the value using the given formatter. Read more
Converts to this type from the input type.
Converts to this type from the input type.
Converts to this type from the input type.

Auto Trait Implementations§

Blanket Implementations§

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

Returns the argument unchanged.

+

Calls U::from(self).

+

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

+
The alignment of pointer.
The type for initializers.
Initializes a with the given initializer. Read more
Dereferences the given pointer. Read more
Mutably dereferences the given pointer. Read more
Drops the object pointed to by the given pointer. Read more
The type returned in the event of a conversion error.
Performs the conversion.
The type returned in the event of a conversion error.
Performs the conversion.
\ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/database/any/enum.AnyDatabaseConfig.html b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/database/any/enum.AnyDatabaseConfig.html index 3d2867a7b7..7be703b53f 100644 --- a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/database/any/enum.AnyDatabaseConfig.html +++ b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/database/any/enum.AnyDatabaseConfig.html @@ -1,12 +1,5 @@ -AnyDatabaseConfig in bdk::database::any - Rust - -
pub enum AnyDatabaseConfig {
+AnyDatabaseConfig in bdk::database::any - Rust
pub enum AnyDatabaseConfig {
     Memory(()),
     Sled(SledDbConfiguration),
     Sqlite(SqliteDbConfiguration),
@@ -14,29 +7,11 @@
 

This allows storing a single configuration that can be loaded into an AnyDatabase instance. Wallets that plan to offer users the ability to switch blockchain backend at runtime will find this particularly useful.

-

Variants

Memory(())

Memory database has no config

-

Sled(SledDbConfiguration)

This is supported on crate feature key-value-db only.

Simple key-value embedded database based on [sled]

-

Sqlite(SqliteDbConfiguration)

This is supported on crate feature sqlite only.

Sqlite embedded database using [rusqlite]

-

Trait Implementations

Formats the value using the given formatter. Read more

-

Deserialize this value from the given Serde deserializer. Read more

-

Performs the conversion.

-

Performs the conversion.

-

Performs the conversion.

-

Serialize this value into the given Serde serializer. Read more

-

Auto Trait Implementations

Blanket Implementations

Gets the TypeId of self. Read more

-

Immutably borrows from an owned value. Read more

-

Mutably borrows from an owned value. Read more

-

Performs the conversion.

-

Performs the conversion.

-

The alignment of pointer.

-

The type for initializers.

-

Initializes a with the given initializer. Read more

-

Dereferences the given pointer. Read more

-

Mutably dereferences the given pointer. Read more

-

Drops the object pointed to by the given pointer. Read more

-

The type returned in the event of a conversion error.

-

Performs the conversion.

-

The type returned in the event of a conversion error.

-

Performs the conversion.

-
- \ No newline at end of file +

Variants§

§

Memory(())

Memory database has no config

+
§

Sled(SledDbConfiguration)

Available on crate feature key-value-db only.

Simple key-value embedded database based on [sled]

+
§

Sqlite(SqliteDbConfiguration)

Available on crate feature sqlite only.

Sqlite embedded database using [rusqlite]

+

Trait Implementations§

Formats the value using the given formatter. Read more
Deserialize this value from the given Serde deserializer. Read more
Converts to this type from the input type.
Converts to this type from the input type.
Converts to this type from the input type.
Serialize this value into the given Serde serializer. Read more

Auto Trait Implementations§

Blanket Implementations§

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

Returns the argument unchanged.

+

Calls U::from(self).

+

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

+
The alignment of pointer.
The type for initializers.
Initializes a with the given initializer. Read more
Dereferences the given pointer. Read more
Mutably dereferences the given pointer. Read more
Drops the object pointed to by the given pointer. Read more
The type returned in the event of a conversion error.
Performs the conversion.
The type returned in the event of a conversion error.
Performs the conversion.
\ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/database/any/index.html b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/database/any/index.html index 0c9e6d0442..3c9075e0c2 100644 --- a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/database/any/index.html +++ b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/database/any/index.html @@ -1,34 +1,19 @@ -bdk::database::any - Rust - -
-

Module bdk::database::any

source · []
Expand description

Runtime-checked database types

+bdk::database::any - Rust

Module bdk::database::any

source ·
Expand description

Runtime-checked database types

This module provides the implementation of AnyDatabase which allows switching the inner Database type at runtime.

-

Example

+

Example

In this example, wallet_memory and wallet_sled have the same type of Wallet<(), AnyDatabase>.

-
let memory = MemoryDatabase::default();
-let wallet_memory = Wallet::new("...", None, Network::Testnet, memory)?;
+
let memory = MemoryDatabase::default();
+let wallet_memory = Wallet::new("...", None, Network::Testnet, memory)?;
 
-let sled = sled::open("my-database")?.open_tree("default_tree")?;
-let wallet_sled = Wallet::new("...", None, Network::Testnet, sled)?;
+let sled = sled::open("my-database")?.open_tree("default_tree")?; +let wallet_sled = Wallet::new("...", None, Network::Testnet, sled)?;

When paired with the use of ConfigurableDatabase, it allows creating wallets with any database supported using a single line of code:

-
let config = serde_json::from_str("...")?;
-let database = AnyDatabase::from_config(&config)?;
-let wallet = Wallet::new("...", None, Network::Testnet, database)?;
-

Structs

-

Configuration type for a [sled::Tree] database

-

Configuration type for a sqlite::SqliteDatabase database

-

Enums

-

Type that contains any of the BatchDatabase::Batch types defined by the library

-

Type that can contain any of the Database types defined by the library

-

Type that can contain any of the database configurations defined by the library

-
- \ No newline at end of file +
let config = serde_json::from_str("...")?;
+let database = AnyDatabase::from_config(&config)?;
+let wallet = Wallet::new("...", None, Network::Testnet, database)?;
+

Structs

Configuration type for a [sled::Tree] database
Configuration type for a sqlite::SqliteDatabase database

Enums

Type that contains any of the BatchDatabase::Batch types defined by the library
Type that can contain any of the Database types defined by the library
Type that can contain any of the database configurations defined by the library
\ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/database/any/sidebar-items.js b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/database/any/sidebar-items.js index b10a47631b..42ce79a41c 100644 --- a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/database/any/sidebar-items.js +++ b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/database/any/sidebar-items.js @@ -1 +1 @@ -initSidebarItems({"enum":[["AnyBatch","Type that contains any of the [`BatchDatabase::Batch`] types defined by the library"],["AnyDatabase","Type that can contain any of the [`Database`] types defined by the library"],["AnyDatabaseConfig","Type that can contain any of the database configurations defined by the library"]],"struct":[["SledDbConfiguration","Configuration type for a [`sled::Tree`] database"],["SqliteDbConfiguration","Configuration type for a [`sqlite::SqliteDatabase`] database"]]}); \ No newline at end of file +window.SIDEBAR_ITEMS = {"enum":[["AnyBatch","Type that contains any of the [`BatchDatabase::Batch`] types defined by the library"],["AnyDatabase","Type that can contain any of the [`Database`] types defined by the library"],["AnyDatabaseConfig","Type that can contain any of the database configurations defined by the library"]],"struct":[["SledDbConfiguration","Configuration type for a [`sled::Tree`] database"],["SqliteDbConfiguration","Configuration type for a [`sqlite::SqliteDatabase`] database"]]}; \ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/database/any/struct.SledDbConfiguration.html b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/database/any/struct.SledDbConfiguration.html index 81ef074e8c..31bbc5381d 100644 --- a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/database/any/struct.SledDbConfiguration.html +++ b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/database/any/struct.SledDbConfiguration.html @@ -1,35 +1,12 @@ -SledDbConfiguration in bdk::database::any - Rust - -
pub struct SledDbConfiguration {
+SledDbConfiguration in bdk::database::any - Rust
pub struct SledDbConfiguration {
     pub path: String,
     pub tree_name: String,
 }
Expand description

Configuration type for a [sled::Tree] database

-

Fields

path: String

Main directory of the db

-
tree_name: String

Name of the database tree, a separated namespace for the data

-

Trait Implementations

Formats the value using the given formatter. Read more

-

Deserialize this value from the given Serde deserializer. Read more

-

Performs the conversion.

-

Serialize this value into the given Serde serializer. Read more

-

Auto Trait Implementations

Blanket Implementations

Gets the TypeId of self. Read more

-

Immutably borrows from an owned value. Read more

-

Mutably borrows from an owned value. Read more

-

Performs the conversion.

-

Performs the conversion.

-

The alignment of pointer.

-

The type for initializers.

-

Initializes a with the given initializer. Read more

-

Dereferences the given pointer. Read more

-

Mutably dereferences the given pointer. Read more

-

Drops the object pointed to by the given pointer. Read more

-

The type returned in the event of a conversion error.

-

Performs the conversion.

-

The type returned in the event of a conversion error.

-

Performs the conversion.

-
- \ No newline at end of file +

Fields§

§path: String

Main directory of the db

+
§tree_name: String

Name of the database tree, a separated namespace for the data

+

Trait Implementations§

Formats the value using the given formatter. Read more
Deserialize this value from the given Serde deserializer. Read more
Converts to this type from the input type.
Serialize this value into the given Serde serializer. Read more

Auto Trait Implementations§

Blanket Implementations§

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

Returns the argument unchanged.

+

Calls U::from(self).

+

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

+
The alignment of pointer.
The type for initializers.
Initializes a with the given initializer. Read more
Dereferences the given pointer. Read more
Mutably dereferences the given pointer. Read more
Drops the object pointed to by the given pointer. Read more
The type returned in the event of a conversion error.
Performs the conversion.
The type returned in the event of a conversion error.
Performs the conversion.
\ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/database/any/struct.SqliteDbConfiguration.html b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/database/any/struct.SqliteDbConfiguration.html index b263ddf506..09b31fc227 100644 --- a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/database/any/struct.SqliteDbConfiguration.html +++ b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/database/any/struct.SqliteDbConfiguration.html @@ -1,33 +1,10 @@ -SqliteDbConfiguration in bdk::database::any - Rust - -
pub struct SqliteDbConfiguration {
+SqliteDbConfiguration in bdk::database::any - Rust
pub struct SqliteDbConfiguration {
     pub path: String,
 }
Expand description

Configuration type for a sqlite::SqliteDatabase database

-

Fields

path: String

Main directory of the db

-

Trait Implementations

Formats the value using the given formatter. Read more

-

Deserialize this value from the given Serde deserializer. Read more

-

Performs the conversion.

-

Serialize this value into the given Serde serializer. Read more

-

Auto Trait Implementations

Blanket Implementations

Gets the TypeId of self. Read more

-

Immutably borrows from an owned value. Read more

-

Mutably borrows from an owned value. Read more

-

Performs the conversion.

-

Performs the conversion.

-

The alignment of pointer.

-

The type for initializers.

-

Initializes a with the given initializer. Read more

-

Dereferences the given pointer. Read more

-

Mutably dereferences the given pointer. Read more

-

Drops the object pointed to by the given pointer. Read more

-

The type returned in the event of a conversion error.

-

Performs the conversion.

-

The type returned in the event of a conversion error.

-

Performs the conversion.

-
- \ No newline at end of file +

Fields§

§path: String

Main directory of the db

+

Trait Implementations§

Formats the value using the given formatter. Read more
Deserialize this value from the given Serde deserializer. Read more
Converts to this type from the input type.
Serialize this value into the given Serde serializer. Read more

Auto Trait Implementations§

Blanket Implementations§

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

Returns the argument unchanged.

+

Calls U::from(self).

+

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

+
The alignment of pointer.
The type for initializers.
Initializes a with the given initializer. Read more
Dereferences the given pointer. Read more
Mutably dereferences the given pointer. Read more
Drops the object pointed to by the given pointer. Read more
The type returned in the event of a conversion error.
Performs the conversion.
The type returned in the event of a conversion error.
Performs the conversion.
\ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/database/index.html b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/database/index.html index 905ef095a8..960b59f15f 100644 --- a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/database/index.html +++ b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/database/index.html @@ -1,12 +1,5 @@ -bdk::database - Rust - -
-

Module bdk::database

source · []
Expand description

Database types

+bdk::database - Rust

Module bdk::database

source ·
Expand description

Database types

This module provides the implementation of some defaults database types, along with traits that can be implemented externally to let Wallets use customized databases.

It’s important to note that the databases defined here only contains “blockchain-related” data. @@ -15,17 +8,4 @@ keys.

The currently recommended database is [sled], which is a pretty simple key-value embedded database written in Rust. If the key-value-db feature is enabled (which by default is), this library automatically implements all the required traits for [sled::Tree].

-

Re-exports

-
pub use any::AnyDatabase;
pub use any::AnyDatabaseConfig;
pub use memory::MemoryDatabase;

Modules

-

Runtime-checked database types

-

In-memory ephemeral database

-

Structs

-

Sqlite database stored on filesystem

-

Blockchain state at the time of syncing

-

Traits

-

Trait for a database that supports batch operations

-

Trait for operations that can be batched

-

Trait for Database types that can be created given a configuration

-

Trait for reading data from a database

-
- \ No newline at end of file +

Re-exports

pub use any::AnyDatabase;
pub use any::AnyDatabaseConfig;
pub use memory::MemoryDatabase;

Modules

Runtime-checked database types
In-memory ephemeral database

Structs

Sqlite database stored on filesystem
Blockchain state at the time of syncing

Traits

Trait for a database that supports batch operations
Trait for operations that can be batched
Trait for Database types that can be created given a configuration
Trait for reading data from a database
\ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/database/memory/index.html b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/database/memory/index.html index 1a079d9933..00b9074d82 100644 --- a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/database/memory/index.html +++ b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/database/memory/index.html @@ -1,15 +1,5 @@ -bdk::database::memory - Rust - -
-

Module bdk::database::memory

source · []
Expand description

In-memory ephemeral database

+bdk::database::memory - Rust

Module bdk::database::memory

source ·
Expand description

In-memory ephemeral database

This module defines an in-memory database type called MemoryDatabase that is based on a BTreeMap.

-

Structs

-

In-memory ephemeral database

-
- \ No newline at end of file +

Structs

In-memory ephemeral database
\ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/database/memory/sidebar-items.js b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/database/memory/sidebar-items.js index 665f6718d0..3275d45f7d 100644 --- a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/database/memory/sidebar-items.js +++ b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/database/memory/sidebar-items.js @@ -1 +1 @@ -initSidebarItems({"struct":[["MemoryDatabase","In-memory ephemeral database"]]}); \ No newline at end of file +window.SIDEBAR_ITEMS = {"struct":[["MemoryDatabase","In-memory ephemeral database"]]}; \ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/database/memory/struct.MemoryDatabase.html b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/database/memory/struct.MemoryDatabase.html index 83e662946b..b08fa1faec 100644 --- a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/database/memory/struct.MemoryDatabase.html +++ b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/database/memory/struct.MemoryDatabase.html @@ -1,68 +1,14 @@ -MemoryDatabase in bdk::database::memory - Rust - -
pub struct MemoryDatabase { /* private fields */ }
Expand description

In-memory ephemeral database

+MemoryDatabase in bdk::database::memory - Rust
pub struct MemoryDatabase { /* private fields */ }
Expand description

In-memory ephemeral database

This database can be used as a temporary storage for wallets that are not kept permanently on a device, or on platforms that don’t provide a filesystem, like wasm32.

Once it’s dropped its content will be lost.

If you are looking for a permanent storage solution, you can try with the default key-value database called [sled]. See the database module documentation for more details.

-

Implementations

Create a new empty database

-

Trait Implementations

Container for the operations

-

Create a new batch container

-

Consume and apply a batch of operations

-

Store a script_pubkey along with its keychain and child number.

-

Store a LocalUtxo

-

Store a raw transaction

-

Store the metadata of a transaction

-

Store the last derivation index for a given keychain.

-

Store the sync time

-

Delete a script_pubkey given the keychain and its child number.

-

Delete the data related to a specific script_pubkey, meaning the keychain and the child -number. Read more

-

Delete a LocalUtxo given its [OutPoint]

-

Delete a raw transaction given its [Txid]

-

Delete the metadata of a transaction and optionally the raw transaction itself

-

Delete the last derivation index for a keychain.

-

Reset the sync time to None Read more

-

Type that contains the configuration

-

Create a new instance given a configuration

-

Read and checks the descriptor checksum for a given keychain. Read more

-

Return the list of script_pubkeys

-

Return the list of LocalUtxos

-

Return the list of raw transactions

-

Return the list of transactions metadata

-

Fetch a script_pubkey given the child number of a keychain.

-

Fetch the keychain and child number of a given script_pubkey

-

Fetch a LocalUtxo given its [OutPoint]

-

Fetch a raw transaction given its [Txid]

-

Fetch the transaction metadata and optionally also the raw transaction

-

Return the last derivation index for a keychain.

-

Return the sync time, if present

-

Increment the last derivation index for a keychain and return it Read more

-

Formats the value using the given formatter. Read more

-

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

-

Performs the conversion.

-

Performs the conversion.

-

Auto Trait Implementations

Blanket Implementations

Gets the TypeId of self. Read more

-

Immutably borrows from an owned value. Read more

-

Mutably borrows from an owned value. Read more

-

Performs the conversion.

-

Performs the conversion.

-

The alignment of pointer.

-

The type for initializers.

-

Initializes a with the given initializer. Read more

-

Dereferences the given pointer. Read more

-

Mutably dereferences the given pointer. Read more

-

Drops the object pointed to by the given pointer. Read more

-

The type returned in the event of a conversion error.

-

Performs the conversion.

-

The type returned in the event of a conversion error.

-

Performs the conversion.

-
- \ No newline at end of file +

Implementations§

Create a new empty database

+

Trait Implementations§

Container for the operations
Create a new batch container
Consume and apply a batch of operations
Store a script_pubkey along with its keychain and child number.
Store a LocalUtxo
Store a raw transaction
Store the metadata of a transaction
Store the last derivation index for a given keychain.
Store the sync time
Delete a script_pubkey given the keychain and its child number.
Delete the data related to a specific script_pubkey, meaning the keychain and the child +number. Read more
Delete a LocalUtxo given its [OutPoint]
Delete a raw transaction given its [Txid]
Delete the metadata of a transaction and optionally the raw transaction itself
Delete the last derivation index for a keychain.
Reset the sync time to None Read more
Type that contains the configuration
Create a new instance given a configuration
Read and checks the descriptor checksum for a given keychain. Read more
Return the list of script_pubkeys
Return the list of LocalUtxos
Return the list of raw transactions
Return the list of transactions metadata
Fetch a script_pubkey given the child number of a keychain.
Fetch the keychain and child number of a given script_pubkey
Fetch a LocalUtxo given its [OutPoint]
Fetch a raw transaction given its [Txid]
Fetch the transaction metadata and optionally also the raw transaction
Return the last derivation index for a keychain.
Return the sync time, if present
Increment the last derivation index for a keychain and return it Read more
Formats the value using the given formatter. Read more
Returns the “default value” for a type. Read more
Converts to this type from the input type.
Converts to this type from the input type.

Auto Trait Implementations§

Blanket Implementations§

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

Returns the argument unchanged.

+

Calls U::from(self).

+

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

+
The alignment of pointer.
The type for initializers.
Initializes a with the given initializer. Read more
Dereferences the given pointer. Read more
Mutably dereferences the given pointer. Read more
Drops the object pointed to by the given pointer. Read more
The type returned in the event of a conversion error.
Performs the conversion.
The type returned in the event of a conversion error.
Performs the conversion.
\ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/database/sidebar-items.js b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/database/sidebar-items.js index 22babbc454..1675cea1c4 100644 --- a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/database/sidebar-items.js +++ b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/database/sidebar-items.js @@ -1 +1 @@ -initSidebarItems({"mod":[["any","Runtime-checked database types"],["memory","In-memory ephemeral database"]],"struct":[["SqliteDatabase","Sqlite database stored on filesystem"],["SyncTime","Blockchain state at the time of syncing"]],"trait":[["BatchDatabase","Trait for a database that supports batch operations"],["BatchOperations","Trait for operations that can be batched"],["ConfigurableDatabase","Trait for [`Database`] types that can be created given a configuration"],["Database","Trait for reading data from a database"]]}); \ No newline at end of file +window.SIDEBAR_ITEMS = {"mod":[["any","Runtime-checked database types"],["memory","In-memory ephemeral database"]],"struct":[["SqliteDatabase","Sqlite database stored on filesystem"],["SyncTime","Blockchain state at the time of syncing"]],"trait":[["BatchDatabase","Trait for a database that supports batch operations"],["BatchOperations","Trait for operations that can be batched"],["ConfigurableDatabase","Trait for [`Database`] types that can be created given a configuration"],["Database","Trait for reading data from a database"]]}; \ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/database/struct.SqliteDatabase.html b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/database/struct.SqliteDatabase.html index 5db4e8545d..a15cf92209 100644 --- a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/database/struct.SqliteDatabase.html +++ b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/database/struct.SqliteDatabase.html @@ -1,70 +1,17 @@ -SqliteDatabase in bdk::database - Rust - -
pub struct SqliteDatabase {
+SqliteDatabase in bdk::database - Rust

Struct bdk::database::SqliteDatabase

source ·
pub struct SqliteDatabase {
     pub path: PathBuf,
     pub connection: Connection,
 }
Expand description

Sqlite database stored on filesystem

This is a permanent storage solution for devices and platforms that provide a filesystem. crate::database

-

Fields

path: PathBuf

Path on the local filesystem to store the sqlite file

-
connection: Connection

A rusqlite connection object to the sqlite database

-

Implementations

Instantiate a new SqliteDatabase instance by creating a connection +

Fields§

§path: PathBuf

Path on the local filesystem to store the sqlite file

+
§connection: Connection

A rusqlite connection object to the sqlite database

+

Implementations§

Instantiate a new SqliteDatabase instance by creating a connection to the database stored at path

-

Trait Implementations

Container for the operations

-

Create a new batch container

-

Consume and apply a batch of operations

-

Store a script_pubkey along with its keychain and child number.

-

Store a LocalUtxo

-

Store a raw transaction

-

Store the metadata of a transaction

-

Store the last derivation index for a given keychain.

-

Store the sync time

-

Delete a script_pubkey given the keychain and its child number.

-

Delete the data related to a specific script_pubkey, meaning the keychain and the child -number. Read more

-

Delete a LocalUtxo given its [OutPoint]

-

Delete a raw transaction given its [Txid]

-

Delete the metadata of a transaction and optionally the raw transaction itself

-

Delete the last derivation index for a keychain.

-

Reset the sync time to None Read more

-

Type that contains the configuration

-

Create a new instance given a configuration

-

Read and checks the descriptor checksum for a given keychain. Read more

-

Return the list of script_pubkeys

-

Return the list of LocalUtxos

-

Return the list of raw transactions

-

Return the list of transactions metadata

-

Fetch a script_pubkey given the child number of a keychain.

-

Fetch the keychain and child number of a given script_pubkey

-

Fetch a LocalUtxo given its [OutPoint]

-

Fetch a raw transaction given its [Txid]

-

Fetch the transaction metadata and optionally also the raw transaction

-

Return the last derivation index for a keychain.

-

Return the sync time, if present

-

Increment the last derivation index for a keychain and return it Read more

-

Formats the value using the given formatter. Read more

-

Performs the conversion.

-

Performs the conversion.

-

Auto Trait Implementations

Blanket Implementations

Gets the TypeId of self. Read more

-

Immutably borrows from an owned value. Read more

-

Mutably borrows from an owned value. Read more

-

Performs the conversion.

-

Performs the conversion.

-

The alignment of pointer.

-

The type for initializers.

-

Initializes a with the given initializer. Read more

-

Dereferences the given pointer. Read more

-

Mutably dereferences the given pointer. Read more

-

Drops the object pointed to by the given pointer. Read more

-

The type returned in the event of a conversion error.

-

Performs the conversion.

-

The type returned in the event of a conversion error.

-

Performs the conversion.

-
- \ No newline at end of file +

Trait Implementations§

Container for the operations
Create a new batch container
Consume and apply a batch of operations
Store a script_pubkey along with its keychain and child number.
Store a LocalUtxo
Store a raw transaction
Store the metadata of a transaction
Store the last derivation index for a given keychain.
Store the sync time
Delete a script_pubkey given the keychain and its child number.
Delete the data related to a specific script_pubkey, meaning the keychain and the child +number. Read more
Delete a LocalUtxo given its [OutPoint]
Delete a raw transaction given its [Txid]
Delete the metadata of a transaction and optionally the raw transaction itself
Delete the last derivation index for a keychain.
Reset the sync time to None Read more
Type that contains the configuration
Create a new instance given a configuration
Read and checks the descriptor checksum for a given keychain. Read more
Return the list of script_pubkeys
Return the list of LocalUtxos
Return the list of raw transactions
Return the list of transactions metadata
Fetch a script_pubkey given the child number of a keychain.
Fetch the keychain and child number of a given script_pubkey
Fetch a LocalUtxo given its [OutPoint]
Fetch a raw transaction given its [Txid]
Fetch the transaction metadata and optionally also the raw transaction
Return the last derivation index for a keychain.
Return the sync time, if present
Increment the last derivation index for a keychain and return it Read more
Formats the value using the given formatter. Read more
Converts to this type from the input type.
Converts to this type from the input type.

Auto Trait Implementations§

Blanket Implementations§

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

Returns the argument unchanged.

+

Calls U::from(self).

+

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

+
The alignment of pointer.
The type for initializers.
Initializes a with the given initializer. Read more
Dereferences the given pointer. Read more
Mutably dereferences the given pointer. Read more
Drops the object pointed to by the given pointer. Read more
The type returned in the event of a conversion error.
Performs the conversion.
The type returned in the event of a conversion error.
Performs the conversion.
\ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/database/struct.SyncTime.html b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/database/struct.SyncTime.html index 3d17025e3c..4eba6b750f 100644 --- a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/database/struct.SyncTime.html +++ b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/database/struct.SyncTime.html @@ -1,38 +1,11 @@ -SyncTime in bdk::database - Rust - -
-

Struct bdk::database::SyncTime

source · []
pub struct SyncTime {
+SyncTime in bdk::database - Rust

Struct bdk::database::SyncTime

source ·
pub struct SyncTime {
     pub block_time: BlockTime,
 }
Expand description

Blockchain state at the time of syncing

Contains only the block time and height at the moment

-

Fields

block_time: BlockTime

Block timestamp and height at the time of sync

-

Trait Implementations

Returns a copy of the value. Read more

-

Performs copy-assignment from source. Read more

-

Formats the value using the given formatter. Read more

-

Deserialize this value from the given Serde deserializer. Read more

-

Serialize this value into the given Serde serializer. Read more

-

Auto Trait Implementations

Blanket Implementations

Gets the TypeId of self. Read more

-

Immutably borrows from an owned value. Read more

-

Mutably borrows from an owned value. Read more

-

Performs the conversion.

-

Performs the conversion.

-

The alignment of pointer.

-

The type for initializers.

-

Initializes a with the given initializer. Read more

-

Dereferences the given pointer. Read more

-

Mutably dereferences the given pointer. Read more

-

Drops the object pointed to by the given pointer. Read more

-

The resulting type after obtaining ownership.

-

Creates owned data from borrowed data, usually by cloning. Read more

-
🔬 This is a nightly-only experimental API. (toowned_clone_into)

Uses borrowed data to replace owned data, usually by cloning. Read more

-

The type returned in the event of a conversion error.

-

Performs the conversion.

-

The type returned in the event of a conversion error.

-

Performs the conversion.

-
- \ No newline at end of file +

Fields§

§block_time: BlockTime

Block timestamp and height at the time of sync

+

Trait Implementations§

Returns a copy of the value. Read more
Performs copy-assignment from source. Read more
Formats the value using the given formatter. Read more
Deserialize this value from the given Serde deserializer. Read more
Serialize this value into the given Serde serializer. Read more

Auto Trait Implementations§

Blanket Implementations§

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

Returns the argument unchanged.

+

Calls U::from(self).

+

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

+
The alignment of pointer.
The type for initializers.
Initializes a with the given initializer. Read more
Dereferences the given pointer. Read more
Mutably dereferences the given pointer. Read more
Drops the object pointed to by the given pointer. Read more
The resulting type after obtaining ownership.
Creates owned data from borrowed data, usually by cloning. Read more
Uses borrowed data to replace owned data, usually by cloning. Read more
The type returned in the event of a conversion error.
Performs the conversion.
The type returned in the event of a conversion error.
Performs the conversion.
\ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/database/trait.BatchDatabase.html b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/database/trait.BatchDatabase.html index 08eecbd1bb..ac39984fe3 100644 --- a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/database/trait.BatchDatabase.html +++ b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/database/trait.BatchDatabase.html @@ -1,19 +1,12 @@ -BatchDatabase in bdk::database - Rust - -
pub trait BatchDatabase: Database {
+BatchDatabase in bdk::database - Rust

Trait bdk::database::BatchDatabase

source ·
pub trait BatchDatabase: Database {
     type Batch: BatchOperations;
-    fn begin_batch(&self) -> Self::Batch;
-
fn commit_batch(&mut self, batch: Self::Batch) -> Result<(), Error>; + + fn begin_batch(&self) -> Self::Batch; + fn commit_batch(&mut self, batch: Self::Batch) -> Result<(), Error>; }
Expand description

Trait for a database that supports batch operations

This trait defines the methods to start and apply a batch of operations.

-

Associated Types

Container for the operations

-

Required methods

Create a new batch container

-

Consume and apply a batch of operations

-

Implementations on Foreign Types

Implementors

- \ No newline at end of file +

Required Associated Types§

Container for the operations

+

Required Methods§

Create a new batch container

+

Consume and apply a batch of operations

+

Implementations on Foreign Types§

Implementors§

\ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/database/trait.BatchOperations.html b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/database/trait.BatchOperations.html index 540aee3720..7e60f5b883 100644 --- a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/database/trait.BatchOperations.html +++ b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/database/trait.BatchOperations.html @@ -1,42 +1,34 @@ -BatchOperations in bdk::database - Rust - -
pub trait BatchOperations {
-
Show 13 methods fn set_script_pubkey(
        &mut self,
        script: &Script,
        keychain: KeychainKind,
        child: u32
    ) -> Result<(), Error>; -
fn set_utxo(&mut self, utxo: &LocalUtxo) -> Result<(), Error>; -
fn set_raw_tx(&mut self, transaction: &Transaction) -> Result<(), Error>; -
fn set_tx(&mut self, transaction: &TransactionDetails) -> Result<(), Error>; -
fn set_last_index(
        &mut self,
        keychain: KeychainKind,
        value: u32
    ) -> Result<(), Error>; -
fn set_sync_time(&mut self, sync_time: SyncTime) -> Result<(), Error>; -
fn del_script_pubkey_from_path(
        &mut self,
        keychain: KeychainKind,
        child: u32
    ) -> Result<Option<Script>, Error>; -
fn del_path_from_script_pubkey(
        &mut self,
        script: &Script
    ) -> Result<Option<(KeychainKind, u32)>, Error>; -
fn del_utxo(
        &mut self,
        outpoint: &OutPoint
    ) -> Result<Option<LocalUtxo>, Error>; -
fn del_raw_tx(&mut self, txid: &Txid) -> Result<Option<Transaction>, Error>; -
fn del_tx(
        &mut self,
        txid: &Txid,
        include_raw: bool
    ) -> Result<Option<TransactionDetails>, Error>; -
fn del_last_index(
        &mut self,
        keychain: KeychainKind
    ) -> Result<Option<u32>, Error>; -
fn del_sync_time(&mut self) -> Result<Option<SyncTime>, Error>; +BatchOperations in bdk::database - Rust
pub trait BatchOperations {
+
Show 13 methods fn set_script_pubkey(
        &mut self,
        script: &Script,
        keychain: KeychainKind,
        child: u32
    ) -> Result<(), Error>; + fn set_utxo(&mut self, utxo: &LocalUtxo) -> Result<(), Error>; + fn set_raw_tx(&mut self, transaction: &Transaction) -> Result<(), Error>; + fn set_tx(&mut self, transaction: &TransactionDetails) -> Result<(), Error>; + fn set_last_index(
        &mut self,
        keychain: KeychainKind,
        value: u32
    ) -> Result<(), Error>; + fn set_sync_time(&mut self, sync_time: SyncTime) -> Result<(), Error>; + fn del_script_pubkey_from_path(
        &mut self,
        keychain: KeychainKind,
        child: u32
    ) -> Result<Option<Script>, Error>; + fn del_path_from_script_pubkey(
        &mut self,
        script: &Script
    ) -> Result<Option<(KeychainKind, u32)>, Error>; + fn del_utxo(
        &mut self,
        outpoint: &OutPoint
    ) -> Result<Option<LocalUtxo>, Error>; + fn del_raw_tx(&mut self, txid: &Txid) -> Result<Option<Transaction>, Error>; + fn del_tx(
        &mut self,
        txid: &Txid,
        include_raw: bool
    ) -> Result<Option<TransactionDetails>, Error>; + fn del_last_index(
        &mut self,
        keychain: KeychainKind
    ) -> Result<Option<u32>, Error>; + fn del_sync_time(&mut self) -> Result<Option<SyncTime>, Error>;
}
Expand description

Trait for operations that can be batched

This trait defines the list of operations that must be implemented on the Database type and the BatchDatabase::Batch type.

-

Required methods

Store a script_pubkey along with its keychain and child number.

-

Store a LocalUtxo

-

Store a raw transaction

-

Store the metadata of a transaction

-

Store the last derivation index for a given keychain.

-

Store the sync time

-

Delete a script_pubkey given the keychain and its child number.

-

Delete the data related to a specific script_pubkey, meaning the keychain and the child +

Required Methods§

Store a script_pubkey along with its keychain and child number.

+

Store a LocalUtxo

+

Store a raw transaction

+

Store the metadata of a transaction

+

Store the last derivation index for a given keychain.

+

Store the sync time

+

Delete a script_pubkey given the keychain and its child number.

+

Delete the data related to a specific script_pubkey, meaning the keychain and the child number.

-

Delete a LocalUtxo given its [OutPoint]

-

Delete a raw transaction given its [Txid]

-

Delete the metadata of a transaction and optionally the raw transaction itself

-

Delete the last derivation index for a keychain.

-

Reset the sync time to None

+

Delete a LocalUtxo given its [OutPoint]

+

Delete a raw transaction given its [Txid]

+

Delete the metadata of a transaction and optionally the raw transaction itself

+

Delete the last derivation index for a keychain.

+

Reset the sync time to None

Returns the removed value

-

Implementations on Foreign Types

Implementors

- \ No newline at end of file +

Implementations on Foreign Types§

Implementors§

\ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/database/trait.ConfigurableDatabase.html b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/database/trait.ConfigurableDatabase.html index 67fa71e62e..75c56fd3ec 100644 --- a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/database/trait.ConfigurableDatabase.html +++ b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/database/trait.ConfigurableDatabase.html @@ -1,16 +1,9 @@ -ConfigurableDatabase in bdk::database - Rust - -
pub trait ConfigurableDatabase: Database + Sized {
+ConfigurableDatabase in bdk::database - Rust
pub trait ConfigurableDatabase: Database + Sized {
     type Config: Debug;
-    fn from_config(config: &Self::Config) -> Result<Self, Error>;
+
+    fn from_config(config: &Self::Config) -> Result<Self, Error>;
 }
Expand description

Trait for Database types that can be created given a configuration

-

Associated Types

Type that contains the configuration

-

Required methods

Create a new instance given a configuration

-

Implementations on Foreign Types

Implementors

- \ No newline at end of file +

Required Associated Types§

Type that contains the configuration

+

Required Methods§

Create a new instance given a configuration

+

Implementations on Foreign Types§

Implementors§

\ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/database/trait.Database.html b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/database/trait.Database.html index 745230828f..384ff5377b 100644 --- a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/database/trait.Database.html +++ b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/database/trait.Database.html @@ -1,43 +1,35 @@ -Database in bdk::database - Rust - -
pub trait Database: BatchOperations {
-
Show 13 methods fn check_descriptor_checksum<B: AsRef<[u8]>>(
        &mut self,
        keychain: KeychainKind,
        bytes: B
    ) -> Result<(), Error>; -
fn iter_script_pubkeys(
        &self,
        keychain: Option<KeychainKind>
    ) -> Result<Vec<Script>, Error>; -
fn iter_utxos(&self) -> Result<Vec<LocalUtxo>, Error>; -
fn iter_raw_txs(&self) -> Result<Vec<Transaction>, Error>; -
fn iter_txs(
        &self,
        include_raw: bool
    ) -> Result<Vec<TransactionDetails>, Error>; -
fn get_script_pubkey_from_path(
        &self,
        keychain: KeychainKind,
        child: u32
    ) -> Result<Option<Script>, Error>; -
fn get_path_from_script_pubkey(
        &self,
        script: &Script
    ) -> Result<Option<(KeychainKind, u32)>, Error>; -
fn get_utxo(&self, outpoint: &OutPoint) -> Result<Option<LocalUtxo>, Error>; -
fn get_raw_tx(&self, txid: &Txid) -> Result<Option<Transaction>, Error>; -
fn get_tx(
        &self,
        txid: &Txid,
        include_raw: bool
    ) -> Result<Option<TransactionDetails>, Error>; -
fn get_last_index(
        &self,
        keychain: KeychainKind
    ) -> Result<Option<u32>, Error>; -
fn get_sync_time(&self) -> Result<Option<SyncTime>, Error>; -
fn increment_last_index(
        &mut self,
        keychain: KeychainKind
    ) -> Result<u32, Error>; +Database in bdk::database - Rust

Trait bdk::database::Database

source ·
pub trait Database: BatchOperations {
+
Show 13 methods fn check_descriptor_checksum<B: AsRef<[u8]>>(
        &mut self,
        keychain: KeychainKind,
        bytes: B
    ) -> Result<(), Error>; + fn iter_script_pubkeys(
        &self,
        keychain: Option<KeychainKind>
    ) -> Result<Vec<Script>, Error>; + fn iter_utxos(&self) -> Result<Vec<LocalUtxo>, Error>; + fn iter_raw_txs(&self) -> Result<Vec<Transaction>, Error>; + fn iter_txs(
        &self,
        include_raw: bool
    ) -> Result<Vec<TransactionDetails>, Error>; + fn get_script_pubkey_from_path(
        &self,
        keychain: KeychainKind,
        child: u32
    ) -> Result<Option<Script>, Error>; + fn get_path_from_script_pubkey(
        &self,
        script: &Script
    ) -> Result<Option<(KeychainKind, u32)>, Error>; + fn get_utxo(&self, outpoint: &OutPoint) -> Result<Option<LocalUtxo>, Error>; + fn get_raw_tx(&self, txid: &Txid) -> Result<Option<Transaction>, Error>; + fn get_tx(
        &self,
        txid: &Txid,
        include_raw: bool
    ) -> Result<Option<TransactionDetails>, Error>; + fn get_last_index(
        &self,
        keychain: KeychainKind
    ) -> Result<Option<u32>, Error>; + fn get_sync_time(&self) -> Result<Option<SyncTime>, Error>; + fn increment_last_index(
        &mut self,
        keychain: KeychainKind
    ) -> Result<u32, Error>;
}
Expand description

Trait for reading data from a database

This traits defines the operations that can be used to read data out of a database

-

Required methods

Read and checks the descriptor checksum for a given keychain.

+

Required Methods§

Read and checks the descriptor checksum for a given keychain.

Should return Error::ChecksumMismatch if the checksum doesn’t match. If there’s no checksum in the database, simply store it for the next time.

-

Return the list of script_pubkeys

-

Return the list of LocalUtxos

-

Return the list of raw transactions

-

Return the list of transactions metadata

-

Fetch a script_pubkey given the child number of a keychain.

-

Fetch the keychain and child number of a given script_pubkey

-

Fetch a LocalUtxo given its [OutPoint]

-

Fetch a raw transaction given its [Txid]

-

Fetch the transaction metadata and optionally also the raw transaction

-

Return the last derivation index for a keychain.

-

Return the sync time, if present

-

Increment the last derivation index for a keychain and return it

+

Return the list of script_pubkeys

+

Return the list of LocalUtxos

+

Return the list of raw transactions

+

Return the list of transactions metadata

+

Fetch a script_pubkey given the child number of a keychain.

+

Fetch the keychain and child number of a given script_pubkey

+

Fetch a LocalUtxo given its [OutPoint]

+

Fetch a raw transaction given its [Txid]

+

Fetch the transaction metadata and optionally also the raw transaction

+

Return the last derivation index for a keychain.

+

Return the sync time, if present

+

Increment the last derivation index for a keychain and return it

It should insert and return 0 if not present in the database

-

Implementations on Foreign Types

Implementors

- \ No newline at end of file +

Implementations on Foreign Types§

Implementors§

\ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/descriptor/checksum/fn.calc_checksum.html b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/descriptor/checksum/fn.calc_checksum.html index 73a66d1147..86ae9f0e9f 100644 --- a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/descriptor/checksum/fn.calc_checksum.html +++ b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/descriptor/checksum/fn.calc_checksum.html @@ -1,11 +1,3 @@ -calc_checksum in bdk::descriptor::checksum - Rust - -
pub fn calc_checksum(desc: &str) -> Result<String, DescriptorError>
Expand description

Compute the checksum of a descriptor, excludes any existing checksum in the descriptor string from the calculation

-
- \ No newline at end of file +calc_checksum in bdk::descriptor::checksum - Rust
pub fn calc_checksum(desc: &str) -> Result<String, DescriptorError>
Expand description

Compute the checksum of a descriptor, excludes any existing checksum in the descriptor string from the calculation

+
\ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/descriptor/checksum/fn.calc_checksum_bytes.html b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/descriptor/checksum/fn.calc_checksum_bytes.html index 87970a2066..d04be67e0e 100644 --- a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/descriptor/checksum/fn.calc_checksum_bytes.html +++ b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/descriptor/checksum/fn.calc_checksum_bytes.html @@ -1,11 +1,3 @@ -calc_checksum_bytes in bdk::descriptor::checksum - Rust - -
pub fn calc_checksum_bytes(desc: &str) -> Result<[u8; 8], DescriptorError>
Expand description

Compute the checksum bytes of a descriptor, excludes any existing checksum in the descriptor string from the calculation

-
- \ No newline at end of file +calc_checksum_bytes in bdk::descriptor::checksum - Rust
pub fn calc_checksum_bytes(desc: &str) -> Result<[u8; 8], DescriptorError>
Expand description

Compute the checksum bytes of a descriptor, excludes any existing checksum in the descriptor string from the calculation

+
\ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/descriptor/checksum/fn.get_checksum.html b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/descriptor/checksum/fn.get_checksum.html index ef763c6725..5ec52b6912 100644 --- a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/descriptor/checksum/fn.get_checksum.html +++ b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/descriptor/checksum/fn.get_checksum.html @@ -1,12 +1,3 @@ -get_checksum in bdk::descriptor::checksum - Rust - -
pub fn get_checksum(desc: &str) -> Result<String, DescriptorError>
👎 Deprecated since 0.24.0:

Use new calc_checksum function which excludes any existing checksum in the descriptor string before calculating the checksum hash. See https://github.com/bitcoindevkit/bdk/pull/765.

-
Expand description

Compute the checksum of a descriptor

-
- \ No newline at end of file +get_checksum in bdk::descriptor::checksum - Rust

Function bdk::descriptor::checksum::get_checksum

source ·
pub fn get_checksum(desc: &str) -> Result<String, DescriptorError>
👎Deprecated since 0.24.0: Use new calc_checksum function which excludes any existing checksum in the descriptor string before calculating the checksum hash. See https://github.com/bitcoindevkit/bdk/pull/765.
Expand description

Compute the checksum of a descriptor

+
\ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/descriptor/checksum/fn.get_checksum_bytes.html b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/descriptor/checksum/fn.get_checksum_bytes.html index abecb8a58c..7c9d89ea5b 100644 --- a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/descriptor/checksum/fn.get_checksum_bytes.html +++ b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/descriptor/checksum/fn.get_checksum_bytes.html @@ -1,12 +1,3 @@ -get_checksum_bytes in bdk::descriptor::checksum - Rust - -
pub fn get_checksum_bytes(desc: &str) -> Result<[u8; 8], DescriptorError>
👎 Deprecated since 0.24.0:

Use new calc_checksum_bytes function which excludes any existing checksum in the descriptor string before calculating the checksum hash bytes. See https://github.com/bitcoindevkit/bdk/pull/765.

-
Expand description

Compute the checksum bytes of a descriptor

-
- \ No newline at end of file +get_checksum_bytes in bdk::descriptor::checksum - Rust
pub fn get_checksum_bytes(desc: &str) -> Result<[u8; 8], DescriptorError>
👎Deprecated since 0.24.0: Use new calc_checksum_bytes function which excludes any existing checksum in the descriptor string before calculating the checksum hash bytes. See https://github.com/bitcoindevkit/bdk/pull/765.
Expand description

Compute the checksum bytes of a descriptor

+
\ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/descriptor/checksum/index.html b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/descriptor/checksum/index.html index ecc9ba05cd..e72865b92d 100644 --- a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/descriptor/checksum/index.html +++ b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/descriptor/checksum/index.html @@ -1,18 +1,5 @@ -bdk::descriptor::checksum - Rust - -
Expand description

Descriptor checksum

+bdk::descriptor::checksum - Rust

Module bdk::descriptor::checksum

source ·
Expand description

Descriptor checksum

This module contains a re-implementation of the function used by Bitcoin Core to calculate the checksum of a descriptor

-

Functions

-

Compute the checksum of a descriptor, excludes any existing checksum in the descriptor string from the calculation

-

Compute the checksum bytes of a descriptor, excludes any existing checksum in the descriptor string from the calculation

-
get_checksumDeprecated

Compute the checksum of a descriptor

-

Compute the checksum bytes of a descriptor

-
- \ No newline at end of file +

Functions

Compute the checksum of a descriptor, excludes any existing checksum in the descriptor string from the calculation
Compute the checksum bytes of a descriptor, excludes any existing checksum in the descriptor string from the calculation
get_checksumDeprecated
Compute the checksum of a descriptor
Compute the checksum bytes of a descriptor
\ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/descriptor/checksum/sidebar-items.js b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/descriptor/checksum/sidebar-items.js index ed86aa47a6..238420f6ae 100644 --- a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/descriptor/checksum/sidebar-items.js +++ b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/descriptor/checksum/sidebar-items.js @@ -1 +1 @@ -initSidebarItems({"fn":[["calc_checksum","Compute the checksum of a descriptor, excludes any existing checksum in the descriptor string from the calculation"],["calc_checksum_bytes","Compute the checksum bytes of a descriptor, excludes any existing checksum in the descriptor string from the calculation"],["get_checksum","Compute the checksum of a descriptor"],["get_checksum_bytes","Compute the checksum bytes of a descriptor"]]}); \ No newline at end of file +window.SIDEBAR_ITEMS = {"fn":[["calc_checksum","Compute the checksum of a descriptor, excludes any existing checksum in the descriptor string from the calculation"],["calc_checksum_bytes","Compute the checksum bytes of a descriptor, excludes any existing checksum in the descriptor string from the calculation"],["get_checksum","Compute the checksum of a descriptor"],["get_checksum_bytes","Compute the checksum bytes of a descriptor"]]}; \ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/descriptor/enum.Descriptor.html b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/descriptor/enum.Descriptor.html index 4a8327ed32..5e72695f81 100644 --- a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/descriptor/enum.Descriptor.html +++ b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/descriptor/enum.Descriptor.html @@ -1,12 +1,5 @@ -Descriptor in bdk::descriptor - Rust - -
pub enum Descriptor<Pk> where
    Pk: MiniscriptKey, 
{ +Descriptor in bdk::descriptor - Rust
pub enum Descriptor<Pk>where
    Pk: MiniscriptKey,
{ Bare(Bare<Pk>), Pkh(Pkh<Pk>), Wpkh(Wpkh<Pk>), @@ -14,190 +7,141 @@ Wsh(Wsh<Pk>), Tr(Tr<Pk>), }
Expand description

Script descriptor

-

Variants

Bare(Bare<Pk>)

A raw scriptpubkey (including pay-to-pubkey) under Legacy context

-

Pkh(Pkh<Pk>)

Pay-to-PubKey-Hash

-

Wpkh(Wpkh<Pk>)

Pay-to-Witness-PubKey-Hash

-

Sh(Sh<Pk>)

Pay-to-ScriptHash(includes nested wsh/wpkh/sorted multi)

-

Wsh(Wsh<Pk>)

Pay-to-Witness-ScriptHash with Segwitv0 context

-

Tr(Tr<Pk>)

Pay-to-Taproot

-

Implementations

Create a new pk descriptor

-

Create a new PkH descriptor

-

Create a new Wpkh descriptor +

Variants§

§

Bare(Bare<Pk>)

A raw scriptpubkey (including pay-to-pubkey) under Legacy context

+
§

Pkh(Pkh<Pk>)

Pay-to-PubKey-Hash

+
§

Wpkh(Wpkh<Pk>)

Pay-to-Witness-PubKey-Hash

+
§

Sh(Sh<Pk>)

Pay-to-ScriptHash(includes nested wsh/wpkh/sorted multi)

+
§

Wsh(Wsh<Pk>)

Pay-to-Witness-ScriptHash with Segwitv0 context

+
§

Tr(Tr<Pk>)

Pay-to-Taproot

+

Implementations§

Create a new pk descriptor

+

Create a new PkH descriptor

+

Create a new Wpkh descriptor Will return Err if uncompressed key is used

-

Create a new sh wrapped wpkh from Pk. +

Create a new sh wrapped wpkh from Pk. Errors when uncompressed keys are supplied

-

Create a new sh for a given redeem script +

Create a new sh for a given redeem script Errors when miniscript exceeds resource limits under p2sh context or does not type check at the top level

-

Create a new wsh descriptor from witness script +

Create a new wsh descriptor from witness script Errors when miniscript exceeds resource limits under p2sh context or does not type check at the top level

-

Create a new sh wrapped wsh descriptor with witness script +

Create a new sh wrapped wsh descriptor with witness script Errors when miniscript exceeds resource limits under wsh context or does not type check at the top level

-

Create a new bare descriptor from witness script +

Create a new bare descriptor from witness script Errors when miniscript exceeds resource limits under bare context or does not type check at the top level

-

Create a new sh wrapper for the given wpkh descriptor

-

Create a new sh wrapper for the given wsh descriptor

-

Create a new sh sortedmulti descriptor with threshold k +

Create a new sh wrapper for the given wpkh descriptor

+

Create a new sh wrapper for the given wsh descriptor

+

Create a new sh sortedmulti descriptor with threshold k and Vec of pks. Errors when miniscript exceeds resource limits under p2sh context

-

Create a new sh wrapped wsh sortedmulti descriptor from threshold +

Create a new sh wrapped wsh sortedmulti descriptor from threshold k and Vec of pks Errors when miniscript exceeds resource limits under segwit context

-

Create a new wsh sorted multi descriptor +

Create a new wsh sorted multi descriptor Errors when miniscript exceeds resource limits under p2sh context

-

Create new tr descriptor +

Create new tr descriptor Errors when miniscript exceeds resource limits under Tap context

-

Get the [DescriptorType] of Descriptor

-

Checks whether the descriptor is safe.

+

Get the [DescriptorType] of Descriptor

+

Checks whether the descriptor is safe.

Checks whether all the spend paths in the descriptor are possible on the bitcoin network under the current standardness and consensus rules. Also checks whether the descriptor requires signatures on all spend paths and whether the script is malleable.

In general, all the guarantees of miniscript hold only for safe scripts. The signer may not be able to find satisfactions even if one exists.

-

Computes an upper bound on the weight of a satisfying witness to the +

Computes an upper bound on the weight of a satisfying witness to the transaction.

Assumes all ec-signatures are 73 bytes, including push opcode and sighash suffix. Includes the weight of the VarInts encoding the scriptSig and witness stack length.

-
Errors
+
Errors

When the descriptor is impossible to safisfy (ex: sh(OP_FALSE)).

-

Computes the Bitcoin address of the descriptor, if one exists

+

Computes the Bitcoin address of the descriptor, if one exists

Some descriptors like pk() don’t have an address.

-
Errors
+
Errors

For raw/bare descriptors that don’t have an address.

-

Computes the scriptpubkey of the descriptor.

-

Computes the scriptSig that will be in place for an unsigned input +

Computes the scriptpubkey of the descriptor.

+

Computes the scriptSig that will be in place for an unsigned input spending an output with this descriptor. For pre-segwit descriptors, which use the scriptSig for signatures, this returns the empty script.

This is used in Segwit transactions to produce an unsigned transaction whose txid will not change during signing (since only the witness data will change).

-

Computes the the underlying script before any hashing is done. For +

Computes the the underlying script before any hashing is done. For Bare, Pkh and Wpkh this is the scriptPubkey; for ShWpkh and Sh this is the redeemScript; for the others it is the witness script.

-
Errors
+
Errors

If the descriptor is a taproot descriptor.

-

Computes the scriptCode of a transaction output.

+

Computes the scriptCode of a transaction output.

The scriptCode is the Script of the previous transaction output being serialized in the sighash when evaluating a CHECKSIG & co. OP code.

-
Errors
+
Errors

If the descriptor is a taproot descriptor.

-

Returns satisfying non-malleable witness and scriptSig to spend an +

Returns satisfying non-malleable witness and scriptSig to spend an output controlled by the given descriptor if it possible to construct one using the satisfier S.

-

Returns a possilbly mallable satisfying non-malleable witness and scriptSig to spend an +

Returns a possilbly mallable satisfying non-malleable witness and scriptSig to spend an output controlled by the given descriptor if it possible to construct one using the satisfier S.

-

Attempts to produce a non-malleable satisfying witness and scriptSig to spend an +

Attempts to produce a non-malleable satisfying witness and scriptSig to spend an output controlled by the given descriptor; add the data to a given TxIn output.

-
👎 Deprecated:

use has_wildcards instead

-

Whether or not the descriptor has any wildcards

-

Whether or not the descriptor has any wildcards i.e. /*.

-

Replaces all wildcards (i.e. /*) in the descriptor with a particular derivation index, +

👎Deprecated: use has_wildcards instead

Whether or not the descriptor has any wildcards

+

Whether or not the descriptor has any wildcards i.e. /*.

+

Replaces all wildcards (i.e. /*) in the descriptor with a particular derivation index, turning it into a definite descriptor.

-
Panics
+
Panics

If index ≥ 2^31

-
👎 Deprecated:

use at_derivation_index instead

-

Deprecated name for [at_derivation_index].

-

Convert all the public keys in the descriptor to [bitcoin::PublicKey] by deriving them or +

👎Deprecated: use at_derivation_index instead

Deprecated name for [at_derivation_index].

+

Convert all the public keys in the descriptor to [bitcoin::PublicKey] by deriving them or otherwise converting them. All [bitcoin::XOnlyPublicKey]s are converted to by adding a default(0x02) y-coordinate.

This is a shorthand for:

-
    .expect("Valid ranged descriptor");
-let derived_descriptor = descriptor.at_derivation_index(index).derived_descriptor(&secp);
+
    .expect("Valid ranged descriptor");
+let derived_descriptor = descriptor.at_derivation_index(index).derived_descriptor(&secp);

and is only here really here for backwards compatbility. See at_derivation_index and [derived_descriptor] for more documentation.

-
Errors
+
Errors

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

-

Parse a descriptor that may contain secret keys

+

Parse a descriptor that may contain secret keys

Internally turns every secret key found into the corresponding public key and then returns a a descriptor that only contains public keys and a map to lookup the secret key given a public key.

-

Serialize a descriptor to string with its secret keys

-

Utility method for deriving the descriptor at each index in a range to find one matching +

Serialize a descriptor to string with its secret keys

+

Utility method for deriving the descriptor at each index in a range to find one matching script_pubkey.

If it finds a match then it returns the index it was derived at and the concrete descriptor at that index. If the descriptor is non-derivable then it will simply check the script pubkey against the descriptor and return it if it matches (in this case the index returned will be meaningless).

-

Convert all the public keys in the descriptor to [bitcoin::PublicKey] by deriving them or +

Convert all the public keys in the descriptor to [bitcoin::PublicKey] by deriving them or otherwise converting them. All [bitcoin::XOnlyPublicKey]s are converted to by adding a default(0x02) y-coordinate.

-
Examples
-
use miniscript::descriptor::{Descriptor, DescriptorPublicKey};
-use miniscript::bitcoin::secp256k1;
-use std::str::FromStr;
+
Examples
+
use miniscript::descriptor::{Descriptor, DescriptorPublicKey};
+use miniscript::bitcoin::secp256k1;
+use std::str::FromStr;
 
-// test from bip 86
-let secp = secp256k1::Secp256k1::verification_only();
-let descriptor = Descriptor::<DescriptorPublicKey>::from_str("tr(xpub6BgBgsespWvERF3LHQu6CnqdvfEvtMcQjYrcRzx53QJjSxarj2afYWcLteoGVky7D3UKDP9QyrLprQ3VCECoY49yfdDEHGCtMMj92pReUsQ/0/*)")
-    .expect("Valid ranged descriptor");
-let result = descriptor.at_derivation_index(0).derived_descriptor(&secp).expect("Non-hardened derivation");
-assert_eq!(result.to_string(), "tr(03cc8a4bc64d897bddc5fbc2f670f7a8ba0b386779106cf1223c6fc5d7cd6fc115)#6qm9h8ym");
-
Errors
+// test from bip 86 +let secp = secp256k1::Secp256k1::verification_only(); +let descriptor = Descriptor::<DescriptorPublicKey>::from_str("tr(xpub6BgBgsespWvERF3LHQu6CnqdvfEvtMcQjYrcRzx53QJjSxarj2afYWcLteoGVky7D3UKDP9QyrLprQ3VCECoY49yfdDEHGCtMMj92pReUsQ/0/*)") + .expect("Valid ranged descriptor"); +let result = descriptor.at_derivation_index(0).derived_descriptor(&secp).expect("Non-hardened derivation"); +assert_eq!(result.to_string(), "tr(03cc8a4bc64d897bddc5fbc2f670f7a8ba0b386779106cf1223c6fc5d7cd6fc115)#6qm9h8ym");
+
Errors

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

-

Trait Implementations

Returns a copy of the value. Read more

-

Performs copy-assignment from source. Read more

-

Formats the value using the given formatter. Read more

-

Deserialize this value from the given Serde deserializer. Read more

-

Formats the value using the given formatter. Read more

-

Extract the spending policy

-

Run a predicate on every key in the descriptor, returning whether -the predicate returned true for every key Read more

-

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

-

Performs the conversion.

-

Performs the conversion.

-

Performs the conversion.

-

Performs the conversion.

-

Performs the conversion.

-

Performs the conversion.

-

The associated error which can be returned from parsing.

-

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

-

Parse an expression tree into a descriptor.

-

Feeds this value into the given Hasher. Read more

-

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

-

Convert the object into an abstract policy

-

This method returns an Ordering between self and other. Read more

-

Compares and returns the maximum of two values. Read more

-

Compares and returns the minimum of two values. Read more

-

Restrict a value to a certain interval. Read more

-

This method tests for self and other values to be equal, and is used -by ==. Read more

-

This method tests for !=.

-

This method returns an ordering between self and other values if one exists. Read more

-

This method tests less than (for self and other) and is used by the < operator. Read more

-

This method tests less than or equal to (for self and other) and is used by the <= -operator. Read more

-

This method tests greater than (for self and other) and is used by the > operator. Read more

-

This method tests greater than or equal to (for self and other) and is used by the >= -operator. Read more

-

Serialize this value into the given Serde serializer. Read more

-

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

-

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

-

Auto Trait Implementations

Blanket Implementations

Gets the TypeId of self. Read more

-

Immutably borrows from an owned value. Read more

-

Mutably borrows from an owned value. Read more

-

Performs the conversion.

-

Performs the conversion.

-

The alignment of pointer.

-

The type for initializers.

-

Initializes a with the given initializer. Read more

-

Dereferences the given pointer. Read more

-

Mutably dereferences the given pointer. Read more

-

Drops the object pointed to by the given pointer. Read more

-

The resulting type after obtaining ownership.

-

Creates owned data from borrowed data, usually by cloning. Read more

-
🔬 This is a nightly-only experimental API. (toowned_clone_into)

Uses borrowed data to replace owned data, usually by cloning. Read more

-

Converts the given value to a String. Read more

-

The type returned in the event of a conversion error.

-

Performs the conversion.

-

The type returned in the event of a conversion error.

-

Performs the conversion.

-
- \ No newline at end of file +

Trait Implementations§

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

Parse an expression tree into a descriptor.

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

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

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

Auto Trait Implementations§

Blanket Implementations§

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

Returns the argument unchanged.

+

Calls U::from(self).

+

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

+
The alignment of pointer.
The type for initializers.
Initializes a with the given initializer. Read more
Dereferences the given pointer. Read more
Mutably dereferences the given pointer. Read more
Drops the object pointed to by the given pointer. Read more
The resulting type after obtaining ownership.
Creates owned data from borrowed data, usually by cloning. Read more
Uses borrowed data to replace owned data, usually by cloning. Read more
Converts the given value to a String. Read more
The type returned in the event of a conversion error.
Performs the conversion.
The type returned in the event of a conversion error.
Performs the conversion.
\ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/descriptor/enum.DescriptorPublicKey.html b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/descriptor/enum.DescriptorPublicKey.html index 959c695c0f..0493530060 100644 --- a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/descriptor/enum.DescriptorPublicKey.html +++ b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/descriptor/enum.DescriptorPublicKey.html @@ -1,89 +1,38 @@ -DescriptorPublicKey in bdk::descriptor - Rust - -
pub enum DescriptorPublicKey {
+DescriptorPublicKey in bdk::descriptor - Rust
pub enum DescriptorPublicKey {
     Single(SinglePub),
     XPub(DescriptorXKey<ExtendedPubKey>),
 }
Expand description

The descriptor pubkey, either a single pubkey or an xpub.

-

Variants

Single(SinglePub)

Single public key.

-

XPub(DescriptorXKey<ExtendedPubKey>)

Extended public key (xpub).

-

Implementations

The fingerprint of the master key associated with this key, 0x00000000 if none.

-

Full path, from the master key

+

Variants§

§

Single(SinglePub)

Single public key.

+
§

XPub(DescriptorXKey<ExtendedPubKey>)

Extended public key (xpub).

+

Implementations§

The fingerprint of the master key associated with this key, 0x00000000 if none.

+

Full path, from the master key

For wildcard keys this will return the path up to the wildcard, so you can get full paths by appending one additional derivation step, according to the wildcard type (hardened or normal)

-
👎 Deprecated:

use has_wildcard instead

-

Whether or not the key has a wildcard

-

Whether or not the key has a wildcard

-
👎 Deprecated:

use at_derivation_index instead

-

Deprecated name of [at_derivation_index].

-

Replaces any wildcard (i.e. /*) in the key with a particular derivation index, turning it into a +

👎Deprecated: use has_wildcard instead

Whether or not the key has a wildcard

+

Whether or not the key has a wildcard

+
👎Deprecated: use at_derivation_index instead

Deprecated name of [at_derivation_index].

+

Replaces any wildcard (i.e. /*) in the key with a particular derivation index, turning it into a definite key (i.e. one where all the derivation paths are set).

-
Returns
+
Returns
  • If this key is not an xpub, returns self.
  • If this key is an xpub but does not have a wildcard, returns self.
  • Otherwise, returns the xpub at derivation index (removing the wildcard).
-
Panics
+
Panics

If index ≥ 2^31

-

Trait Implementations

Returns a copy of the value. Read more

-

Performs copy-assignment from source. Read more

-

Formats the value using the given formatter. Read more

-

Formats the value using the given formatter. Read more

-

Performs the conversion.

-

The associated error which can be returned from parsing.

-

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

-

Feeds this value into the given Hasher. Read more

-

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

-

Turn the key into a DescriptorKey within the requested ScriptContext

-

The associated [sha256::Hash] for this [MiniscriptKey], -used in the hash256 fragment. Read more

-

The associated [hash256::Hash] for this [MiniscriptKey], -used in the hash256 fragment. Read more

-

The associated [ripedmd160::Hash] for this [MiniscriptKey] type. -used in the ripemd160 fragment Read more

-

The associated [hash160::Hash] for this [MiniscriptKey] type. -used in the hash160 fragment Read more

-

Returns true if the pubkey is uncompressed. Defaults to false.

-

Returns true if the pubkey is an x-only pubkey. Defaults to false.

-

This method returns an Ordering between self and other. Read more

-

Compares and returns the maximum of two values. Read more

-

Compares and returns the minimum of two values. Read more

-

Restrict a value to a certain interval. Read more

-

This method tests for self and other values to be equal, and is used -by ==. Read more

-

This method tests for !=.

-

This method returns an ordering between self and other values if one exists. Read more

-

This method tests less than (for self and other) and is used by the < operator. Read more

-

This method tests less than or equal to (for self and other) and is used by the <= -operator. Read more

-

This method tests greater than (for self and other) and is used by the > operator. Read more

-

This method tests greater than or equal to (for self and other) and is used by the >= -operator. Read more

-

Auto Trait Implementations

Blanket Implementations

Gets the TypeId of self. Read more

-

Immutably borrows from an owned value. Read more

-

Mutably borrows from an owned value. Read more

-

Performs the conversion.

-

Performs the conversion.

-

The alignment of pointer.

-

The type for initializers.

-

Initializes a with the given initializer. Read more

-

Dereferences the given pointer. Read more

-

Mutably dereferences the given pointer. Read more

-

Drops the object pointed to by the given pointer. Read more

-

The resulting type after obtaining ownership.

-

Creates owned data from borrowed data, usually by cloning. Read more

-
🔬 This is a nightly-only experimental API. (toowned_clone_into)

Uses borrowed data to replace owned data, usually by cloning. Read more

-

Converts the given value to a String. Read more

-

The type returned in the event of a conversion error.

-

Performs the conversion.

-

The type returned in the event of a conversion error.

-

Performs the conversion.

-
- \ No newline at end of file +

Trait Implementations§

Returns a copy of the value. Read more
Performs copy-assignment from source. Read more
Formats the value using the given formatter. Read more
Formats the value using the given formatter. Read more
Converts to this type from the input type.
The associated error which can be returned from parsing.
Parses a string s to return a value of this type. Read more
Feeds this value into the given Hasher. Read more
Feeds a slice of this type into the given Hasher. Read more
Turn the key into a DescriptorKey within the requested ScriptContext
The associated [sha256::Hash] for this [MiniscriptKey], +used in the hash256 fragment. Read more
The associated [hash256::Hash] for this [MiniscriptKey], +used in the hash256 fragment. Read more
The associated [ripedmd160::Hash] for this [MiniscriptKey] type. +used in the ripemd160 fragment Read more
The associated [hash160::Hash] for this [MiniscriptKey] type. +used in the hash160 fragment Read more
Returns true if the pubkey is uncompressed. Defaults to false.
Returns true if the pubkey is an x-only pubkey. Defaults to false.
This method returns an Ordering between self and other. Read more
Compares and returns the maximum of two values. Read more
Compares and returns the minimum of two values. Read more
Restrict a value to a certain interval. Read more
This method tests for self and other values to be equal, and is used +by ==. Read more
This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason. Read more
This method returns an ordering between self and other values if one exists. Read more
This method tests less than (for self and other) and is used by the < operator. Read more
This method tests less than or equal to (for self and other) and is used by the <= +operator. Read more
This method tests greater than (for self and other) and is used by the > operator. Read more
This method tests greater than or equal to (for self and other) and is used by the >= +operator. Read more

Auto Trait Implementations§

Blanket Implementations§

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

Returns the argument unchanged.

+

Calls U::from(self).

+

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

+
The alignment of pointer.
The type for initializers.
Initializes a with the given initializer. Read more
Dereferences the given pointer. Read more
Mutably dereferences the given pointer. Read more
Drops the object pointed to by the given pointer. Read more
The resulting type after obtaining ownership.
Creates owned data from borrowed data, usually by cloning. Read more
Uses borrowed data to replace owned data, usually by cloning. Read more
Converts the given value to a String. Read more
The type returned in the event of a conversion error.
Performs the conversion.
The type returned in the event of a conversion error.
Performs the conversion.
\ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/descriptor/enum.Legacy.html b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/descriptor/enum.Legacy.html index 8c820c6538..e9741a5f0c 100644 --- a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/descriptor/enum.Legacy.html +++ b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/descriptor/enum.Legacy.html @@ -1,47 +1,22 @@ -Legacy in bdk::descriptor - Rust - -
pub enum Legacy {}
Expand description

Legacy ScriptContext +Legacy in bdk::descriptor - Rust

Enum bdk::descriptor::Legacy

pub enum Legacy {}
Expand description

Legacy ScriptContext To be used as P2SH scripts For creation of Bare scriptpubkeys, construct the Miniscript under Bare ScriptContext

-

Trait Implementations

Returns a copy of the value. Read more

-

Performs copy-assignment from source. Read more

-

Formats the value using the given formatter. Read more

-

Feeds this value into the given Hasher. Read more

-

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

-

This method returns an Ordering between self and other. Read more

-

Compares and returns the maximum of two values. Read more

-

Compares and returns the minimum of two values. Read more

-

Restrict a value to a certain interval. Read more

-

This method tests for self and other values to be equal, and is used -by ==. Read more

-

This method tests for !=.

-

This method returns an ordering between self and other values if one exists. Read more

-

This method tests less than (for self and other) and is used by the < operator. Read more

-

This method tests less than or equal to (for self and other) and is used by the <= -operator. Read more

-

This method tests greater than (for self and other) and is used by the > operator. Read more

-

This method tests greater than or equal to (for self and other) and is used by the >= -operator. Read more

-

The consensus key associated with the type. Must be a parseable key

-

Depending on ScriptContext, fragments can be malleable. For Example, +

Trait Implementations§

Returns a copy of the value. Read more
Performs copy-assignment from source. Read more
Formats the value using the given formatter. Read more
Feeds this value into the given Hasher. Read more
Feeds a slice of this type into the given Hasher. Read more
This method returns an Ordering between self and other. Read more
Compares and returns the maximum of two values. Read more
Compares and returns the minimum of two values. Read more
Restrict a value to a certain interval. Read more
This method tests for self and other values to be equal, and is used +by ==. Read more
This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason. Read more
This method returns an ordering between self and other values if one exists. Read more
This method tests less than (for self and other) and is used by the < operator. Read more
This method tests less than or equal to (for self and other) and is used by the <= +operator. Read more
This method tests greater than (for self and other) and is used by the > operator. Read more
This method tests greater than or equal to (for self and other) and is used by the >= +operator. Read more
The consensus key associated with the type. Must be a parseable key
Depending on ScriptContext, fragments can be malleable. For Example, under Legacy context, PkH is malleable because it is possible to estimate the cost of satisfaction because of compressed keys This is currently only used in compiler code for removing malleable compilations. This does NOT recursively check if the children of the fragment are valid or not. Since the compilation proceeds in a leaf to root fashion, -a recursive check is unnecessary. Read more

-

Check whether the given satisfaction is valid under the ScriptContext +a recursive check is unnecessary. Read more

Check whether the given satisfaction is valid under the ScriptContext For example, segwit satisfactions may fail if the witness len is more -3600 or number of stack elements are more than 100. Read more

-

Depending on script Context, some of the Terminals might not +3600 or number of stack elements are more than 100. Read more

Depending on script Context, some of the Terminals might not be valid under the current consensus rules. Or some of the script resource limits may have been exceeded. These miniscripts would never be accepted by the Bitcoin network and hence @@ -50,59 +25,27 @@ For example, in Segwit Context with MiniscriptKey as bitcoin::PublicKey uncompressed public keys are non-standard and thus invalid. In LegacyP2SH context, scripts above 520 bytes are invalid. Post Tapscript upgrade, this would have to consider other nodes. -This does NOT recursively check the miniscript fragments. Read more

-

Consensus rules at the Miniscript satisfaction time. +This does NOT recursively check the miniscript fragments. Read more

Consensus rules at the Miniscript satisfaction time. It is possible that some paths of miniscript may exceed resource limits and our current satisfier and lifting analysis would not work correctly. -For example, satisfaction path(Legacy/Segwitv0) may require more than 201 opcodes. Read more

-

Policy rules at the Miniscript satisfaction time. +For example, satisfaction path(Legacy/Segwitv0) may require more than 201 opcodes. Read more

Policy rules at the Miniscript satisfaction time. It is possible that some paths of miniscript may exceed resource limits and our current satisfier and lifting analysis would not work correctly. For example, satisfaction path in Legacy context scriptSig more -than 1650 bytes Read more

-

Depending on script context, the size of a satifaction witness may slightly differ.

-

Get the len of public key when serialized based on context +than 1650 bytes Read more

Depending on script context, the size of a satifaction witness may slightly differ.
Get the len of public key when serialized based on context Note that this includes the serialization prefix. Returns 34/66 for Bare/Legacy based on key compressedness -34 for Segwitv0, 33 for Tap Read more

-

Local helper function to display error messages with context

-

The type of signature required for satisfaction

-

Depending on script Context, some of the script resource limits +34 for Segwitv0, 33 for Tap Read more

Local helper function to display error messages with context
The type of signature required for satisfaction
Depending on script Context, some of the script resource limits may have been exceeded under the current bitcoin core policy rules These miniscripts would never be accepted by the Bitcoin network and hence it is safe to discard them. (unless explicitly disabled by non-standard flag) For example, in Segwit Context with MiniscriptKey as bitcoin::PublicKey scripts over 3600 bytes are invalid. Post Tapscript upgrade, this would have to consider other nodes. -This does NOT recursively check the miniscript fragments. Read more

-

Check the consensus + policy(if not disabled) rules that are not based -satisfaction Read more

-

Check the consensus + policy(if not disabled) rules including the -ones for satisfaction Read more

-

Check whether the top-level is type B

-

Other top level checks that are context specific

-

Check top level consensus rules.

-

Auto Trait Implementations

Blanket Implementations

Gets the TypeId of self. Read more

-

Immutably borrows from an owned value. Read more

-

Mutably borrows from an owned value. Read more

-

Returns the ScriptContext as a ScriptContextEnum

-

Returns whether the script context is Legacy

-

Returns whether the script context is Segwitv0

-

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

-

Performs the conversion.

-

Performs the conversion.

-

The alignment of pointer.

-

The type for initializers.

-

Initializes a with the given initializer. Read more

-

Dereferences the given pointer. Read more

-

Mutably dereferences the given pointer. Read more

-

Drops the object pointed to by the given pointer. Read more

-

The resulting type after obtaining ownership.

-

Creates owned data from borrowed data, usually by cloning. Read more

-
🔬 This is a nightly-only experimental API. (toowned_clone_into)

Uses borrowed data to replace owned data, usually by cloning. Read more

-

The type returned in the event of a conversion error.

-

Performs the conversion.

-

The type returned in the event of a conversion error.

-

Performs the conversion.

-
- \ No newline at end of file +This does NOT recursively check the miniscript fragments. Read more
Check the consensus + policy(if not disabled) rules that are not based +satisfaction Read more
Check the consensus + policy(if not disabled) rules including the +ones for satisfaction Read more
Check whether the top-level is type B
Other top level checks that are context specific
Check top level consensus rules.

Auto Trait Implementations§

Blanket Implementations§

Gets the TypeId of self. Read more
Immutably borrows from an owned value. Read more
Mutably borrows from an owned value. Read more
Returns whether the script context is Legacy
Returns whether the script context is Segwitv0
Returns whether the script context is Tap, aka Taproot or Segwit V1

Returns the argument unchanged.

+

Calls U::from(self).

+

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

+
The alignment of pointer.
The type for initializers.
Initializes a with the given initializer. Read more
Dereferences the given pointer. Read more
Mutably dereferences the given pointer. Read more
Drops the object pointed to by the given pointer. Read more
The resulting type after obtaining ownership.
Creates owned data from borrowed data, usually by cloning. Read more
Uses borrowed data to replace owned data, usually by cloning. Read more
The type returned in the event of a conversion error.
Performs the conversion.
The type returned in the event of a conversion error.
Performs the conversion.
\ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/descriptor/enum.Segwitv0.html b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/descriptor/enum.Segwitv0.html index 1f89cb1c1b..5685161db5 100644 --- a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/descriptor/enum.Segwitv0.html +++ b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/descriptor/enum.Segwitv0.html @@ -1,44 +1,19 @@ -Segwitv0 in bdk::descriptor - Rust - -
pub enum Segwitv0 {}
Expand description

Segwitv0 ScriptContext

-

Trait Implementations

Returns a copy of the value. Read more

-

Performs copy-assignment from source. Read more

-

Formats the value using the given formatter. Read more

-

Feeds this value into the given Hasher. Read more

-

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

-

This method returns an Ordering between self and other. Read more

-

Compares and returns the maximum of two values. Read more

-

Compares and returns the minimum of two values. Read more

-

Restrict a value to a certain interval. Read more

-

This method tests for self and other values to be equal, and is used -by ==. Read more

-

This method tests for !=.

-

This method returns an ordering between self and other values if one exists. Read more

-

This method tests less than (for self and other) and is used by the < operator. Read more

-

This method tests less than or equal to (for self and other) and is used by the <= -operator. Read more

-

This method tests greater than (for self and other) and is used by the > operator. Read more

-

This method tests greater than or equal to (for self and other) and is used by the >= -operator. Read more

-

The consensus key associated with the type. Must be a parseable key

-

Depending on ScriptContext, fragments can be malleable. For Example, +Segwitv0 in bdk::descriptor - Rust

Enum bdk::descriptor::Segwitv0

pub enum Segwitv0 {}
Expand description

Segwitv0 ScriptContext

+

Trait Implementations§

Returns a copy of the value. Read more
Performs copy-assignment from source. Read more
Formats the value using the given formatter. Read more
Feeds this value into the given Hasher. Read more
Feeds a slice of this type into the given Hasher. Read more
This method returns an Ordering between self and other. Read more
Compares and returns the maximum of two values. Read more
Compares and returns the minimum of two values. Read more
Restrict a value to a certain interval. Read more
This method tests for self and other values to be equal, and is used +by ==. Read more
This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason. Read more
This method returns an ordering between self and other values if one exists. Read more
This method tests less than (for self and other) and is used by the < operator. Read more
This method tests less than or equal to (for self and other) and is used by the <= +operator. Read more
This method tests greater than (for self and other) and is used by the > operator. Read more
This method tests greater than or equal to (for self and other) and is used by the >= +operator. Read more
The consensus key associated with the type. Must be a parseable key
Depending on ScriptContext, fragments can be malleable. For Example, under Legacy context, PkH is malleable because it is possible to estimate the cost of satisfaction because of compressed keys This is currently only used in compiler code for removing malleable compilations. This does NOT recursively check if the children of the fragment are valid or not. Since the compilation proceeds in a leaf to root fashion, -a recursive check is unnecessary. Read more

-

Check whether the given satisfaction is valid under the ScriptContext +a recursive check is unnecessary. Read more

Check whether the given satisfaction is valid under the ScriptContext For example, segwit satisfactions may fail if the witness len is more -3600 or number of stack elements are more than 100. Read more

-

Depending on script Context, some of the Terminals might not +3600 or number of stack elements are more than 100. Read more

Depending on script Context, some of the Terminals might not be valid under the current consensus rules. Or some of the script resource limits may have been exceeded. These miniscripts would never be accepted by the Bitcoin network and hence @@ -47,59 +22,27 @@ For example, in Segwit Context with MiniscriptKey as bitcoin::PublicKey uncompressed public keys are non-standard and thus invalid. In LegacyP2SH context, scripts above 520 bytes are invalid. Post Tapscript upgrade, this would have to consider other nodes. -This does NOT recursively check the miniscript fragments. Read more

-

Consensus rules at the Miniscript satisfaction time. +This does NOT recursively check the miniscript fragments. Read more

Consensus rules at the Miniscript satisfaction time. It is possible that some paths of miniscript may exceed resource limits and our current satisfier and lifting analysis would not work correctly. -For example, satisfaction path(Legacy/Segwitv0) may require more than 201 opcodes. Read more

-

Depending on script Context, some of the script resource limits +For example, satisfaction path(Legacy/Segwitv0) may require more than 201 opcodes. Read more

Depending on script Context, some of the script resource limits may have been exceeded under the current bitcoin core policy rules These miniscripts would never be accepted by the Bitcoin network and hence it is safe to discard them. (unless explicitly disabled by non-standard flag) For example, in Segwit Context with MiniscriptKey as bitcoin::PublicKey scripts over 3600 bytes are invalid. Post Tapscript upgrade, this would have to consider other nodes. -This does NOT recursively check the miniscript fragments. Read more

-

Policy rules at the Miniscript satisfaction time. +This does NOT recursively check the miniscript fragments. Read more

Policy rules at the Miniscript satisfaction time. It is possible that some paths of miniscript may exceed resource limits and our current satisfier and lifting analysis would not work correctly. For example, satisfaction path in Legacy context scriptSig more -than 1650 bytes Read more

-

Depending on script context, the size of a satifaction witness may slightly differ.

-

Get the len of public key when serialized based on context +than 1650 bytes Read more

Depending on script context, the size of a satifaction witness may slightly differ.
Get the len of public key when serialized based on context Note that this includes the serialization prefix. Returns 34/66 for Bare/Legacy based on key compressedness -34 for Segwitv0, 33 for Tap Read more

-

Local helper function to display error messages with context

-

The type of signature required for satisfaction

-

Check the consensus + policy(if not disabled) rules that are not based -satisfaction Read more

-

Check the consensus + policy(if not disabled) rules including the -ones for satisfaction Read more

-

Check whether the top-level is type B

-

Other top level checks that are context specific

-

Check top level consensus rules.

-

Auto Trait Implementations

Blanket Implementations

Gets the TypeId of self. Read more

-

Immutably borrows from an owned value. Read more

-

Mutably borrows from an owned value. Read more

-

Returns the ScriptContext as a ScriptContextEnum

-

Returns whether the script context is Legacy

-

Returns whether the script context is Segwitv0

-

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

-

Performs the conversion.

-

Performs the conversion.

-

The alignment of pointer.

-

The type for initializers.

-

Initializes a with the given initializer. Read more

-

Dereferences the given pointer. Read more

-

Mutably dereferences the given pointer. Read more

-

Drops the object pointed to by the given pointer. Read more

-

The resulting type after obtaining ownership.

-

Creates owned data from borrowed data, usually by cloning. Read more

-
🔬 This is a nightly-only experimental API. (toowned_clone_into)

Uses borrowed data to replace owned data, usually by cloning. Read more

-

The type returned in the event of a conversion error.

-

Performs the conversion.

-

The type returned in the event of a conversion error.

-

Performs the conversion.

-
- \ No newline at end of file +34 for Segwitv0, 33 for Tap Read more
Local helper function to display error messages with context
The type of signature required for satisfaction
Check the consensus + policy(if not disabled) rules that are not based +satisfaction Read more
Check the consensus + policy(if not disabled) rules including the +ones for satisfaction Read more
Check whether the top-level is type B
Other top level checks that are context specific
Check top level consensus rules.

Auto Trait Implementations§

Blanket Implementations§

Gets the TypeId of self. Read more
Immutably borrows from an owned value. Read more
Mutably borrows from an owned value. Read more
Returns whether the script context is Legacy
Returns whether the script context is Segwitv0
Returns whether the script context is Tap, aka Taproot or Segwit V1

Returns the argument unchanged.

+

Calls U::from(self).

+

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

+
The alignment of pointer.
The type for initializers.
Initializes a with the given initializer. Read more
Dereferences the given pointer. Read more
Mutably dereferences the given pointer. Read more
Drops the object pointed to by the given pointer. Read more
The resulting type after obtaining ownership.
Creates owned data from borrowed data, usually by cloning. Read more
Uses borrowed data to replace owned data, usually by cloning. Read more
The type returned in the event of a conversion error.
Performs the conversion.
The type returned in the event of a conversion error.
Performs the conversion.
\ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/descriptor/enum.Wildcard.html b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/descriptor/enum.Wildcard.html index 96a6d5d46e..d9e35cbb30 100644 --- a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/descriptor/enum.Wildcard.html +++ b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/descriptor/enum.Wildcard.html @@ -1,55 +1,18 @@ -Wildcard in bdk::descriptor - Rust - -
pub enum Wildcard {
+Wildcard in bdk::descriptor - Rust

Enum bdk::descriptor::Wildcard

pub enum Wildcard {
     None,
     Unhardened,
     Hardened,
 }
Expand description

Whether a descriptor has a wildcard in it

-

Variants

None

No wildcard

-

Unhardened

Unhardened wildcard, e.g. *

-

Hardened

Unhardened wildcard, e.g. *h

-

Trait Implementations

Returns a copy of the value. Read more

-

Performs copy-assignment from source. Read more

-

Formats the value using the given formatter. Read more

-

Feeds this value into the given Hasher. Read more

-

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

-

This method returns an Ordering between self and other. Read more

-

Compares and returns the maximum of two values. Read more

-

Compares and returns the minimum of two values. Read more

-

Restrict a value to a certain interval. Read more

-

This method tests for self and other values to be equal, and is used -by ==. Read more

-

This method tests for !=.

-

This method returns an ordering between self and other values if one exists. Read more

-

This method tests less than (for self and other) and is used by the < operator. Read more

-

This method tests less than or equal to (for self and other) and is used by the <= -operator. Read more

-

This method tests greater than (for self and other) and is used by the > operator. Read more

-

This method tests greater than or equal to (for self and other) and is used by the >= -operator. Read more

-

Auto Trait Implementations

Blanket Implementations

Gets the TypeId of self. Read more

-

Immutably borrows from an owned value. Read more

-

Mutably borrows from an owned value. Read more

-

Performs the conversion.

-

Performs the conversion.

-

The alignment of pointer.

-

The type for initializers.

-

Initializes a with the given initializer. Read more

-

Dereferences the given pointer. Read more

-

Mutably dereferences the given pointer. Read more

-

Drops the object pointed to by the given pointer. Read more

-

The resulting type after obtaining ownership.

-

Creates owned data from borrowed data, usually by cloning. Read more

-
🔬 This is a nightly-only experimental API. (toowned_clone_into)

Uses borrowed data to replace owned data, usually by cloning. Read more

-

The type returned in the event of a conversion error.

-

Performs the conversion.

-

The type returned in the event of a conversion error.

-

Performs the conversion.

-
- \ No newline at end of file +

Variants§

§

None

No wildcard

+
§

Unhardened

Unhardened wildcard, e.g. *

+
§

Hardened

Unhardened wildcard, e.g. *h

+

Trait Implementations§

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

Auto Trait Implementations§

Blanket Implementations§

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

Returns the argument unchanged.

+

Calls U::from(self).

+

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

+
The alignment of pointer.
The type for initializers.
Initializes a with the given initializer. Read more
Dereferences the given pointer. Read more
Mutably dereferences the given pointer. Read more
Drops the object pointed to by the given pointer. Read more
The resulting type after obtaining ownership.
Creates owned data from borrowed data, usually by cloning. Read more
Uses borrowed data to replace owned data, usually by cloning. Read more
The type returned in the event of a conversion error.
Performs the conversion.
The type returned in the event of a conversion error.
Performs the conversion.
\ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/descriptor/error/enum.Error.html b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/descriptor/error/enum.Error.html index b018009c5b..81f36e7b76 100644 --- a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/descriptor/error/enum.Error.html +++ b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/descriptor/error/enum.Error.html @@ -1,12 +1,5 @@ -Error in bdk::descriptor::error - Rust - -
pub enum Error {
+Error in bdk::descriptor::error - Rust

Enum bdk::descriptor::error::Error

source ·
pub enum Error {
     InvalidHdKeyPath,
     InvalidDescriptorChecksum,
     HardenedDerivationXpub,
@@ -19,46 +12,20 @@
     Miniscript(Error),
     Hex(Error),
 }
Expand description

Errors related to the parsing and usage of descriptors

-

Variants

InvalidHdKeyPath

Invalid HD Key path, such as having a wildcard but a length != 1

-

InvalidDescriptorChecksum

The provided descriptor doesn’t match its checksum

-

HardenedDerivationXpub

The descriptor contains hardened derivation steps on public extended keys

-

Key(KeyError)

Error thrown while working with keys

-

Policy(PolicyError)

Error while extracting and manipulating policies

-

InvalidDescriptorCharacter(u8)

Invalid byte found in the descriptor checksum

-

Bip32(Error)

BIP32 error

-

Base58(Error)

Error during base58 decoding

-

Pk(Error)

Key-related error

-

Miniscript(Error)

Miniscript error

-

Hex(Error)

Hex decoding error

-

Trait Implementations

Formats the value using the given formatter. Read more

-

Formats the value using the given formatter. Read more

-

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

-
🔬 This is a nightly-only experimental API. (backtrace)

Returns a stack backtrace, if available, of where this error occurred. Read more

-
👎 Deprecated since 1.42.0:

use the Display impl or to_string()

-
👎 Deprecated since 1.33.0:

replaced by Error::source, which can support downcasting

-

Performs the conversion.

-

Performs the conversion.

-

Performs the conversion.

-

Performs the conversion.

-

Performs the conversion.

-

Performs the conversion.

-

Performs the conversion.

-

Performs the conversion.

-

Auto Trait Implementations

Blanket Implementations

Gets the TypeId of self. Read more

-

Immutably borrows from an owned value. Read more

-

Mutably borrows from an owned value. Read more

-

Performs the conversion.

-

Performs the conversion.

-

The alignment of pointer.

-

The type for initializers.

-

Initializes a with the given initializer. Read more

-

Dereferences the given pointer. Read more

-

Mutably dereferences the given pointer. Read more

-

Drops the object pointed to by the given pointer. Read more

-

Converts the given value to a String. Read more

-

The type returned in the event of a conversion error.

-

Performs the conversion.

-

The type returned in the event of a conversion error.

-

Performs the conversion.

-
- \ No newline at end of file +

Variants§

§

InvalidHdKeyPath

Invalid HD Key path, such as having a wildcard but a length != 1

+
§

InvalidDescriptorChecksum

The provided descriptor doesn’t match its checksum

+
§

HardenedDerivationXpub

The descriptor contains hardened derivation steps on public extended keys

+
§

Key(KeyError)

Error thrown while working with keys

+
§

Policy(PolicyError)

Error while extracting and manipulating policies

+
§

InvalidDescriptorCharacter(u8)

Invalid byte found in the descriptor checksum

+
§

Bip32(Error)

BIP32 error

+
§

Base58(Error)

Error during base58 decoding

+
§

Pk(Error)

Key-related error

+
§

Miniscript(Error)

Miniscript error

+
§

Hex(Error)

Hex decoding error

+

Trait Implementations§

Formats the value using the given formatter. Read more
Formats the value using the given formatter. Read more
The lower-level source of this error, if any. Read more
👎Deprecated since 1.42.0: use the Display impl or to_string()
👎Deprecated since 1.33.0: replaced by Error::source, which can support downcasting
🔬This is a nightly-only experimental API. (error_generic_member_access)
Provides type based access to context intended for error reports. Read more
Converts to this type from the input type.
Converts to this type from the input type.
Converts to this type from the input type.
Converts to this type from the input type.
Converts to this type from the input type.
Converts to this type from the input type.
Converts to this type from the input type.
Converts to this type from the input type.

Auto Trait Implementations§

Blanket Implementations§

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

Returns the argument unchanged.

+

Calls U::from(self).

+

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

+
The alignment of pointer.
The type for initializers.
Initializes a with the given initializer. Read more
Dereferences the given pointer. Read more
Mutably dereferences the given pointer. Read more
Drops the object pointed to by the given pointer. Read more
🔬This is a nightly-only experimental API. (provide_any)
Data providers should implement this method to provide all values they are able to +provide by using demand. Read more
Converts the given value to a String. Read more
The type returned in the event of a conversion error.
Performs the conversion.
The type returned in the event of a conversion error.
Performs the conversion.
\ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/descriptor/error/index.html b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/descriptor/error/index.html index c1a64cb1c2..d82b924e1f 100644 --- a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/descriptor/error/index.html +++ b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/descriptor/error/index.html @@ -1,13 +1,3 @@ -bdk::descriptor::error - Rust - -
-

Module bdk::descriptor::error

source · []
Expand description

Descriptor errors

-

Enums

-

Errors related to the parsing and usage of descriptors

-
- \ No newline at end of file +bdk::descriptor::error - Rust

Module bdk::descriptor::error

source ·
Expand description

Descriptor errors

+

Enums

Errors related to the parsing and usage of descriptors
\ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/descriptor/error/sidebar-items.js b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/descriptor/error/sidebar-items.js index 1ad99d4faf..eb47e2c4d1 100644 --- a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/descriptor/error/sidebar-items.js +++ b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/descriptor/error/sidebar-items.js @@ -1 +1 @@ -initSidebarItems({"enum":[["Error","Errors related to the parsing and usage of descriptors"]]}); \ No newline at end of file +window.SIDEBAR_ITEMS = {"enum":[["Error","Errors related to the parsing and usage of descriptors"]]}; \ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/descriptor/index.html b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/descriptor/index.html index 3dea62f5b4..3589458fcd 100644 --- a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/descriptor/index.html +++ b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/descriptor/index.html @@ -1,46 +1,13 @@ -bdk::descriptor - Rust - -
-

Module bdk::descriptor

source · []
Expand description

Descriptors

+bdk::descriptor - Rust

Module bdk::descriptor

source ·
Expand description

Descriptors

This module contains generic utilities to work with descriptors, plus some re-exported types from [miniscript].

-

Re-exports

-
pub use self::checksum::calc_checksum;
pub use self::error::Error as DescriptorError;
pub use self::policy::Policy;

Modules

-

Descriptor checksum

-

Descriptor errors

-

Descriptor policy

-

Descriptor templates

-

Structs

-

An extended key with origin, derivation path, and wildcard.

-

Top-level script AST type

-

Enums

-

Script descriptor

-

The descriptor pubkey, either a single pubkey or an xpub.

-

Legacy ScriptContext +

Re-exports

pub use self::checksum::calc_checksum;
pub use self::error::Error as DescriptorError;
pub use self::policy::Policy;

Modules

Descriptor checksum
Descriptor errors
Descriptor policy
Descriptor templates

Structs

An extended key with origin, derivation path, and wildcard.
Top-level script AST type

Enums

Script descriptor
The descriptor pubkey, either a single pubkey or an xpub.
Legacy ScriptContext To be used as P2SH scripts For creation of Bare scriptpubkeys, construct the Miniscript -under Bare ScriptContext

-

Segwitv0 ScriptContext

-

Whether a descriptor has a wildcard in it

-

Traits

-

Trait implemented on Descriptors to add a method to extract the spending policy

-

Trait for types which can be converted into an ExtendedDescriptor and a KeyMap usable by a wallet in a specific [Network]

-

The ScriptContext for Miniscript. Additional type information associated with +under Bare ScriptContext

Segwitv0 ScriptContext
Whether a descriptor has a wildcard in it

Traits

Trait implemented on Descriptors to add a method to extract the spending policy
Trait for types which can be converted into an ExtendedDescriptor and a KeyMap usable by a wallet in a specific [Network]
The ScriptContext for Miniscript. Additional type information associated with miniscript that is used for carrying out checks that dependent on the context under which the script is used. -For example, disallowing uncompressed keys in Segwit context

-

Type Definitions

-

Alias for a Descriptor that contains extended derived keys

-

Alias for a Descriptor that can contain extended keys using DescriptorPublicKey

-

Alias for the type of maps that represent derivation paths in a psbt::Input or -psbt::Output

-

Alias type for a map of public key to secret key

-

Alias for the type of maps that represent taproot key origins in a psbt::Input or -psbt::Output

-
- \ No newline at end of file +For example, disallowing uncompressed keys in Segwit context

Type Definitions

Alias for a Descriptor that contains extended derived keys
Alias for a Descriptor that can contain extended keys using DescriptorPublicKey
Alias for the type of maps that represent derivation paths in a psbt::Input or +psbt::Output
Alias type for a map of public key to secret key
Alias for the type of maps that represent taproot key origins in a psbt::Input or +psbt::Output
\ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/descriptor/policy/enum.BuildSatisfaction.html b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/descriptor/policy/enum.BuildSatisfaction.html index 1f6b2be32c..40304bebc7 100644 --- a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/descriptor/policy/enum.BuildSatisfaction.html +++ b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/descriptor/policy/enum.BuildSatisfaction.html @@ -1,12 +1,5 @@ -BuildSatisfaction in bdk::descriptor::policy - Rust - -
pub enum BuildSatisfaction<'a> {
+BuildSatisfaction in bdk::descriptor::policy - Rust
pub enum BuildSatisfaction<'a> {
     None,
     Psbt(&'a Psbt),
     PsbtTimelocks {
@@ -15,33 +8,15 @@
         input_max_height: u32,
     },
 }
Expand description

Options to build the satisfaction field in the policy

-

Variants

None

Don’t generate satisfaction field

-

Psbt(&'a Psbt)

Analyze the given PSBT to check for existing signatures

-

PsbtTimelocks

Fields

psbt: &'a Psbt

Given PSBT

-
current_height: u32

Current blockchain height

-
input_max_height: u32

The highest confirmation height between the inputs +

Variants§

§

None

Don’t generate satisfaction field

+
§

Psbt(&'a Psbt)

Analyze the given PSBT to check for existing signatures

+
§

PsbtTimelocks

Fields

§psbt: &'a Psbt

Given PSBT

+
§current_height: u32

Current blockchain height

+
§input_max_height: u32

The highest confirmation height between the inputs CSV should consider different inputs, but we consider the worst condition for the tx as whole

Like Psbt variant and also check for expired timelocks

-

Trait Implementations

Returns a copy of the value. Read more

-

Performs copy-assignment from source. Read more

-

Formats the value using the given formatter. Read more

-

Auto Trait Implementations

Blanket Implementations

Gets the TypeId of self. Read more

-

Immutably borrows from an owned value. Read more

-

Mutably borrows from an owned value. Read more

-

Performs the conversion.

-

Performs the conversion.

-

The alignment of pointer.

-

The type for initializers.

-

Initializes a with the given initializer. Read more

-

Dereferences the given pointer. Read more

-

Mutably dereferences the given pointer. Read more

-

Drops the object pointed to by the given pointer. Read more

-

The resulting type after obtaining ownership.

-

Creates owned data from borrowed data, usually by cloning. Read more

-
🔬 This is a nightly-only experimental API. (toowned_clone_into)

Uses borrowed data to replace owned data, usually by cloning. Read more

-

The type returned in the event of a conversion error.

-

Performs the conversion.

-

The type returned in the event of a conversion error.

-

Performs the conversion.

-
- \ No newline at end of file +

Trait Implementations§

Returns a copy of the value. Read more
Performs copy-assignment from source. Read more
Formats the value using the given formatter. Read more

Auto Trait Implementations§

Blanket Implementations§

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

Returns the argument unchanged.

+

Calls U::from(self).

+

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

+
The alignment of pointer.
The type for initializers.
Initializes a with the given initializer. Read more
Dereferences the given pointer. Read more
Mutably dereferences the given pointer. Read more
Drops the object pointed to by the given pointer. Read more
The resulting type after obtaining ownership.
Creates owned data from borrowed data, usually by cloning. Read more
Uses borrowed data to replace owned data, usually by cloning. Read more
The type returned in the event of a conversion error.
Performs the conversion.
The type returned in the event of a conversion error.
Performs the conversion.
\ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/descriptor/policy/enum.PkOrF.html b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/descriptor/policy/enum.PkOrF.html index c7a11d35ad..4ec1f62a87 100644 --- a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/descriptor/policy/enum.PkOrF.html +++ b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/descriptor/policy/enum.PkOrF.html @@ -1,45 +1,16 @@ -PkOrF in bdk::descriptor::policy - Rust - -
pub enum PkOrF {
+PkOrF in bdk::descriptor::policy - Rust

Enum bdk::descriptor::policy::PkOrF

source ·
pub enum PkOrF {
     Pubkey(PublicKey),
     XOnlyPubkey(XOnlyPublicKey),
     Fingerprint(Fingerprint),
 }
Expand description

A unique identifier for a key

-

Variants

Pubkey(PublicKey)

A legacy public key

-

XOnlyPubkey(XOnlyPublicKey)

A x-only public key

-

Fingerprint(Fingerprint)

An extended key fingerprint

-

Trait Implementations

Returns a copy of the value. Read more

-

Performs copy-assignment from source. Read more

-

Formats the value using the given formatter. Read more

-

Feeds this value into the given Hasher. Read more

-

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

-

This method tests for self and other values to be equal, and is used -by ==. Read more

-

This method tests for !=.

-

Serialize this value into the given Serde serializer. Read more

-

Auto Trait Implementations

Blanket Implementations

Gets the TypeId of self. Read more

-

Immutably borrows from an owned value. Read more

-

Mutably borrows from an owned value. Read more

-

Performs the conversion.

-

Performs the conversion.

-

The alignment of pointer.

-

The type for initializers.

-

Initializes a with the given initializer. Read more

-

Dereferences the given pointer. Read more

-

Mutably dereferences the given pointer. Read more

-

Drops the object pointed to by the given pointer. Read more

-

The resulting type after obtaining ownership.

-

Creates owned data from borrowed data, usually by cloning. Read more

-
🔬 This is a nightly-only experimental API. (toowned_clone_into)

Uses borrowed data to replace owned data, usually by cloning. Read more

-

The type returned in the event of a conversion error.

-

Performs the conversion.

-

The type returned in the event of a conversion error.

-

Performs the conversion.

-
- \ No newline at end of file +

Variants§

§

Pubkey(PublicKey)

A legacy public key

+
§

XOnlyPubkey(XOnlyPublicKey)

A x-only public key

+
§

Fingerprint(Fingerprint)

An extended key fingerprint

+

Trait Implementations§

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

Auto Trait Implementations§

Blanket Implementations§

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

Returns the argument unchanged.

+

Calls U::from(self).

+

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

+
The alignment of pointer.
The type for initializers.
Initializes a with the given initializer. Read more
Dereferences the given pointer. Read more
Mutably dereferences the given pointer. Read more
Drops the object pointed to by the given pointer. Read more
The resulting type after obtaining ownership.
Creates owned data from borrowed data, usually by cloning. Read more
Uses borrowed data to replace owned data, usually by cloning. Read more
The type returned in the event of a conversion error.
Performs the conversion.
The type returned in the event of a conversion error.
Performs the conversion.
\ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/descriptor/policy/enum.PolicyError.html b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/descriptor/policy/enum.PolicyError.html index ad38b7d7fb..90e3b7f196 100644 --- a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/descriptor/policy/enum.PolicyError.html +++ b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/descriptor/policy/enum.PolicyError.html @@ -1,12 +1,5 @@ -PolicyError in bdk::descriptor::policy - Rust - -
pub enum PolicyError {
+PolicyError in bdk::descriptor::policy - Rust
pub enum PolicyError {
     NotEnoughItemsSelected(String),
     IndexOutOfRange(usize),
     AddOnLeaf,
@@ -14,38 +7,17 @@
     MixedTimelockUnits,
     IncompatibleConditions,
 }
Expand description

Errors that can happen while extracting and manipulating policies

-

Variants

NotEnoughItemsSelected(String)

Not enough items are selected to satisfy a SatisfiableItem::Thresh or a SatisfiableItem::Multisig

-

IndexOutOfRange(usize)

Index out of range for an item to satisfy a SatisfiableItem::Thresh or a SatisfiableItem::Multisig

-

AddOnLeaf

Can not add to an item that is Satisfaction::None or Satisfaction::Complete

-

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

Formats the value using the given formatter. Read more

-

Formats the value using the given formatter. Read more

-

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

-
🔬 This is a nightly-only experimental API. (backtrace)

Returns a stack backtrace, if available, of where this error occurred. Read more

-
👎 Deprecated since 1.42.0:

use the Display impl or to_string()

-
👎 Deprecated since 1.33.0:

replaced by Error::source, which can support downcasting

-

Performs the conversion.

-

Performs the conversion.

-

This method tests for self and other values to be equal, and is used -by ==. Read more

-

This method tests for !=.

-

Auto Trait Implementations

Blanket Implementations

Gets the TypeId of self. Read more

-

Immutably borrows from an owned value. Read more

-

Mutably borrows from an owned value. Read more

-

Performs the conversion.

-

Performs the conversion.

-

The alignment of pointer.

-

The type for initializers.

-

Initializes a with the given initializer. Read more

-

Dereferences the given pointer. Read more

-

Mutably dereferences the given pointer. Read more

-

Drops the object pointed to by the given pointer. Read more

-

Converts the given value to a String. Read more

-

The type returned in the event of a conversion error.

-

Performs the conversion.

-

The type returned in the event of a conversion error.

-

Performs the conversion.

-
- \ No newline at end of file +

Variants§

§

NotEnoughItemsSelected(String)

Not enough items are selected to satisfy a SatisfiableItem::Thresh or a SatisfiableItem::Multisig

+
§

IndexOutOfRange(usize)

Index out of range for an item to satisfy a SatisfiableItem::Thresh or a SatisfiableItem::Multisig

+
§

AddOnLeaf

Can not add to an item that is Satisfaction::None or Satisfaction::Complete

+
§

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§

Formats the value using the given formatter. Read more
Formats the value using the given formatter. Read more
The lower-level source of this error, if any. Read more
👎Deprecated since 1.42.0: use the Display impl or to_string()
👎Deprecated since 1.33.0: replaced by Error::source, which can support downcasting
🔬This is a nightly-only experimental API. (error_generic_member_access)
Provides type based access to context intended for error reports. Read more
Converts to this type from the input type.
Converts to this type from the input type.
This method tests for self and other values to be equal, and is used +by ==. Read more
This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason. Read more

Auto Trait Implementations§

Blanket Implementations§

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

Returns the argument unchanged.

+

Calls U::from(self).

+

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

+
The alignment of pointer.
The type for initializers.
Initializes a with the given initializer. Read more
Dereferences the given pointer. Read more
Mutably dereferences the given pointer. Read more
Drops the object pointed to by the given pointer. Read more
🔬This is a nightly-only experimental API. (provide_any)
Data providers should implement this method to provide all values they are able to +provide by using demand. Read more
Converts the given value to a String. Read more
The type returned in the event of a conversion error.
Performs the conversion.
The type returned in the event of a conversion error.
Performs the conversion.
\ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/descriptor/policy/enum.Satisfaction.html b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/descriptor/policy/enum.Satisfaction.html index 3b5d8e936d..d9305365af 100644 --- a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/descriptor/policy/enum.Satisfaction.html +++ b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/descriptor/policy/enum.Satisfaction.html @@ -1,12 +1,5 @@ -Satisfaction in bdk::descriptor::policy - Rust - -
pub enum Satisfaction {
+Satisfaction in bdk::descriptor::policy - Rust
pub enum Satisfaction {
     Partial {
         n: usize,
         m: usize,
@@ -26,47 +19,26 @@
     },
     None,
 }
Expand description

Represent if and how much a policy item is satisfied by the wallet’s descriptor

-

Variants

Partial

Fields

n: usize

Total number of items

-
m: usize

Threshold

-
items: Vec<usize>

The items that can be satisfied by the descriptor or are satisfied in the PSBT

-
sorted: Option<bool>

Whether the items are sorted in lexicographic order (used by sortedmulti)

-
conditions: ConditionMap

Extra conditions that also need to be satisfied

+

Variants§

§

Partial

Fields

§n: usize

Total number of items

+
§m: usize

Threshold

+
§items: Vec<usize>

The items that can be satisfied by the descriptor or are satisfied in the PSBT

+
§sorted: Option<bool>

Whether the items are sorted in lexicographic order (used by sortedmulti)

+
§conditions: ConditionMap

Extra conditions that also need to be satisfied

Only a partial satisfaction of some kind of threshold policy

-

PartialComplete

Fields

n: usize

Total number of items

-
m: usize

Threshold

-
items: Vec<usize>

The items that can be satisfied by the descriptor

-
sorted: Option<bool>

Whether the items are sorted in lexicographic order (used by sortedmulti)

-
conditions: FoldedConditionMap

Extra conditions that also need to be satisfied

+
§

PartialComplete

Fields

§n: usize

Total number of items

+
§m: usize

Threshold

+
§items: Vec<usize>

The items that can be satisfied by the descriptor

+
§sorted: Option<bool>

Whether the items are sorted in lexicographic order (used by sortedmulti)

+
§conditions: FoldedConditionMap

Extra conditions that also need to be satisfied

Can reach the threshold of some kind of threshold policy

-

Complete

Fields

condition: Condition

Extra conditions that also need to be satisfied

+
§

Complete

Fields

§condition: Condition

Extra conditions that also need to be satisfied

Can satisfy the policy item

-

None

Cannot satisfy or contribute to the policy item

-

Implementations

Returns whether the Satisfaction is a leaf item

-

Trait Implementations

Returns a copy of the value. Read more

-

Performs copy-assignment from source. Read more

-

Formats the value using the given formatter. Read more

-

Performs the conversion.

-

This method tests for self and other values to be equal, and is used -by ==. Read more

-

This method tests for !=.

-

Serialize this value into the given Serde serializer. Read more

-

Auto Trait Implementations

Blanket Implementations

Gets the TypeId of self. Read more

-

Immutably borrows from an owned value. Read more

-

Mutably borrows from an owned value. Read more

-

Performs the conversion.

-

Performs the conversion.

-

The alignment of pointer.

-

The type for initializers.

-

Initializes a with the given initializer. Read more

-

Dereferences the given pointer. Read more

-

Mutably dereferences the given pointer. Read more

-

Drops the object pointed to by the given pointer. Read more

-

The resulting type after obtaining ownership.

-

Creates owned data from borrowed data, usually by cloning. Read more

-
🔬 This is a nightly-only experimental API. (toowned_clone_into)

Uses borrowed data to replace owned data, usually by cloning. Read more

-

The type returned in the event of a conversion error.

-

Performs the conversion.

-

The type returned in the event of a conversion error.

-

Performs the conversion.

-
- \ No newline at end of file +
§

None

Cannot satisfy or contribute to the policy item

+

Implementations§

Returns whether the Satisfaction is a leaf item

+

Trait Implementations§

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

Auto Trait Implementations§

Blanket Implementations§

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

Returns the argument unchanged.

+

Calls U::from(self).

+

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

+
The alignment of pointer.
The type for initializers.
Initializes a with the given initializer. Read more
Dereferences the given pointer. Read more
Mutably dereferences the given pointer. Read more
Drops the object pointed to by the given pointer. Read more
The resulting type after obtaining ownership.
Creates owned data from borrowed data, usually by cloning. Read more
Uses borrowed data to replace owned data, usually by cloning. Read more
The type returned in the event of a conversion error.
Performs the conversion.
The type returned in the event of a conversion error.
Performs the conversion.
\ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/descriptor/policy/enum.SatisfiableItem.html b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/descriptor/policy/enum.SatisfiableItem.html index 184e0a091e..8d40c2e248 100644 --- a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/descriptor/policy/enum.SatisfiableItem.html +++ b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/descriptor/policy/enum.SatisfiableItem.html @@ -1,12 +1,5 @@ -SatisfiableItem in bdk::descriptor::policy - Rust - -
pub enum SatisfiableItem {
+SatisfiableItem in bdk::descriptor::policy - Rust
pub enum SatisfiableItem {
     EcdsaSignature(PkOrF),
     SchnorrSignature(PkOrF),
     Sha256Preimage {
@@ -36,53 +29,32 @@
         threshold: usize,
     },
 }
Expand description

An item that needs to be satisfied

-

Variants

EcdsaSignature(PkOrF)

ECDSA Signature for a raw public key

-

SchnorrSignature(PkOrF)

Schnorr Signature for a raw public key

-

Sha256Preimage

Fields

hash: Hash

The digest value

+

Variants§

§

EcdsaSignature(PkOrF)

ECDSA Signature for a raw public key

+
§

SchnorrSignature(PkOrF)

Schnorr Signature for a raw public key

+
§

Sha256Preimage

Fields

§hash: Hash

The digest value

SHA256 preimage hash

-

Hash256Preimage

Fields

hash: Hash

The digest value

+
§

Hash256Preimage

Fields

§hash: Hash

The digest value

Double SHA256 preimage hash

-

Ripemd160Preimage

Fields

hash: Hash

The digest value

+
§

Ripemd160Preimage

Fields

§hash: Hash

The digest value

RIPEMD160 preimage hash

-

Hash160Preimage

Fields

hash: Hash

The digest value

+
§

Hash160Preimage

Fields

§hash: Hash

The digest value

SHA256 then RIPEMD160 preimage hash

-

AbsoluteTimelock

Fields

value: LockTime

The timelock value

+
§

AbsoluteTimelock

Fields

§value: LockTime

The timelock value

Absolute timeclock timestamp

-

RelativeTimelock

Fields

value: Sequence

The timelock value

+
§

RelativeTimelock

Fields

§value: Sequence

The timelock value

Relative timelock locktime

-

Multisig

Fields

keys: Vec<PkOrF>

The raw public key or extended key fingerprint

-
threshold: usize

The required threshold count

+
§

Multisig

Fields

§keys: Vec<PkOrF>

The raw public key or extended key fingerprint

+
§threshold: usize

The required threshold count

Multi-signature public keys with threshold count

-

Thresh

Fields

items: Vec<Policy>

The policy items

-
threshold: usize

The required threshold count

+
§

Thresh

Fields

§items: Vec<Policy>

The policy items

+
§threshold: usize

The required threshold count

Threshold items with threshold count

-

Implementations

Returns whether the SatisfiableItem is a leaf item

-

Returns a unique id for the SatisfiableItem

-

Trait Implementations

Returns a copy of the value. Read more

-

Performs copy-assignment from source. Read more

-

Formats the value using the given formatter. Read more

-

Performs the conversion.

-

This method tests for self and other values to be equal, and is used -by ==. Read more

-

This method tests for !=.

-

Serialize this value into the given Serde serializer. Read more

-

Auto Trait Implementations

Blanket Implementations

Gets the TypeId of self. Read more

-

Immutably borrows from an owned value. Read more

-

Mutably borrows from an owned value. Read more

-

Performs the conversion.

-

Performs the conversion.

-

The alignment of pointer.

-

The type for initializers.

-

Initializes a with the given initializer. Read more

-

Dereferences the given pointer. Read more

-

Mutably dereferences the given pointer. Read more

-

Drops the object pointed to by the given pointer. Read more

-

The resulting type after obtaining ownership.

-

Creates owned data from borrowed data, usually by cloning. Read more

-
🔬 This is a nightly-only experimental API. (toowned_clone_into)

Uses borrowed data to replace owned data, usually by cloning. Read more

-

The type returned in the event of a conversion error.

-

Performs the conversion.

-

The type returned in the event of a conversion error.

-

Performs the conversion.

-
- \ No newline at end of file +

Implementations§

Returns whether the SatisfiableItem is a leaf item

+

Returns a unique id for the SatisfiableItem

+

Trait Implementations§

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

Auto Trait Implementations§

Blanket Implementations§

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

Returns the argument unchanged.

+

Calls U::from(self).

+

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

+
The alignment of pointer.
The type for initializers.
Initializes a with the given initializer. Read more
Dereferences the given pointer. Read more
Mutably dereferences the given pointer. Read more
Drops the object pointed to by the given pointer. Read more
The resulting type after obtaining ownership.
Creates owned data from borrowed data, usually by cloning. Read more
Uses borrowed data to replace owned data, usually by cloning. Read more
The type returned in the event of a conversion error.
Performs the conversion.
The type returned in the event of a conversion error.
Performs the conversion.
\ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/descriptor/policy/index.html b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/descriptor/policy/index.html index 0e27d9a3ed..7f5ea7f940 100644 --- a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/descriptor/policy/index.html +++ b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/descriptor/policy/index.html @@ -1,38 +1,18 @@ -bdk::descriptor::policy - Rust - -
-

Module bdk::descriptor::policy

source · []
Expand description

Descriptor policy

+bdk::descriptor::policy - Rust

Module bdk::descriptor::policy

source ·
Expand description

Descriptor policy

This module implements the logic to extract and represent the spending policies of a descriptor in a more human-readable format.

This is an EXPERIMENTAL feature, API and other major changes are expected.

-

Example

-
use bdk::descriptor::policy::BuildSatisfaction;
-let secp = Secp256k1::new();
-let desc = "wsh(and_v(v:pk(cV3oCth6zxZ1UVsHLnGothsWNsaoxRhC6aeNi5VbSdFpwUkgkEci),or_d(pk(cVMTy7uebJgvFaSBwcgvwk8qn8xSLc97dKow4MBetjrrahZoimm2),older(12960))))";
+

Example

+
use bdk::descriptor::policy::BuildSatisfaction;
+let secp = Secp256k1::new();
+let desc = "wsh(and_v(v:pk(cV3oCth6zxZ1UVsHLnGothsWNsaoxRhC6aeNi5VbSdFpwUkgkEci),or_d(pk(cVMTy7uebJgvFaSBwcgvwk8qn8xSLc97dKow4MBetjrrahZoimm2),older(12960))))";
 
-let (extended_desc, key_map) = ExtendedDescriptor::parse_descriptor(&secp, desc)?;
-println!("{:?}", extended_desc);
+let (extended_desc, key_map) = ExtendedDescriptor::parse_descriptor(&secp, desc)?;
+println!("{:?}", extended_desc);
 
-let signers = Arc::new(SignersContainer::build(key_map, &extended_desc, &secp));
-let policy = extended_desc.extract_policy(&signers, BuildSatisfaction::None, &secp)?;
-println!("policy: {}", serde_json::to_string(&policy)?);
-

Structs

-

An extra condition that must be satisfied but that is out of control of the user -TODO: use bitcoin::LockTime and bitcoin::Sequence

-

Descriptor spending policy

-

Enums

-

Options to build the satisfaction field in the policy

-

A unique identifier for a key

-

Errors that can happen while extracting and manipulating policies

-

Represent if and how much a policy item is satisfied by the wallet’s descriptor

-

An item that needs to be satisfied

-

Type Definitions

-

Type for a map of sets of Condition items keyed by each set’s index

-

Type for a map of folded sets of Condition items keyed by a vector of the combined set’s indexes

-
- \ No newline at end of file +let signers = Arc::new(SignersContainer::build(key_map, &extended_desc, &secp)); +let policy = extended_desc.extract_policy(&signers, BuildSatisfaction::None, &secp)?; +println!("policy: {}", serde_json::to_string(&policy)?);
+

Structs

An extra condition that must be satisfied but that is out of control of the user +TODO: use bitcoin::LockTime and bitcoin::Sequence
Descriptor spending policy

Enums

Options to build the satisfaction field in the policy
A unique identifier for a key
Errors that can happen while extracting and manipulating policies
Represent if and how much a policy item is satisfied by the wallet’s descriptor
An item that needs to be satisfied

Type Definitions

Type for a map of sets of Condition items keyed by each set’s index
Type for a map of folded sets of Condition items keyed by a vector of the combined set’s indexes
\ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/descriptor/policy/sidebar-items.js b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/descriptor/policy/sidebar-items.js index f785c48037..0b375ed6fb 100644 --- a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/descriptor/policy/sidebar-items.js +++ b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/descriptor/policy/sidebar-items.js @@ -1 +1 @@ -initSidebarItems({"enum":[["BuildSatisfaction","Options to build the satisfaction field in the policy"],["PkOrF","A unique identifier for a key"],["PolicyError","Errors that can happen while extracting and manipulating policies"],["Satisfaction","Represent if and how much a policy item is satisfied by the wallet’s descriptor"],["SatisfiableItem","An item that needs to be satisfied"]],"struct":[["Condition","An extra condition that must be satisfied but that is out of control of the user TODO: use `bitcoin::LockTime` and `bitcoin::Sequence`"],["Policy","Descriptor spending policy"]],"type":[["ConditionMap","Type for a map of sets of [`Condition`] items keyed by each set’s index"],["FoldedConditionMap","Type for a map of folded sets of [`Condition`] items keyed by a vector of the combined set’s indexes"]]}); \ No newline at end of file +window.SIDEBAR_ITEMS = {"enum":[["BuildSatisfaction","Options to build the satisfaction field in the policy"],["PkOrF","A unique identifier for a key"],["PolicyError","Errors that can happen while extracting and manipulating policies"],["Satisfaction","Represent if and how much a policy item is satisfied by the wallet’s descriptor"],["SatisfiableItem","An item that needs to be satisfied"]],"struct":[["Condition","An extra condition that must be satisfied but that is out of control of the user TODO: use `bitcoin::LockTime` and `bitcoin::Sequence`"],["Policy","Descriptor spending policy"]],"type":[["ConditionMap","Type for a map of sets of [`Condition`] items keyed by each set’s index"],["FoldedConditionMap","Type for a map of folded sets of [`Condition`] items keyed by a vector of the combined set’s indexes"]]}; \ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/descriptor/policy/struct.Condition.html b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/descriptor/policy/struct.Condition.html index 6577ea87e7..0378ee25b9 100644 --- a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/descriptor/policy/struct.Condition.html +++ b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/descriptor/policy/struct.Condition.html @@ -1,53 +1,18 @@ -Condition in bdk::descriptor::policy - Rust - -
pub struct Condition {
+Condition in bdk::descriptor::policy - Rust

Struct bdk::descriptor::policy::Condition

source ·
pub struct Condition {
     pub csv: Option<Sequence>,
     pub timelock: Option<LockTime>,
 }
Expand description

An extra condition that must be satisfied but that is out of control of the user TODO: use bitcoin::LockTime and bitcoin::Sequence

-

Fields

csv: Option<Sequence>

Optional CheckSequenceVerify condition

-
timelock: Option<LockTime>

Optional timelock condition

-

Implementations

Returns true if there are no extra conditions to verify

-

Trait Implementations

Returns a copy of the value. Read more

-

Performs copy-assignment from source. Read more

-

Formats the value using the given formatter. Read more

-

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

-

Feeds this value into the given Hasher. Read more

-

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

-

This method tests for self and other values to be equal, and is used -by ==. Read more

-

This method tests for !=.

-

This method returns an ordering between self and other values if one exists. Read more

-

This method tests less than (for self and other) and is used by the < operator. Read more

-

This method tests less than or equal to (for self and other) and is used by the <= -operator. Read more

-

This method tests greater than (for self and other) and is used by the > operator. Read more

-

This method tests greater than or equal to (for self and other) and is used by the >= -operator. Read more

-

Serialize this value into the given Serde serializer. Read more

-

Auto Trait Implementations

Blanket Implementations

Gets the TypeId of self. Read more

-

Immutably borrows from an owned value. Read more

-

Mutably borrows from an owned value. Read more

-

Performs the conversion.

-

Performs the conversion.

-

The alignment of pointer.

-

The type for initializers.

-

Initializes a with the given initializer. Read more

-

Dereferences the given pointer. Read more

-

Mutably dereferences the given pointer. Read more

-

Drops the object pointed to by the given pointer. Read more

-

The resulting type after obtaining ownership.

-

Creates owned data from borrowed data, usually by cloning. Read more

-
🔬 This is a nightly-only experimental API. (toowned_clone_into)

Uses borrowed data to replace owned data, usually by cloning. Read more

-

The type returned in the event of a conversion error.

-

Performs the conversion.

-

The type returned in the event of a conversion error.

-

Performs the conversion.

-
- \ No newline at end of file +

Fields§

§csv: Option<Sequence>

Optional CheckSequenceVerify condition

+
§timelock: Option<LockTime>

Optional timelock condition

+

Implementations§

Returns true if there are no extra conditions to verify

+

Trait Implementations§

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

Auto Trait Implementations§

Blanket Implementations§

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

Returns the argument unchanged.

+

Calls U::from(self).

+

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

+
The alignment of pointer.
The type for initializers.
Initializes a with the given initializer. Read more
Dereferences the given pointer. Read more
Mutably dereferences the given pointer. Read more
Drops the object pointed to by the given pointer. Read more
The resulting type after obtaining ownership.
Creates owned data from borrowed data, usually by cloning. Read more
Uses borrowed data to replace owned data, usually by cloning. Read more
The type returned in the event of a conversion error.
Performs the conversion.
The type returned in the event of a conversion error.
Performs the conversion.
\ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/descriptor/policy/struct.Policy.html b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/descriptor/policy/struct.Policy.html index 2b6a1ad6bd..1b1932e7b9 100644 --- a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/descriptor/policy/struct.Policy.html +++ b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/descriptor/policy/struct.Policy.html @@ -1,53 +1,25 @@ -Policy in bdk::descriptor::policy - Rust - -
pub struct Policy {
+Policy in bdk::descriptor::policy - Rust

Struct bdk::descriptor::policy::Policy

source ·
pub struct Policy {
     pub id: String,
     pub item: SatisfiableItem,
     pub satisfaction: Satisfaction,
     pub contribution: Satisfaction,
 }
Expand description

Descriptor spending policy

-

Fields

id: String

Identifier for this policy node

-
item: SatisfiableItem

Type of this policy node

-
satisfaction: Satisfaction

How much a given PSBT already satisfies this policy node in terms of signatures

-
contribution: Satisfaction

How the wallet’s descriptor can satisfy this policy node

-

Implementations

Return whether or not a specific path in the policy tree is required to unambiguously +

Fields§

§id: String

Identifier for this policy node

+
§item: SatisfiableItem

Type of this policy node

+
§satisfaction: Satisfaction

How much a given PSBT already satisfies this policy node in terms of signatures

+
§contribution: Satisfaction

How the wallet’s descriptor can satisfy this policy node

+

Implementations§

Return whether or not a specific path in the policy tree is required to unambiguously create a transaction

What this means is that for some spending policies the user should select which paths in the tree it intends to satisfy while signing, because the transaction must be created differently based on that.

-

Return the conditions that are set by the spending policy for a given path in the +

Return the conditions that are set by the spending policy for a given path in the policy tree

-

Trait Implementations

Returns a copy of the value. Read more

-

Performs copy-assignment from source. Read more

-

Formats the value using the given formatter. Read more

-

Performs the conversion.

-

This method tests for self and other values to be equal, and is used -by ==. Read more

-

This method tests for !=.

-

Serialize this value into the given Serde serializer. Read more

-

Auto Trait Implementations

Blanket Implementations

Gets the TypeId of self. Read more

-

Immutably borrows from an owned value. Read more

-

Mutably borrows from an owned value. Read more

-

Performs the conversion.

-

Performs the conversion.

-

The alignment of pointer.

-

The type for initializers.

-

Initializes a with the given initializer. Read more

-

Dereferences the given pointer. Read more

-

Mutably dereferences the given pointer. Read more

-

Drops the object pointed to by the given pointer. Read more

-

The resulting type after obtaining ownership.

-

Creates owned data from borrowed data, usually by cloning. Read more

-
🔬 This is a nightly-only experimental API. (toowned_clone_into)

Uses borrowed data to replace owned data, usually by cloning. Read more

-

The type returned in the event of a conversion error.

-

Performs the conversion.

-

The type returned in the event of a conversion error.

-

Performs the conversion.

-
- \ No newline at end of file +

Trait Implementations§

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

Auto Trait Implementations§

Blanket Implementations§

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

Returns the argument unchanged.

+

Calls U::from(self).

+

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

+
The alignment of pointer.
The type for initializers.
Initializes a with the given initializer. Read more
Dereferences the given pointer. Read more
Mutably dereferences the given pointer. Read more
Drops the object pointed to by the given pointer. Read more
The resulting type after obtaining ownership.
Creates owned data from borrowed data, usually by cloning. Read more
Uses borrowed data to replace owned data, usually by cloning. Read more
The type returned in the event of a conversion error.
Performs the conversion.
The type returned in the event of a conversion error.
Performs the conversion.
\ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/descriptor/policy/type.ConditionMap.html b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/descriptor/policy/type.ConditionMap.html index 8947a7cd6c..ae8dc5722c 100644 --- a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/descriptor/policy/type.ConditionMap.html +++ b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/descriptor/policy/type.ConditionMap.html @@ -1,11 +1,3 @@ -ConditionMap in bdk::descriptor::policy - Rust - -
-

Type Definition bdk::descriptor::policy::ConditionMap

source · []
pub type ConditionMap = BTreeMap<usize, HashSet<Condition>>;
Expand description

Type for a map of sets of Condition items keyed by each set’s index

-
- \ No newline at end of file +ConditionMap in bdk::descriptor::policy - Rust

Type Definition bdk::descriptor::policy::ConditionMap

source ·
pub type ConditionMap = BTreeMap<usize, HashSet<Condition>>;
Expand description

Type for a map of sets of Condition items keyed by each set’s index

+
\ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/descriptor/policy/type.FoldedConditionMap.html b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/descriptor/policy/type.FoldedConditionMap.html index 0f0cff21e0..f30a400000 100644 --- a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/descriptor/policy/type.FoldedConditionMap.html +++ b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/descriptor/policy/type.FoldedConditionMap.html @@ -1,11 +1,3 @@ -FoldedConditionMap in bdk::descriptor::policy - Rust - -
pub type FoldedConditionMap = BTreeMap<Vec<usize>, HashSet<Condition>>;
Expand description

Type for a map of folded sets of Condition items keyed by a vector of the combined set’s indexes

-
- \ No newline at end of file +FoldedConditionMap in bdk::descriptor::policy - Rust

Type Definition bdk::descriptor::policy::FoldedConditionMap

source ·
pub type FoldedConditionMap = BTreeMap<Vec<usize>, HashSet<Condition>>;
Expand description

Type for a map of folded sets of Condition items keyed by a vector of the combined set’s indexes

+
\ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/descriptor/sidebar-items.js b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/descriptor/sidebar-items.js index 9ada5a941a..553ef4efb2 100644 --- a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/descriptor/sidebar-items.js +++ b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/descriptor/sidebar-items.js @@ -1 +1 @@ -initSidebarItems({"enum":[["Descriptor","Script descriptor"],["DescriptorPublicKey","The descriptor pubkey, either a single pubkey or an xpub."],["Legacy","Legacy ScriptContext To be used as P2SH scripts For creation of Bare scriptpubkeys, construct the Miniscript under `Bare` ScriptContext"],["Segwitv0","Segwitv0 ScriptContext"],["Wildcard","Whether a descriptor has a wildcard in it"]],"mod":[["checksum","Descriptor checksum"],["error","Descriptor errors"],["policy","Descriptor policy"],["template","Descriptor templates"]],"struct":[["DescriptorXKey","An extended key with origin, derivation path, and wildcard."],["Miniscript","Top-level script AST type"]],"trait":[["ExtractPolicy","Trait implemented on [`Descriptor`]s to add a method to extract the spending [`policy`]"],["IntoWalletDescriptor","Trait for types which can be converted into an [`ExtendedDescriptor`] and a [`KeyMap`] usable by a wallet in a specific [`Network`]"],["ScriptContext","The ScriptContext for Miniscript. Additional type information associated with miniscript that is used for carrying out checks that dependent on the context under which the script is used. For example, disallowing uncompressed keys in Segwit context"]],"type":[["DerivedDescriptor","Alias for a [`Descriptor`] that contains extended derived keys"],["ExtendedDescriptor","Alias for a [`Descriptor`] that can contain extended keys using [`DescriptorPublicKey`]"],["HdKeyPaths","Alias for the type of maps that represent derivation paths in a `psbt::Input` or `psbt::Output`"],["KeyMap","Alias type for a map of public key to secret key"],["TapKeyOrigins","Alias for the type of maps that represent taproot key origins in a `psbt::Input` or `psbt::Output`"]]}); \ No newline at end of file +window.SIDEBAR_ITEMS = {"enum":[["Descriptor","Script descriptor"],["DescriptorPublicKey","The descriptor pubkey, either a single pubkey or an xpub."],["Legacy","Legacy ScriptContext To be used as P2SH scripts For creation of Bare scriptpubkeys, construct the Miniscript under `Bare` ScriptContext"],["Segwitv0","Segwitv0 ScriptContext"],["Wildcard","Whether a descriptor has a wildcard in it"]],"mod":[["checksum","Descriptor checksum"],["error","Descriptor errors"],["policy","Descriptor policy"],["template","Descriptor templates"]],"struct":[["DescriptorXKey","An extended key with origin, derivation path, and wildcard."],["Miniscript","Top-level script AST type"]],"trait":[["ExtractPolicy","Trait implemented on [`Descriptor`]s to add a method to extract the spending [`policy`]"],["IntoWalletDescriptor","Trait for types which can be converted into an [`ExtendedDescriptor`] and a [`KeyMap`] usable by a wallet in a specific [`Network`]"],["ScriptContext","The ScriptContext for Miniscript. Additional type information associated with miniscript that is used for carrying out checks that dependent on the context under which the script is used. For example, disallowing uncompressed keys in Segwit context"]],"type":[["DerivedDescriptor","Alias for a [`Descriptor`] that contains extended derived keys"],["ExtendedDescriptor","Alias for a [`Descriptor`] that can contain extended keys using [`DescriptorPublicKey`]"],["HdKeyPaths","Alias for the type of maps that represent derivation paths in a `psbt::Input` or `psbt::Output`"],["KeyMap","Alias type for a map of public key to secret key"],["TapKeyOrigins","Alias for the type of maps that represent taproot key origins in a `psbt::Input` or `psbt::Output`"]]}; \ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/descriptor/struct.DescriptorXKey.html b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/descriptor/struct.DescriptorXKey.html index 9347a04ed7..8095bf0a13 100644 --- a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/descriptor/struct.DescriptorXKey.html +++ b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/descriptor/struct.DescriptorXKey.html @@ -1,95 +1,58 @@ -DescriptorXKey in bdk::descriptor - Rust - -
pub struct DescriptorXKey<K> where
    K: InnerXKey, 
{ - pub origin: Option<(Fingerprint, DerivationPath)>, +DescriptorXKey in bdk::descriptor - Rust
pub struct DescriptorXKey<K>where
    K: InnerXKey,
{ + pub origin: Option<(Fingerprint, DerivationPath)>, pub xkey: K, pub derivation_path: DerivationPath, pub wildcard: Wildcard, }
Expand description

An extended key with origin, derivation path, and wildcard.

-

Fields

origin: Option<(Fingerprint, DerivationPath)>

Origin information

-
xkey: K

The extended key

-
derivation_path: DerivationPath

The derivation path

-
wildcard: Wildcard

Whether the descriptor is wildcard

-

Implementations

Compares this key with a keysource and returns the matching derivation path, if any.

+

Fields§

§origin: Option<(Fingerprint, DerivationPath)>

Origin information

+
§xkey: K

The extended key

+
§derivation_path: DerivationPath

The derivation path

+
§wildcard: Wildcard

Whether the descriptor is wildcard

+

Implementations§

Compares this key with a keysource and returns the matching derivation path, if any.

For keys that have an origin, the keysource’s fingerprint will be compared with the origin’s fingerprint, and the keysource’s path will be compared with the concatenation of the origin’s and key’s paths.

If the key wildcard, the last item of the keysource’s path will be ignored,

-
Examples
-
use miniscript::bitcoin::util::bip32;
-use miniscript::descriptor::DescriptorPublicKey;
+
Examples
+
use miniscript::bitcoin::util::bip32;
+use miniscript::descriptor::DescriptorPublicKey;
 
-let ctx = miniscript::bitcoin::secp256k1::Secp256k1::signing_only();
+let ctx = miniscript::bitcoin::secp256k1::Secp256k1::signing_only();
 
-let key = DescriptorPublicKey::from_str("[d34db33f/44'/0'/0']xpub6ERApfZwUNrhLCkDtcHTcxd75RbzS1ed54G1LkBUHQVHQKqhMkhgbmJbZRkrgZw4koxb5JaHWkY4ALHY2grBGRjaDMzQLcgJvLJuZZvRcEL/1/*").or(Err(()))?;
-let xpub = match key {
-    DescriptorPublicKey::XPub(xpub) => xpub,
-    _ => panic!("Parsing Error"),
+let key = DescriptorPublicKey::from_str("[d34db33f/44'/0'/0']xpub6ERApfZwUNrhLCkDtcHTcxd75RbzS1ed54G1LkBUHQVHQKqhMkhgbmJbZRkrgZw4koxb5JaHWkY4ALHY2grBGRjaDMzQLcgJvLJuZZvRcEL/1/*").or(Err(()))?;
+let xpub = match key {
+    DescriptorPublicKey::XPub(xpub) => xpub,
+    _ => panic!("Parsing Error"),
 };
 
 assert_eq!(
-    xpub.matches(&(
-        bip32::Fingerprint::from_str("d34db33f").or(Err(()))?,
-        bip32::DerivationPath::from_str("m/44'/0'/0'/1/42").or(Err(()))?
-    ), &ctx),
-    Some(bip32::DerivationPath::from_str("m/44'/0'/0'/1").or(Err(()))?)
+    xpub.matches(&(
+        bip32::Fingerprint::from_str("d34db33f").or(Err(()))?,
+        bip32::DerivationPath::from_str("m/44'/0'/0'/1/42").or(Err(()))?
+    ), &ctx),
+    Some(bip32::DerivationPath::from_str("m/44'/0'/0'/1").or(Err(()))?)
 );
 assert_eq!(
-    xpub.matches(&(
-        bip32::Fingerprint::from_str("ffffffff").or(Err(()))?,
-        bip32::DerivationPath::from_str("m/44'/0'/0'/1/42").or(Err(()))?
-    ), &ctx),
-    None
-);
+    xpub.matches(&(
+        bip32::Fingerprint::from_str("ffffffff").or(Err(()))?,
+        bip32::DerivationPath::from_str("m/44'/0'/0'/1/42").or(Err(()))?
+    ), &ctx),
+    None
+);
 assert_eq!(
-    xpub.matches(&(
-        bip32::Fingerprint::from_str("d34db33f").or(Err(()))?,
-        bip32::DerivationPath::from_str("m/44'/0'/0'/100/0").or(Err(()))?
-    ), &ctx),
-    None
-);
-

Trait Implementations

Returns a copy of the value. Read more

-

Performs copy-assignment from source. Read more

-

Formats the value using the given formatter. Read more

-

Feeds this value into the given Hasher. Read more

-

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

-

This method returns an Ordering between self and other. Read more

-

Compares and returns the maximum of two values. Read more

-

Compares and returns the minimum of two values. Read more

-

Restrict a value to a certain interval. Read more

-

This method tests for self and other values to be equal, and is used -by ==. Read more

-

This method tests for !=.

-

This method returns an ordering between self and other values if one exists. Read more

-

This method tests less than (for self and other) and is used by the < operator. Read more

-

This method tests less than or equal to (for self and other) and is used by the <= -operator. Read more

-

This method tests greater than (for self and other) and is used by the > operator. Read more

-

This method tests greater than or equal to (for self and other) and is used by the >= -operator. Read more

-

Auto Trait Implementations

Blanket Implementations

Gets the TypeId of self. Read more

-

Immutably borrows from an owned value. Read more

-

Mutably borrows from an owned value. Read more

-

Performs the conversion.

-

Performs the conversion.

-

The alignment of pointer.

-

The type for initializers.

-

Initializes a with the given initializer. Read more

-

Dereferences the given pointer. Read more

-

Mutably dereferences the given pointer. Read more

-

Drops the object pointed to by the given pointer. Read more

-

The resulting type after obtaining ownership.

-

Creates owned data from borrowed data, usually by cloning. Read more

-
🔬 This is a nightly-only experimental API. (toowned_clone_into)

Uses borrowed data to replace owned data, usually by cloning. Read more

-

The type returned in the event of a conversion error.

-

Performs the conversion.

-

The type returned in the event of a conversion error.

-

Performs the conversion.

-
- \ No newline at end of file + xpub.matches(&( + bip32::Fingerprint::from_str("d34db33f").or(Err(()))?, + bip32::DerivationPath::from_str("m/44'/0'/0'/100/0").or(Err(()))? + ), &ctx), + None +);
+

Trait Implementations§

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

Auto Trait Implementations§

Blanket Implementations§

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

Returns the argument unchanged.

+

Calls U::from(self).

+

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

+
The alignment of pointer.
The type for initializers.
Initializes a with the given initializer. Read more
Dereferences the given pointer. Read more
Mutably dereferences the given pointer. Read more
Drops the object pointed to by the given pointer. Read more
The resulting type after obtaining ownership.
Creates owned data from borrowed data, usually by cloning. Read more
Uses borrowed data to replace owned data, usually by cloning. Read more
The type returned in the event of a conversion error.
Performs the conversion.
The type returned in the event of a conversion error.
Performs the conversion.
\ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/descriptor/struct.Miniscript.html b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/descriptor/struct.Miniscript.html index c05d421556..5543cd4ca2 100644 --- a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/descriptor/struct.Miniscript.html +++ b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/descriptor/struct.Miniscript.html @@ -1,27 +1,20 @@ -Miniscript in bdk::descriptor - Rust - -
pub struct Miniscript<Pk, Ctx> where
    Pk: MiniscriptKey,
    Ctx: ScriptContext
{ +Miniscript in bdk::descriptor - Rust

Struct bdk::descriptor::Miniscript

pub struct Miniscript<Pk, Ctx>where
    Pk: MiniscriptKey,
    Ctx: ScriptContext,
{ pub node: Terminal<Pk, Ctx>, pub ty: Type, pub ext: ExtData, /* private fields */ }
Expand description

Top-level script AST type

-

Fields

node: Terminal<Pk, Ctx>

A node in the Abstract Syntax Tree(

-
ty: Type

The correctness and malleability type information for the AST node

-
ext: ExtData

Additional information helpful for extra analysis.

-

Implementations

Whether all spend paths of miniscript require a signature

-

Whether the miniscript is malleable

-

Whether the miniscript can exceed the resource limits(Opcodes, Stack limit etc)

-

Whether the miniscript contains a combination of timelocks

-

Whether the miniscript has repeated Pk or Pkh

-

Whether the given miniscript contains a raw pkh fragment

-

Check whether the underlying Miniscript is safe under the current context +

Fields§

§node: Terminal<Pk, Ctx>

A node in the Abstract Syntax Tree(

+
§ty: Type

The correctness and malleability type information for the AST node

+
§ext: ExtData

Additional information helpful for extra analysis.

+

Implementations§

Whether all spend paths of miniscript require a signature

+

Whether the miniscript is malleable

+

Whether the miniscript can exceed the resource limits(Opcodes, Stack limit etc)

+

Whether the miniscript contains a combination of timelocks

+

Whether the miniscript has repeated Pk or Pkh

+

Whether the given miniscript contains a raw pkh fragment

+

Check whether the underlying Miniscript is safe under the current context Lifting these polices would create a semantic representation that does not represent the underlying semantics when miniscript is spent. Signing logic may not find satisfaction even if one exists.

@@ -29,80 +22,80 @@ Signing logic may not find satisfaction even if one exists.

Use this function to check whether the guarantees of library hold. Most functions of the library like would still work, but results cannot be relied upon

-

Check whether the miniscript follows the given Extra policy [ExtParams]

-

Iterator-related extensions for Miniscript

-

Creates a new [Iter] iterator that will iterate over all Miniscript items within +

Check whether the miniscript follows the given Extra policy [ExtParams]

+

Iterator-related extensions for Miniscript

+

Creates a new [Iter] iterator that will iterate over all Miniscript items within AST by traversing its branches. For the specific algorithm please see [Iter::next] function.

-

Creates a new [PkIter] iterator that will iterate over all plain public keys (and not +

Creates a new [PkIter] iterator that will iterate over all plain public keys (and not key hash values) present in Miniscript items within AST by traversing all its branches. For the specific algorithm please see [PkIter::next] function.

-

Enumerates all child nodes of the current AST node (self) and returns a Vec referencing +

Enumerates all child nodes of the current AST node (self) and returns a Vec referencing them.

-

Returns child node with given index, if any

-

Returns Option::Some with cloned n’th public key from the current miniscript item, +

Returns child node with given index, if any

+

Returns Option::Some with cloned n’th public key from the current miniscript item, if any. Otherwise returns Option::None.

NB: The function analyzes only single miniscript item and not any of its descendants in AST.

-

Add type information(Type and Extdata) to Miniscript based on +

Add type information(Type and Extdata) to Miniscript based on AstElem fragment. Dependent on display and clone because of Error Display code of type_check.

-

Extracts the AstElem representing the root of the miniscript

-

Get a reference to the inner AstElem representing the root of miniscript

-

Attempt to parse an insane(scripts don’t clear sanity checks) +

Extracts the AstElem representing the root of the miniscript

+

Get a reference to the inner AstElem representing the root of miniscript

+

Attempt to parse an insane(scripts don’t clear sanity checks) script into a Miniscript representation. Use this to parse scripts with repeated pubkeys, timelock mixing, malleable scripts without sig or scripts that can exceed resource limits. Some of the analysis guarantees of miniscript are lost when dealing with insane scripts. In general, in a multi-party setting users should only accept sane scripts.

-

Attempt to parse an miniscript with extra features that not yet specified in the spec. +

Attempt to parse an miniscript with extra features that not yet specified in the spec. Users should not use this function unless they scripts can/will change in the future. Currently, this function supports the following features: - Parsing all insane scripts - Parsing miniscripts with raw pubkey hashes

Allowed extra features can be specified by the ext [ExtParams] argument.

-

Attempt to parse a Script into Miniscript representation.

+

Attempt to parse a Script into Miniscript representation.

This function will fail parsing for scripts that do not clear the Miniscript::sanity_check checks. Use Miniscript::parse_insane to parse such scripts.

-
Decode/Parse a miniscript from script hex
-
use miniscript::{Miniscript, Segwitv0, Tap};
-use miniscript::bitcoin::secp256k1::XOnlyPublicKey;
-use miniscript::bitcoin::hashes::hex::FromHex;
+
Decode/Parse a miniscript from script hex
+
use miniscript::{Miniscript, Segwitv0, Tap};
+use miniscript::bitcoin::secp256k1::XOnlyPublicKey;
+use miniscript::bitcoin::hashes::hex::FromHex;
 
-type Segwitv0Script = Miniscript<bitcoin::PublicKey, Segwitv0>;
-type TapScript = Miniscript<XOnlyPublicKey, Tap>;
+type Segwitv0Script = Miniscript<bitcoin::PublicKey, Segwitv0>;
+type TapScript = Miniscript<XOnlyPublicKey, Tap>;
 
-// parse x-only miniscript in Taproot context
-let tapscript_ms = TapScript::parse(&bitcoin::Script::from(Vec::<u8>::from_hex(
+// parse x-only miniscript in Taproot context
+let tapscript_ms = TapScript::parse(&bitcoin::Script::from(Vec::<u8>::from_hex(
     "202788ee41e76f4f3af603da5bc8fa22997bc0344bb0f95666ba6aaff0242baa99ac",
-).expect("Even length hex")))
-    .expect("Xonly keys are valid only in taproot context");
-// tapscript fails decoding when we use them with compressed keys
-let err = TapScript::parse(&bitcoin::Script::from(Vec::<u8>::from_hex(
+).expect("Even length hex")))
+    .expect("Xonly keys are valid only in taproot context");
+// tapscript fails decoding when we use them with compressed keys
+let err = TapScript::parse(&bitcoin::Script::from(Vec::<u8>::from_hex(
     "21022788ee41e76f4f3af603da5bc8fa22997bc0344bb0f95666ba6aaff0242baa99ac",
-).expect("Even length hex")))
-    .expect_err("Compressed keys cannot be used in Taproot context");
-// Segwitv0 succeeds decoding with full keys.
-Segwitv0Script::parse(&bitcoin::Script::from(Vec::<u8>::from_hex(
+).expect("Even length hex")))
+    .expect_err("Compressed keys cannot be used in Taproot context");
+// Segwitv0 succeeds decoding with full keys.
+Segwitv0Script::parse(&bitcoin::Script::from(Vec::<u8>::from_hex(
     "21022788ee41e76f4f3af603da5bc8fa22997bc0344bb0f95666ba6aaff0242baa99ac",
-).expect("Even length hex")))
-    .expect("Compressed keys are allowed in Segwit context");
+).expect("Even length hex")))
+    .expect("Compressed keys are allowed in Segwit context");
 
-

Encode as a Bitcoin script

-

Size, in bytes of the script-pubkey. If this Miniscript is used outside +

Encode as a Bitcoin script

+

Size, in bytes of the script-pubkey. If this Miniscript is used outside of segwit (e.g. in a bare or P2SH descriptor), this quantity should be multiplied by 4 to compute the weight.

In general, it is not recommended to use this function directly, but to instead call the corresponding function on a Descriptor, which will handle the segwit/non-segwit technicalities for you.

-

Maximum number of witness elements used to satisfy the Miniscript +

Maximum number of witness elements used to satisfy the Miniscript fragment, including the witness script itself. Used to estimate the weight of the VarInt that specifies this number in a serialized transaction.

This function may returns Error when the Miniscript is impossible to satisfy

-

Maximum size, in bytes, of a satisfying witness. For Segwit outputs +

Maximum size, in bytes, of a satisfying witness. For Segwit outputs one_cost should be set to 2, since the number 1 requires two bytes to encode. For non-segwit outputs one_cost should be set to 1, since OP_1 is available in scriptSigs.

@@ -112,11 +105,22 @@ will handle the segwit/non-segwit technicalities for you.

All signatures are assumed to be 73 bytes in size, including the length prefix (segwit) or push opcode (pre-segwit) and sighash postfix.

-

Attempt to produce non-malleable satisfying witness for the +

Attempt to parse an insane(scripts don’t clear sanity checks) +from string into a Miniscript representation. +Use this to parse scripts with repeated pubkeys, timelock mixing, malleable +scripts without sig or scripts that can exceed resource limits. +Some of the analysis guarantees of miniscript are lost when dealing with +insane scripts. In general, in a multi-party setting users should only +accept sane scripts.

+

Attempt to parse an Miniscripts that don’t follow the spec. +Use this to parse scripts with repeated pubkeys, timelock mixing, malleable +scripts, raw pubkey hashes without sig or scripts that can exceed resource limits.

+

Use [ExtParams] builder to specify the types of non-sane rules to allow while parsing.

+

Attempt to produce non-malleable satisfying witness for the witness script represented by the parse tree

-

Attempt to produce a malleable satisfying witness for the +

Attempt to produce a malleable satisfying witness for the witness script represented by the parse tree

-

Lifting corresponds conversion of miniscript into Policy +

Lifting corresponds conversion of miniscript into Policy [policy.semantic.Policy] for human readable or machine analysis. However, naively lifting miniscripts can result in incorrect interpretations that don’t correspond underlying semantics when @@ -126,84 +130,33 @@ This can occur if the miniscript contains a

  • Timelock combination
  • Contains a spend that exceeds resource limits
  • -

    Attempt to parse an insane(scripts don’t clear sanity checks) -from string into a Miniscript representation. -Use this to parse scripts with repeated pubkeys, timelock mixing, malleable -scripts without sig or scripts that can exceed resource limits. -Some of the analysis guarantees of miniscript are lost when dealing with -insane scripts. In general, in a multi-party setting users should only -accept sane scripts.

    -

    Attempt to parse an Miniscripts that don’t follow the spec. -Use this to parse scripts with repeated pubkeys, timelock mixing, malleable -scripts, raw pubkey hashes without sig or scripts that can exceed resource limits.

    -

    Use [ExtParams] builder to specify the types of non-sane rules to allow while parsing.

    -

    Trait Implementations

    Returns a copy of the value. Read more

    -

    Performs copy-assignment from source. Read more

    -

    Formats the value using the given formatter. Read more

    -

    Deserialize this value from the given Serde deserializer. Read more

    -

    Formats the value using the given formatter. Read more

    -

    Extract the spending policy

    -

    Run a predicate on every key in the descriptor, returning whether -the predicate returned true for every key Read more

    -

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

    -

    Parse a Miniscript from string and perform sanity checks +

    Trait Implementations§

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

    Parse a Miniscript from string and perform sanity checks See Miniscript::from_str_insane to parse scripts from string that do not clear the Miniscript::sanity_check checks.

    -

    The associated error which can be returned from parsing.

    -

    Parse an expression tree into a Miniscript. As a general rule, this +

    The associated error which can be returned from parsing.

    Parse an expression tree into a Miniscript. As a general rule, this should not be called directly; rather go through the descriptor API.

    -

    Feeds this value into the given Hasher. Read more

    -

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

    -

    Convert the object into an abstract policy

    -

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

    Feeds this value into the given Hasher. Read more
    Feeds a slice of this type into the given Hasher. Read more
    Convert the object into an abstract policy

    Ord of Miniscript must depend only on node and not the type information. The type information and extra_properties can be deterministically determined by the ast.

    -

    This method returns an Ordering between self and other. Read more

    -

    Compares and returns the maximum of two values. Read more

    -

    Compares and returns the minimum of two values. Read more

    -

    Restrict a value to a certain interval. Read more

    -

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

    This method returns an Ordering between self and other. Read more
    Compares and returns the maximum of two values. Read more
    Compares and returns the minimum of two values. Read more
    Restrict a value to a certain interval. Read more

    PartialEq of Miniscript must depend only on node and not the type information. The type information and extra_properties can be deterministically determined by the ast.

    -

    This method tests for self and other values to be equal, and is used -by ==. Read more

    -

    This method tests for !=.

    -

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

    This method tests for self and other values to be equal, and is used +by ==. Read more
    This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason. Read more

    PartialOrd of Miniscript must depend only on node and not the type information. The type information and extra_properties can be deterministically determined by the ast.

    -

    This method returns an ordering between self and other values if one exists. Read more

    -

    This method tests less than (for self and other) and is used by the < operator. Read more

    -

    This method tests less than or equal to (for self and other) and is used by the <= -operator. Read more

    -

    This method tests greater than (for self and other) and is used by the > operator. Read more

    -

    This method tests greater than or equal to (for self and other) and is used by the >= -operator. Read more

    -

    Serialize this value into the given Serde serializer. Read more

    -

    Translates a struct from one generic to another where the translation +

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

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

    -

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

    -

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

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

    Eq of Miniscript must depend only on node and not the type information. The type information and extra_properties can be deterministically determined by the ast.

    -

    Auto Trait Implementations

    Blanket Implementations

    Gets the TypeId of self. Read more

    -

    Immutably borrows from an owned value. Read more

    -

    Mutably borrows from an owned value. Read more

    -

    Performs the conversion.

    -

    Performs the conversion.

    -

    The alignment of pointer.

    -

    The type for initializers.

    -

    Initializes a with the given initializer. Read more

    -

    Dereferences the given pointer. Read more

    -

    Mutably dereferences the given pointer. Read more

    -

    Drops the object pointed to by the given pointer. Read more

    -

    The resulting type after obtaining ownership.

    -

    Creates owned data from borrowed data, usually by cloning. Read more

    -
    🔬 This is a nightly-only experimental API. (toowned_clone_into)

    Uses borrowed data to replace owned data, usually by cloning. Read more

    -

    Converts the given value to a String. Read more

    -

    The type returned in the event of a conversion error.

    -

    Performs the conversion.

    -

    The type returned in the event of a conversion error.

    -

    Performs the conversion.

    -
    - \ No newline at end of file +

    Auto Trait Implementations§

    Blanket Implementations§

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

    Returns the argument unchanged.

    +

    Calls U::from(self).

    +

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

    +
    The alignment of pointer.
    The type for initializers.
    Initializes a with the given initializer. Read more
    Dereferences the given pointer. Read more
    Mutably dereferences the given pointer. Read more
    Drops the object pointed to by the given pointer. Read more
    The resulting type after obtaining ownership.
    Creates owned data from borrowed data, usually by cloning. Read more
    Uses borrowed data to replace owned data, usually by cloning. Read more
    Converts the given value to a String. Read more
    The type returned in the event of a conversion error.
    Performs the conversion.
    The type returned in the event of a conversion error.
    Performs the conversion.
    \ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/descriptor/template/index.html b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/descriptor/template/index.html index 9f3eb04e5c..4b6d33c4e1 100644 --- a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/descriptor/template/index.html +++ b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/descriptor/template/index.html @@ -1,27 +1,5 @@ -bdk::descriptor::template - Rust - -
    Expand description

    Descriptor templates

    +bdk::descriptor::template - Rust

    Module bdk::descriptor::template

    source ·
    Expand description

    Descriptor templates

    This module contains the definition of various common script templates that are ready to be used. See the documentation of each template for an example.

    -

    Structs

    -

    BIP44 template. Expands to pkh(key/44'/{0,1}'/0'/{0,1}/*)

    -

    BIP44 public template. Expands to pkh(key/{0,1}/*)

    -

    BIP49 template. Expands to sh(wpkh(key/49'/{0,1}'/0'/{0,1}/*))

    -

    BIP49 public template. Expands to sh(wpkh(key/{0,1}/*))

    -

    BIP84 template. Expands to wpkh(key/84'/{0,1}'/0'/{0,1}/*)

    -

    BIP84 public template. Expands to wpkh(key/{0,1}/*)

    -

    P2PKH template. Expands to a descriptor pkh(key)

    -

    P2WPKH template. Expands to a descriptor wpkh(key)

    -

    P2WPKH-P2SH template. Expands to a descriptor sh(wpkh(key))

    -

    Traits

    -

    Trait for descriptor templates that can be built into a full descriptor

    -

    Type Definitions

    -

    Type alias for the return type of DescriptorTemplate, descriptor! and others

    -
    - \ No newline at end of file +

    Structs

    BIP44 template. Expands to pkh(key/44'/{0,1}'/0'/{0,1}/*)
    BIP44 public template. Expands to pkh(key/{0,1}/*)
    BIP49 template. Expands to sh(wpkh(key/49'/{0,1}'/0'/{0,1}/*))
    BIP49 public template. Expands to sh(wpkh(key/{0,1}/*))
    BIP84 template. Expands to wpkh(key/84'/{0,1}'/0'/{0,1}/*)
    BIP84 public template. Expands to wpkh(key/{0,1}/*)
    P2PKH template. Expands to a descriptor pkh(key)
    P2WPKH template. Expands to a descriptor wpkh(key)
    P2WPKH-P2SH template. Expands to a descriptor sh(wpkh(key))

    Traits

    Trait for descriptor templates that can be built into a full descriptor

    Type Definitions

    Type alias for the return type of DescriptorTemplate, descriptor! and others
    \ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/descriptor/template/sidebar-items.js b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/descriptor/template/sidebar-items.js index 22d94f9a11..b0a0975620 100644 --- a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/descriptor/template/sidebar-items.js +++ b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/descriptor/template/sidebar-items.js @@ -1 +1 @@ -initSidebarItems({"struct":[["Bip44","BIP44 template. Expands to `pkh(key/44'/{0,1}'/0'/{0,1}/*)`"],["Bip44Public","BIP44 public template. Expands to `pkh(key/{0,1}/*)`"],["Bip49","BIP49 template. Expands to `sh(wpkh(key/49'/{0,1}'/0'/{0,1}/*))`"],["Bip49Public","BIP49 public template. Expands to `sh(wpkh(key/{0,1}/*))`"],["Bip84","BIP84 template. Expands to `wpkh(key/84'/{0,1}'/0'/{0,1}/*)`"],["Bip84Public","BIP84 public template. Expands to `wpkh(key/{0,1}/*)`"],["P2Pkh","P2PKH template. Expands to a descriptor `pkh(key)`"],["P2Wpkh","P2WPKH template. Expands to a descriptor `wpkh(key)`"],["P2Wpkh_P2Sh","P2WPKH-P2SH template. Expands to a descriptor `sh(wpkh(key))`"]],"trait":[["DescriptorTemplate","Trait for descriptor templates that can be built into a full descriptor"]],"type":[["DescriptorTemplateOut","Type alias for the return type of [`DescriptorTemplate`], `descriptor!` and others"]]}); \ No newline at end of file +window.SIDEBAR_ITEMS = {"struct":[["Bip44","BIP44 template. Expands to `pkh(key/44'/{0,1}'/0'/{0,1}/*)`"],["Bip44Public","BIP44 public template. Expands to `pkh(key/{0,1}/*)`"],["Bip49","BIP49 template. Expands to `sh(wpkh(key/49'/{0,1}'/0'/{0,1}/*))`"],["Bip49Public","BIP49 public template. Expands to `sh(wpkh(key/{0,1}/*))`"],["Bip84","BIP84 template. Expands to `wpkh(key/84'/{0,1}'/0'/{0,1}/*)`"],["Bip84Public","BIP84 public template. Expands to `wpkh(key/{0,1}/*)`"],["P2Pkh","P2PKH template. Expands to a descriptor `pkh(key)`"],["P2Wpkh","P2WPKH template. Expands to a descriptor `wpkh(key)`"],["P2Wpkh_P2Sh","P2WPKH-P2SH template. Expands to a descriptor `sh(wpkh(key))`"]],"trait":[["DescriptorTemplate","Trait for descriptor templates that can be built into a full descriptor"]],"type":[["DescriptorTemplateOut","Type alias for the return type of [`DescriptorTemplate`], `descriptor!` and others"]]}; \ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/descriptor/template/struct.Bip44.html b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/descriptor/template/struct.Bip44.html index 0f7983d1a6..bd44d21c6e 100644 --- a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/descriptor/template/struct.Bip44.html +++ b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/descriptor/template/struct.Bip44.html @@ -1,43 +1,22 @@ -Bip44 in bdk::descriptor::template - Rust - -
    pub struct Bip44<K: DerivableKey<Legacy>>(pub K, pub KeychainKind);
    Expand description

    BIP44 template. Expands to pkh(key/44'/{0,1}'/0'/{0,1}/*)

    +Bip44 in bdk::descriptor::template - Rust

    Struct bdk::descriptor::template::Bip44

    source ·
    pub struct Bip44<K: DerivableKey<Legacy>>(pub K, pub KeychainKind);
    Expand description

    BIP44 template. Expands to pkh(key/44'/{0,1}'/0'/{0,1}/*)

    Since there are hardened derivation steps, this template requires a private derivable key (generally a xprv/tprv).

    See Bip44Public for a template that can work with a xpub/tpub.

    -

    Example

    -
    use bdk::template::Bip44;
    +

    Example

    +
    use bdk::template::Bip44;
     
    -let key = bitcoin::util::bip32::ExtendedPrivKey::from_str("tprv8ZgxMBicQKsPeZRHk4rTG6orPS2CRNFX3njhUXx5vj9qGog5ZMH4uGReDWN5kCkY3jmWEtWause41CDvBRXD1shKknAMKxT99o9qUTRVC6m")?;
    -let wallet = Wallet::new(
    -    Bip44(key.clone(), KeychainKind::External),
    -    Some(Bip44(key, KeychainKind::Internal)),
    -    Network::Testnet,
    -    MemoryDatabase::default()
    +let key = bitcoin::util::bip32::ExtendedPrivKey::from_str("tprv8ZgxMBicQKsPeZRHk4rTG6orPS2CRNFX3njhUXx5vj9qGog5ZMH4uGReDWN5kCkY3jmWEtWause41CDvBRXD1shKknAMKxT99o9qUTRVC6m")?;
    +let wallet = Wallet::new(
    +    Bip44(key.clone(), KeychainKind::External),
    +    Some(Bip44(key, KeychainKind::Internal)),
    +    Network::Testnet,
    +    MemoryDatabase::default()
     )?;
     
    -assert_eq!(wallet.get_address(New)?.to_string(), "mmogjc7HJEZkrLqyQYqJmxUqFaC7i4uf89");
    -assert_eq!(wallet.public_descriptor(KeychainKind::External)?.unwrap().to_string(), "pkh([c55b303f/44'/1'/0']tpubDCuorCpzvYS2LCD75BR46KHE8GdDeg1wsAgNZeNr6DaB5gQK1o14uErKwKLuFmeemkQ6N2m3rNgvctdJLyr7nwu2yia7413Hhg8WWE44cgT/0/*)#5wrnv0xt");
    -

    Tuple Fields

    0: K1: KeychainKind

    Trait Implementations

    Build the complete descriptor

    -

    Auto Trait Implementations

    Blanket Implementations

    Gets the TypeId of self. Read more

    -

    Immutably borrows from an owned value. Read more

    -

    Mutably borrows from an owned value. Read more

    -

    Performs the conversion.

    -

    Performs the conversion.

    -

    Convert to wallet descriptor

    -

    The alignment of pointer.

    -

    The type for initializers.

    -

    Initializes a with the given initializer. Read more

    -

    Dereferences the given pointer. Read more

    -

    Mutably dereferences the given pointer. Read more

    -

    Drops the object pointed to by the given pointer. Read more

    -

    The type returned in the event of a conversion error.

    -

    Performs the conversion.

    -

    The type returned in the event of a conversion error.

    -

    Performs the conversion.

    -
    - \ No newline at end of file +assert_eq!(wallet.get_address(New)?.to_string(), "mmogjc7HJEZkrLqyQYqJmxUqFaC7i4uf89"); +assert_eq!(wallet.public_descriptor(KeychainKind::External)?.unwrap().to_string(), "pkh([c55b303f/44'/1'/0']tpubDCuorCpzvYS2LCD75BR46KHE8GdDeg1wsAgNZeNr6DaB5gQK1o14uErKwKLuFmeemkQ6N2m3rNgvctdJLyr7nwu2yia7413Hhg8WWE44cgT/0/*)#5wrnv0xt");
    +

    Tuple Fields§

    §0: K§1: KeychainKind

    Trait Implementations§

    Build the complete descriptor

    Auto Trait Implementations§

    Blanket Implementations§

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

    Returns the argument unchanged.

    +

    Calls U::from(self).

    +

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

    +
    Convert to wallet descriptor
    The alignment of pointer.
    The type for initializers.
    Initializes a with the given initializer. Read more
    Dereferences the given pointer. Read more
    Mutably dereferences the given pointer. Read more
    Drops the object pointed to by the given pointer. Read more
    The type returned in the event of a conversion error.
    Performs the conversion.
    The type returned in the event of a conversion error.
    Performs the conversion.
    \ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/descriptor/template/struct.Bip44Public.html b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/descriptor/template/struct.Bip44Public.html index 1bd4ac1fcd..92b5ef6df0 100644 --- a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/descriptor/template/struct.Bip44Public.html +++ b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/descriptor/template/struct.Bip44Public.html @@ -1,46 +1,25 @@ -Bip44Public in bdk::descriptor::template - Rust - -
    pub struct Bip44Public<K: DerivableKey<Legacy>>(pub K, pub Fingerprint, pub KeychainKind);
    Expand description

    BIP44 public template. Expands to pkh(key/{0,1}/*)

    +Bip44Public in bdk::descriptor::template - Rust
    pub struct Bip44Public<K: DerivableKey<Legacy>>(pub K, pub Fingerprint, pub KeychainKind);
    Expand description

    BIP44 public template. Expands to pkh(key/{0,1}/*)

    This assumes that the key used has already been derived with m/44'/0'/0' for Mainnet or m/44'/1'/0' for Testnet.

    This template requires the parent fingerprint to populate correctly the metadata of PSBTs.

    See Bip44 for a template that does the full derivation, but requires private data for the key.

    -

    Example

    -
    use bdk::template::Bip44Public;
    +

    Example

    +
    use bdk::template::Bip44Public;
     
    -let key = bitcoin::util::bip32::ExtendedPubKey::from_str("tpubDDDzQ31JkZB7VxUr9bjvBivDdqoFLrDPyLWtLapArAi51ftfmCb2DPxwLQzX65iNcXz1DGaVvyvo6JQ6rTU73r2gqdEo8uov9QKRb7nKCSU")?;
    -let fingerprint = bitcoin::util::bip32::Fingerprint::from_str("c55b303f")?;
    -let wallet = Wallet::new(
    -    Bip44Public(key.clone(), fingerprint, KeychainKind::External),
    -    Some(Bip44Public(key, fingerprint, KeychainKind::Internal)),
    -    Network::Testnet,
    -    MemoryDatabase::default()
    +let key = bitcoin::util::bip32::ExtendedPubKey::from_str("tpubDDDzQ31JkZB7VxUr9bjvBivDdqoFLrDPyLWtLapArAi51ftfmCb2DPxwLQzX65iNcXz1DGaVvyvo6JQ6rTU73r2gqdEo8uov9QKRb7nKCSU")?;
    +let fingerprint = bitcoin::util::bip32::Fingerprint::from_str("c55b303f")?;
    +let wallet = Wallet::new(
    +    Bip44Public(key.clone(), fingerprint, KeychainKind::External),
    +    Some(Bip44Public(key, fingerprint, KeychainKind::Internal)),
    +    Network::Testnet,
    +    MemoryDatabase::default()
     )?;
     
    -assert_eq!(wallet.get_address(New)?.to_string(), "miNG7dJTzJqNbFS19svRdTCisC65dsubtR");
    -assert_eq!(wallet.public_descriptor(KeychainKind::External)?.unwrap().to_string(), "pkh([c55b303f/44'/0'/0']tpubDDDzQ31JkZB7VxUr9bjvBivDdqoFLrDPyLWtLapArAi51ftfmCb2DPxwLQzX65iNcXz1DGaVvyvo6JQ6rTU73r2gqdEo8uov9QKRb7nKCSU/0/*)#xgaaevjx");
    -

    Tuple Fields

    0: K1: Fingerprint2: KeychainKind

    Trait Implementations

    Build the complete descriptor

    -

    Auto Trait Implementations

    Blanket Implementations

    Gets the TypeId of self. Read more

    -

    Immutably borrows from an owned value. Read more

    -

    Mutably borrows from an owned value. Read more

    -

    Performs the conversion.

    -

    Performs the conversion.

    -

    Convert to wallet descriptor

    -

    The alignment of pointer.

    -

    The type for initializers.

    -

    Initializes a with the given initializer. Read more

    -

    Dereferences the given pointer. Read more

    -

    Mutably dereferences the given pointer. Read more

    -

    Drops the object pointed to by the given pointer. Read more

    -

    The type returned in the event of a conversion error.

    -

    Performs the conversion.

    -

    The type returned in the event of a conversion error.

    -

    Performs the conversion.

    -
    - \ No newline at end of file +assert_eq!(wallet.get_address(New)?.to_string(), "miNG7dJTzJqNbFS19svRdTCisC65dsubtR"); +assert_eq!(wallet.public_descriptor(KeychainKind::External)?.unwrap().to_string(), "pkh([c55b303f/44'/0'/0']tpubDDDzQ31JkZB7VxUr9bjvBivDdqoFLrDPyLWtLapArAi51ftfmCb2DPxwLQzX65iNcXz1DGaVvyvo6JQ6rTU73r2gqdEo8uov9QKRb7nKCSU/0/*)#xgaaevjx");
    +

    Tuple Fields§

    §0: K§1: Fingerprint§2: KeychainKind

    Trait Implementations§

    Build the complete descriptor

    Auto Trait Implementations§

    Blanket Implementations§

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

    Returns the argument unchanged.

    +

    Calls U::from(self).

    +

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

    +
    Convert to wallet descriptor
    The alignment of pointer.
    The type for initializers.
    Initializes a with the given initializer. Read more
    Dereferences the given pointer. Read more
    Mutably dereferences the given pointer. Read more
    Drops the object pointed to by the given pointer. Read more
    The type returned in the event of a conversion error.
    Performs the conversion.
    The type returned in the event of a conversion error.
    Performs the conversion.
    \ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/descriptor/template/struct.Bip49.html b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/descriptor/template/struct.Bip49.html index 7782ffc3ef..943a9f9dbe 100644 --- a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/descriptor/template/struct.Bip49.html +++ b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/descriptor/template/struct.Bip49.html @@ -1,43 +1,22 @@ -Bip49 in bdk::descriptor::template - Rust - -
    pub struct Bip49<K: DerivableKey<Segwitv0>>(pub K, pub KeychainKind);
    Expand description

    BIP49 template. Expands to sh(wpkh(key/49'/{0,1}'/0'/{0,1}/*))

    +Bip49 in bdk::descriptor::template - Rust

    Struct bdk::descriptor::template::Bip49

    source ·
    pub struct Bip49<K: DerivableKey<Segwitv0>>(pub K, pub KeychainKind);
    Expand description

    BIP49 template. Expands to sh(wpkh(key/49'/{0,1}'/0'/{0,1}/*))

    Since there are hardened derivation steps, this template requires a private derivable key (generally a xprv/tprv).

    See Bip49Public for a template that can work with a xpub/tpub.

    -

    Example

    -
    use bdk::template::Bip49;
    +

    Example

    +
    use bdk::template::Bip49;
     
    -let key = bitcoin::util::bip32::ExtendedPrivKey::from_str("tprv8ZgxMBicQKsPeZRHk4rTG6orPS2CRNFX3njhUXx5vj9qGog5ZMH4uGReDWN5kCkY3jmWEtWause41CDvBRXD1shKknAMKxT99o9qUTRVC6m")?;
    -let wallet = Wallet::new(
    -    Bip49(key.clone(), KeychainKind::External),
    -    Some(Bip49(key, KeychainKind::Internal)),
    -    Network::Testnet,
    -    MemoryDatabase::default()
    +let key = bitcoin::util::bip32::ExtendedPrivKey::from_str("tprv8ZgxMBicQKsPeZRHk4rTG6orPS2CRNFX3njhUXx5vj9qGog5ZMH4uGReDWN5kCkY3jmWEtWause41CDvBRXD1shKknAMKxT99o9qUTRVC6m")?;
    +let wallet = Wallet::new(
    +    Bip49(key.clone(), KeychainKind::External),
    +    Some(Bip49(key, KeychainKind::Internal)),
    +    Network::Testnet,
    +    MemoryDatabase::default()
     )?;
     
    -assert_eq!(wallet.get_address(New)?.to_string(), "2N4zkWAoGdUv4NXhSsU8DvS5MB36T8nKHEB");
    -assert_eq!(wallet.public_descriptor(KeychainKind::External)?.unwrap().to_string(), "sh(wpkh([c55b303f/49'/1'/0']tpubDDYr4kdnZgjjShzYNjZUZXUUtpXaofdkMaipyS8ThEh45qFmhT4hKYways7UXmg6V7het1QiFo9kf4kYUXyDvV4rHEyvSpys9pjCB3pukxi/0/*))#s9vxlc8e");
    -

    Tuple Fields

    0: K1: KeychainKind

    Trait Implementations

    Build the complete descriptor

    -

    Auto Trait Implementations

    Blanket Implementations

    Gets the TypeId of self. Read more

    -

    Immutably borrows from an owned value. Read more

    -

    Mutably borrows from an owned value. Read more

    -

    Performs the conversion.

    -

    Performs the conversion.

    -

    Convert to wallet descriptor

    -

    The alignment of pointer.

    -

    The type for initializers.

    -

    Initializes a with the given initializer. Read more

    -

    Dereferences the given pointer. Read more

    -

    Mutably dereferences the given pointer. Read more

    -

    Drops the object pointed to by the given pointer. Read more

    -

    The type returned in the event of a conversion error.

    -

    Performs the conversion.

    -

    The type returned in the event of a conversion error.

    -

    Performs the conversion.

    -
    - \ No newline at end of file +assert_eq!(wallet.get_address(New)?.to_string(), "2N4zkWAoGdUv4NXhSsU8DvS5MB36T8nKHEB"); +assert_eq!(wallet.public_descriptor(KeychainKind::External)?.unwrap().to_string(), "sh(wpkh([c55b303f/49'/1'/0']tpubDDYr4kdnZgjjShzYNjZUZXUUtpXaofdkMaipyS8ThEh45qFmhT4hKYways7UXmg6V7het1QiFo9kf4kYUXyDvV4rHEyvSpys9pjCB3pukxi/0/*))#s9vxlc8e");
    +

    Tuple Fields§

    §0: K§1: KeychainKind

    Trait Implementations§

    Build the complete descriptor

    Auto Trait Implementations§

    Blanket Implementations§

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

    Returns the argument unchanged.

    +

    Calls U::from(self).

    +

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

    +
    Convert to wallet descriptor
    The alignment of pointer.
    The type for initializers.
    Initializes a with the given initializer. Read more
    Dereferences the given pointer. Read more
    Mutably dereferences the given pointer. Read more
    Drops the object pointed to by the given pointer. Read more
    The type returned in the event of a conversion error.
    Performs the conversion.
    The type returned in the event of a conversion error.
    Performs the conversion.
    \ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/descriptor/template/struct.Bip49Public.html b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/descriptor/template/struct.Bip49Public.html index ccfc634746..8e60c774ee 100644 --- a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/descriptor/template/struct.Bip49Public.html +++ b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/descriptor/template/struct.Bip49Public.html @@ -1,46 +1,25 @@ -Bip49Public in bdk::descriptor::template - Rust - -
    pub struct Bip49Public<K: DerivableKey<Segwitv0>>(pub K, pub Fingerprint, pub KeychainKind);
    Expand description

    BIP49 public template. Expands to sh(wpkh(key/{0,1}/*))

    +Bip49Public in bdk::descriptor::template - Rust
    pub struct Bip49Public<K: DerivableKey<Segwitv0>>(pub K, pub Fingerprint, pub KeychainKind);
    Expand description

    BIP49 public template. Expands to sh(wpkh(key/{0,1}/*))

    This assumes that the key used has already been derived with m/49'/0'/0'.

    This template requires the parent fingerprint to populate correctly the metadata of PSBTs.

    See Bip49 for a template that does the full derivation, but requires private data for the key.

    -

    Example

    -
    use bdk::template::Bip49Public;
    +

    Example

    +
    use bdk::template::Bip49Public;
     
    -let key = bitcoin::util::bip32::ExtendedPubKey::from_str("tpubDC49r947KGK52X5rBWS4BLs5m9SRY3pYHnvRrm7HcybZ3BfdEsGFyzCMzayi1u58eT82ZeyFZwH7DD6Q83E3fM9CpfMtmnTygnLfP59jL9L")?;
    -let fingerprint = bitcoin::util::bip32::Fingerprint::from_str("c55b303f")?;
    -let wallet = Wallet::new(
    -    Bip49Public(key.clone(), fingerprint, KeychainKind::External),
    -    Some(Bip49Public(key, fingerprint, KeychainKind::Internal)),
    -    Network::Testnet,
    -    MemoryDatabase::default()
    +let key = bitcoin::util::bip32::ExtendedPubKey::from_str("tpubDC49r947KGK52X5rBWS4BLs5m9SRY3pYHnvRrm7HcybZ3BfdEsGFyzCMzayi1u58eT82ZeyFZwH7DD6Q83E3fM9CpfMtmnTygnLfP59jL9L")?;
    +let fingerprint = bitcoin::util::bip32::Fingerprint::from_str("c55b303f")?;
    +let wallet = Wallet::new(
    +    Bip49Public(key.clone(), fingerprint, KeychainKind::External),
    +    Some(Bip49Public(key, fingerprint, KeychainKind::Internal)),
    +    Network::Testnet,
    +    MemoryDatabase::default()
     )?;
     
    -assert_eq!(wallet.get_address(New)?.to_string(), "2N3K4xbVAHoiTQSwxkZjWDfKoNC27pLkYnt");
    -assert_eq!(wallet.public_descriptor(KeychainKind::External)?.unwrap().to_string(), "sh(wpkh([c55b303f/49'/0'/0']tpubDC49r947KGK52X5rBWS4BLs5m9SRY3pYHnvRrm7HcybZ3BfdEsGFyzCMzayi1u58eT82ZeyFZwH7DD6Q83E3fM9CpfMtmnTygnLfP59jL9L/0/*))#gsmdv4xr");
    -

    Tuple Fields

    0: K1: Fingerprint2: KeychainKind

    Trait Implementations

    Build the complete descriptor

    -

    Auto Trait Implementations

    Blanket Implementations

    Gets the TypeId of self. Read more

    -

    Immutably borrows from an owned value. Read more

    -

    Mutably borrows from an owned value. Read more

    -

    Performs the conversion.

    -

    Performs the conversion.

    -

    Convert to wallet descriptor

    -

    The alignment of pointer.

    -

    The type for initializers.

    -

    Initializes a with the given initializer. Read more

    -

    Dereferences the given pointer. Read more

    -

    Mutably dereferences the given pointer. Read more

    -

    Drops the object pointed to by the given pointer. Read more

    -

    The type returned in the event of a conversion error.

    -

    Performs the conversion.

    -

    The type returned in the event of a conversion error.

    -

    Performs the conversion.

    -
    - \ No newline at end of file +assert_eq!(wallet.get_address(New)?.to_string(), "2N3K4xbVAHoiTQSwxkZjWDfKoNC27pLkYnt"); +assert_eq!(wallet.public_descriptor(KeychainKind::External)?.unwrap().to_string(), "sh(wpkh([c55b303f/49'/0'/0']tpubDC49r947KGK52X5rBWS4BLs5m9SRY3pYHnvRrm7HcybZ3BfdEsGFyzCMzayi1u58eT82ZeyFZwH7DD6Q83E3fM9CpfMtmnTygnLfP59jL9L/0/*))#gsmdv4xr");
    +

    Tuple Fields§

    §0: K§1: Fingerprint§2: KeychainKind

    Trait Implementations§

    Build the complete descriptor

    Auto Trait Implementations§

    Blanket Implementations§

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

    Returns the argument unchanged.

    +

    Calls U::from(self).

    +

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

    +
    Convert to wallet descriptor
    The alignment of pointer.
    The type for initializers.
    Initializes a with the given initializer. Read more
    Dereferences the given pointer. Read more
    Mutably dereferences the given pointer. Read more
    Drops the object pointed to by the given pointer. Read more
    The type returned in the event of a conversion error.
    Performs the conversion.
    The type returned in the event of a conversion error.
    Performs the conversion.
    \ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/descriptor/template/struct.Bip84.html b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/descriptor/template/struct.Bip84.html index d08f87c922..f19fb0ef2e 100644 --- a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/descriptor/template/struct.Bip84.html +++ b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/descriptor/template/struct.Bip84.html @@ -1,43 +1,22 @@ -Bip84 in bdk::descriptor::template - Rust - -
    pub struct Bip84<K: DerivableKey<Segwitv0>>(pub K, pub KeychainKind);
    Expand description

    BIP84 template. Expands to wpkh(key/84'/{0,1}'/0'/{0,1}/*)

    +Bip84 in bdk::descriptor::template - Rust

    Struct bdk::descriptor::template::Bip84

    source ·
    pub struct Bip84<K: DerivableKey<Segwitv0>>(pub K, pub KeychainKind);
    Expand description

    BIP84 template. Expands to wpkh(key/84'/{0,1}'/0'/{0,1}/*)

    Since there are hardened derivation steps, this template requires a private derivable key (generally a xprv/tprv).

    See Bip84Public for a template that can work with a xpub/tpub.

    -

    Example

    -
    use bdk::template::Bip84;
    +

    Example

    +
    use bdk::template::Bip84;
     
    -let key = bitcoin::util::bip32::ExtendedPrivKey::from_str("tprv8ZgxMBicQKsPeZRHk4rTG6orPS2CRNFX3njhUXx5vj9qGog5ZMH4uGReDWN5kCkY3jmWEtWause41CDvBRXD1shKknAMKxT99o9qUTRVC6m")?;
    -let wallet = Wallet::new(
    -    Bip84(key.clone(), KeychainKind::External),
    -    Some(Bip84(key, KeychainKind::Internal)),
    -    Network::Testnet,
    -    MemoryDatabase::default()
    +let key = bitcoin::util::bip32::ExtendedPrivKey::from_str("tprv8ZgxMBicQKsPeZRHk4rTG6orPS2CRNFX3njhUXx5vj9qGog5ZMH4uGReDWN5kCkY3jmWEtWause41CDvBRXD1shKknAMKxT99o9qUTRVC6m")?;
    +let wallet = Wallet::new(
    +    Bip84(key.clone(), KeychainKind::External),
    +    Some(Bip84(key, KeychainKind::Internal)),
    +    Network::Testnet,
    +    MemoryDatabase::default()
     )?;
     
    -assert_eq!(wallet.get_address(New)?.to_string(), "tb1qhl85z42h7r4su5u37rvvw0gk8j2t3n9y7zsg4n");
    -assert_eq!(wallet.public_descriptor(KeychainKind::External)?.unwrap().to_string(), "wpkh([c55b303f/84'/1'/0']tpubDDc5mum24DekpNw92t6fHGp8Gr2JjF9J7i4TZBtN6Vp8xpAULG5CFaKsfugWa5imhrQQUZKXe261asP5koDHo5bs3qNTmf3U3o4v9SaB8gg/0/*)#6kfecsmr");
    -

    Tuple Fields

    0: K1: KeychainKind

    Trait Implementations

    Build the complete descriptor

    -

    Auto Trait Implementations

    Blanket Implementations

    Gets the TypeId of self. Read more

    -

    Immutably borrows from an owned value. Read more

    -

    Mutably borrows from an owned value. Read more

    -

    Performs the conversion.

    -

    Performs the conversion.

    -

    Convert to wallet descriptor

    -

    The alignment of pointer.

    -

    The type for initializers.

    -

    Initializes a with the given initializer. Read more

    -

    Dereferences the given pointer. Read more

    -

    Mutably dereferences the given pointer. Read more

    -

    Drops the object pointed to by the given pointer. Read more

    -

    The type returned in the event of a conversion error.

    -

    Performs the conversion.

    -

    The type returned in the event of a conversion error.

    -

    Performs the conversion.

    -
    - \ No newline at end of file +assert_eq!(wallet.get_address(New)?.to_string(), "tb1qhl85z42h7r4su5u37rvvw0gk8j2t3n9y7zsg4n"); +assert_eq!(wallet.public_descriptor(KeychainKind::External)?.unwrap().to_string(), "wpkh([c55b303f/84'/1'/0']tpubDDc5mum24DekpNw92t6fHGp8Gr2JjF9J7i4TZBtN6Vp8xpAULG5CFaKsfugWa5imhrQQUZKXe261asP5koDHo5bs3qNTmf3U3o4v9SaB8gg/0/*)#6kfecsmr");
    +

    Tuple Fields§

    §0: K§1: KeychainKind

    Trait Implementations§

    Build the complete descriptor

    Auto Trait Implementations§

    Blanket Implementations§

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

    Returns the argument unchanged.

    +

    Calls U::from(self).

    +

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

    +
    Convert to wallet descriptor
    The alignment of pointer.
    The type for initializers.
    Initializes a with the given initializer. Read more
    Dereferences the given pointer. Read more
    Mutably dereferences the given pointer. Read more
    Drops the object pointed to by the given pointer. Read more
    The type returned in the event of a conversion error.
    Performs the conversion.
    The type returned in the event of a conversion error.
    Performs the conversion.
    \ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/descriptor/template/struct.Bip84Public.html b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/descriptor/template/struct.Bip84Public.html index 11ae3c42a5..114ce642f7 100644 --- a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/descriptor/template/struct.Bip84Public.html +++ b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/descriptor/template/struct.Bip84Public.html @@ -1,46 +1,25 @@ -Bip84Public in bdk::descriptor::template - Rust - -
    pub struct Bip84Public<K: DerivableKey<Segwitv0>>(pub K, pub Fingerprint, pub KeychainKind);
    Expand description

    BIP84 public template. Expands to wpkh(key/{0,1}/*)

    +Bip84Public in bdk::descriptor::template - Rust
    pub struct Bip84Public<K: DerivableKey<Segwitv0>>(pub K, pub Fingerprint, pub KeychainKind);
    Expand description

    BIP84 public template. Expands to wpkh(key/{0,1}/*)

    This assumes that the key used has already been derived with m/84'/0'/0'.

    This template requires the parent fingerprint to populate correctly the metadata of PSBTs.

    See Bip84 for a template that does the full derivation, but requires private data for the key.

    -

    Example

    -
    use bdk::template::Bip84Public;
    +

    Example

    +
    use bdk::template::Bip84Public;
     
    -let key = bitcoin::util::bip32::ExtendedPubKey::from_str("tpubDC2Qwo2TFsaNC4ju8nrUJ9mqVT3eSgdmy1yPqhgkjwmke3PRXutNGRYAUo6RCHTcVQaDR3ohNU9we59brGHuEKPvH1ags2nevW5opEE9Z5Q")?;
    -let fingerprint = bitcoin::util::bip32::Fingerprint::from_str("c55b303f")?;
    -let wallet = Wallet::new(
    -    Bip84Public(key.clone(), fingerprint, KeychainKind::External),
    -    Some(Bip84Public(key, fingerprint, KeychainKind::Internal)),
    -    Network::Testnet,
    -    MemoryDatabase::default()
    +let key = bitcoin::util::bip32::ExtendedPubKey::from_str("tpubDC2Qwo2TFsaNC4ju8nrUJ9mqVT3eSgdmy1yPqhgkjwmke3PRXutNGRYAUo6RCHTcVQaDR3ohNU9we59brGHuEKPvH1ags2nevW5opEE9Z5Q")?;
    +let fingerprint = bitcoin::util::bip32::Fingerprint::from_str("c55b303f")?;
    +let wallet = Wallet::new(
    +    Bip84Public(key.clone(), fingerprint, KeychainKind::External),
    +    Some(Bip84Public(key, fingerprint, KeychainKind::Internal)),
    +    Network::Testnet,
    +    MemoryDatabase::default()
     )?;
     
    -assert_eq!(wallet.get_address(New)?.to_string(), "tb1qedg9fdlf8cnnqfd5mks6uz5w4kgpk2pr6y4qc7");
    -assert_eq!(wallet.public_descriptor(KeychainKind::External)?.unwrap().to_string(), "wpkh([c55b303f/84\'/0\'/0\']tpubDC2Qwo2TFsaNC4ju8nrUJ9mqVT3eSgdmy1yPqhgkjwmke3PRXutNGRYAUo6RCHTcVQaDR3ohNU9we59brGHuEKPvH1ags2nevW5opEE9Z5Q/0/*)#nkk5dtkg");
    -

    Tuple Fields

    0: K1: Fingerprint2: KeychainKind

    Trait Implementations

    Build the complete descriptor

    -

    Auto Trait Implementations

    Blanket Implementations

    Gets the TypeId of self. Read more

    -

    Immutably borrows from an owned value. Read more

    -

    Mutably borrows from an owned value. Read more

    -

    Performs the conversion.

    -

    Performs the conversion.

    -

    Convert to wallet descriptor

    -

    The alignment of pointer.

    -

    The type for initializers.

    -

    Initializes a with the given initializer. Read more

    -

    Dereferences the given pointer. Read more

    -

    Mutably dereferences the given pointer. Read more

    -

    Drops the object pointed to by the given pointer. Read more

    -

    The type returned in the event of a conversion error.

    -

    Performs the conversion.

    -

    The type returned in the event of a conversion error.

    -

    Performs the conversion.

    -
    - \ No newline at end of file +assert_eq!(wallet.get_address(New)?.to_string(), "tb1qedg9fdlf8cnnqfd5mks6uz5w4kgpk2pr6y4qc7"); +assert_eq!(wallet.public_descriptor(KeychainKind::External)?.unwrap().to_string(), "wpkh([c55b303f/84\'/0\'/0\']tpubDC2Qwo2TFsaNC4ju8nrUJ9mqVT3eSgdmy1yPqhgkjwmke3PRXutNGRYAUo6RCHTcVQaDR3ohNU9we59brGHuEKPvH1ags2nevW5opEE9Z5Q/0/*)#nkk5dtkg");
    +

    Tuple Fields§

    §0: K§1: Fingerprint§2: KeychainKind

    Trait Implementations§

    Build the complete descriptor

    Auto Trait Implementations§

    Blanket Implementations§

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

    Returns the argument unchanged.

    +

    Calls U::from(self).

    +

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

    +
    Convert to wallet descriptor
    The alignment of pointer.
    The type for initializers.
    Initializes a with the given initializer. Read more
    Dereferences the given pointer. Read more
    Mutably dereferences the given pointer. Read more
    Drops the object pointed to by the given pointer. Read more
    The type returned in the event of a conversion error.
    Performs the conversion.
    The type returned in the event of a conversion error.
    Performs the conversion.
    \ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/descriptor/template/struct.P2Pkh.html b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/descriptor/template/struct.P2Pkh.html index 08a020b2eb..5413a68d73 100644 --- a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/descriptor/template/struct.P2Pkh.html +++ b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/descriptor/template/struct.P2Pkh.html @@ -1,44 +1,23 @@ -P2Pkh in bdk::descriptor::template - Rust - -
    pub struct P2Pkh<K: IntoDescriptorKey<Legacy>>(pub K);
    Expand description

    P2PKH template. Expands to a descriptor pkh(key)

    -

    Example

    -
    use bdk::template::P2Pkh;
    +P2Pkh in bdk::descriptor::template - Rust

    Struct bdk::descriptor::template::P2Pkh

    source ·
    pub struct P2Pkh<K: IntoDescriptorKey<Legacy>>(pub K);
    Expand description

    P2PKH template. Expands to a descriptor pkh(key)

    +

    Example

    +
    use bdk::template::P2Pkh;
     
    -let key =
    -    bitcoin::PrivateKey::from_wif("cTc4vURSzdx6QE6KVynWGomDbLaA75dNALMNyfjh3p8DRRar84Um")?;
    -let wallet = Wallet::new(
    -    P2Pkh(key),
    +let key =
    +    bitcoin::PrivateKey::from_wif("cTc4vURSzdx6QE6KVynWGomDbLaA75dNALMNyfjh3p8DRRar84Um")?;
    +let wallet = Wallet::new(
    +    P2Pkh(key),
         None,
    -    Network::Testnet,
    -    MemoryDatabase::default(),
    +    Network::Testnet,
    +    MemoryDatabase::default(),
     )?;
     
     assert_eq!(
    -    wallet.get_address(New)?.to_string(),
    -    "mwJ8hxFYW19JLuc65RCTaP4v1rzVU8cVMT"
    -);
    -

    Tuple Fields

    0: K

    Trait Implementations

    Build the complete descriptor

    -

    Auto Trait Implementations

    Blanket Implementations

    Gets the TypeId of self. Read more

    -

    Immutably borrows from an owned value. Read more

    -

    Mutably borrows from an owned value. Read more

    -

    Performs the conversion.

    -

    Performs the conversion.

    -

    Convert to wallet descriptor

    -

    The alignment of pointer.

    -

    The type for initializers.

    -

    Initializes a with the given initializer. Read more

    -

    Dereferences the given pointer. Read more

    -

    Mutably dereferences the given pointer. Read more

    -

    Drops the object pointed to by the given pointer. Read more

    -

    The type returned in the event of a conversion error.

    -

    Performs the conversion.

    -

    The type returned in the event of a conversion error.

    -

    Performs the conversion.

    -
    - \ No newline at end of file + wallet.get_address(New)?.to_string(), + "mwJ8hxFYW19JLuc65RCTaP4v1rzVU8cVMT" +);
    +

    Tuple Fields§

    §0: K

    Trait Implementations§

    Build the complete descriptor

    Auto Trait Implementations§

    Blanket Implementations§

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

    Returns the argument unchanged.

    +

    Calls U::from(self).

    +

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

    +
    Convert to wallet descriptor
    The alignment of pointer.
    The type for initializers.
    Initializes a with the given initializer. Read more
    Dereferences the given pointer. Read more
    Mutably dereferences the given pointer. Read more
    Drops the object pointed to by the given pointer. Read more
    The type returned in the event of a conversion error.
    Performs the conversion.
    The type returned in the event of a conversion error.
    Performs the conversion.
    \ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/descriptor/template/struct.P2Wpkh.html b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/descriptor/template/struct.P2Wpkh.html index 4e25693d4d..58f559e143 100644 --- a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/descriptor/template/struct.P2Wpkh.html +++ b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/descriptor/template/struct.P2Wpkh.html @@ -1,44 +1,23 @@ -P2Wpkh in bdk::descriptor::template - Rust - -
    pub struct P2Wpkh<K: IntoDescriptorKey<Segwitv0>>(pub K);
    Expand description

    P2WPKH template. Expands to a descriptor wpkh(key)

    -

    Example

    -
    use bdk::template::P2Wpkh;
    +P2Wpkh in bdk::descriptor::template - Rust

    Struct bdk::descriptor::template::P2Wpkh

    source ·
    pub struct P2Wpkh<K: IntoDescriptorKey<Segwitv0>>(pub K);
    Expand description

    P2WPKH template. Expands to a descriptor wpkh(key)

    +

    Example

    +
    use bdk::template::P2Wpkh;
     
    -let key =
    -    bitcoin::PrivateKey::from_wif("cTc4vURSzdx6QE6KVynWGomDbLaA75dNALMNyfjh3p8DRRar84Um")?;
    -let wallet = Wallet::new(
    -    P2Wpkh(key),
    +let key =
    +    bitcoin::PrivateKey::from_wif("cTc4vURSzdx6QE6KVynWGomDbLaA75dNALMNyfjh3p8DRRar84Um")?;
    +let wallet = Wallet::new(
    +    P2Wpkh(key),
         None,
    -    Network::Testnet,
    -    MemoryDatabase::default(),
    +    Network::Testnet,
    +    MemoryDatabase::default(),
     )?;
     
     assert_eq!(
    -    wallet.get_address(New)?.to_string(),
    -    "tb1q4525hmgw265tl3drrl8jjta7ayffu6jf68ltjd"
    -);
    -

    Tuple Fields

    0: K

    Trait Implementations

    Build the complete descriptor

    -

    Auto Trait Implementations

    Blanket Implementations

    Gets the TypeId of self. Read more

    -

    Immutably borrows from an owned value. Read more

    -

    Mutably borrows from an owned value. Read more

    -

    Performs the conversion.

    -

    Performs the conversion.

    -

    Convert to wallet descriptor

    -

    The alignment of pointer.

    -

    The type for initializers.

    -

    Initializes a with the given initializer. Read more

    -

    Dereferences the given pointer. Read more

    -

    Mutably dereferences the given pointer. Read more

    -

    Drops the object pointed to by the given pointer. Read more

    -

    The type returned in the event of a conversion error.

    -

    Performs the conversion.

    -

    The type returned in the event of a conversion error.

    -

    Performs the conversion.

    -
    - \ No newline at end of file + wallet.get_address(New)?.to_string(), + "tb1q4525hmgw265tl3drrl8jjta7ayffu6jf68ltjd" +);
    +

    Tuple Fields§

    §0: K

    Trait Implementations§

    Build the complete descriptor

    Auto Trait Implementations§

    Blanket Implementations§

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

    Returns the argument unchanged.

    +

    Calls U::from(self).

    +

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

    +
    Convert to wallet descriptor
    The alignment of pointer.
    The type for initializers.
    Initializes a with the given initializer. Read more
    Dereferences the given pointer. Read more
    Mutably dereferences the given pointer. Read more
    Drops the object pointed to by the given pointer. Read more
    The type returned in the event of a conversion error.
    Performs the conversion.
    The type returned in the event of a conversion error.
    Performs the conversion.
    \ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/descriptor/template/struct.P2Wpkh_P2Sh.html b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/descriptor/template/struct.P2Wpkh_P2Sh.html index 31f695d4e2..e96636285c 100644 --- a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/descriptor/template/struct.P2Wpkh_P2Sh.html +++ b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/descriptor/template/struct.P2Wpkh_P2Sh.html @@ -1,44 +1,23 @@ -P2Wpkh_P2Sh in bdk::descriptor::template - Rust - -
    pub struct P2Wpkh_P2Sh<K: IntoDescriptorKey<Segwitv0>>(pub K);
    Expand description

    P2WPKH-P2SH template. Expands to a descriptor sh(wpkh(key))

    -

    Example

    -
    use bdk::template::P2Wpkh_P2Sh;
    +P2Wpkh_P2Sh in bdk::descriptor::template - Rust
    pub struct P2Wpkh_P2Sh<K: IntoDescriptorKey<Segwitv0>>(pub K);
    Expand description

    P2WPKH-P2SH template. Expands to a descriptor sh(wpkh(key))

    +

    Example

    +
    use bdk::template::P2Wpkh_P2Sh;
     
    -let key =
    -    bitcoin::PrivateKey::from_wif("cTc4vURSzdx6QE6KVynWGomDbLaA75dNALMNyfjh3p8DRRar84Um")?;
    -let wallet = Wallet::new(
    -    P2Wpkh_P2Sh(key),
    +let key =
    +    bitcoin::PrivateKey::from_wif("cTc4vURSzdx6QE6KVynWGomDbLaA75dNALMNyfjh3p8DRRar84Um")?;
    +let wallet = Wallet::new(
    +    P2Wpkh_P2Sh(key),
         None,
    -    Network::Testnet,
    -    MemoryDatabase::default(),
    +    Network::Testnet,
    +    MemoryDatabase::default(),
     )?;
     
     assert_eq!(
    -    wallet.get_address(New)?.to_string(),
    -    "2NB4ox5VDRw1ecUv6SnT3VQHPXveYztRqk5"
    -);
    -

    Tuple Fields

    0: K

    Trait Implementations

    Build the complete descriptor

    -

    Auto Trait Implementations

    Blanket Implementations

    Gets the TypeId of self. Read more

    -

    Immutably borrows from an owned value. Read more

    -

    Mutably borrows from an owned value. Read more

    -

    Performs the conversion.

    -

    Performs the conversion.

    -

    Convert to wallet descriptor

    -

    The alignment of pointer.

    -

    The type for initializers.

    -

    Initializes a with the given initializer. Read more

    -

    Dereferences the given pointer. Read more

    -

    Mutably dereferences the given pointer. Read more

    -

    Drops the object pointed to by the given pointer. Read more

    -

    The type returned in the event of a conversion error.

    -

    Performs the conversion.

    -

    The type returned in the event of a conversion error.

    -

    Performs the conversion.

    -
    - \ No newline at end of file + wallet.get_address(New)?.to_string(), + "2NB4ox5VDRw1ecUv6SnT3VQHPXveYztRqk5" +);
    +

    Tuple Fields§

    §0: K

    Trait Implementations§

    Build the complete descriptor

    Auto Trait Implementations§

    Blanket Implementations§

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

    Returns the argument unchanged.

    +

    Calls U::from(self).

    +

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

    +
    Convert to wallet descriptor
    The alignment of pointer.
    The type for initializers.
    Initializes a with the given initializer. Read more
    Dereferences the given pointer. Read more
    Mutably dereferences the given pointer. Read more
    Drops the object pointed to by the given pointer. Read more
    The type returned in the event of a conversion error.
    Performs the conversion.
    The type returned in the event of a conversion error.
    Performs the conversion.
    \ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/descriptor/template/trait.DescriptorTemplate.html b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/descriptor/template/trait.DescriptorTemplate.html index 5a02a4ccbf..2d8134b0c2 100644 --- a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/descriptor/template/trait.DescriptorTemplate.html +++ b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/descriptor/template/trait.DescriptorTemplate.html @@ -1,30 +1,22 @@ -DescriptorTemplate in bdk::descriptor::template - Rust - -
    pub trait DescriptorTemplate {
    -    fn build(
            self,
            network: Network
        ) -> Result<DescriptorTemplateOut, DescriptorError>; +DescriptorTemplate in bdk::descriptor::template - Rust
    pub trait DescriptorTemplate {
    +    fn build(
            self,
            network: Network
        ) -> Result<DescriptorTemplateOut, DescriptorError>; }
    Expand description

    Trait for descriptor templates that can be built into a full descriptor

    Since IntoWalletDescriptor is implemented for any DescriptorTemplate, they can also be passed directly to the Wallet constructor.

    -

    Example

    -
    use bdk::descriptor::error::Error as DescriptorError;
    -use bdk::keys::{IntoDescriptorKey, KeyError};
    -use bdk::miniscript::Legacy;
    -use bdk::template::{DescriptorTemplate, DescriptorTemplateOut};
    -use bitcoin::Network;
    +

    Example

    +
    use bdk::descriptor::error::Error as DescriptorError;
    +use bdk::keys::{IntoDescriptorKey, KeyError};
    +use bdk::miniscript::Legacy;
    +use bdk::template::{DescriptorTemplate, DescriptorTemplateOut};
    +use bitcoin::Network;
     
    -struct MyP2PKH<K: IntoDescriptorKey<Legacy>>(K);
    +struct MyP2PKH<K: IntoDescriptorKey<Legacy>>(K);
     
    -impl<K: IntoDescriptorKey<Legacy>> DescriptorTemplate for MyP2PKH<K> {
    -    fn build(self, network: Network) -> Result<DescriptorTemplateOut, DescriptorError> {
    -        Ok(bdk::descriptor!(pkh(self.0))?)
    +impl<K: IntoDescriptorKey<Legacy>> DescriptorTemplate for MyP2PKH<K> {
    +    fn build(self, network: Network) -> Result<DescriptorTemplateOut, DescriptorError> {
    +        Ok(bdk::descriptor!(pkh(self.0))?)
         }
     }
    -

    Required methods

    Build the complete descriptor

    -

    Implementors

    - \ No newline at end of file +

    Required Methods§

    Build the complete descriptor

    +

    Implementors§

    \ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/descriptor/template/type.DescriptorTemplateOut.html b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/descriptor/template/type.DescriptorTemplateOut.html index a23105ed6d..7579f1d4f2 100644 --- a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/descriptor/template/type.DescriptorTemplateOut.html +++ b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/descriptor/template/type.DescriptorTemplateOut.html @@ -1,12 +1,3 @@ -DescriptorTemplateOut in bdk::descriptor::template - Rust - -
    pub type DescriptorTemplateOut = (ExtendedDescriptor, KeyMap, ValidNetworks);
    Expand description

    Type alias for the return type of DescriptorTemplate, descriptor! and others

    -

    Trait Implementations

    Convert to wallet descriptor

    -
    - \ No newline at end of file +DescriptorTemplateOut in bdk::descriptor::template - Rust

    Type Definition bdk::descriptor::template::DescriptorTemplateOut

    source ·
    pub type DescriptorTemplateOut = (ExtendedDescriptor, KeyMap, ValidNetworks);
    Expand description

    Type alias for the return type of DescriptorTemplate, descriptor! and others

    +

    Trait Implementations§

    Convert to wallet descriptor
    \ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/descriptor/trait.ExtractPolicy.html b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/descriptor/trait.ExtractPolicy.html index 9d53692305..5f876566d1 100644 --- a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/descriptor/trait.ExtractPolicy.html +++ b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/descriptor/trait.ExtractPolicy.html @@ -1,14 +1,6 @@ -ExtractPolicy in bdk::descriptor - Rust - -
    pub trait ExtractPolicy {
    -    fn extract_policy(
            &self,
            signers: &SignersContainer,
            psbt: BuildSatisfaction<'_>,
            secp: &Secp256k1<All>
        ) -> Result<Option<Policy>, DescriptorError>; +ExtractPolicy in bdk::descriptor - Rust
    pub trait ExtractPolicy {
    +    fn extract_policy(
            &self,
            signers: &SignersContainer,
            psbt: BuildSatisfaction<'_>,
            secp: &Secp256k1<All>
        ) -> Result<Option<Policy>, DescriptorError>; }
    Expand description

    Trait implemented on Descriptors to add a method to extract the spending policy

    -

    Required methods

    Extract the spending policy

    -

    Implementors

    - \ No newline at end of file +

    Required Methods§

    Extract the spending policy

    +

    Implementors§

    \ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/descriptor/trait.IntoWalletDescriptor.html b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/descriptor/trait.IntoWalletDescriptor.html index ae70c61ade..b977dea5fb 100644 --- a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/descriptor/trait.IntoWalletDescriptor.html +++ b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/descriptor/trait.IntoWalletDescriptor.html @@ -1,16 +1,8 @@ -IntoWalletDescriptor in bdk::descriptor - Rust - -
    pub trait IntoWalletDescriptor {
    -    fn into_wallet_descriptor(
            self,
            secp: &Secp256k1<All>,
            network: Network
        ) -> Result<(ExtendedDescriptor, KeyMap), DescriptorError>; +IntoWalletDescriptor in bdk::descriptor - Rust
    pub trait IntoWalletDescriptor {
    +    fn into_wallet_descriptor(
            self,
            secp: &Secp256k1<All>,
            network: Network
        ) -> Result<(ExtendedDescriptor, KeyMap), DescriptorError>; }
    Expand description

    Trait for types which can be converted into an ExtendedDescriptor and a KeyMap usable by a wallet in a specific [Network]

    -

    Required methods

    Convert to wallet descriptor

    -

    Implementations on Foreign Types

    Implementors

    Turns a DescriptorTemplate into a valid wallet descriptor by calling its +

    Required Methods§

    Convert to wallet descriptor

    +

    Implementations on Foreign Types§

    Implementors§

    - \ No newline at end of file +
    \ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/descriptor/trait.ScriptContext.html b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/descriptor/trait.ScriptContext.html index 6d60b6c570..aaaf313ffc 100644 --- a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/descriptor/trait.ScriptContext.html +++ b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/descriptor/trait.ScriptContext.html @@ -1,45 +1,39 @@ -ScriptContext in bdk::descriptor - Rust - -
    pub trait ScriptContext: Debug + Clone + Ord + PartialOrd<Self> + Eq + PartialEq<Self> + Hash + Sealed {
    -    type Key: ParseableKey + MiniscriptKey;
    -
    Show 15 methods fn check_terminal_non_malleable<Pk>(
            _frag: &Terminal<Pk, Self>
        ) -> Result<(), ScriptContextError>
        where
            Pk: MiniscriptKey
    ; -
    fn max_satisfaction_size<Pk>(ms: &Miniscript<Pk, Self>) -> Option<usize>
        where
            Pk: MiniscriptKey
    ; -
    fn sig_type() -> SigType; -
    fn pk_len<Pk>(pk: &Pk) -> usize
        where
            Pk: MiniscriptKey
    ; -
    fn name_str() -> &'static str; +ScriptContext in bdk::descriptor - Rust
    pub trait ScriptContext: Debug + Clone + Ord + PartialOrd<Self> + Eq + PartialEq<Self> + Hash + Sealed {
    +    type Key: ParseableKey<Sha256 = Hash, Hash256 = Hash, Ripemd160 = Hash, Hash160 = Hash> + MiniscriptKey;
     
    -    fn check_witness<Pk>(
            _witness: &[Vec<u8, Global>]
        ) -> Result<(), ScriptContextError>
        where
            Pk: MiniscriptKey
    , +
    Show 15 methods fn check_terminal_non_malleable<Pk>(
            _frag: &Terminal<Pk, Self>
        ) -> Result<(), ScriptContextError>
        where
            Pk: MiniscriptKey
    ; + fn max_satisfaction_size<Pk>(ms: &Miniscript<Pk, Self>) -> Option<usize>
        where
            Pk: MiniscriptKey
    ; + fn sig_type() -> SigType; + fn pk_len<Pk>(pk: &Pk) -> usize
        where
            Pk: MiniscriptKey
    ; + fn name_str() -> &'static str; + + fn check_witness<Pk>(
            _witness: &[Vec<u8, Global>]
        ) -> Result<(), ScriptContextError>
        where
            Pk: MiniscriptKey
    , { ... } -
    fn check_global_consensus_validity<Pk>(
            _ms: &Miniscript<Pk, Self>
        ) -> Result<(), ScriptContextError>
        where
            Pk: MiniscriptKey
    , + fn check_global_consensus_validity<Pk>(
            _ms: &Miniscript<Pk, Self>
        ) -> Result<(), ScriptContextError>
        where
            Pk: MiniscriptKey
    , { ... } -
    fn check_global_policy_validity<Pk>(
            _ms: &Miniscript<Pk, Self>
        ) -> Result<(), ScriptContextError>
        where
            Pk: MiniscriptKey
    , + fn check_global_policy_validity<Pk>(
            _ms: &Miniscript<Pk, Self>
        ) -> Result<(), ScriptContextError>
        where
            Pk: MiniscriptKey
    , { ... } -
    fn check_local_consensus_validity<Pk>(
            _ms: &Miniscript<Pk, Self>
        ) -> Result<(), ScriptContextError>
        where
            Pk: MiniscriptKey
    , + fn check_local_consensus_validity<Pk>(
            _ms: &Miniscript<Pk, Self>
        ) -> Result<(), ScriptContextError>
        where
            Pk: MiniscriptKey
    , { ... } -
    fn check_local_policy_validity<Pk>(
            _ms: &Miniscript<Pk, Self>
        ) -> Result<(), ScriptContextError>
        where
            Pk: MiniscriptKey
    , + fn check_local_policy_validity<Pk>(
            _ms: &Miniscript<Pk, Self>
        ) -> Result<(), ScriptContextError>
        where
            Pk: MiniscriptKey
    , { ... } -
    fn check_global_validity<Pk>(
            ms: &Miniscript<Pk, Self>
        ) -> Result<(), ScriptContextError>
        where
            Pk: MiniscriptKey
    , + fn check_global_validity<Pk>(
            ms: &Miniscript<Pk, Self>
        ) -> Result<(), ScriptContextError>
        where
            Pk: MiniscriptKey
    , { ... } -
    fn check_local_validity<Pk>(
            ms: &Miniscript<Pk, Self>
        ) -> Result<(), ScriptContextError>
        where
            Pk: MiniscriptKey
    , + fn check_local_validity<Pk>(
            ms: &Miniscript<Pk, Self>
        ) -> Result<(), ScriptContextError>
        where
            Pk: MiniscriptKey
    , { ... } -
    fn top_level_type_check<Pk>(ms: &Miniscript<Pk, Self>) -> Result<(), Error>
        where
            Pk: MiniscriptKey
    , + fn top_level_type_check<Pk>(ms: &Miniscript<Pk, Self>) -> Result<(), Error>
        where
            Pk: MiniscriptKey
    , { ... } -
    fn other_top_level_checks<Pk>(
            _ms: &Miniscript<Pk, Self>
        ) -> Result<(), Error>
        where
            Pk: MiniscriptKey
    , + fn other_top_level_checks<Pk>(
            _ms: &Miniscript<Pk, Self>
        ) -> Result<(), Error>
        where
            Pk: MiniscriptKey
    , { ... } -
    fn top_level_checks<Pk>(ms: &Miniscript<Pk, Self>) -> Result<(), Error>
        where
            Pk: MiniscriptKey
    , + fn top_level_checks<Pk>(ms: &Miniscript<Pk, Self>) -> Result<(), Error>
        where
            Pk: MiniscriptKey
    , { ... }
    }
    Expand description

    The ScriptContext for Miniscript. Additional type information associated with miniscript that is used for carrying out checks that dependent on the context under which the script is used. For example, disallowing uncompressed keys in Segwit context

    -

    Associated Types

    The consensus key associated with the type. Must be a parseable key

    -

    Required methods

    Depending on ScriptContext, fragments can be malleable. For Example, +

    Required Associated Types§

    The consensus key associated with the type. Must be a parseable key

    +

    Required Methods§

    Depending on ScriptContext, fragments can be malleable. For Example, under Legacy context, PkH is malleable because it is possible to estimate the cost of satisfaction because of compressed keys This is currently only used in compiler code for removing malleable @@ -47,17 +41,17 @@ compilations. This does NOT recursively check if the children of the fragment are valid or not. Since the compilation proceeds in a leaf to root fashion, a recursive check is unnecessary.

    -

    Depending on script context, the size of a satifaction witness may slightly differ.

    -

    The type of signature required for satisfaction

    -

    Get the len of public key when serialized based on context +

    Depending on script context, the size of a satifaction witness may slightly differ.

    +

    The type of signature required for satisfaction

    +

    Get the len of public key when serialized based on context Note that this includes the serialization prefix. Returns 34/66 for Bare/Legacy based on key compressedness 34 for Segwitv0, 33 for Tap

    -

    Local helper function to display error messages with context

    -

    Provided methods

    Check whether the given satisfaction is valid under the ScriptContext +

    Local helper function to display error messages with context

    +

    Provided Methods§

    Check whether the given satisfaction is valid under the ScriptContext For example, segwit satisfactions may fail if the witness len is more 3600 or number of stack elements are more than 100.

    -

    Depending on script Context, some of the Terminals might not +

    Depending on script Context, some of the Terminals might not be valid under the current consensus rules. Or some of the script resource limits may have been exceeded. These miniscripts would never be accepted by the Bitcoin network and hence @@ -67,7 +61,7 @@ uncompressed public keys are non-standard and thus invalid. In LegacyP2SH context, scripts above 520 bytes are invalid. Post Tapscript upgrade, this would have to consider other nodes. This does NOT recursively check the miniscript fragments.

    -

    Depending on script Context, some of the script resource limits +

    Depending on script Context, some of the script resource limits may have been exceeded under the current bitcoin core policy rules These miniscripts would never be accepted by the Bitcoin network and hence it is safe to discard them. (unless explicitly disabled by non-standard flag) @@ -75,21 +69,20 @@ For example, in Segwit Context with MiniscriptKey as bitcoin::PublicKey scripts over 3600 bytes are invalid. Post Tapscript upgrade, this would have to consider other nodes. This does NOT recursively check the miniscript fragments.

    -

    Consensus rules at the Miniscript satisfaction time. +

    Consensus rules at the Miniscript satisfaction time. It is possible that some paths of miniscript may exceed resource limits and our current satisfier and lifting analysis would not work correctly. For example, satisfaction path(Legacy/Segwitv0) may require more than 201 opcodes.

    -

    Policy rules at the Miniscript satisfaction time. +

    Policy rules at the Miniscript satisfaction time. It is possible that some paths of miniscript may exceed resource limits and our current satisfier and lifting analysis would not work correctly. For example, satisfaction path in Legacy context scriptSig more than 1650 bytes

    -

    Check the consensus + policy(if not disabled) rules that are not based +

    Check the consensus + policy(if not disabled) rules that are not based satisfaction

    -

    Check the consensus + policy(if not disabled) rules including the +

    Check the consensus + policy(if not disabled) rules including the ones for satisfaction

    -

    Check whether the top-level is type B

    -

    Other top level checks that are context specific

    -

    Check top level consensus rules.

    -

    Implementations on Foreign Types

    Implementors

    - \ No newline at end of file +

    Check whether the top-level is type B

    +

    Other top level checks that are context specific

    +

    Check top level consensus rules.

    +

    Implementors§

    \ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/descriptor/type.DerivedDescriptor.html b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/descriptor/type.DerivedDescriptor.html index 2d709eaaac..8dbc048988 100644 --- a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/descriptor/type.DerivedDescriptor.html +++ b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/descriptor/type.DerivedDescriptor.html @@ -1,11 +1,3 @@ -DerivedDescriptor in bdk::descriptor - Rust - -
    -

    Type Definition bdk::descriptor::DerivedDescriptor

    source · []
    pub type DerivedDescriptor = Descriptor<DefiniteDescriptorKey>;
    Expand description

    Alias for a Descriptor that contains extended derived keys

    -
    - \ No newline at end of file +DerivedDescriptor in bdk::descriptor - Rust

    Type Definition bdk::descriptor::DerivedDescriptor

    source ·
    pub type DerivedDescriptor = Descriptor<DefiniteDescriptorKey>;
    Expand description

    Alias for a Descriptor that contains extended derived keys

    +
    \ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/descriptor/type.ExtendedDescriptor.html b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/descriptor/type.ExtendedDescriptor.html index 5996ad5aca..44cbbbf09c 100644 --- a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/descriptor/type.ExtendedDescriptor.html +++ b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/descriptor/type.ExtendedDescriptor.html @@ -1,12 +1,3 @@ -ExtendedDescriptor in bdk::descriptor - Rust - -
    -

    Type Definition bdk::descriptor::ExtendedDescriptor

    source · []
    pub type ExtendedDescriptor = Descriptor<DescriptorPublicKey>;
    Expand description

    Alias for a Descriptor that can contain extended keys using DescriptorPublicKey

    -

    Trait Implementations

    Convert to wallet descriptor

    -
    - \ No newline at end of file +ExtendedDescriptor in bdk::descriptor - Rust

    Type Definition bdk::descriptor::ExtendedDescriptor

    source ·
    pub type ExtendedDescriptor = Descriptor<DescriptorPublicKey>;
    Expand description

    Alias for a Descriptor that can contain extended keys using DescriptorPublicKey

    +

    Trait Implementations§

    Convert to wallet descriptor
    \ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/descriptor/type.HdKeyPaths.html b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/descriptor/type.HdKeyPaths.html index d4205ec9b8..085e2f1167 100644 --- a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/descriptor/type.HdKeyPaths.html +++ b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/descriptor/type.HdKeyPaths.html @@ -1,12 +1,4 @@ -HdKeyPaths in bdk::descriptor - Rust - -
    -

    Type Definition bdk::descriptor::HdKeyPaths

    source · []
    pub type HdKeyPaths = BTreeMap<PublicKey, KeySource>;
    Expand description

    Alias for the type of maps that represent derivation paths in a psbt::Input or +HdKeyPaths in bdk::descriptor - Rust

    Type Definition bdk::descriptor::HdKeyPaths

    source ·
    pub type HdKeyPaths = BTreeMap<PublicKey, KeySource>;
    Expand description

    Alias for the type of maps that represent derivation paths in a psbt::Input or psbt::Output

    -
    - \ No newline at end of file +
    \ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/descriptor/type.KeyMap.html b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/descriptor/type.KeyMap.html index 37c682747d..d4fbfda5ca 100644 --- a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/descriptor/type.KeyMap.html +++ b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/descriptor/type.KeyMap.html @@ -1,15 +1,7 @@ -KeyMap in bdk::descriptor - Rust - -
    -

    Type Definition bdk::descriptor::KeyMap

    []
    Expand description

    Alias type for a map of public key to secret key

    +KeyMap in bdk::descriptor - Rust

    Type Definition bdk::descriptor::KeyMap

    Expand description

    Alias type for a map of public key to secret key

    This map is returned whenever a descriptor that contains secrets is parsed using Descriptor::parse_descriptor, since the descriptor will always only contain public keys. This map allows looking up the corresponding secret key given a public key from the descriptor.

    -
    - \ No newline at end of file +
    \ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/descriptor/type.TapKeyOrigins.html b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/descriptor/type.TapKeyOrigins.html index 6521a88838..1a142aa271 100644 --- a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/descriptor/type.TapKeyOrigins.html +++ b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/descriptor/type.TapKeyOrigins.html @@ -1,12 +1,4 @@ -TapKeyOrigins in bdk::descriptor - Rust - -
    -

    Type Definition bdk::descriptor::TapKeyOrigins

    source · []
    pub type TapKeyOrigins = BTreeMap<XOnlyPublicKey, (Vec<TapLeafHash>, KeySource)>;
    Expand description

    Alias for the type of maps that represent taproot key origins in a psbt::Input or +TapKeyOrigins in bdk::descriptor - Rust

    Type Definition bdk::descriptor::TapKeyOrigins

    source ·
    pub type TapKeyOrigins = BTreeMap<XOnlyPublicKey, (Vec<TapLeafHash>, KeySource)>;
    Expand description

    Alias for the type of maps that represent taproot key origins in a psbt::Input or psbt::Output

    -
    - \ No newline at end of file +
    \ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/enum.Error.html b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/enum.Error.html index 58d4545e3e..215d1d4e4e 100644 --- a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/enum.Error.html +++ b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/enum.Error.html @@ -1,12 +1,5 @@ -Error in bdk - Rust - -
    -

    Enum bdk::Error

    source · []
    pub enum Error {
    +Error in bdk - Rust

    Enum bdk::Error

    source ·
    pub enum Error {
     
    Show 44 variants InvalidU32Bytes(Vec<u8>), Generic(String), ScriptDoesntHaveAddressForm, @@ -62,103 +55,64 @@ Rpc(Error), Rusqlite(Error),
    }
    Expand description

    Errors that can be thrown by the Wallet

    -

    Variants

    InvalidU32Bytes(Vec<u8>)

    Wrong number of bytes found when trying to convert to u32

    -

    Generic(String)

    Generic error

    -

    ScriptDoesntHaveAddressForm

    This error is thrown when trying to convert Bare and Public key script to address

    -

    NoRecipients

    Cannot build a tx without recipients

    -

    NoUtxosSelected

    manually_selected_only option is selected but no utxo has been passed

    -

    OutputBelowDustLimit(usize)

    Output created is under the dust limit, 546 satoshis

    -

    InsufficientFunds

    Fields

    needed: u64

    Sats needed for some transaction

    -
    available: u64

    Sats available for spending

    +

    Variants§

    §

    InvalidU32Bytes(Vec<u8>)

    Wrong number of bytes found when trying to convert to u32

    +
    §

    Generic(String)

    Generic error

    +
    §

    ScriptDoesntHaveAddressForm

    This error is thrown when trying to convert Bare and Public key script to address

    +
    §

    NoRecipients

    Cannot build a tx without recipients

    +
    §

    NoUtxosSelected

    manually_selected_only option is selected but no utxo has been passed

    +
    §

    OutputBelowDustLimit(usize)

    Output created is under the dust limit, 546 satoshis

    +
    §

    InsufficientFunds

    Fields

    §needed: u64

    Sats needed for some transaction

    +
    §available: u64

    Sats available for spending

    Wallet’s UTXO set is not enough to cover recipient’s requested plus fee

    -

    BnBTotalTriesExceeded

    Branch and bound coin selection possible attempts with sufficiently big UTXO set could grow +

    §

    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

    -

    BnBNoExactMatch

    Branch and bound coin selection tries to avoid needing a change by finding the right inputs for +

    §

    BnBNoExactMatch

    Branch and bound coin selection tries to avoid needing a change by finding the right inputs for the desired outputs plus fee, if there is not such combination this error is thrown

    -

    UnknownUtxo

    Happens when trying to spend an UTXO that is not in the internal database

    -

    TransactionNotFound

    Thrown when a tx is not found in the internal database

    -

    TransactionConfirmed

    Happens when trying to bump a transaction that is already confirmed

    -

    IrreplaceableTransaction

    Trying to replace a tx that has a sequence >= 0xFFFFFFFE

    -

    FeeRateTooLow

    Fields

    required: FeeRate

    Required fee rate (satoshi/vbyte)

    +
    §

    UnknownUtxo

    Happens when trying to spend an UTXO that is not in the internal database

    +
    §

    TransactionNotFound

    Thrown when a tx is not found in the internal database

    +
    §

    TransactionConfirmed

    Happens when trying to bump a transaction that is already confirmed

    +
    §

    IrreplaceableTransaction

    Trying to replace a tx that has a sequence >= 0xFFFFFFFE

    +
    §

    FeeRateTooLow

    Fields

    §required: FeeRate

    Required fee rate (satoshi/vbyte)

    When bumping a tx the fee rate requested is lower than required

    -

    FeeTooLow

    Fields

    required: u64

    Required fee absolute value (satoshi)

    +
    §

    FeeTooLow

    Fields

    §required: u64

    Required fee absolute value (satoshi)

    When bumping a tx the absolute fee requested is lower than replaced tx absolute fee

    -

    FeeRateUnavailable

    Node doesn’t have data to estimate a fee rate

    -

    MissingKeyOrigin(String)

    In order to use the TxBuilder::add_global_xpubs option every extended +

    §

    FeeRateUnavailable

    Node doesn’t have data to estimate a fee rate

    +
    §

    MissingKeyOrigin(String)

    In order to use the TxBuilder::add_global_xpubs option every extended key in the descriptor must either be a master key itself (having depth = 0) or have an explicit origin provided

    -

    Key(KeyError)

    Error while working with keys

    -

    ChecksumMismatch

    Descriptor checksum mismatch

    -

    SpendingPolicyRequired(KeychainKind)

    Spending policy is not compatible with this KeychainKind

    -

    InvalidPolicyPathError(PolicyError)

    Error while extracting and manipulating policies

    -

    Signer(SignerError)

    Signing error

    -

    InvalidNetwork

    Fields

    requested: Network

    requested network, for example what is given as bdk-cli option

    -
    found: Network

    found network, for example the network of the bitcoin node

    +
    §

    Key(KeyError)

    Error while working with keys

    +
    §

    ChecksumMismatch

    Descriptor checksum mismatch

    +
    §

    SpendingPolicyRequired(KeychainKind)

    Spending policy is not compatible with this KeychainKind

    +
    §

    InvalidPolicyPathError(PolicyError)

    Error while extracting and manipulating policies

    +
    §

    Signer(SignerError)

    Signing error

    +
    §

    InvalidNetwork

    Fields

    §requested: Network

    requested network, for example what is given as bdk-cli option

    +
    §found: Network

    found network, for example the network of the bitcoin node

    Invalid network

    -

    Verification(VerifyError)

    Transaction verification error

    -

    InvalidProgressValue(f32)

    Progress value must be between 0.0 (included) and 100.0 (included)

    -

    ProgressUpdateError

    Progress update error (maybe the channel has been closed)

    -

    InvalidOutpoint(OutPoint)

    Requested outpoint doesn’t exist in the tx (vout greater than available outputs)

    -

    Descriptor(Error)

    Error related to the parsing and usage of descriptors

    -

    Encode(Error)

    Encoding error

    -

    Miniscript(Error)

    Miniscript error

    -

    MiniscriptPsbt(MiniscriptPsbtError)

    Miniscript PSBT error

    -

    Bip32(Error)

    BIP32 error

    -

    Secp256k1(Error)

    An ECDSA error

    -

    Json(Error)

    Error serializing or deserializing JSON data

    -

    Hex(Error)

    Hex decoding error

    -

    Psbt(Error)

    Partially signed bitcoin transaction error

    -

    PsbtParse(PsbtParseError)

    Partially signed bitcoin transaction parse error

    -

    MissingCachedScripts(MissingCachedScripts)

    crate::blockchain::WalletSync sync attempt failed due to missing scripts in cache which +

    §

    Verification(VerifyError)

    Transaction verification error

    +
    §

    InvalidProgressValue(f32)

    Progress value must be between 0.0 (included) and 100.0 (included)

    +
    §

    ProgressUpdateError

    Progress update error (maybe the channel has been closed)

    +
    §

    InvalidOutpoint(OutPoint)

    Requested outpoint doesn’t exist in the tx (vout greater than available outputs)

    +
    §

    Descriptor(Error)

    Error related to the parsing and usage of descriptors

    +
    §

    Encode(Error)

    Encoding error

    +
    §

    Miniscript(Error)

    Miniscript error

    +
    §

    MiniscriptPsbt(MiniscriptPsbtError)

    Miniscript PSBT error

    +
    §

    Bip32(Error)

    BIP32 error

    +
    §

    Secp256k1(Error)

    An ECDSA error

    +
    §

    Json(Error)

    Error serializing or deserializing JSON data

    +
    §

    Hex(Error)

    Hex decoding error

    +
    §

    Psbt(Error)

    Partially signed bitcoin transaction error

    +
    §

    PsbtParse(PsbtParseError)

    Partially signed bitcoin transaction parse error

    +
    §

    MissingCachedScripts(MissingCachedScripts)

    crate::blockchain::WalletSync sync attempt failed due to missing scripts in cache which are needed to satisfy stop_gap.

    -

    Electrum(Error)

    Electrum client error

    -

    Esplora(Box<EsploraError>)

    Esplora client error

    -

    CompactFilters(CompactFiltersError)

    Compact filters client error)

    -

    Sled(Error)

    Sled database error

    -

    Rpc(Error)

    Rpc client error

    -

    Rusqlite(Error)

    Rusqlite client error

    -

    Trait Implementations

    Formats the value using the given formatter. Read more

    -

    Formats the value using the given formatter. Read more

    -

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

    -
    🔬 This is a nightly-only experimental API. (backtrace)

    Returns a stack backtrace, if available, of where this error occurred. Read more

    -
    👎 Deprecated since 1.42.0:

    use the Display impl or to_string()

    -
    👎 Deprecated since 1.33.0:

    replaced by Error::source, which can support downcasting

    -

    Performs the conversion.

    -

    Performs the conversion.

    -

    Performs the conversion.

    -

    Performs the conversion.

    -

    Performs the conversion.

    -

    Performs the conversion.

    -

    Performs the conversion.

    -

    Performs the conversion.

    -

    Performs the conversion.

    -

    Performs the conversion.

    -

    Performs the conversion.

    -

    Performs the conversion.

    -

    Performs the conversion.

    -

    Performs the conversion.

    -

    Performs the conversion.

    -

    Performs the conversion.

    -

    Performs the conversion.

    -

    Performs the conversion.

    -

    Performs the conversion.

    -

    Performs the conversion.

    -

    Performs the conversion.

    -

    Auto Trait Implementations

    Blanket Implementations

    Gets the TypeId of self. Read more

    -

    Immutably borrows from an owned value. Read more

    -

    Mutably borrows from an owned value. Read more

    -

    Performs the conversion.

    -

    Performs the conversion.

    -

    The alignment of pointer.

    -

    The type for initializers.

    -

    Initializes a with the given initializer. Read more

    -

    Dereferences the given pointer. Read more

    -

    Mutably dereferences the given pointer. Read more

    -

    Drops the object pointed to by the given pointer. Read more

    -

    Converts the given value to a String. Read more

    -

    The type returned in the event of a conversion error.

    -

    Performs the conversion.

    -

    The type returned in the event of a conversion error.

    -

    Performs the conversion.

    -
    - \ No newline at end of file +
    §

    Electrum(Error)

    Electrum client error

    +
    §

    Esplora(Box<EsploraError>)

    Esplora client error

    +
    §

    CompactFilters(CompactFiltersError)

    Compact filters client error)

    +
    §

    Sled(Error)

    Sled database error

    +
    §

    Rpc(Error)

    Rpc client error

    +
    §

    Rusqlite(Error)

    Rusqlite client error

    +

    Trait Implementations§

    Formats the value using the given formatter. Read more
    Formats the value using the given formatter. Read more
    The lower-level source of this error, if any. Read more
    👎Deprecated since 1.42.0: use the Display impl or to_string()
    👎Deprecated since 1.33.0: replaced by Error::source, which can support downcasting
    🔬This is a nightly-only experimental API. (error_generic_member_access)
    Provides type based access to context intended for error reports. Read more
    Converts to this type from the input type.
    Converts to this type from the input type.
    Converts to this type from the input type.
    Converts to this type from the input type.
    Converts to this type from the input type.
    Converts to this type from the input type.
    Converts to this type from the input type.
    Converts to this type from the input type.
    Converts to this type from the input type.
    Converts to this type from the input type.
    Converts to this type from the input type.
    Converts to this type from the input type.
    Converts to this type from the input type.
    Converts to this type from the input type.
    Converts to this type from the input type.
    Converts to this type from the input type.
    Converts to this type from the input type.
    Converts to this type from the input type.
    Converts to this type from the input type.
    Converts to this type from the input type.
    Converts to this type from the input type.

    Auto Trait Implementations§

    Blanket Implementations§

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

    Returns the argument unchanged.

    +

    Calls U::from(self).

    +

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

    +
    The alignment of pointer.
    The type for initializers.
    Initializes a with the given initializer. Read more
    Dereferences the given pointer. Read more
    Mutably dereferences the given pointer. Read more
    Drops the object pointed to by the given pointer. Read more
    🔬This is a nightly-only experimental API. (provide_any)
    Data providers should implement this method to provide all values they are able to +provide by using demand. Read more
    Converts the given value to a String. Read more
    The type returned in the event of a conversion error.
    Performs the conversion.
    The type returned in the event of a conversion error.
    Performs the conversion.
    \ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/enum.KeychainKind.html b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/enum.KeychainKind.html index 0853e35b5d..dfedf907a4 100644 --- a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/enum.KeychainKind.html +++ b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/enum.KeychainKind.html @@ -1,52 +1,16 @@ -KeychainKind in bdk - Rust - -
    pub enum KeychainKind {
    +KeychainKind in bdk - Rust

    Enum bdk::KeychainKind

    source ·
    pub enum KeychainKind {
         External,
         Internal,
     }
    Expand description

    Types of keychains

    -

    Variants

    External

    External

    -

    Internal

    Internal, usually used for change outputs

    -

    Implementations

    Return KeychainKind as a byte

    -

    Trait Implementations

    Performs the conversion.

    -

    Returns a copy of the value. Read more

    -

    Performs copy-assignment from source. Read more

    -

    Formats the value using the given formatter. Read more

    -

    Deserialize this value from the given Serde deserializer. Read more

    -

    Feeds this value into the given Hasher. Read more

    -

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

    -

    This method tests for self and other values to be equal, and is used -by ==. Read more

    -

    This method tests for !=.

    -

    Serialize this value into the given Serde serializer. Read more

    -

    Auto Trait Implementations

    Blanket Implementations

    Gets the TypeId of self. Read more

    -

    Calculate the base32 serialized length

    -

    Immutably borrows from an owned value. Read more

    -

    Mutably borrows from an owned value. Read more

    -

    Error type if conversion fails

    -

    Check if all values are in range and return array-like struct of u5 values

    -

    Performs the conversion.

    -

    Performs the conversion.

    -

    The alignment of pointer.

    -

    The type for initializers.

    -

    Initializes a with the given initializer. Read more

    -

    Dereferences the given pointer. Read more

    -

    Mutably dereferences the given pointer. Read more

    -

    Drops the object pointed to by the given pointer. Read more

    -

    Encode as base32 and write it to the supplied writer -Implementations shouldn’t allocate. Read more

    -

    Convert Self to base32 vector

    -

    The resulting type after obtaining ownership.

    -

    Creates owned data from borrowed data, usually by cloning. Read more

    -
    🔬 This is a nightly-only experimental API. (toowned_clone_into)

    Uses borrowed data to replace owned data, usually by cloning. Read more

    -

    The type returned in the event of a conversion error.

    -

    Performs the conversion.

    -

    The type returned in the event of a conversion error.

    -

    Performs the conversion.

    -
    - \ No newline at end of file +

    Variants§

    §

    External

    External

    +
    §

    Internal

    Internal, usually used for change outputs

    +

    Implementations§

    Return KeychainKind as a byte

    +

    Trait Implementations§

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

    Auto Trait Implementations§

    Blanket Implementations§

    Gets the TypeId of self. Read more
    Calculate the base32 serialized length
    Immutably borrows from an owned value. Read more
    Mutably borrows from an owned value. Read more
    Error type if conversion fails
    Check if all values are in range and return array-like struct of u5 values

    Returns the argument unchanged.

    +

    Calls U::from(self).

    +

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

    +
    The alignment of pointer.
    The type for initializers.
    Initializes a with the given initializer. Read more
    Dereferences the given pointer. Read more
    Mutably dereferences the given pointer. Read more
    Drops the object pointed to by the given pointer. Read more
    Encode as base32 and write it to the supplied writer +Implementations shouldn’t allocate. Read more
    Convert Self to base32 vector
    The resulting type after obtaining ownership.
    Creates owned data from borrowed data, usually by cloning. Read more
    Uses borrowed data to replace owned data, usually by cloning. Read more
    The type returned in the event of a conversion error.
    Performs the conversion.
    The type returned in the event of a conversion error.
    Performs the conversion.
    \ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/enum.Utxo.html b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/enum.Utxo.html index a7142a1613..77381f247e 100644 --- a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/enum.Utxo.html +++ b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/enum.Utxo.html @@ -1,47 +1,21 @@ -Utxo in bdk - Rust - -
    -

    Enum bdk::Utxo

    source · []
    pub enum Utxo {
    +Utxo in bdk - Rust

    Enum bdk::Utxo

    source ·
    pub enum Utxo {
         Local(LocalUtxo),
         Foreign {
             outpoint: OutPoint,
             psbt_input: Box<Input>,
         },
     }
    Expand description

    An unspent transaction output (UTXO).

    -

    Variants

    Local(LocalUtxo)

    A UTXO owned by the local wallet.

    -

    Foreign

    Fields

    outpoint: OutPoint

    The location of the output.

    -
    psbt_input: Box<Input>

    The information about the input we require to add it to a PSBT.

    +

    Variants§

    §

    Local(LocalUtxo)

    A UTXO owned by the local wallet.

    +
    §

    Foreign

    Fields

    §outpoint: OutPoint

    The location of the output.

    +
    §psbt_input: Box<Input>

    The information about the input we require to add it to a PSBT.

    A UTXO owned by another wallet.

    -

    Implementations

    Get the location of the UTXO

    -

    Get the TxOut of the UTXO

    -

    Trait Implementations

    Returns a copy of the value. Read more

    -

    Performs copy-assignment from source. Read more

    -

    Formats the value using the given formatter. Read more

    -

    This method tests for self and other values to be equal, and is used -by ==. Read more

    -

    This method tests for !=.

    -

    Auto Trait Implementations

    Blanket Implementations

    Gets the TypeId of self. Read more

    -

    Immutably borrows from an owned value. Read more

    -

    Mutably borrows from an owned value. Read more

    -

    Performs the conversion.

    -

    Performs the conversion.

    -

    The alignment of pointer.

    -

    The type for initializers.

    -

    Initializes a with the given initializer. Read more

    -

    Dereferences the given pointer. Read more

    -

    Mutably dereferences the given pointer. Read more

    -

    Drops the object pointed to by the given pointer. Read more

    -

    The resulting type after obtaining ownership.

    -

    Creates owned data from borrowed data, usually by cloning. Read more

    -
    🔬 This is a nightly-only experimental API. (toowned_clone_into)

    Uses borrowed data to replace owned data, usually by cloning. Read more

    -

    The type returned in the event of a conversion error.

    -

    Performs the conversion.

    -

    The type returned in the event of a conversion error.

    -

    Performs the conversion.

    -
    - \ No newline at end of file +

    Implementations§

    Get the location of the UTXO

    +

    Get the TxOut of the UTXO

    +

    Trait Implementations§

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

    Auto Trait Implementations§

    Blanket Implementations§

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

    Returns the argument unchanged.

    +

    Calls U::from(self).

    +

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

    +
    The alignment of pointer.
    The type for initializers.
    Initializes a with the given initializer. Read more
    Dereferences the given pointer. Read more
    Mutably dereferences the given pointer. Read more
    Drops the object pointed to by the given pointer. Read more
    The resulting type after obtaining ownership.
    Creates owned data from borrowed data, usually by cloning. Read more
    Uses borrowed data to replace owned data, usually by cloning. Read more
    The type returned in the event of a conversion error.
    Performs the conversion.
    The type returned in the event of a conversion error.
    Performs the conversion.
    \ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/fn.version.html b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/fn.version.html index 26d058bd84..cc5777496c 100644 --- a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/fn.version.html +++ b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/fn.version.html @@ -1,11 +1,3 @@ -version in bdk - Rust - -
    -

    Function bdk::version

    source · []
    pub fn version() -> &'static str
    Expand description

    Get the version of BDK at runtime

    -
    - \ No newline at end of file +version in bdk - Rust

    Function bdk::version

    source ·
    pub fn version() -> &'static str
    Expand description

    Get the version of BDK at runtime

    +
    \ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/index.html b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/index.html index 6d1aacab5d..468838c4ab 100644 --- a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/index.html +++ b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/index.html @@ -1,13 +1,6 @@ -bdk - Rust - -
    -

    Crate bdk

    source · []
    Expand description

    A modern, lightweight, descriptor-based wallet library written in Rust.

    -

    About

    +bdk - Rust

    Crate bdk

    source ·
    Expand description

    A modern, lightweight, descriptor-based wallet library written in Rust.

    +

    About

    The BDK library aims to be the core building block for Bitcoin wallets of any kind.

    • It uses Miniscript to support descriptors with generalized conditions. This exact same library can be used to build @@ -16,7 +9,7 @@ single-sig wallets, multisigs, timelocked contracts and more.
    • It is built to be cross-platform: the core logic works on desktop, mobile, and even WebAssembly.
    • It is very easy to extend: developers can implement customized logic for blockchain backends, databases, signers, coin selection, and more, without having to fork and modify this library.
    -

    A Tour of BDK

    +

    A Tour of BDK

    BDK consists of a number of modules that provide a range of functionality essential for implementing descriptor based Bitcoin wallet applications in Rust. In this section, we will take a brief tour of BDK, summarizing the major APIs and @@ -25,108 +18,108 @@ their uses.

    The default features include a simple key-value database (sled) to cache blockchain data and an electrum blockchain client to interact with the bitcoin P2P network.

    -

    Examples

    Sync the balance of a descriptor

    -
    use bdk::{Wallet, SyncOptions};
    -use bdk::database::MemoryDatabase;
    -use bdk::blockchain::ElectrumBlockchain;
    -use bdk::electrum_client::Client;
    -
    -fn main() -> Result<(), bdk::Error> {
    -    let client = Client::new("ssl://electrum.blockstream.info:60002")?;
    -    let blockchain = ElectrumBlockchain::from(client);
    -    let wallet = Wallet::new(
    +

    Examples

    Sync the balance of a descriptor

    +
    use bdk::{Wallet, SyncOptions};
    +use bdk::database::MemoryDatabase;
    +use bdk::blockchain::ElectrumBlockchain;
    +use bdk::electrum_client::Client;
    +
    +fn main() -> Result<(), bdk::Error> {
    +    let client = Client::new("ssl://electrum.blockstream.info:60002")?;
    +    let blockchain = ElectrumBlockchain::from(client);
    +    let wallet = Wallet::new(
             "wpkh([c258d2e4/84h/1h/0h]tpubDDYkZojQFQjht8Tm4jsS3iuEmKjTiEGjG6KnuFNKKJb5A6ZUCUZKdvLdSDWofKi4ToRCwb9poe1XdqfUnP4jaJjCB2Zwv11ZLgSbnZSNecE/0/*)",
             Some("wpkh([c258d2e4/84h/1h/0h]tpubDDYkZojQFQjht8Tm4jsS3iuEmKjTiEGjG6KnuFNKKJb5A6ZUCUZKdvLdSDWofKi4ToRCwb9poe1XdqfUnP4jaJjCB2Zwv11ZLgSbnZSNecE/1/*)"),
    -        bitcoin::Network::Testnet,
    -        MemoryDatabase::default(),
    +        bitcoin::Network::Testnet,
    +        MemoryDatabase::default(),
         )?;
     
    -    wallet.sync(&blockchain, SyncOptions::default())?;
    +    wallet.sync(&blockchain, SyncOptions::default())?;
     
    -    println!("Descriptor balance: {} SAT", wallet.get_balance()?);
    +    println!("Descriptor balance: {} SAT", wallet.get_balance()?);
     
         Ok(())
     }
    -

    Generate a few addresses

    Example

    -
    use bdk::{Wallet};
    -use bdk::database::MemoryDatabase;
    -use bdk::wallet::AddressIndex::New;
    +

    Generate a few addresses

    Example

    +
    use bdk::{Wallet};
    +use bdk::database::MemoryDatabase;
    +use bdk::wallet::AddressIndex::New;
     
    -fn main() -> Result<(), bdk::Error> {
    -let wallet = Wallet::new(
    +fn main() -> Result<(), bdk::Error> {
    +let wallet = Wallet::new(
             "wpkh([c258d2e4/84h/1h/0h]tpubDDYkZojQFQjht8Tm4jsS3iuEmKjTiEGjG6KnuFNKKJb5A6ZUCUZKdvLdSDWofKi4ToRCwb9poe1XdqfUnP4jaJjCB2Zwv11ZLgSbnZSNecE/0/*)",
             Some("wpkh([c258d2e4/84h/1h/0h]tpubDDYkZojQFQjht8Tm4jsS3iuEmKjTiEGjG6KnuFNKKJb5A6ZUCUZKdvLdSDWofKi4ToRCwb9poe1XdqfUnP4jaJjCB2Zwv11ZLgSbnZSNecE/1/*)"),
    -        bitcoin::Network::Testnet,
    -        MemoryDatabase::default(),
    +        bitcoin::Network::Testnet,
    +        MemoryDatabase::default(),
         )?;
     
    -    println!("Address #0: {}", wallet.get_address(New)?);
    -    println!("Address #1: {}", wallet.get_address(New)?);
    -    println!("Address #2: {}", wallet.get_address(New)?);
    +    println!("Address #0: {}", wallet.get_address(New)?);
    +    println!("Address #1: {}", wallet.get_address(New)?);
    +    println!("Address #2: {}", wallet.get_address(New)?);
     
         Ok(())
     }
    -

    Create a transaction

    -
    use bdk::{FeeRate, Wallet, SyncOptions};
    -use bdk::database::MemoryDatabase;
    -use bdk::blockchain::ElectrumBlockchain;
    -use bdk::electrum_client::Client;
    -
    -use bitcoin::consensus::serialize;
    -use bdk::wallet::AddressIndex::New;
    -
    -fn main() -> Result<(), bdk::Error> {
    -    let client = Client::new("ssl://electrum.blockstream.info:60002")?;
    -    let wallet = Wallet::new(
    +

    Create a transaction

    +
    use bdk::{FeeRate, Wallet, SyncOptions};
    +use bdk::database::MemoryDatabase;
    +use bdk::blockchain::ElectrumBlockchain;
    +use bdk::electrum_client::Client;
    +
    +use bitcoin::consensus::serialize;
    +use bdk::wallet::AddressIndex::New;
    +
    +fn main() -> Result<(), bdk::Error> {
    +    let client = Client::new("ssl://electrum.blockstream.info:60002")?;
    +    let wallet = Wallet::new(
             "wpkh([c258d2e4/84h/1h/0h]tpubDDYkZojQFQjht8Tm4jsS3iuEmKjTiEGjG6KnuFNKKJb5A6ZUCUZKdvLdSDWofKi4ToRCwb9poe1XdqfUnP4jaJjCB2Zwv11ZLgSbnZSNecE/0/*)",
             Some("wpkh([c258d2e4/84h/1h/0h]tpubDDYkZojQFQjht8Tm4jsS3iuEmKjTiEGjG6KnuFNKKJb5A6ZUCUZKdvLdSDWofKi4ToRCwb9poe1XdqfUnP4jaJjCB2Zwv11ZLgSbnZSNecE/1/*)"),
    -        bitcoin::Network::Testnet,
    -        MemoryDatabase::default(),
    +        bitcoin::Network::Testnet,
    +        MemoryDatabase::default(),
         )?;
    -    let blockchain = ElectrumBlockchain::from(client);
    +    let blockchain = ElectrumBlockchain::from(client);
     
    -    wallet.sync(&blockchain, SyncOptions::default())?;
    +    wallet.sync(&blockchain, SyncOptions::default())?;
     
    -    let send_to = wallet.get_address(New)?;
    -    let (psbt, details) = {
    -        let mut builder =  wallet.build_tx();
    -        builder
    -            .add_recipient(send_to.script_pubkey(), 50_000)
    -            .enable_rbf()
    -            .do_not_spend_change()
    -            .fee_rate(FeeRate::from_sat_per_vb(5.0));
    -        builder.finish()?
    -    };
    +    let send_to = wallet.get_address(New)?;
    +    let (psbt, details) = {
    +        let mut builder =  wallet.build_tx();
    +        builder
    +            .add_recipient(send_to.script_pubkey(), 50_000)
    +            .enable_rbf()
    +            .do_not_spend_change()
    +            .fee_rate(FeeRate::from_sat_per_vb(5.0));
    +        builder.finish()?
    +    };
     
    -    println!("Transaction details: {:#?}", details);
    -    println!("Unsigned PSBT: {}", &psbt);
    +    println!("Transaction details: {:#?}", details);
    +    println!("Unsigned PSBT: {}", &psbt);
     
         Ok(())
     }
    -

    Sign a transaction

    -
    use std::str::FromStr;
    +

    Sign a transaction

    +
    use std::str::FromStr;
     
    -use bitcoin::util::psbt::PartiallySignedTransaction as Psbt;
    +use bitcoin::util::psbt::PartiallySignedTransaction as Psbt;
     
    -use bdk::{Wallet, SignOptions};
    -use bdk::database::MemoryDatabase;
    +use bdk::{Wallet, SignOptions};
    +use bdk::database::MemoryDatabase;
     
    -fn main() -> Result<(), bdk::Error> {
    -    let wallet = Wallet::new(
    +fn main() -> Result<(), bdk::Error> {
    +    let wallet = Wallet::new(
             "wpkh([c258d2e4/84h/1h/0h]tprv8griRPhA7342zfRyB6CqeKF8CJDXYu5pgnj1cjL1u2ngKcJha5jjTRimG82ABzJQ4MQe71CV54xfn25BbhCNfEGGJZnxvCDQCd6JkbvxW6h/0/*)",
             Some("wpkh([c258d2e4/84h/1h/0h]tprv8griRPhA7342zfRyB6CqeKF8CJDXYu5pgnj1cjL1u2ngKcJha5jjTRimG82ABzJQ4MQe71CV54xfn25BbhCNfEGGJZnxvCDQCd6JkbvxW6h/1/*)"),
    -        bitcoin::Network::Testnet,
    -        MemoryDatabase::default(),
    +        bitcoin::Network::Testnet,
    +        MemoryDatabase::default(),
         )?;
     
    -    let psbt = "...";
    -    let mut psbt = Psbt::from_str(psbt)?;
    +    let psbt = "...";
    +    let mut psbt = Psbt::from_str(psbt)?;
     
    -    let finalized = wallet.sign(&mut psbt, SignOptions::default())?;
    +    let finalized = wallet.sign(&mut psbt, SignOptions::default())?;
     
         Ok(())
     }
    -

    Feature flags

    +

    Feature flags

    BDK uses a set of feature flags to reduce the amount of compiled code by allowing projects to only enable the features they need. By default, BDK enables two internal features, key-value-db and electrum.

    @@ -139,7 +132,7 @@ Below is a list of the available feature flags and the additional functionality
  • async-interface: async functions in bdk traits
  • keys-bip39: BIP-39 mnemonic codes for generating deterministic keys
  • -

    Internal features

    +

    Internal features

    These features do not expose any new API, but influence internal implementation aspects of BDK.

      @@ -148,33 +141,4 @@ BDK.

    • esplora: esplora client protocol for interacting with blockstream electrs servers
    • key-value-db: key value database based on sled for caching blockchain data
    -

    Re-exports

    -
    pub extern crate bitcoin;
    pub extern crate bitcoincore_rpc;
    pub extern crate electrum_client;
    pub extern crate esplora_client;
    pub extern crate hwi;
    pub extern crate miniscript;
    pub extern crate rusqlite;
    pub extern crate sled;
    pub use descriptor::template;
    pub use descriptor::HdKeyPaths;
    pub use wallet::signer;
    pub use wallet::signer::SignOptions;
    pub use wallet::tx_builder::TxBuilder;
    pub use wallet::SyncOptions;
    pub use wallet::Wallet;

    Modules

    -

    Blockchain backends

    -

    Database types

    -

    Descriptors

    -

    Key formats

    -

    Additional functions on the rust-bitcoin PartiallySignedTransaction structure.

    -

    Wallet

    -

    Macros

    -

    Macro to write full descriptors with code

    -

    Macro to write descriptor fragments with code

    -

    Structs

    -

    Balance differentiated in various categories

    -

    Block height and timestamp of a block

    -

    Fee rate

    -

    An unspent output owned by a Wallet.

    -

    A wallet transaction

    -

    A Utxo with its satisfaction_weight.

    -

    Enums

    -

    Errors that can be thrown by the Wallet

    -

    Types of keychains

    -

    An unspent transaction output (UTXO).

    -

    Traits

    -

    Trait implemented by types that can be used to measure weight units.

    -

    Functions

    -

    Get the version of BDK at runtime

    -

    Type Definitions

    -

    DEPRECATED: Confirmation time of a transaction

    -
    - \ No newline at end of file +

    Re-exports

    pub extern crate bitcoin;
    pub extern crate bitcoincore_rpc;
    pub extern crate electrum_client;
    pub extern crate esplora_client;
    pub extern crate hwi;
    pub extern crate miniscript;
    pub extern crate rusqlite;
    pub extern crate sled;
    pub use descriptor::template;
    pub use descriptor::HdKeyPaths;
    pub use wallet::signer;
    pub use wallet::signer::SignOptions;
    pub use wallet::tx_builder::TxBuilder;
    pub use wallet::SyncOptions;
    pub use wallet::Wallet;

    Modules

    Blockchain backends
    Database types
    Descriptors
    Key formats
    Additional functions on the rust-bitcoin PartiallySignedTransaction structure.
    Wallet

    Macros

    Macro to write full descriptors with code
    Macro to write descriptor fragments with code

    Structs

    Balance differentiated in various categories
    Block height and timestamp of a block
    Fee rate
    An unspent output owned by a Wallet.
    A wallet transaction
    A Utxo with its satisfaction_weight.

    Enums

    Errors that can be thrown by the Wallet
    Types of keychains
    An unspent transaction output (UTXO).

    Traits

    Trait implemented by types that can be used to measure weight units.

    Functions

    Get the version of BDK at runtime

    Type Definitions

    DEPRECATED: Confirmation time of a transaction
    \ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/keys/bip39/enum.Error.html b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/keys/bip39/enum.Error.html index e0749370e7..bae2a50aa4 100644 --- a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/keys/bip39/enum.Error.html +++ b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/keys/bip39/enum.Error.html @@ -1,56 +1,25 @@ -Error in bdk::keys::bip39 - Rust - -
    pub enum Error {
    +Error in bdk::keys::bip39 - Rust

    Enum bdk::keys::bip39::Error

    pub enum Error {
         BadWordCount(usize),
         UnknownWord(usize),
         BadEntropyBitCount(usize),
         InvalidChecksum,
         AmbiguousLanguages(AmbiguousLanguages),
    -}
    This is supported on crate feature keys-bip39 only.
    Expand description

    A BIP39 error.

    -

    Variants

    BadWordCount(usize)

    Mnemonic has a word count that is not a multiple of 6.

    -

    UnknownWord(usize)

    Mnemonic contains an unknown word. +}

    Available on crate feature keys-bip39 only.
    Expand description

    A BIP39 error.

    +

    Variants§

    §

    BadWordCount(usize)

    Mnemonic has a word count that is not a multiple of 6.

    +
    §

    UnknownWord(usize)

    Mnemonic contains an unknown word. Error contains the index of the word. Use mnemonic.split_whitespace().get(i) to get the word.

    -

    BadEntropyBitCount(usize)

    Entropy was not a multiple of 32 bits or between 128-256n bits in length.

    -

    InvalidChecksum

    The mnemonic has an invalid checksum.

    -

    AmbiguousLanguages(AmbiguousLanguages)

    The mnemonic can be interpreted as multiple languages. +

    §

    BadEntropyBitCount(usize)

    Entropy was not a multiple of 32 bits or between 128-256n bits in length.

    +
    §

    InvalidChecksum

    The mnemonic has an invalid checksum.

    +
    §

    AmbiguousLanguages(AmbiguousLanguages)

    The mnemonic can be interpreted as multiple languages. Use the helper methods of the inner struct to inspect which languages are possible.

    -

    Trait Implementations

    Returns a copy of the value. Read more

    -

    Performs copy-assignment from source. Read more

    -

    Formats the value using the given formatter. Read more

    -

    Formats the value using the given formatter. Read more

    -

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

    -
    🔬 This is a nightly-only experimental API. (backtrace)

    Returns a stack backtrace, if available, of where this error occurred. Read more

    -
    👎 Deprecated since 1.42.0:

    use the Display impl or to_string()

    -
    👎 Deprecated since 1.33.0:

    replaced by Error::source, which can support downcasting

    -

    This method tests for self and other values to be equal, and is used -by ==. Read more

    -

    This method tests for !=.

    -

    Auto Trait Implementations

    Blanket Implementations

    Gets the TypeId of self. Read more

    -

    Immutably borrows from an owned value. Read more

    -

    Mutably borrows from an owned value. Read more

    -

    Performs the conversion.

    -

    Performs the conversion.

    -

    The alignment of pointer.

    -

    The type for initializers.

    -

    Initializes a with the given initializer. Read more

    -

    Dereferences the given pointer. Read more

    -

    Mutably dereferences the given pointer. Read more

    -

    Drops the object pointed to by the given pointer. Read more

    -

    The resulting type after obtaining ownership.

    -

    Creates owned data from borrowed data, usually by cloning. Read more

    -
    🔬 This is a nightly-only experimental API. (toowned_clone_into)

    Uses borrowed data to replace owned data, usually by cloning. Read more

    -

    Converts the given value to a String. Read more

    -

    The type returned in the event of a conversion error.

    -

    Performs the conversion.

    -

    The type returned in the event of a conversion error.

    -

    Performs the conversion.

    -
    - \ No newline at end of file +

    Trait Implementations§

    Returns a copy of the value. Read more
    Performs copy-assignment from source. Read more
    Formats the value using the given formatter. Read more
    Formats the value using the given formatter. Read more
    The lower-level source of this error, if any. Read more
    👎Deprecated since 1.42.0: use the Display impl or to_string()
    👎Deprecated since 1.33.0: replaced by Error::source, which can support downcasting
    🔬This is a nightly-only experimental API. (error_generic_member_access)
    Provides type based access to context intended for error reports. Read more
    This method tests for self and other values to be equal, and is used +by ==. Read more
    This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason. Read more

    Auto Trait Implementations§

    Blanket Implementations§

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

    Returns the argument unchanged.

    +

    Calls U::from(self).

    +

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

    +
    The alignment of pointer.
    The type for initializers.
    Initializes a with the given initializer. Read more
    Dereferences the given pointer. Read more
    Mutably dereferences the given pointer. Read more
    Drops the object pointed to by the given pointer. Read more
    🔬This is a nightly-only experimental API. (provide_any)
    Data providers should implement this method to provide all values they are able to +provide by using demand. Read more
    The resulting type after obtaining ownership.
    Creates owned data from borrowed data, usually by cloning. Read more
    Uses borrowed data to replace owned data, usually by cloning. Read more
    Converts the given value to a String. Read more
    The type returned in the event of a conversion error.
    Performs the conversion.
    The type returned in the event of a conversion error.
    Performs the conversion.
    \ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/keys/bip39/enum.Language.html b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/keys/bip39/enum.Language.html index b585369263..7ca4f34b63 100644 --- a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/keys/bip39/enum.Language.html +++ b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/keys/bip39/enum.Language.html @@ -1,58 +1,19 @@ -Language in bdk::keys::bip39 - Rust - -
    Available on crate feature keys-bip39 only.
    Expand description

    Language to be used for the mnemonic phrase.

    The English language is always available, other languages are enabled using the compilation features.

    -

    Variants

    English

    The English language.

    -

    Implementations

    The list of supported languages. +

    Variants§

    §

    English

    The English language.

    +

    Implementations§

    The list of supported languages. Language support is managed by compile features.

    -

    Get words from the word list that start with the given prefix.

    -

    Trait Implementations

    Returns a copy of the value. Read more

    -

    Performs copy-assignment from source. Read more

    -

    Formats the value using the given formatter. Read more

    -

    Formats the value using the given formatter. Read more

    -

    Feeds this value into the given Hasher. Read more

    -

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

    -

    This method returns an Ordering between self and other. Read more

    -

    Compares and returns the maximum of two values. Read more

    -

    Compares and returns the minimum of two values. Read more

    -

    Restrict a value to a certain interval. Read more

    -

    This method tests for self and other values to be equal, and is used -by ==. Read more

    -

    This method tests for !=.

    -

    This method returns an ordering between self and other values if one exists. Read more

    -

    This method tests less than (for self and other) and is used by the < operator. Read more

    -

    This method tests less than or equal to (for self and other) and is used by the <= -operator. Read more

    -

    This method tests greater than (for self and other) and is used by the > operator. Read more

    -

    This method tests greater than or equal to (for self and other) and is used by the >= -operator. Read more

    -

    Auto Trait Implementations

    Blanket Implementations

    Gets the TypeId of self. Read more

    -

    Immutably borrows from an owned value. Read more

    -

    Mutably borrows from an owned value. Read more

    -

    Performs the conversion.

    -

    Performs the conversion.

    -

    The alignment of pointer.

    -

    The type for initializers.

    -

    Initializes a with the given initializer. Read more

    -

    Dereferences the given pointer. Read more

    -

    Mutably dereferences the given pointer. Read more

    -

    Drops the object pointed to by the given pointer. Read more

    -

    The resulting type after obtaining ownership.

    -

    Creates owned data from borrowed data, usually by cloning. Read more

    -
    🔬 This is a nightly-only experimental API. (toowned_clone_into)

    Uses borrowed data to replace owned data, usually by cloning. Read more

    -

    Converts the given value to a String. Read more

    -

    The type returned in the event of a conversion error.

    -

    Performs the conversion.

    -

    The type returned in the event of a conversion error.

    -

    Performs the conversion.

    -
    - \ No newline at end of file +

    Get words from the word list that start with the given prefix.

    +

    Trait Implementations§

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

    Auto Trait Implementations§

    Blanket Implementations§

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

    Returns the argument unchanged.

    +

    Calls U::from(self).

    +

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

    +
    The alignment of pointer.
    The type for initializers.
    Initializes a with the given initializer. Read more
    Dereferences the given pointer. Read more
    Mutably dereferences the given pointer. Read more
    Drops the object pointed to by the given pointer. Read more
    The resulting type after obtaining ownership.
    Creates owned data from borrowed data, usually by cloning. Read more
    Uses borrowed data to replace owned data, usually by cloning. Read more
    Converts the given value to a String. Read more
    The type returned in the event of a conversion error.
    Performs the conversion.
    The type returned in the event of a conversion error.
    Performs the conversion.
    \ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/keys/bip39/enum.WordCount.html b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/keys/bip39/enum.WordCount.html index 49803e6d72..a60c995654 100644 --- a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/keys/bip39/enum.WordCount.html +++ b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/keys/bip39/enum.WordCount.html @@ -1,37 +1,18 @@ -WordCount in bdk::keys::bip39 - Rust - -
    pub enum WordCount {
    +WordCount in bdk::keys::bip39 - Rust

    Enum bdk::keys::bip39::WordCount

    source ·
    pub enum WordCount {
         Words12,
         Words15,
         Words18,
         Words21,
         Words24,
    -}
    This is supported on crate feature keys-bip39 only.
    Expand description

    Type describing entropy length (aka word count) in the mnemonic

    -

    Variants

    Words12

    12 words mnemonic (128 bits entropy)

    -

    Words15

    15 words mnemonic (160 bits entropy)

    -

    Words18

    18 words mnemonic (192 bits entropy)

    -

    Words21

    21 words mnemonic (224 bits entropy)

    -

    Words24

    24 words mnemonic (256 bits entropy)

    -

    Auto Trait Implementations

    Blanket Implementations

    Gets the TypeId of self. Read more

    -

    Immutably borrows from an owned value. Read more

    -

    Mutably borrows from an owned value. Read more

    -

    Performs the conversion.

    -

    Performs the conversion.

    -

    The alignment of pointer.

    -

    The type for initializers.

    -

    Initializes a with the given initializer. Read more

    -

    Dereferences the given pointer. Read more

    -

    Mutably dereferences the given pointer. Read more

    -

    Drops the object pointed to by the given pointer. Read more

    -

    The type returned in the event of a conversion error.

    -

    Performs the conversion.

    -

    The type returned in the event of a conversion error.

    -

    Performs the conversion.

    -
    - \ No newline at end of file +}
    Available on crate feature keys-bip39 only.
    Expand description

    Type describing entropy length (aka word count) in the mnemonic

    +

    Variants§

    §

    Words12

    12 words mnemonic (128 bits entropy)

    +
    §

    Words15

    15 words mnemonic (160 bits entropy)

    +
    §

    Words18

    18 words mnemonic (192 bits entropy)

    +
    §

    Words21

    21 words mnemonic (224 bits entropy)

    +
    §

    Words24

    24 words mnemonic (256 bits entropy)

    +

    Auto Trait Implementations§

    Blanket Implementations§

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

    Returns the argument unchanged.

    +

    Calls U::from(self).

    +

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

    +
    The alignment of pointer.
    The type for initializers.
    Initializes a with the given initializer. Read more
    Dereferences the given pointer. Read more
    Mutably dereferences the given pointer. Read more
    Drops the object pointed to by the given pointer. Read more
    The type returned in the event of a conversion error.
    Performs the conversion.
    The type returned in the event of a conversion error.
    Performs the conversion.
    \ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/keys/bip39/index.html b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/keys/bip39/index.html index ec168205cd..8e736b08f9 100644 --- a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/keys/bip39/index.html +++ b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/keys/bip39/index.html @@ -1,19 +1,3 @@ -bdk::keys::bip39 - Rust - -
    -

    Module bdk::keys::bip39

    source · []
    This is supported on crate feature keys-bip39 only.
    Expand description

    BIP-0039

    -

    Structs

    -

    A mnemonic code.

    -

    Enums

    -

    A BIP39 error.

    -

    Language to be used for the mnemonic phrase.

    -

    Type describing entropy length (aka word count) in the mnemonic

    -

    Type Definitions

    -

    Type for a BIP39 mnemonic with an optional passphrase

    -
    - \ No newline at end of file +bdk::keys::bip39 - Rust

    Module bdk::keys::bip39

    source ·
    Available on crate feature keys-bip39 only.
    Expand description

    BIP-0039

    +

    Structs

    A mnemonic code.

    Enums

    A BIP39 error.
    Language to be used for the mnemonic phrase.
    Type describing entropy length (aka word count) in the mnemonic

    Type Definitions

    Type for a BIP39 mnemonic with an optional passphrase
    \ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/keys/bip39/sidebar-items.js b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/keys/bip39/sidebar-items.js index 414d0bcef0..0ed5efca1c 100644 --- a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/keys/bip39/sidebar-items.js +++ b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/keys/bip39/sidebar-items.js @@ -1 +1 @@ -initSidebarItems({"enum":[["Error","A BIP39 error."],["Language","Language to be used for the mnemonic phrase."],["WordCount","Type describing entropy length (aka word count) in the mnemonic"]],"struct":[["Mnemonic","A mnemonic code."]],"type":[["MnemonicWithPassphrase","Type for a BIP39 mnemonic with an optional passphrase"]]}); \ No newline at end of file +window.SIDEBAR_ITEMS = {"enum":[["Error","A BIP39 error."],["Language","Language to be used for the mnemonic phrase."],["WordCount","Type describing entropy length (aka word count) in the mnemonic"]],"struct":[["Mnemonic","A mnemonic code."]],"type":[["MnemonicWithPassphrase","Type for a BIP39 mnemonic with an optional passphrase"]]}; \ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/keys/bip39/struct.Mnemonic.html b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/keys/bip39/struct.Mnemonic.html index 04543f4d14..267db67c43 100644 --- a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/keys/bip39/struct.Mnemonic.html +++ b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/keys/bip39/struct.Mnemonic.html @@ -1,35 +1,28 @@ -Mnemonic in bdk::keys::bip39 - Rust - -
    pub struct Mnemonic { /* private fields */ }
    This is supported on crate feature keys-bip39 only.
    Expand description

    A mnemonic code.

    +Mnemonic in bdk::keys::bip39 - Rust

    Struct bdk::keys::bip39::Mnemonic

    pub struct Mnemonic { /* private fields */ }
    Available on crate feature keys-bip39 only.
    Expand description

    A mnemonic code.

    The core::str::FromStr implementation will try to determine the language of the mnemonic from all the supported languages. (Languages have to be explicitly enabled using the Cargo features.)

    Supported number of words are 12, 18 and 24.

    -

    Implementations

    Create a new Mnemonic in the specified language from the given entropy. +

    Implementations§

    Create a new Mnemonic in the specified language from the given entropy. Entropy must be a multiple of 32 bits (4 bytes) and 128-256 bits in length.

    -

    Create a new English Mnemonic from the given entropy. +

    Create a new English Mnemonic from the given entropy. Entropy must be a multiple of 32 bits (4 bytes) and 128-256 bits in length.

    -

    Generate a new Mnemonic in the given language +

    Generate a new Mnemonic in the given language with the given randomness source. For the different supported word counts, see documentation on Mnemonic.

    Example:

    -
    extern crate rand;
    -extern crate bip39;
    +
    extern crate rand;
    +extern crate bip39;
     
    -use bip39::{Mnemonic, Language};
    +use bip39::{Mnemonic, Language};
     
    -let mut rng = rand::thread_rng();
    -let m = Mnemonic::generate_in_with(&mut rng, Language::English, 24).unwrap();
    -

    Get the language of the Mnemonic.

    -

    Get an iterator over the words.

    -

    Determine the language of the mnemonic.

    +let mut rng = rand::thread_rng(); +let m = Mnemonic::generate_in_with(&mut rng, Language::English, 24).unwrap();
    +

    Get the language of the Mnemonic.

    +

    Get an iterator over the words.

    +

    Determine the language of the mnemonic.

    NOTE: This method only guarantees that the returned language is the correct language on the assumption that the mnemonic is valid. It does not itself validate the mnemonic.

    @@ -37,67 +30,24 @@ It does not itself validate the mnemonic.

    word lists. In the extremely unlikely case that a word list can be interpreted in multiple languages, an Error::AmbiguousLanguages is returned, containing the possible languages.

    -

    Parse a mnemonic in normalized UTF8 in the given language.

    -

    Parse a mnemonic in normalized UTF8.

    -

    Parse a mnemonic in the given language.

    -

    Parse a mnemonic and detect the language from the enabled languages.

    -

    Get the number of words in the mnemonic.

    -

    Convert to seed bytes with a passphrase in normalized UTF8.

    -

    Convert to seed bytes.

    -

    Convert the mnemonic back to the entropy used to generate it. +

    Parse a mnemonic in normalized UTF8 in the given language.

    +

    Parse a mnemonic in normalized UTF8.

    +

    Parse a mnemonic in the given language.

    +

    Parse a mnemonic and detect the language from the enabled languages.

    +

    Get the number of words in the mnemonic.

    +

    Convert to seed bytes with a passphrase in normalized UTF8.

    +

    Convert to seed bytes.

    +

    Convert the mnemonic back to the entropy used to generate it. The return value is a byte array and the size. Use Mnemonic::to_entropy (needs std) to get a Vec.

    -

    Convert the mnemonic back to the entropy used to generate it.

    -

    Trait Implementations

    Returns a copy of the value. Read more

    -

    Performs copy-assignment from source. Read more

    -

    Formats the value using the given formatter. Read more

    -

    Consume self and turn it into an ExtendedKey Read more

    -

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

    -

    Deserialize this value from the given Serde deserializer. Read more

    -

    Formats the value using the given formatter. Read more

    -

    The associated error which can be returned from parsing.

    -

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

    -

    Type specifying the amount of entropy required e.g. [u8;32]

    -

    Extra options required by the generate_with_entropy

    -

    Returned error in case of failure

    -

    Generate a key given the extra options and the entropy

    -

    Generate a key given the options with a random entropy

    -

    Feeds this value into the given Hasher. Read more

    -

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

    -

    This method returns an Ordering between self and other. Read more

    -

    Compares and returns the maximum of two values. Read more

    -

    Compares and returns the minimum of two values. Read more

    -

    Restrict a value to a certain interval. Read more

    -

    This method tests for self and other values to be equal, and is used -by ==. Read more

    -

    This method tests for !=.

    -

    This method returns an ordering between self and other values if one exists. Read more

    -

    This method tests less than (for self and other) and is used by the < operator. Read more

    -

    This method tests less than or equal to (for self and other) and is used by the <= -operator. Read more

    -

    This method tests greater than (for self and other) and is used by the > operator. Read more

    -

    This method tests greater than or equal to (for self and other) and is used by the >= -operator. Read more

    -

    Serialize this value into the given Serde serializer. Read more

    -

    Auto Trait Implementations

    Blanket Implementations

    Gets the TypeId of self. Read more

    -

    Immutably borrows from an owned value. Read more

    -

    Mutably borrows from an owned value. Read more

    -

    Performs the conversion.

    -

    Performs the conversion.

    -

    The alignment of pointer.

    -

    The type for initializers.

    -

    Initializes a with the given initializer. Read more

    -

    Dereferences the given pointer. Read more

    -

    Mutably dereferences the given pointer. Read more

    -

    Drops the object pointed to by the given pointer. Read more

    -

    The resulting type after obtaining ownership.

    -

    Creates owned data from borrowed data, usually by cloning. Read more

    -
    🔬 This is a nightly-only experimental API. (toowned_clone_into)

    Uses borrowed data to replace owned data, usually by cloning. Read more

    -

    Converts the given value to a String. Read more

    -

    The type returned in the event of a conversion error.

    -

    Performs the conversion.

    -

    The type returned in the event of a conversion error.

    -

    Performs the conversion.

    -
    - \ No newline at end of file +

    Convert the mnemonic back to the entropy used to generate it.

    +

    Trait Implementations§

    Returns a copy of the value. Read more
    Performs copy-assignment from source. Read more
    Formats the value using the given formatter. Read more
    Consume self and turn it into an ExtendedKey Read more
    Consume self and turn it into a DescriptorKey by adding the extra metadata, such as +key origin and derivation path Read more
    Deserialize this value from the given Serde deserializer. Read more
    Formats the value using the given formatter. Read more
    The associated error which can be returned from parsing.
    Parses a string s to return a value of this type. Read more
    Type specifying the amount of entropy required e.g. [u8;32]
    Extra options required by the generate_with_entropy
    Returned error in case of failure
    Generate a key given the extra options and the entropy
    Generate a key given the options with a random entropy
    Feeds this value into the given Hasher. Read more
    Feeds a slice of this type into the given Hasher. Read more
    This method returns an Ordering between self and other. Read more
    Compares and returns the maximum of two values. Read more
    Compares and returns the minimum of two values. Read more
    Restrict a value to a certain interval. Read more
    This method tests for self and other values to be equal, and is used +by ==. Read more
    This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason. Read more
    This method returns an ordering between self and other values if one exists. Read more
    This method tests less than (for self and other) and is used by the < operator. Read more
    This method tests less than or equal to (for self and other) and is used by the <= +operator. Read more
    This method tests greater than (for self and other) and is used by the > operator. Read more
    This method tests greater than or equal to (for self and other) and is used by the >= +operator. Read more
    Serialize this value into the given Serde serializer. Read more

    Auto Trait Implementations§

    Blanket Implementations§

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

    Returns the argument unchanged.

    +

    Calls U::from(self).

    +

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

    +
    The alignment of pointer.
    The type for initializers.
    Initializes a with the given initializer. Read more
    Dereferences the given pointer. Read more
    Mutably dereferences the given pointer. Read more
    Drops the object pointed to by the given pointer. Read more
    The resulting type after obtaining ownership.
    Creates owned data from borrowed data, usually by cloning. Read more
    Uses borrowed data to replace owned data, usually by cloning. Read more
    Converts the given value to a String. Read more
    The type returned in the event of a conversion error.
    Performs the conversion.
    The type returned in the event of a conversion error.
    Performs the conversion.
    \ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/keys/bip39/type.MnemonicWithPassphrase.html b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/keys/bip39/type.MnemonicWithPassphrase.html index cc22548c7a..7dc19c6f7a 100644 --- a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/keys/bip39/type.MnemonicWithPassphrase.html +++ b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/keys/bip39/type.MnemonicWithPassphrase.html @@ -1,14 +1,4 @@ -MnemonicWithPassphrase in bdk::keys::bip39 - Rust - -
    -

    Type Definition bdk::keys::bip39::MnemonicWithPassphrase

    source · []
    pub type MnemonicWithPassphrase = (Mnemonic, Option<String>);
    This is supported on crate feature keys-bip39 only.
    Expand description

    Type for a BIP39 mnemonic with an optional passphrase

    -

    Trait Implementations

    Consume self and turn it into an ExtendedKey Read more

    -

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

    -
    - \ No newline at end of file +MnemonicWithPassphrase in bdk::keys::bip39 - Rust

    Type Definition bdk::keys::bip39::MnemonicWithPassphrase

    source ·
    pub type MnemonicWithPassphrase = (Mnemonic, Option<String>);
    Available on crate feature keys-bip39 only.
    Expand description

    Type for a BIP39 mnemonic with an optional passphrase

    +

    Trait Implementations§

    Consume self and turn it into an ExtendedKey Read more
    Consume self and turn it into a DescriptorKey by adding the extra metadata, such as +key origin and derivation path Read more
    \ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/keys/enum.DescriptorKey.html b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/keys/enum.DescriptorKey.html index b716d91e6e..54bcc3be88 100644 --- a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/keys/enum.DescriptorKey.html +++ b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/keys/enum.DescriptorKey.html @@ -1,34 +1,13 @@ -DescriptorKey in bdk::keys - Rust - -
    pub enum DescriptorKey<Ctx: ScriptContext> {
    +DescriptorKey in bdk::keys - Rust

    Enum bdk::keys::DescriptorKey

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

    Container for public or secret keys

    -

    Implementations

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

    -

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

    -

    Override the computed set of valid networks

    -

    Trait Implementations

    Formats the value using the given formatter. Read more

    -

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

    -

    Turn the key into a DescriptorKey within the requested ScriptContext

    -

    Auto Trait Implementations

    Blanket Implementations

    Gets the TypeId of self. Read more

    -

    Immutably borrows from an owned value. Read more

    -

    Mutably borrows from an owned value. Read more

    -

    Performs the conversion.

    -

    Performs the conversion.

    -

    The alignment of pointer.

    -

    The type for initializers.

    -

    Initializes a with the given initializer. Read more

    -

    Dereferences the given pointer. Read more

    -

    Mutably dereferences the given pointer. Read more

    -

    Drops the object pointed to by the given pointer. Read more

    -

    The type returned in the event of a conversion error.

    -

    Performs the conversion.

    -

    The type returned in the event of a conversion error.

    -

    Performs the conversion.

    -
    - \ No newline at end of file +

    Implementations§

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

    +

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

    +

    Override the computed set of valid networks

    +

    Trait Implementations§

    Formats the value using the given formatter. Read more

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

    +
    Turn the key into a DescriptorKey within the requested ScriptContext

    Auto Trait Implementations§

    Blanket Implementations§

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

    Returns the argument unchanged.

    +

    Calls U::from(self).

    +

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

    +
    The alignment of pointer.
    The type for initializers.
    Initializes a with the given initializer. Read more
    Dereferences the given pointer. Read more
    Mutably dereferences the given pointer. Read more
    Drops the object pointed to by the given pointer. Read more
    The type returned in the event of a conversion error.
    Performs the conversion.
    The type returned in the event of a conversion error.
    Performs the conversion.
    \ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/keys/enum.DescriptorPublicKey.html b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/keys/enum.DescriptorPublicKey.html index c47cb982bb..52f0326710 100644 --- a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/keys/enum.DescriptorPublicKey.html +++ b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/keys/enum.DescriptorPublicKey.html @@ -1,89 +1,38 @@ -DescriptorPublicKey in bdk::keys - Rust - -
    pub enum DescriptorPublicKey {
    +DescriptorPublicKey in bdk::keys - Rust
    pub enum DescriptorPublicKey {
         Single(SinglePub),
         XPub(DescriptorXKey<ExtendedPubKey>),
     }
    Expand description

    The descriptor pubkey, either a single pubkey or an xpub.

    -

    Variants

    Single(SinglePub)

    Single public key.

    -

    XPub(DescriptorXKey<ExtendedPubKey>)

    Extended public key (xpub).

    -

    Implementations

    The fingerprint of the master key associated with this key, 0x00000000 if none.

    -

    Full path, from the master key

    +

    Variants§

    §

    Single(SinglePub)

    Single public key.

    +
    §

    XPub(DescriptorXKey<ExtendedPubKey>)

    Extended public key (xpub).

    +

    Implementations§

    The fingerprint of the master key associated with this key, 0x00000000 if none.

    +

    Full path, from the master key

    For wildcard keys this will return the path up to the wildcard, so you can get full paths by appending one additional derivation step, according to the wildcard type (hardened or normal)

    -
    👎 Deprecated:

    use has_wildcard instead

    -

    Whether or not the key has a wildcard

    -

    Whether or not the key has a wildcard

    -
    👎 Deprecated:

    use at_derivation_index instead

    -

    Deprecated name of [at_derivation_index].

    -

    Replaces any wildcard (i.e. /*) in the key with a particular derivation index, turning it into a +

    👎Deprecated: use has_wildcard instead

    Whether or not the key has a wildcard

    +

    Whether or not the key has a wildcard

    +
    👎Deprecated: use at_derivation_index instead

    Deprecated name of [at_derivation_index].

    +

    Replaces any wildcard (i.e. /*) in the key with a particular derivation index, turning it into a definite key (i.e. one where all the derivation paths are set).

    -
    Returns
    +
    Returns
    • If this key is not an xpub, returns self.
    • If this key is an xpub but does not have a wildcard, returns self.
    • Otherwise, returns the xpub at derivation index (removing the wildcard).
    -
    Panics
    +
    Panics

    If index ≥ 2^31

    -

    Trait Implementations

    Returns a copy of the value. Read more

    -

    Performs copy-assignment from source. Read more

    -

    Formats the value using the given formatter. Read more

    -

    Formats the value using the given formatter. Read more

    -

    Performs the conversion.

    -

    The associated error which can be returned from parsing.

    -

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

    -

    Feeds this value into the given Hasher. Read more

    -

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

    -

    Turn the key into a DescriptorKey within the requested ScriptContext

    -

    The associated [sha256::Hash] for this [MiniscriptKey], -used in the hash256 fragment. Read more

    -

    The associated [hash256::Hash] for this [MiniscriptKey], -used in the hash256 fragment. Read more

    -

    The associated [ripedmd160::Hash] for this [MiniscriptKey] type. -used in the ripemd160 fragment Read more

    -

    The associated [hash160::Hash] for this [MiniscriptKey] type. -used in the hash160 fragment Read more

    -

    Returns true if the pubkey is uncompressed. Defaults to false.

    -

    Returns true if the pubkey is an x-only pubkey. Defaults to false.

    -

    This method returns an Ordering between self and other. Read more

    -

    Compares and returns the maximum of two values. Read more

    -

    Compares and returns the minimum of two values. Read more

    -

    Restrict a value to a certain interval. Read more

    -

    This method tests for self and other values to be equal, and is used -by ==. Read more

    -

    This method tests for !=.

    -

    This method returns an ordering between self and other values if one exists. Read more

    -

    This method tests less than (for self and other) and is used by the < operator. Read more

    -

    This method tests less than or equal to (for self and other) and is used by the <= -operator. Read more

    -

    This method tests greater than (for self and other) and is used by the > operator. Read more

    -

    This method tests greater than or equal to (for self and other) and is used by the >= -operator. Read more

    -

    Auto Trait Implementations

    Blanket Implementations

    Gets the TypeId of self. Read more

    -

    Immutably borrows from an owned value. Read more

    -

    Mutably borrows from an owned value. Read more

    -

    Performs the conversion.

    -

    Performs the conversion.

    -

    The alignment of pointer.

    -

    The type for initializers.

    -

    Initializes a with the given initializer. Read more

    -

    Dereferences the given pointer. Read more

    -

    Mutably dereferences the given pointer. Read more

    -

    Drops the object pointed to by the given pointer. Read more

    -

    The resulting type after obtaining ownership.

    -

    Creates owned data from borrowed data, usually by cloning. Read more

    -
    🔬 This is a nightly-only experimental API. (toowned_clone_into)

    Uses borrowed data to replace owned data, usually by cloning. Read more

    -

    Converts the given value to a String. Read more

    -

    The type returned in the event of a conversion error.

    -

    Performs the conversion.

    -

    The type returned in the event of a conversion error.

    -

    Performs the conversion.

    -
    - \ No newline at end of file +

    Trait Implementations§

    Returns a copy of the value. Read more
    Performs copy-assignment from source. Read more
    Formats the value using the given formatter. Read more
    Formats the value using the given formatter. Read more
    Converts to this type from the input type.
    The associated error which can be returned from parsing.
    Parses a string s to return a value of this type. Read more
    Feeds this value into the given Hasher. Read more
    Feeds a slice of this type into the given Hasher. Read more
    Turn the key into a DescriptorKey within the requested ScriptContext
    The associated [sha256::Hash] for this [MiniscriptKey], +used in the hash256 fragment. Read more
    The associated [hash256::Hash] for this [MiniscriptKey], +used in the hash256 fragment. Read more
    The associated [ripedmd160::Hash] for this [MiniscriptKey] type. +used in the ripemd160 fragment Read more
    The associated [hash160::Hash] for this [MiniscriptKey] type. +used in the hash160 fragment Read more
    Returns true if the pubkey is uncompressed. Defaults to false.
    Returns true if the pubkey is an x-only pubkey. Defaults to false.
    This method returns an Ordering between self and other. Read more
    Compares and returns the maximum of two values. Read more
    Compares and returns the minimum of two values. Read more
    Restrict a value to a certain interval. Read more
    This method tests for self and other values to be equal, and is used +by ==. Read more
    This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason. Read more
    This method returns an ordering between self and other values if one exists. Read more
    This method tests less than (for self and other) and is used by the < operator. Read more
    This method tests less than or equal to (for self and other) and is used by the <= +operator. Read more
    This method tests greater than (for self and other) and is used by the > operator. Read more
    This method tests greater than or equal to (for self and other) and is used by the >= +operator. Read more

    Auto Trait Implementations§

    Blanket Implementations§

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

    Returns the argument unchanged.

    +

    Calls U::from(self).

    +

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

    +
    The alignment of pointer.
    The type for initializers.
    Initializes a with the given initializer. Read more
    Dereferences the given pointer. Read more
    Mutably dereferences the given pointer. Read more
    Drops the object pointed to by the given pointer. Read more
    The resulting type after obtaining ownership.
    Creates owned data from borrowed data, usually by cloning. Read more
    Uses borrowed data to replace owned data, usually by cloning. Read more
    Converts the given value to a String. Read more
    The type returned in the event of a conversion error.
    Performs the conversion.
    The type returned in the event of a conversion error.
    Performs the conversion.
    \ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/keys/enum.DescriptorSecretKey.html b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/keys/enum.DescriptorSecretKey.html index ecfdd10150..432492ccc7 100644 --- a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/keys/enum.DescriptorSecretKey.html +++ b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/keys/enum.DescriptorSecretKey.html @@ -1,40 +1,15 @@ -DescriptorSecretKey in bdk::keys - Rust - -
    pub enum DescriptorSecretKey {
    +DescriptorSecretKey in bdk::keys - Rust
    pub enum DescriptorSecretKey {
         Single(SinglePriv),
         XPrv(DescriptorXKey<ExtendedPrivKey>),
     }
    Expand description

    The descriptor secret key, either a single private key or an xprv.

    -

    Variants

    Single(SinglePriv)

    Single private key.

    -

    XPrv(DescriptorXKey<ExtendedPrivKey>)

    Extended private key (xpriv).

    -

    Implementations

    Returns the public version of this key.

    +

    Variants§

    §

    Single(SinglePriv)

    Single private key.

    +
    §

    XPrv(DescriptorXKey<ExtendedPrivKey>)

    Extended private key (xpriv).

    +

    Implementations§

    Returns the public version of this key.

    If the key is an “XPrv”, the hardened derivation steps will be applied before converting it to a public key.

    -

    Trait Implementations

    Formats the value using the given formatter. Read more

    -

    Formats the value using the given formatter. Read more

    -

    The associated error which can be returned from parsing.

    -

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

    -

    Turn the key into a DescriptorKey within the requested ScriptContext

    -

    Auto Trait Implementations

    Blanket Implementations

    Gets the TypeId of self. Read more

    -

    Immutably borrows from an owned value. Read more

    -

    Mutably borrows from an owned value. Read more

    -

    Performs the conversion.

    -

    Performs the conversion.

    -

    The alignment of pointer.

    -

    The type for initializers.

    -

    Initializes a with the given initializer. Read more

    -

    Dereferences the given pointer. Read more

    -

    Mutably dereferences the given pointer. Read more

    -

    Drops the object pointed to by the given pointer. Read more

    -

    Converts the given value to a String. Read more

    -

    The type returned in the event of a conversion error.

    -

    Performs the conversion.

    -

    The type returned in the event of a conversion error.

    -

    Performs the conversion.

    -
    - \ No newline at end of file +

    Trait Implementations§

    Formats the value using the given formatter. Read more
    Formats the value using the given formatter. Read more
    The associated error which can be returned from parsing.
    Parses a string s to return a value of this type. Read more
    Turn the key into a DescriptorKey within the requested ScriptContext

    Auto Trait Implementations§

    Blanket Implementations§

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

    Returns the argument unchanged.

    +

    Calls U::from(self).

    +

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

    +
    The alignment of pointer.
    The type for initializers.
    Initializes a with the given initializer. Read more
    Dereferences the given pointer. Read more
    Mutably dereferences the given pointer. Read more
    Drops the object pointed to by the given pointer. Read more
    Converts the given value to a String. Read more
    The type returned in the event of a conversion error.
    Performs the conversion.
    The type returned in the event of a conversion error.
    Performs the conversion.
    \ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/keys/enum.ExtendedKey.html b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/keys/enum.ExtendedKey.html index 071e4eac5d..244c0d58c8 100644 --- a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/keys/enum.ExtendedKey.html +++ b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/keys/enum.ExtendedKey.html @@ -1,45 +1,22 @@ -ExtendedKey in bdk::keys - Rust - -
    pub enum ExtendedKey<Ctx: ScriptContext = Legacy> {
    -    Private((ExtendedPrivKey, PhantomData<Ctx>)),
    -    Public((ExtendedPubKey, PhantomData<Ctx>)),
    +ExtendedKey in bdk::keys - Rust

    Enum bdk::keys::ExtendedKey

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

    Enum for extended keys that can be either xprv or xpub

    An instance of ExtendedKey can be constructed from an ExtendedPrivKey or an ExtendedPubKey by using the From trait.

    Defaults to the Legacy context.

    -

    Variants

    Private((ExtendedPrivKey, PhantomData<Ctx>))

    A private extended key, aka an xprv

    -

    Public((ExtendedPubKey, PhantomData<Ctx>))

    A public extended key, aka an xpub

    -

    Implementations

    Return whether or not the key contains the private data

    -

    Transform the ExtendedKey into an ExtendedPrivKey for the +

    Variants§

    §

    Private((ExtendedPrivKey, PhantomData<Ctx>))

    A private extended key, aka an xprv

    +
    §

    Public((ExtendedPubKey, PhantomData<Ctx>))

    A public extended key, aka an xpub

    +

    Implementations§

    Return whether or not the key contains the private data

    +

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

    -

    Transform the ExtendedKey into an ExtendedPubKey for the +

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

    -

    Trait Implementations

    Identity conversion

    -

    Consume self and turn it into an ExtendedKey Read more

    -

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

    -

    Performs the conversion.

    -

    Performs the conversion.

    -

    Auto Trait Implementations

    Blanket Implementations

    Gets the TypeId of self. Read more

    -

    Immutably borrows from an owned value. Read more

    -

    Mutably borrows from an owned value. Read more

    -

    Performs the conversion.

    -

    Performs the conversion.

    -

    The alignment of pointer.

    -

    The type for initializers.

    -

    Initializes a with the given initializer. Read more

    -

    Dereferences the given pointer. Read more

    -

    Mutably dereferences the given pointer. Read more

    -

    Drops the object pointed to by the given pointer. Read more

    -

    The type returned in the event of a conversion error.

    -

    Performs the conversion.

    -

    The type returned in the event of a conversion error.

    -

    Performs the conversion.

    -
    - \ No newline at end of file +

    Trait Implementations§

    Identity conversion

    +
    Consume self and turn it into an ExtendedKey Read more
    Consume self and turn it into a DescriptorKey by adding the extra metadata, such as +key origin and derivation path Read more
    Converts to this type from the input type.
    Converts to this type from the input type.

    Auto Trait Implementations§

    Blanket Implementations§

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

    Returns the argument unchanged.

    +

    Calls U::from(self).

    +

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

    +
    The alignment of pointer.
    The type for initializers.
    Initializes a with the given initializer. Read more
    Dereferences the given pointer. Read more
    Mutably dereferences the given pointer. Read more
    Drops the object pointed to by the given pointer. Read more
    The type returned in the event of a conversion error.
    Performs the conversion.
    The type returned in the event of a conversion error.
    Performs the conversion.
    \ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/keys/enum.KeyError.html b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/keys/enum.KeyError.html index 5d6aa09535..56f3158022 100644 --- a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/keys/enum.KeyError.html +++ b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/keys/enum.KeyError.html @@ -1,12 +1,5 @@ -KeyError in bdk::keys - Rust - -
    -

    Enum bdk::keys::KeyError

    source · []
    pub enum KeyError {
    +KeyError in bdk::keys - Rust

    Enum bdk::keys::KeyError

    source ·
    pub enum KeyError {
         InvalidScriptContext,
         InvalidNetwork,
         InvalidChecksum,
    @@ -14,37 +7,15 @@
         Bip32(Error),
         Miniscript(Error),
     }
    Expand description

    Errors thrown while working with keys

    -

    Variants

    InvalidScriptContext

    The key cannot exist in the given script context

    -

    InvalidNetwork

    The key is not valid for the given network

    -

    InvalidChecksum

    The key has an invalid checksum

    -

    Message(String)

    Custom error message

    -

    Bip32(Error)

    BIP32 error

    -

    Miniscript(Error)

    Miniscript error

    -

    Trait Implementations

    Formats the value using the given formatter. Read more

    -

    Formats the value using the given formatter. Read more

    -

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

    -
    🔬 This is a nightly-only experimental API. (backtrace)

    Returns a stack backtrace, if available, of where this error occurred. Read more

    -
    👎 Deprecated since 1.42.0:

    use the Display impl or to_string()

    -
    👎 Deprecated since 1.33.0:

    replaced by Error::source, which can support downcasting

    -

    Performs the conversion.

    -

    Performs the conversion.

    -

    Performs the conversion.

    -

    Performs the conversion.

    -

    Auto Trait Implementations

    Blanket Implementations

    Gets the TypeId of self. Read more

    -

    Immutably borrows from an owned value. Read more

    -

    Mutably borrows from an owned value. Read more

    -

    Performs the conversion.

    -

    Performs the conversion.

    -

    The alignment of pointer.

    -

    The type for initializers.

    -

    Initializes a with the given initializer. Read more

    -

    Dereferences the given pointer. Read more

    -

    Mutably dereferences the given pointer. Read more

    -

    Drops the object pointed to by the given pointer. Read more

    -

    Converts the given value to a String. Read more

    -

    The type returned in the event of a conversion error.

    -

    Performs the conversion.

    -

    The type returned in the event of a conversion error.

    -

    Performs the conversion.

    -
    - \ No newline at end of file +

    Variants§

    §

    InvalidScriptContext

    The key cannot exist in the given script context

    +
    §

    InvalidNetwork

    The key is not valid for the given network

    +
    §

    InvalidChecksum

    The key has an invalid checksum

    +
    §

    Message(String)

    Custom error message

    +
    §

    Bip32(Error)

    BIP32 error

    +
    §

    Miniscript(Error)

    Miniscript error

    +

    Trait Implementations§

    Formats the value using the given formatter. Read more
    Formats the value using the given formatter. Read more
    The lower-level source of this error, if any. Read more
    👎Deprecated since 1.42.0: use the Display impl or to_string()
    👎Deprecated since 1.33.0: replaced by Error::source, which can support downcasting
    🔬This is a nightly-only experimental API. (error_generic_member_access)
    Provides type based access to context intended for error reports. Read more
    Converts to this type from the input type.
    Converts to this type from the input type.
    Converts to this type from the input type.
    Converts to this type from the input type.

    Auto Trait Implementations§

    Blanket Implementations§

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

    Returns the argument unchanged.

    +

    Calls U::from(self).

    +

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

    +
    The alignment of pointer.
    The type for initializers.
    Initializes a with the given initializer. Read more
    Dereferences the given pointer. Read more
    Mutably dereferences the given pointer. Read more
    Drops the object pointed to by the given pointer. Read more
    🔬This is a nightly-only experimental API. (provide_any)
    Data providers should implement this method to provide all values they are able to +provide by using demand. Read more
    Converts the given value to a String. Read more
    The type returned in the event of a conversion error.
    Performs the conversion.
    The type returned in the event of a conversion error.
    Performs the conversion.
    \ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/keys/enum.ScriptContextEnum.html b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/keys/enum.ScriptContextEnum.html index fd4a442aca..cdd5ee8e6b 100644 --- a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/keys/enum.ScriptContextEnum.html +++ b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/keys/enum.ScriptContextEnum.html @@ -1,45 +1,19 @@ -ScriptContextEnum in bdk::keys - Rust - -
    pub enum ScriptContextEnum {
    +ScriptContextEnum in bdk::keys - Rust

    Enum bdk::keys::ScriptContextEnum

    source ·
    pub enum ScriptContextEnum {
         Legacy,
         Segwitv0,
         Tap,
     }
    Expand description

    Enum representation of the known valid ScriptContexts

    -

    Variants

    Legacy

    Legacy scripts

    -

    Segwitv0

    Segwitv0 scripts

    -

    Tap

    Taproot scripts

    -

    Implementations

    Returns whether the script context is ScriptContextEnum::Legacy

    -

    Returns whether the script context is ScriptContextEnum::Segwitv0

    -

    Returns whether the script context is ScriptContextEnum::Tap

    -

    Trait Implementations

    Returns a copy of the value. Read more

    -

    Performs copy-assignment from source. Read more

    -

    Formats the value using the given formatter. Read more

    -

    This method tests for self and other values to be equal, and is used -by ==. Read more

    -

    This method tests for !=.

    -

    Auto Trait Implementations

    Blanket Implementations

    Gets the TypeId of self. Read more

    -

    Immutably borrows from an owned value. Read more

    -

    Mutably borrows from an owned value. Read more

    -

    Performs the conversion.

    -

    Performs the conversion.

    -

    The alignment of pointer.

    -

    The type for initializers.

    -

    Initializes a with the given initializer. Read more

    -

    Dereferences the given pointer. Read more

    -

    Mutably dereferences the given pointer. Read more

    -

    Drops the object pointed to by the given pointer. Read more

    -

    The resulting type after obtaining ownership.

    -

    Creates owned data from borrowed data, usually by cloning. Read more

    -
    🔬 This is a nightly-only experimental API. (toowned_clone_into)

    Uses borrowed data to replace owned data, usually by cloning. Read more

    -

    The type returned in the event of a conversion error.

    -

    Performs the conversion.

    -

    The type returned in the event of a conversion error.

    -

    Performs the conversion.

    -
    - \ No newline at end of file +

    Variants§

    §

    Legacy

    Legacy scripts

    +
    §

    Segwitv0

    Segwitv0 scripts

    +
    §

    Tap

    Taproot scripts

    +

    Implementations§

    Returns whether the script context is ScriptContextEnum::Legacy

    +

    Returns whether the script context is ScriptContextEnum::Segwitv0

    +

    Returns whether the script context is ScriptContextEnum::Tap

    +

    Trait Implementations§

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

    Auto Trait Implementations§

    Blanket Implementations§

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

    Returns the argument unchanged.

    +

    Calls U::from(self).

    +

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

    +
    The alignment of pointer.
    The type for initializers.
    Initializes a with the given initializer. Read more
    Dereferences the given pointer. Read more
    Mutably dereferences the given pointer. Read more
    Drops the object pointed to by the given pointer. Read more
    The resulting type after obtaining ownership.
    Creates owned data from borrowed data, usually by cloning. Read more
    Uses borrowed data to replace owned data, usually by cloning. Read more
    The type returned in the event of a conversion error.
    Performs the conversion.
    The type returned in the event of a conversion error.
    Performs the conversion.
    \ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/keys/enum.SinglePubKey.html b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/keys/enum.SinglePubKey.html index c55d7c67b9..d42db77612 100644 --- a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/keys/enum.SinglePubKey.html +++ b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/keys/enum.SinglePubKey.html @@ -1,53 +1,16 @@ -SinglePubKey in bdk::keys - Rust - -
    pub enum SinglePubKey {
    +SinglePubKey in bdk::keys - Rust

    Enum bdk::keys::SinglePubKey

    pub enum SinglePubKey {
         FullKey(PublicKey),
         XOnly(XOnlyPublicKey),
     }
    Expand description

    Single public key without any origin or range information.

    -

    Variants

    FullKey(PublicKey)

    A bitcoin public key (compressed or uncompressed).

    -

    XOnly(XOnlyPublicKey)

    An xonly public key.

    -

    Trait Implementations

    Returns a copy of the value. Read more

    -

    Performs copy-assignment from source. Read more

    -

    Formats the value using the given formatter. Read more

    -

    Feeds this value into the given Hasher. Read more

    -

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

    -

    This method returns an Ordering between self and other. Read more

    -

    Compares and returns the maximum of two values. Read more

    -

    Compares and returns the minimum of two values. Read more

    -

    Restrict a value to a certain interval. Read more

    -

    This method tests for self and other values to be equal, and is used -by ==. Read more

    -

    This method tests for !=.

    -

    This method returns an ordering between self and other values if one exists. Read more

    -

    This method tests less than (for self and other) and is used by the < operator. Read more

    -

    This method tests less than or equal to (for self and other) and is used by the <= -operator. Read more

    -

    This method tests greater than (for self and other) and is used by the > operator. Read more

    -

    This method tests greater than or equal to (for self and other) and is used by the >= -operator. Read more

    -

    Auto Trait Implementations

    Blanket Implementations

    Gets the TypeId of self. Read more

    -

    Immutably borrows from an owned value. Read more

    -

    Mutably borrows from an owned value. Read more

    -

    Performs the conversion.

    -

    Performs the conversion.

    -

    The alignment of pointer.

    -

    The type for initializers.

    -

    Initializes a with the given initializer. Read more

    -

    Dereferences the given pointer. Read more

    -

    Mutably dereferences the given pointer. Read more

    -

    Drops the object pointed to by the given pointer. Read more

    -

    The resulting type after obtaining ownership.

    -

    Creates owned data from borrowed data, usually by cloning. Read more

    -
    🔬 This is a nightly-only experimental API. (toowned_clone_into)

    Uses borrowed data to replace owned data, usually by cloning. Read more

    -

    The type returned in the event of a conversion error.

    -

    Performs the conversion.

    -

    The type returned in the event of a conversion error.

    -

    Performs the conversion.

    -
    - \ No newline at end of file +

    Variants§

    §

    FullKey(PublicKey)

    A bitcoin public key (compressed or uncompressed).

    +
    §

    XOnly(XOnlyPublicKey)

    An xonly public key.

    +

    Trait Implementations§

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

    Auto Trait Implementations§

    Blanket Implementations§

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

    Returns the argument unchanged.

    +

    Calls U::from(self).

    +

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

    +
    The alignment of pointer.
    The type for initializers.
    Initializes a with the given initializer. Read more
    Dereferences the given pointer. Read more
    Mutably dereferences the given pointer. Read more
    Drops the object pointed to by the given pointer. Read more
    The resulting type after obtaining ownership.
    Creates owned data from borrowed data, usually by cloning. Read more
    Uses borrowed data to replace owned data, usually by cloning. Read more
    The type returned in the event of a conversion error.
    Performs the conversion.
    The type returned in the event of a conversion error.
    Performs the conversion.
    \ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/keys/fn.any_network.html b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/keys/fn.any_network.html index 8f3fb799b9..9d82bdf14e 100644 --- a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/keys/fn.any_network.html +++ b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/keys/fn.any_network.html @@ -1,11 +1,3 @@ -any_network in bdk::keys - Rust - -
    -

    Function bdk::keys::any_network

    source · []
    pub fn any_network() -> ValidNetworks
    Expand description

    Create a set containing mainnet, testnet and regtest

    -
    - \ No newline at end of file +any_network in bdk::keys - Rust

    Function bdk::keys::any_network

    source ·
    pub fn any_network() -> ValidNetworks
    Expand description

    Create a set containing mainnet, testnet and regtest

    +
    \ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/keys/fn.mainnet_network.html b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/keys/fn.mainnet_network.html index eebeca5c55..c7106b9a94 100644 --- a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/keys/fn.mainnet_network.html +++ b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/keys/fn.mainnet_network.html @@ -1,11 +1,3 @@ -mainnet_network in bdk::keys - Rust - -
    -

    Function bdk::keys::mainnet_network

    source · []
    pub fn mainnet_network() -> ValidNetworks
    Expand description

    Create a set only containing mainnet

    -
    - \ No newline at end of file +mainnet_network in bdk::keys - Rust

    Function bdk::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/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/keys/fn.merge_networks.html b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/keys/fn.merge_networks.html index 79a8ad700c..6e4c1620d2 100644 --- a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/keys/fn.merge_networks.html +++ b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/keys/fn.merge_networks.html @@ -1,11 +1,3 @@ -merge_networks in bdk::keys - Rust - -
    -

    Function bdk::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 +merge_networks in bdk::keys - Rust

    Function bdk::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/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/keys/fn.test_networks.html b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/keys/fn.test_networks.html index 8c93e75414..8fc6cf361d 100644 --- a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/keys/fn.test_networks.html +++ b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/keys/fn.test_networks.html @@ -1,11 +1,3 @@ -test_networks in bdk::keys - Rust - -
    -

    Function bdk::keys::test_networks

    source · []
    pub fn test_networks() -> ValidNetworks
    Expand description

    Create a set containing testnet and regtest

    -
    - \ No newline at end of file +test_networks in bdk::keys - Rust

    Function bdk::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/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/keys/index.html b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/keys/index.html index 0778c51260..548e2b1192 100644 --- a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/keys/index.html +++ b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/keys/index.html @@ -1,45 +1,6 @@ -bdk::keys - Rust - -
    -

    Module bdk::keys

    source · []
    Expand description

    Key formats

    -

    Modules

    -
    bip39keys-bip39

    BIP-0039

    -

    Structs

    -

    Output of a GeneratableKey key generation

    -

    Options for generating a [PrivateKey]

    -

    A descriptor [bitcoin::PrivateKey] with optional origin information.

    -

    A descriptor SinglePubKey with optional origin information.

    -

    Contents of a “sortedmulti” descriptor

    -

    Enums

    -

    Container for public or secret keys

    -

    The descriptor pubkey, either a single pubkey or an xpub.

    -

    The descriptor secret key, either a single private key or an xprv.

    -

    Enum for extended keys that can be either xprv or xpub

    -

    Errors thrown while working with keys

    -

    Enum representation of the known valid ScriptContexts

    -

    Single public key without any origin or range information.

    -

    Traits

    -

    Trait for keys that can be derived.

    -

    Trait that adds extra useful methods to ScriptContexts

    -

    Trait that allows generating a key with the default options

    -

    Trait for keys that can be generated

    -

    Trait for objects that can be turned into a public or secret DescriptorKey

    -

    The ScriptContext for Miniscript. Additional type information associated with +bdk::keys - Rust

    Module bdk::keys

    source ·
    Expand description

    Key formats

    +

    Modules

    bip39keys-bip39
    BIP-0039

    Structs

    Output of a GeneratableKey key generation
    Options for generating a [PrivateKey]
    A descriptor [bitcoin::PrivateKey] with optional origin information.
    A descriptor SinglePubKey with optional origin information.
    Contents of a “sortedmulti” descriptor

    Enums

    Container for public or secret keys
    The descriptor pubkey, either a single pubkey or an xpub.
    The descriptor secret key, either a single private key or an xprv.
    Enum for extended keys that can be either xprv or xpub
    Errors thrown while working with keys
    Enum representation of the known valid ScriptContexts
    Single public key without any origin or range information.

    Traits

    Trait for keys that can be derived.
    Trait that adds extra useful methods to ScriptContexts
    Trait that allows generating a key with the default options
    Trait for keys that can be generated
    Trait for objects that can be turned into a public or secret DescriptorKey
    The ScriptContext for Miniscript. Additional type information associated with miniscript that is used for carrying out checks that dependent on the context under which the script is used. -For example, disallowing uncompressed keys in Segwit context

    -

    Functions

    -

    Create a set containing mainnet, testnet and regtest

    -

    Create a set only containing mainnet

    -

    Compute the intersection of two sets

    -

    Create a set containing testnet and regtest

    -

    Type Definitions

    -

    Alias type for a map of public key to secret key

    -

    Set of valid networks for a key

    -
    - \ No newline at end of file +For example, disallowing uncompressed keys in Segwit context

    Functions

    Create a set containing mainnet, testnet and regtest
    Create a set only containing mainnet
    Compute the intersection of two sets
    Create a set containing testnet and regtest

    Type Definitions

    Alias type for a map of public key to secret key
    Set of valid networks for a key
    \ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/keys/sidebar-items.js b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/keys/sidebar-items.js index 6ce19abf5b..9e4dddf388 100644 --- a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/keys/sidebar-items.js +++ b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/keys/sidebar-items.js @@ -1 +1 @@ -initSidebarItems({"enum":[["DescriptorKey","Container for public or secret keys"],["DescriptorPublicKey","The descriptor pubkey, either a single pubkey or an xpub."],["DescriptorSecretKey","The descriptor secret key, either a single private key or an xprv."],["ExtendedKey","Enum for extended keys that can be either `xprv` or `xpub`"],["KeyError","Errors thrown while working with `keys`"],["ScriptContextEnum","Enum representation of the known valid [`ScriptContext`]s"],["SinglePubKey","Single public key without any origin or range information."]],"fn":[["any_network","Create a set containing mainnet, testnet and regtest"],["mainnet_network","Create a set only containing mainnet"],["merge_networks","Compute the intersection of two sets"],["test_networks","Create a set containing testnet and regtest"]],"mod":[["bip39","BIP-0039"]],"struct":[["GeneratedKey","Output of a [`GeneratableKey`] key generation"],["PrivateKeyGenerateOptions","Options for generating a [`PrivateKey`]"],["SinglePriv","A descriptor [`bitcoin::PrivateKey`] with optional origin information."],["SinglePub","A descriptor [`SinglePubKey`] with optional origin information."],["SortedMultiVec","Contents of a “sortedmulti” descriptor"]],"trait":[["DerivableKey","Trait for keys that can be derived."],["ExtScriptContext","Trait that adds extra useful methods to [`ScriptContext`]s"],["GeneratableDefaultOptions","Trait that allows generating a key with the default options"],["GeneratableKey","Trait for keys that can be generated"],["IntoDescriptorKey","Trait for objects that can be turned into a public or secret [`DescriptorKey`]"],["ScriptContext","The ScriptContext for Miniscript. Additional type information associated with miniscript that is used for carrying out checks that dependent on the context under which the script is used. For example, disallowing uncompressed keys in Segwit context"]],"type":[["KeyMap","Alias type for a map of public key to secret key"],["ValidNetworks","Set of valid networks for a key"]]}); \ No newline at end of file +window.SIDEBAR_ITEMS = {"enum":[["DescriptorKey","Container for public or secret keys"],["DescriptorPublicKey","The descriptor pubkey, either a single pubkey or an xpub."],["DescriptorSecretKey","The descriptor secret key, either a single private key or an xprv."],["ExtendedKey","Enum for extended keys that can be either `xprv` or `xpub`"],["KeyError","Errors thrown while working with `keys`"],["ScriptContextEnum","Enum representation of the known valid [`ScriptContext`]s"],["SinglePubKey","Single public key without any origin or range information."]],"fn":[["any_network","Create a set containing mainnet, testnet and regtest"],["mainnet_network","Create a set only containing mainnet"],["merge_networks","Compute the intersection of two sets"],["test_networks","Create a set containing testnet and regtest"]],"mod":[["bip39","BIP-0039"]],"struct":[["GeneratedKey","Output of a [`GeneratableKey`] key generation"],["PrivateKeyGenerateOptions","Options for generating a [`PrivateKey`]"],["SinglePriv","A descriptor [`bitcoin::PrivateKey`] with optional origin information."],["SinglePub","A descriptor [`SinglePubKey`] with optional origin information."],["SortedMultiVec","Contents of a “sortedmulti” descriptor"]],"trait":[["DerivableKey","Trait for keys that can be derived."],["ExtScriptContext","Trait that adds extra useful methods to [`ScriptContext`]s"],["GeneratableDefaultOptions","Trait that allows generating a key with the default options"],["GeneratableKey","Trait for keys that can be generated"],["IntoDescriptorKey","Trait for objects that can be turned into a public or secret [`DescriptorKey`]"],["ScriptContext","The ScriptContext for Miniscript. Additional type information associated with miniscript that is used for carrying out checks that dependent on the context under which the script is used. For example, disallowing uncompressed keys in Segwit context"]],"type":[["KeyMap","Alias type for a map of public key to secret key"],["ValidNetworks","Set of valid networks for a key"]]}; \ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/keys/struct.GeneratedKey.html b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/keys/struct.GeneratedKey.html index 778c9c84bc..361fee444a 100644 --- a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/keys/struct.GeneratedKey.html +++ b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/keys/struct.GeneratedKey.html @@ -1,38 +1,9 @@ -GeneratedKey in bdk::keys - Rust - -
    -

    Struct bdk::keys::GeneratedKey

    source · []
    pub struct GeneratedKey<K, Ctx: ScriptContext> { /* private fields */ }
    Expand description

    Output of a GeneratableKey key generation

    -

    Implementations

    Consumes self and returns the key

    -

    Trait Implementations

    Returns a copy of the value. Read more

    -

    Performs copy-assignment from source. Read more

    -

    The resulting type after dereferencing.

    -

    Dereferences the value.

    -

    Consume self and turn it into an ExtendedKey Read more

    -

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

    -

    Turn the key into a DescriptorKey within the requested ScriptContext

    -

    Auto Trait Implementations

    Blanket Implementations

    Gets the TypeId of self. Read more

    -

    Immutably borrows from an owned value. Read more

    -

    Mutably borrows from an owned value. Read more

    -

    Performs the conversion.

    -

    Performs the conversion.

    -

    The alignment of pointer.

    -

    The type for initializers.

    -

    Initializes a with the given initializer. Read more

    -

    Dereferences the given pointer. Read more

    -

    Mutably dereferences the given pointer. Read more

    -

    Drops the object pointed to by the given pointer. Read more

    -

    The resulting type after obtaining ownership.

    -

    Creates owned data from borrowed data, usually by cloning. Read more

    -
    🔬 This is a nightly-only experimental API. (toowned_clone_into)

    Uses borrowed data to replace owned data, usually by cloning. Read more

    -

    The type returned in the event of a conversion error.

    -

    Performs the conversion.

    -

    The type returned in the event of a conversion error.

    -

    Performs the conversion.

    -
    - \ No newline at end of file +GeneratedKey in bdk::keys - Rust

    Struct bdk::keys::GeneratedKey

    source ·
    pub struct GeneratedKey<K, Ctx: ScriptContext> { /* private fields */ }
    Expand description

    Output of a GeneratableKey key generation

    +

    Implementations§

    Consumes self and returns the key

    +

    Trait Implementations§

    Returns a copy of the value. Read more
    Performs copy-assignment from source. Read more
    The resulting type after dereferencing.
    Dereferences the value.
    Consume self and turn it into an ExtendedKey Read more
    Consume self and turn it into a DescriptorKey by adding the extra metadata, such as +key origin and derivation path Read more
    Turn the key into a DescriptorKey within the requested ScriptContext

    Auto Trait Implementations§

    Blanket Implementations§

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

    Returns the argument unchanged.

    +

    Calls U::from(self).

    +

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

    +
    The alignment of pointer.
    The type for initializers.
    Initializes a with the given initializer. Read more
    Dereferences the given pointer. Read more
    Mutably dereferences the given pointer. Read more
    Drops the object pointed to by the given pointer. Read more
    The resulting type after obtaining ownership.
    Creates owned data from borrowed data, usually by cloning. Read more
    Uses borrowed data to replace owned data, usually by cloning. Read more
    The type returned in the event of a conversion error.
    Performs the conversion.
    The type returned in the event of a conversion error.
    Performs the conversion.
    \ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/keys/struct.PrivateKeyGenerateOptions.html b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/keys/struct.PrivateKeyGenerateOptions.html index 71c2971f49..3b20437518 100644 --- a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/keys/struct.PrivateKeyGenerateOptions.html +++ b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/keys/struct.PrivateKeyGenerateOptions.html @@ -1,37 +1,11 @@ -PrivateKeyGenerateOptions in bdk::keys - Rust - -
    pub struct PrivateKeyGenerateOptions {
    +PrivateKeyGenerateOptions in bdk::keys - Rust
    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

    Returns a copy of the value. Read more

    -

    Performs copy-assignment from source. Read more

    -

    Formats the value using the given formatter. Read more

    -

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

    -

    Auto Trait Implementations

    Blanket Implementations

    Gets the TypeId of self. Read more

    -

    Immutably borrows from an owned value. Read more

    -

    Mutably borrows from an owned value. Read more

    -

    Performs the conversion.

    -

    Performs the conversion.

    -

    The alignment of pointer.

    -

    The type for initializers.

    -

    Initializes a with the given initializer. Read more

    -

    Dereferences the given pointer. Read more

    -

    Mutably dereferences the given pointer. Read more

    -

    Drops the object pointed to by the given pointer. Read more

    -

    The resulting type after obtaining ownership.

    -

    Creates owned data from borrowed data, usually by cloning. Read more

    -
    🔬 This is a nightly-only experimental API. (toowned_clone_into)

    Uses borrowed data to replace owned data, usually by cloning. Read more

    -

    The type returned in the event of a conversion error.

    -

    Performs the conversion.

    -

    The type returned in the event of a conversion error.

    -

    Performs the conversion.

    -
    - \ No newline at end of file +

    Fields§

    §compressed: bool

    Whether the generated key should be “compressed” or not

    +

    Trait Implementations§

    Returns a copy of the value. Read more
    Performs copy-assignment from source. Read more
    Formats the value using the given formatter. Read more
    Returns the “default value” for a type. Read more

    Auto Trait Implementations§

    Blanket Implementations§

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

    Returns the argument unchanged.

    +

    Calls U::from(self).

    +

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

    +
    The alignment of pointer.
    The type for initializers.
    Initializes a with the given initializer. Read more
    Dereferences the given pointer. Read more
    Mutably dereferences the given pointer. Read more
    Drops the object pointed to by the given pointer. Read more
    The resulting type after obtaining ownership.
    Creates owned data from borrowed data, usually by cloning. Read more
    Uses borrowed data to replace owned data, usually by cloning. Read more
    The type returned in the event of a conversion error.
    Performs the conversion.
    The type returned in the event of a conversion error.
    Performs the conversion.
    \ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/keys/struct.SinglePriv.html b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/keys/struct.SinglePriv.html index 3e5a27ed7b..087eacb400 100644 --- a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/keys/struct.SinglePriv.html +++ b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/keys/struct.SinglePriv.html @@ -1,32 +1,12 @@ -SinglePriv in bdk::keys - Rust - -
    pub struct SinglePriv {
    -    pub origin: Option<(Fingerprint, DerivationPath)>,
    +SinglePriv in bdk::keys - Rust

    Struct bdk::keys::SinglePriv

    pub struct SinglePriv {
    +    pub origin: Option<(Fingerprint, DerivationPath)>,
         pub key: PrivateKey,
     }
    Expand description

    A descriptor [bitcoin::PrivateKey] with optional origin information.

    -

    Fields

    origin: Option<(Fingerprint, DerivationPath)>

    Origin information (fingerprint and derivation path).

    -
    key: PrivateKey

    The private key.

    -

    Trait Implementations

    Formats the value using the given formatter. Read more

    -

    Auto Trait Implementations

    Blanket Implementations

    Gets the TypeId of self. Read more

    -

    Immutably borrows from an owned value. Read more

    -

    Mutably borrows from an owned value. Read more

    -

    Performs the conversion.

    -

    Performs the conversion.

    -

    The alignment of pointer.

    -

    The type for initializers.

    -

    Initializes a with the given initializer. Read more

    -

    Dereferences the given pointer. Read more

    -

    Mutably dereferences the given pointer. Read more

    -

    Drops the object pointed to by the given pointer. Read more

    -

    The type returned in the event of a conversion error.

    -

    Performs the conversion.

    -

    The type returned in the event of a conversion error.

    -

    Performs the conversion.

    -
    - \ No newline at end of file +

    Fields§

    §origin: Option<(Fingerprint, DerivationPath)>

    Origin information (fingerprint and derivation path).

    +
    §key: PrivateKey

    The private key.

    +

    Trait Implementations§

    Formats the value using the given formatter. Read more

    Auto Trait Implementations§

    Blanket Implementations§

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

    Returns the argument unchanged.

    +

    Calls U::from(self).

    +

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

    +
    The alignment of pointer.
    The type for initializers.
    Initializes a with the given initializer. Read more
    Dereferences the given pointer. Read more
    Mutably dereferences the given pointer. Read more
    Drops the object pointed to by the given pointer. Read more
    The type returned in the event of a conversion error.
    Performs the conversion.
    The type returned in the event of a conversion error.
    Performs the conversion.
    \ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/keys/struct.SinglePub.html b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/keys/struct.SinglePub.html index 7dbce9a1b0..effbffa9c9 100644 --- a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/keys/struct.SinglePub.html +++ b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/keys/struct.SinglePub.html @@ -1,53 +1,16 @@ -SinglePub in bdk::keys - Rust - -
    -

    Struct bdk::keys::SinglePub

    []
    pub struct SinglePub {
    -    pub origin: Option<(Fingerprint, DerivationPath)>,
    +SinglePub in bdk::keys - Rust

    Struct bdk::keys::SinglePub

    pub struct SinglePub {
    +    pub origin: Option<(Fingerprint, DerivationPath)>,
         pub key: SinglePubKey,
     }
    Expand description

    A descriptor SinglePubKey with optional origin information.

    -

    Fields

    origin: Option<(Fingerprint, DerivationPath)>

    Origin information (fingerprint and derivation path).

    -
    key: SinglePubKey

    The public key.

    -

    Trait Implementations

    Returns a copy of the value. Read more

    -

    Performs copy-assignment from source. Read more

    -

    Formats the value using the given formatter. Read more

    -

    Feeds this value into the given Hasher. Read more

    -

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

    -

    This method returns an Ordering between self and other. Read more

    -

    Compares and returns the maximum of two values. Read more

    -

    Compares and returns the minimum of two values. Read more

    -

    Restrict a value to a certain interval. Read more

    -

    This method tests for self and other values to be equal, and is used -by ==. Read more

    -

    This method tests for !=.

    -

    This method returns an ordering between self and other values if one exists. Read more

    -

    This method tests less than (for self and other) and is used by the < operator. Read more

    -

    This method tests less than or equal to (for self and other) and is used by the <= -operator. Read more

    -

    This method tests greater than (for self and other) and is used by the > operator. Read more

    -

    This method tests greater than or equal to (for self and other) and is used by the >= -operator. Read more

    -

    Auto Trait Implementations

    Blanket Implementations

    Gets the TypeId of self. Read more

    -

    Immutably borrows from an owned value. Read more

    -

    Mutably borrows from an owned value. Read more

    -

    Performs the conversion.

    -

    Performs the conversion.

    -

    The alignment of pointer.

    -

    The type for initializers.

    -

    Initializes a with the given initializer. Read more

    -

    Dereferences the given pointer. Read more

    -

    Mutably dereferences the given pointer. Read more

    -

    Drops the object pointed to by the given pointer. Read more

    -

    The resulting type after obtaining ownership.

    -

    Creates owned data from borrowed data, usually by cloning. Read more

    -
    🔬 This is a nightly-only experimental API. (toowned_clone_into)

    Uses borrowed data to replace owned data, usually by cloning. Read more

    -

    The type returned in the event of a conversion error.

    -

    Performs the conversion.

    -

    The type returned in the event of a conversion error.

    -

    Performs the conversion.

    -
    - \ No newline at end of file +

    Fields§

    §origin: Option<(Fingerprint, DerivationPath)>

    Origin information (fingerprint and derivation path).

    +
    §key: SinglePubKey

    The public key.

    +

    Trait Implementations§

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

    Auto Trait Implementations§

    Blanket Implementations§

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

    Returns the argument unchanged.

    +

    Calls U::from(self).

    +

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

    +
    The alignment of pointer.
    The type for initializers.
    Initializes a with the given initializer. Read more
    Dereferences the given pointer. Read more
    Mutably dereferences the given pointer. Read more
    Drops the object pointed to by the given pointer. Read more
    The resulting type after obtaining ownership.
    Creates owned data from borrowed data, usually by cloning. Read more
    Uses borrowed data to replace owned data, usually by cloning. Read more
    The type returned in the event of a conversion error.
    Performs the conversion.
    The type returned in the event of a conversion error.
    Performs the conversion.
    \ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/keys/struct.SortedMultiVec.html b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/keys/struct.SortedMultiVec.html index 04993a957f..f25500a420 100644 --- a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/keys/struct.SortedMultiVec.html +++ b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/keys/struct.SortedMultiVec.html @@ -1,92 +1,50 @@ -SortedMultiVec in bdk::keys - Rust - -
    pub struct SortedMultiVec<Pk, Ctx> where
        Pk: MiniscriptKey,
        Ctx: ScriptContext
    { +SortedMultiVec in bdk::keys - Rust

    Struct bdk::keys::SortedMultiVec

    pub struct SortedMultiVec<Pk, Ctx>where
        Pk: MiniscriptKey,
        Ctx: ScriptContext,
    { pub k: usize, pub pks: Vec<Pk, Global>, /* private fields */ }
    Expand description

    Contents of a “sortedmulti” descriptor

    -

    Fields

    k: usize

    signatures required

    -
    pks: Vec<Pk, Global>

    public keys inside sorted Multi

    -

    Implementations

    Create a new instance of SortedMultiVec given a list of keys and the threshold

    +

    Fields§

    §k: usize

    signatures required

    +
    §pks: Vec<Pk, Global>

    public keys inside sorted Multi

    +

    Implementations§

    Create a new instance of SortedMultiVec given a list of keys and the threshold

    Internally checks all the applicable size limits and pubkey types limitations according to the current Ctx.

    -

    Parse an expression tree into a SortedMultiVec

    -

    This will panic if fpk returns an uncompressed key when +

    Parse an expression tree into a SortedMultiVec

    +

    This will panic if fpk returns an uncompressed key when converting to a Segwit descriptor. To prevent this panic, ensure fpk returns an error in this case instead.

    -

    utility function to sanity a sorted multi vec

    -

    Create Terminal::Multi containing sorted pubkeys

    -

    Encode as a Bitcoin script

    -

    Attempt to produce a satisfying witness for the +

    utility function to sanity a sorted multi vec

    +

    Create Terminal::Multi containing sorted pubkeys

    +

    Encode as a Bitcoin script

    +

    Attempt to produce a satisfying witness for the witness script represented by the parse tree

    -

    Size, in bytes of the script-pubkey. If this Miniscript is used outside +

    Size, in bytes of the script-pubkey. If this Miniscript is used outside of segwit (e.g. in a bare or P2SH descriptor), this quantity should be multiplied by 4 to compute the weight.

    In general, it is not recommended to use this function directly, but to instead call the corresponding function on a Descriptor, which will handle the segwit/non-segwit technicalities for you.

    -

    Maximum number of witness elements used to satisfy the Miniscript +

    Maximum number of witness elements used to satisfy the Miniscript fragment, including the witness script itself. Used to estimate the weight of the VarInt that specifies this number in a serialized transaction.

    This function may panic on malformed Miniscript objects which do not correspond to semantically sane Scripts. (Such scripts should be rejected at parse time. Any exceptions are bugs.)

    -

    Maximum size, in bytes, of a satisfying witness. +

    Maximum size, in bytes, of a satisfying witness. In general, it is not recommended to use this function directly, but to instead call the corresponding function on a Descriptor, which will handle the segwit/non-segwit technicalities for you.

    All signatures are assumed to be 73 bytes in size, including the length prefix (segwit) or push opcode (pre-segwit) and sighash postfix.

    -

    Trait Implementations

    Returns a copy of the value. Read more

    -

    Performs copy-assignment from source. Read more

    -

    Formats the value using the given formatter. Read more

    -

    Formats the value using the given formatter. Read more

    -

    Run a predicate on every key in the descriptor, returning whether -the predicate returned true for every key Read more

    -

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

    -

    Feeds this value into the given Hasher. Read more

    -

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

    -

    Convert the object into an abstract policy

    -

    This method returns an Ordering between self and other. Read more

    -

    Compares and returns the maximum of two values. Read more

    -

    Compares and returns the minimum of two values. Read more

    -

    Restrict a value to a certain interval. Read more

    -

    This method tests for self and other values to be equal, and is used -by ==. Read more

    -

    This method tests for !=.

    -

    This method returns an ordering between self and other values if one exists. Read more

    -

    This method tests less than (for self and other) and is used by the < operator. Read more

    -

    This method tests less than or equal to (for self and other) and is used by the <= -operator. Read more

    -

    This method tests greater than (for self and other) and is used by the > operator. Read more

    -

    This method tests greater than or equal to (for self and other) and is used by the >= -operator. Read more

    -

    Auto Trait Implementations

    Blanket Implementations

    Gets the TypeId of self. Read more

    -

    Immutably borrows from an owned value. Read more

    -

    Mutably borrows from an owned value. Read more

    -

    Performs the conversion.

    -

    Performs the conversion.

    -

    The alignment of pointer.

    -

    The type for initializers.

    -

    Initializes a with the given initializer. Read more

    -

    Dereferences the given pointer. Read more

    -

    Mutably dereferences the given pointer. Read more

    -

    Drops the object pointed to by the given pointer. Read more

    -

    The resulting type after obtaining ownership.

    -

    Creates owned data from borrowed data, usually by cloning. Read more

    -
    🔬 This is a nightly-only experimental API. (toowned_clone_into)

    Uses borrowed data to replace owned data, usually by cloning. Read more

    -

    Converts the given value to a String. Read more

    -

    The type returned in the event of a conversion error.

    -

    Performs the conversion.

    -

    The type returned in the event of a conversion error.

    -

    Performs the conversion.

    -
    - \ No newline at end of file +

    Trait Implementations§

    Returns a copy of the value. Read more
    Performs copy-assignment from source. Read more
    Formats the value using the given formatter. Read more
    Formats the value using the given formatter. Read more
    Run a predicate on every key in the descriptor, returning whether +the predicate returned true for every key Read more
    Run a predicate on every key in the descriptor, returning whether +the predicate returned true for any key Read more
    Feeds this value into the given Hasher. Read more
    Feeds a slice of this type into the given Hasher. Read more
    Convert the object into an abstract policy
    This method returns an Ordering between self and other. Read more
    Compares and returns the maximum of two values. Read more
    Compares and returns the minimum of two values. Read more
    Restrict a value to a certain interval. Read more
    This method tests for self and other values to be equal, and is used +by ==. Read more
    This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason. Read more
    This method returns an ordering between self and other values if one exists. Read more
    This method tests less than (for self and other) and is used by the < operator. Read more
    This method tests less than or equal to (for self and other) and is used by the <= +operator. Read more
    This method tests greater than (for self and other) and is used by the > operator. Read more
    This method tests greater than or equal to (for self and other) and is used by the >= +operator. Read more

    Auto Trait Implementations§

    Blanket Implementations§

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

    Returns the argument unchanged.

    +

    Calls U::from(self).

    +

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

    +
    The alignment of pointer.
    The type for initializers.
    Initializes a with the given initializer. Read more
    Dereferences the given pointer. Read more
    Mutably dereferences the given pointer. Read more
    Drops the object pointed to by the given pointer. Read more
    The resulting type after obtaining ownership.
    Creates owned data from borrowed data, usually by cloning. Read more
    Uses borrowed data to replace owned data, usually by cloning. Read more
    Converts the given value to a String. Read more
    The type returned in the event of a conversion error.
    Performs the conversion.
    The type returned in the event of a conversion error.
    Performs the conversion.
    \ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/keys/trait.DerivableKey.html b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/keys/trait.DerivableKey.html index ded8486131..f0b6ed90ee 100644 --- a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/keys/trait.DerivableKey.html +++ b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/keys/trait.DerivableKey.html @@ -1,15 +1,8 @@ -DerivableKey in bdk::keys - Rust - -
    pub trait DerivableKey<Ctx: ScriptContext = Legacy>: Sized {
    -    fn into_extended_key(self) -> Result<ExtendedKey<Ctx>, KeyError>;
    +DerivableKey in bdk::keys - Rust

    Trait bdk::keys::DerivableKey

    source ·
    pub trait DerivableKey<Ctx: ScriptContext = Legacy>: Sized {
    +    fn into_extended_key(self) -> Result<ExtendedKey<Ctx>, KeyError>;
     
    -    fn into_descriptor_key(
            self,
            origin: Option<KeySource>,
            derivation_path: DerivationPath
        ) -> Result<DescriptorKey<Ctx>, KeyError> { ... } + fn into_descriptor_key(
            self,
            origin: Option<KeySource>,
            derivation_path: DerivationPath
        ) -> Result<DescriptorKey<Ctx>, KeyError> { ... } }
    Expand description

    Trait for keys that can be derived.

    When extra metadata are provided, a DerivableKey can be transformed into a DescriptorKey: the trait IntoDescriptorKey is automatically implemented @@ -18,93 +11,92 @@ for (DerivableKey, DerivationPath) and

    For key types that don’t encode any indication about the path to use (like bip39), it’s generally recommended to implemented this trait instead of IntoDescriptorKey. The same rules regarding script context and valid networks apply.

    -

    Examples

    +

    Examples

    Key types that can be directly converted into an ExtendedPrivKey or an ExtendedPubKey can implement only the required into_extended_key() method.

    -
    use bdk::bitcoin;
    -use bdk::bitcoin::util::bip32;
    -use bdk::keys::{DerivableKey, ExtendedKey, KeyError, ScriptContext};
    +
    use bdk::bitcoin;
    +use bdk::bitcoin::util::bip32;
    +use bdk::keys::{DerivableKey, ExtendedKey, KeyError, ScriptContext};
     
    -struct MyCustomKeyType {
    -    key_data: bitcoin::PrivateKey,
    -    chain_code: Vec<u8>,
    -    network: bitcoin::Network,
    +struct MyCustomKeyType {
    +    key_data: bitcoin::PrivateKey,
    +    chain_code: Vec<u8>,
    +    network: bitcoin::Network,
     }
     
    -impl<Ctx: ScriptContext> DerivableKey<Ctx> for MyCustomKeyType {
    -    fn into_extended_key(self) -> Result<ExtendedKey<Ctx>, KeyError> {
    -        let xprv = bip32::ExtendedPrivKey {
    -            network: self.network,
    -            depth: 0,
    -            parent_fingerprint: bip32::Fingerprint::default(),
    -            private_key: self.key_data.inner,
    -            chain_code: bip32::ChainCode::from(self.chain_code.as_ref()),
    -            child_number: bip32::ChildNumber::Normal { index: 0 },
    +impl<Ctx: ScriptContext> DerivableKey<Ctx> for MyCustomKeyType {
    +    fn into_extended_key(self) -> Result<ExtendedKey<Ctx>, KeyError> {
    +        let xprv = bip32::ExtendedPrivKey {
    +            network: self.network,
    +            depth: 0,
    +            parent_fingerprint: bip32::Fingerprint::default(),
    +            private_key: self.key_data.inner,
    +            chain_code: bip32::ChainCode::from(self.chain_code.as_ref()),
    +            child_number: bip32::ChildNumber::Normal { index: 0 },
             };
     
    -        xprv.into_extended_key()
    +        xprv.into_extended_key()
         }
     }

    Types that don’t internally encode the Network in which they are valid need some extra steps to override the set of valid networks, otherwise only the network specified in the ExtendedPrivKey or ExtendedPubKey will be considered valid.

    -
    use bdk::bitcoin;
    -use bdk::bitcoin::util::bip32;
    -use bdk::keys::{
    -    any_network, DerivableKey, DescriptorKey, ExtendedKey, KeyError, ScriptContext,
    +
    use bdk::bitcoin;
    +use bdk::bitcoin::util::bip32;
    +use bdk::keys::{
    +    any_network, DerivableKey, DescriptorKey, ExtendedKey, KeyError, ScriptContext,
     };
     
    -struct MyCustomKeyType {
    -    key_data: bitcoin::PrivateKey,
    -    chain_code: Vec<u8>,
    +struct MyCustomKeyType {
    +    key_data: bitcoin::PrivateKey,
    +    chain_code: Vec<u8>,
     }
     
    -impl<Ctx: ScriptContext> DerivableKey<Ctx> for MyCustomKeyType {
    -    fn into_extended_key(self) -> Result<ExtendedKey<Ctx>, KeyError> {
    -        let xprv = bip32::ExtendedPrivKey {
    -            network: bitcoin::Network::Bitcoin, // pick an arbitrary network here
    -            depth: 0,
    -            parent_fingerprint: bip32::Fingerprint::default(),
    -            private_key: self.key_data.inner,
    -            chain_code: bip32::ChainCode::from(self.chain_code.as_ref()),
    -            child_number: bip32::ChildNumber::Normal { index: 0 },
    +impl<Ctx: ScriptContext> DerivableKey<Ctx> for MyCustomKeyType {
    +    fn into_extended_key(self) -> Result<ExtendedKey<Ctx>, KeyError> {
    +        let xprv = bip32::ExtendedPrivKey {
    +            network: bitcoin::Network::Bitcoin, // pick an arbitrary network here
    +            depth: 0,
    +            parent_fingerprint: bip32::Fingerprint::default(),
    +            private_key: self.key_data.inner,
    +            chain_code: bip32::ChainCode::from(self.chain_code.as_ref()),
    +            child_number: bip32::ChildNumber::Normal { index: 0 },
             };
     
    -        xprv.into_extended_key()
    +        xprv.into_extended_key()
         }
     
    -    fn into_descriptor_key(
    +    fn into_descriptor_key(
             self,
    -        source: Option<bip32::KeySource>,
    -        derivation_path: bip32::DerivationPath,
    -    ) -> Result<DescriptorKey<Ctx>, KeyError> {
    -        let descriptor_key = self
    -            .into_extended_key()?
    -            .into_descriptor_key(source, derivation_path)?;
    +        source: Option<bip32::KeySource>,
    +        derivation_path: bip32::DerivationPath,
    +    ) -> Result<DescriptorKey<Ctx>, KeyError> {
    +        let descriptor_key = self
    +            .into_extended_key()?
    +            .into_descriptor_key(source, derivation_path)?;
     
    -        // Override the set of valid networks here
    -        Ok(descriptor_key.override_valid_networks(any_network()))
    +        // Override the set of valid networks here
    +        Ok(descriptor_key.override_valid_networks(any_network()))
         }
     }
    -

    Required methods

    Consume self and turn it into an ExtendedKey

    +

    Required Methods§

    Consume self and turn it into an ExtendedKey

    This can be used to get direct access to xprvs and xpubs for types that implement this trait, like Mnemonic when the keys-bip39 feature is enabled.

    -
    use bdk::bitcoin::Network;
    -use bdk::keys::{DerivableKey, ExtendedKey};
    -use bdk::keys::bip39::{Mnemonic, Language};
    +
    use bdk::bitcoin::Network;
    +use bdk::keys::{DerivableKey, ExtendedKey};
    +use bdk::keys::bip39::{Mnemonic, Language};
     
    -let xkey: ExtendedKey =
    -    Mnemonic::parse_in(
    -        Language::English,
    +let xkey: ExtendedKey =
    +    Mnemonic::parse_in(
    +        Language::English,
             "jelly crash boy whisper mouse ecology tuna soccer memory million news short",
    -    )?
    -    .into_extended_key()?;
    -let xprv = xkey.into_xprv(Network::Bitcoin).unwrap();
    -

    Provided methods

    Consume self and turn it into a DescriptorKey by adding the extra metadata, such as + )? + .into_extended_key()?; +let xprv = xkey.into_xprv(Network::Bitcoin).unwrap();

    +

    Provided Methods§

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

    -

    Implementations on Foreign Types

    Implementors

    Identity conversion

    -
    - \ No newline at end of file +

    Implementations on Foreign Types§

    Implementors§

    Identity conversion

    +
    \ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/keys/trait.ExtScriptContext.html b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/keys/trait.ExtScriptContext.html index 9e9103381a..f9d1ecc137 100644 --- a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/keys/trait.ExtScriptContext.html +++ b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/keys/trait.ExtScriptContext.html @@ -1,21 +1,13 @@ -ExtScriptContext in bdk::keys - Rust - -
    pub trait ExtScriptContext: ScriptContext {
    -    fn as_enum() -> ScriptContextEnum;
    +ExtScriptContext in bdk::keys - Rust

    Trait bdk::keys::ExtScriptContext

    source ·
    pub trait ExtScriptContext: ScriptContext {
    +    fn as_enum() -> ScriptContextEnum;
     
    -    fn is_legacy() -> bool { ... }
    -
    fn is_segwit_v0() -> bool { ... } -
    fn is_taproot() -> bool { ... } + fn is_legacy() -> bool { ... } + fn is_segwit_v0() -> bool { ... } + fn is_taproot() -> bool { ... } }
    Expand description

    Trait that adds extra useful methods to ScriptContexts

    -

    Required methods

    Provided methods

    Returns whether the script context is Legacy

    -

    Returns whether the script context is Segwitv0

    -

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

    -

    Implementors

    - \ No newline at end of file +

    Required Methods§

    Provided Methods§

    Returns whether the script context is Legacy

    +

    Returns whether the script context is Segwitv0

    +

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

    +

    Implementors§

    \ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/keys/trait.GeneratableDefaultOptions.html b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/keys/trait.GeneratableDefaultOptions.html index 632af29c3c..12fc760a21 100644 --- a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/keys/trait.GeneratableDefaultOptions.html +++ b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/keys/trait.GeneratableDefaultOptions.html @@ -1,19 +1,11 @@ -GeneratableDefaultOptions in bdk::keys - Rust - -
    pub trait GeneratableDefaultOptions<Ctx>: GeneratableKey<Ctx> where
        Ctx: ScriptContext,
        <Self as GeneratableKey<Ctx>>::Options: Default
    { - fn generate_with_entropy_default(
            entropy: Self::Entropy
        ) -> Result<GeneratedKey<Self, Ctx>, Self::Error> { ... } -
    fn generate_default() -> Result<GeneratedKey<Self, Ctx>, Self::Error> { ... } +GeneratableDefaultOptions in bdk::keys - Rust
    pub trait GeneratableDefaultOptions<Ctx>: GeneratableKey<Ctx>where
        Ctx: ScriptContext,
        <Self as GeneratableKey<Ctx>>::Options: Default,
    { + fn generate_with_entropy_default(
            entropy: Self::Entropy
        ) -> Result<GeneratedKey<Self, Ctx>, Self::Error> { ... } + fn generate_default() -> 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

    Generate a key with the default options and a given entropy

    -

    Generate a key with the default options and a random entropy

    -

    Implementors

    Automatic implementation of GeneratableDefaultOptions for GeneratableKeys where +

    Provided Methods§

    Generate a key with the default options and a given entropy

    +

    Generate a key with the default options and a random entropy

    +

    Implementors§

    Automatic implementation of GeneratableDefaultOptions for GeneratableKeys where Options implements Default

    -
    - \ No newline at end of file +
    \ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/keys/trait.GeneratableKey.html b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/keys/trait.GeneratableKey.html index 1f7ffd6b0b..c8352b7620 100644 --- a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/keys/trait.GeneratableKey.html +++ b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/keys/trait.GeneratableKey.html @@ -1,28 +1,21 @@ -GeneratableKey in bdk::keys - Rust - -
    pub trait GeneratableKey<Ctx: ScriptContext>: Sized {
    -    type Entropy: AsMut<[u8]> + Default;
    +GeneratableKey in bdk::keys - Rust

    Trait bdk::keys::GeneratableKey

    source ·
    pub trait GeneratableKey<Ctx: ScriptContext>: Sized {
    +    type Entropy: AsMut<[u8]> + Default;
         type Options;
         type Error: Debug;
    -    fn generate_with_entropy(
            options: Self::Options,
            entropy: Self::Entropy
        ) -> Result<GeneratedKey<Self, Ctx>, Self::Error>; - fn generate(
            options: Self::Options
        ) -> Result<GeneratedKey<Self, Ctx>, Self::Error> { ... } + fn generate_with_entropy(
            options: Self::Options,
            entropy: Self::Entropy
        ) -> Result<GeneratedKey<Self, Ctx>, Self::Error>; + + fn generate(
            options: Self::Options
        ) -> 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.

    -

    Associated Types

    Type specifying the amount of entropy required e.g. [u8;32]

    -

    Extra options required by the generate_with_entropy

    -

    Returned error in case of failure

    -

    Required methods

    Generate a key given the extra options and the entropy

    -

    Provided methods

    Generate a key given the options with a random entropy

    -

    Implementations on Foreign Types

    Implementors

    - \ No newline at end of file +

    Required Associated Types§

    Type specifying the amount of entropy required e.g. [u8;32]

    +

    Extra options required by the generate_with_entropy

    +

    Returned error in case of failure

    +

    Required Methods§

    Generate a key given the extra options and the entropy

    +

    Provided Methods§

    Generate a key given the options with a random entropy

    +

    Implementations on Foreign Types§

    Implementors§

    \ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/keys/trait.IntoDescriptorKey.html b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/keys/trait.IntoDescriptorKey.html index b39601a2b6..f147b4174b 100644 --- a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/keys/trait.IntoDescriptorKey.html +++ b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/keys/trait.IntoDescriptorKey.html @@ -1,13 +1,6 @@ -IntoDescriptorKey in bdk::keys - Rust - -
    pub trait IntoDescriptorKey<Ctx: ScriptContext>: Sized {
    -    fn into_descriptor_key(self) -> Result<DescriptorKey<Ctx>, KeyError>;
    +IntoDescriptorKey in bdk::keys - Rust

    Trait bdk::keys::IntoDescriptorKey

    source ·
    pub trait IntoDescriptorKey<Ctx: ScriptContext>: Sized {
    +    fn into_descriptor_key(self) -> Result<DescriptorKey<Ctx>, KeyError>;
     }
    Expand description

    Trait for objects that can be turned into a public or secret DescriptorKey

    The generic type Ctx is used to define the context in which the key is valid: some key formats, like the mnemonics used by Electrum wallets, encode internally whether the wallet is @@ -21,63 +14,63 @@ checking.

    Keys also have control over the networks they support: constructing the return object with DescriptorKey::from_public or DescriptorKey::from_secret allows to specify a set of ValidNetworks.

    -

    Examples

    +

    Examples

    Key type valid in any context:

    -
    use bdk::bitcoin::PublicKey;
    +
    use bdk::bitcoin::PublicKey;
     
    -use bdk::keys::{DescriptorKey, IntoDescriptorKey, KeyError, ScriptContext};
    +use bdk::keys::{DescriptorKey, IntoDescriptorKey, KeyError, ScriptContext};
     
    -pub struct MyKeyType {
    -    pubkey: PublicKey,
    +pub struct MyKeyType {
    +    pubkey: PublicKey,
     }
     
    -impl<Ctx: ScriptContext> IntoDescriptorKey<Ctx> for MyKeyType {
    -    fn into_descriptor_key(self) -> Result<DescriptorKey<Ctx>, KeyError> {
    -        self.pubkey.into_descriptor_key()
    +impl<Ctx: ScriptContext> IntoDescriptorKey<Ctx> for MyKeyType {
    +    fn into_descriptor_key(self) -> Result<DescriptorKey<Ctx>, KeyError> {
    +        self.pubkey.into_descriptor_key()
         }
     }

    Key type that is only valid on mainnet:

    -
    use bdk::bitcoin::PublicKey;
    +
    use bdk::bitcoin::PublicKey;
     
    -use bdk::keys::{
    -    mainnet_network, DescriptorKey, DescriptorPublicKey, IntoDescriptorKey, KeyError,
    -    ScriptContext, SinglePub, SinglePubKey,
    +use bdk::keys::{
    +    mainnet_network, DescriptorKey, DescriptorPublicKey, IntoDescriptorKey, KeyError,
    +    ScriptContext, SinglePub, SinglePubKey,
     };
     
    -pub struct MyKeyType {
    -    pubkey: PublicKey,
    +pub struct MyKeyType {
    +    pubkey: PublicKey,
     }
     
    -impl<Ctx: ScriptContext> IntoDescriptorKey<Ctx> for MyKeyType {
    -    fn into_descriptor_key(self) -> Result<DescriptorKey<Ctx>, KeyError> {
    -        Ok(DescriptorKey::from_public(
    -            DescriptorPublicKey::Single(SinglePub {
    -                origin: None,
    -                key: SinglePubKey::FullKey(self.pubkey),
    +impl<Ctx: ScriptContext> IntoDescriptorKey<Ctx> for MyKeyType {
    +    fn into_descriptor_key(self) -> Result<DescriptorKey<Ctx>, KeyError> {
    +        Ok(DescriptorKey::from_public(
    +            DescriptorPublicKey::Single(SinglePub {
    +                origin: None,
    +                key: SinglePubKey::FullKey(self.pubkey),
                 }),
    -            mainnet_network(),
    +            mainnet_network(),
             ))
         }
     }

    Key type that internally encodes in which context it’s valid. The context is checked at runtime:

    -
    use bdk::bitcoin::PublicKey;
    +
    use bdk::bitcoin::PublicKey;
     
    -use bdk::keys::{DescriptorKey, ExtScriptContext, IntoDescriptorKey, KeyError, ScriptContext};
    +use bdk::keys::{DescriptorKey, ExtScriptContext, IntoDescriptorKey, KeyError, ScriptContext};
     
    -pub struct MyKeyType {
    -    is_legacy: bool,
    -    pubkey: PublicKey,
    +pub struct MyKeyType {
    +    is_legacy: bool,
    +    pubkey: PublicKey,
     }
     
    -impl<Ctx: ScriptContext + 'static> IntoDescriptorKey<Ctx> for MyKeyType {
    -    fn into_descriptor_key(self) -> Result<DescriptorKey<Ctx>, KeyError> {
    -        if Ctx::is_legacy() == self.is_legacy {
    -            self.pubkey.into_descriptor_key()
    -        } else {
    -            Err(KeyError::InvalidScriptContext)
    +impl<Ctx: ScriptContext + 'static> IntoDescriptorKey<Ctx> for MyKeyType {
    +    fn into_descriptor_key(self) -> Result<DescriptorKey<Ctx>, KeyError> {
    +        if Ctx::is_legacy() == self.is_legacy {
    +            self.pubkey.into_descriptor_key()
    +        } else {
    +            Err(KeyError::InvalidScriptContext)
             }
         }
     }
    @@ -87,28 +80,27 @@ of the trait is implemented.

    are misused. In this case, the “segwit-only” key is used to build a pkh() descriptor, which makes the compiler (correctly) fail.

    -
    ⓘ
    use bdk::bitcoin::PublicKey;
    -use std::str::FromStr;
    +
    ⓘ
    use bdk::bitcoin::PublicKey;
    +use std::str::FromStr;
     
    -use bdk::keys::{DescriptorKey, IntoDescriptorKey, KeyError};
    +use bdk::keys::{DescriptorKey, IntoDescriptorKey, KeyError};
     
    -pub struct MySegwitOnlyKeyType {
    -    pubkey: PublicKey,
    +pub struct MySegwitOnlyKeyType {
    +    pubkey: PublicKey,
     }
     
    -impl IntoDescriptorKey<bdk::miniscript::Segwitv0> for MySegwitOnlyKeyType {
    -    fn into_descriptor_key(self) -> Result<DescriptorKey<bdk::miniscript::Segwitv0>, KeyError> {
    -        self.pubkey.into_descriptor_key()
    +impl IntoDescriptorKey<bdk::miniscript::Segwitv0> for MySegwitOnlyKeyType {
    +    fn into_descriptor_key(self) -> Result<DescriptorKey<bdk::miniscript::Segwitv0>, KeyError> {
    +        self.pubkey.into_descriptor_key()
         }
     }
     
    -let key = MySegwitOnlyKeyType {
    -    pubkey: PublicKey::from_str("...")?,
    +let key = MySegwitOnlyKeyType {
    +    pubkey: PublicKey::from_str("...")?,
     };
    -let (descriptor, _, _) = bdk::descriptor!(pkh(key))?;
    -//                                       ^^^^^ changing this to `wpkh` would make it compile
    -
    -

    Required methods

    Turn the key into a DescriptorKey within the requested ScriptContext

    -

    Implementations on Foreign Types

    Implementors

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

    -
    - \ No newline at end of file +let (descriptor, _, _) = bdk::descriptor!(pkh(key))?; +// ^^^^^ changing this to `wpkh` would make it compile +
    +

    Required Methods§

    Turn the key into a DescriptorKey within the requested ScriptContext

    +

    Implementations on Foreign Types§

    Implementors§

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

    +
    \ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/keys/trait.ScriptContext.html b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/keys/trait.ScriptContext.html index 0561acb6fb..44df5b0fc7 100644 --- a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/keys/trait.ScriptContext.html +++ b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/keys/trait.ScriptContext.html @@ -1,45 +1,39 @@ -ScriptContext in bdk::keys - Rust - -
    pub trait ScriptContext: Debug + Clone + Ord + PartialOrd<Self> + Eq + PartialEq<Self> + Hash + Sealed {
    -    type Key: ParseableKey + MiniscriptKey;
    -
    Show 15 methods fn check_terminal_non_malleable<Pk>(
            _frag: &Terminal<Pk, Self>
        ) -> Result<(), ScriptContextError>
        where
            Pk: MiniscriptKey
    ; -
    fn max_satisfaction_size<Pk>(ms: &Miniscript<Pk, Self>) -> Option<usize>
        where
            Pk: MiniscriptKey
    ; -
    fn sig_type() -> SigType; -
    fn pk_len<Pk>(pk: &Pk) -> usize
        where
            Pk: MiniscriptKey
    ; -
    fn name_str() -> &'static str; +ScriptContext in bdk::keys - Rust

    Trait bdk::keys::ScriptContext

    pub trait ScriptContext: Debug + Clone + Ord + PartialOrd<Self> + Eq + PartialEq<Self> + Hash + Sealed {
    +    type Key: ParseableKey<Sha256 = Hash, Hash256 = Hash, Ripemd160 = Hash, Hash160 = Hash> + MiniscriptKey;
     
    -    fn check_witness<Pk>(
            _witness: &[Vec<u8, Global>]
        ) -> Result<(), ScriptContextError>
        where
            Pk: MiniscriptKey
    , +
    Show 15 methods fn check_terminal_non_malleable<Pk>(
            _frag: &Terminal<Pk, Self>
        ) -> Result<(), ScriptContextError>
        where
            Pk: MiniscriptKey
    ; + fn max_satisfaction_size<Pk>(ms: &Miniscript<Pk, Self>) -> Option<usize>
        where
            Pk: MiniscriptKey
    ; + fn sig_type() -> SigType; + fn pk_len<Pk>(pk: &Pk) -> usize
        where
            Pk: MiniscriptKey
    ; + fn name_str() -> &'static str; + + fn check_witness<Pk>(
            _witness: &[Vec<u8, Global>]
        ) -> Result<(), ScriptContextError>
        where
            Pk: MiniscriptKey
    , { ... } -
    fn check_global_consensus_validity<Pk>(
            _ms: &Miniscript<Pk, Self>
        ) -> Result<(), ScriptContextError>
        where
            Pk: MiniscriptKey
    , + fn check_global_consensus_validity<Pk>(
            _ms: &Miniscript<Pk, Self>
        ) -> Result<(), ScriptContextError>
        where
            Pk: MiniscriptKey
    , { ... } -
    fn check_global_policy_validity<Pk>(
            _ms: &Miniscript<Pk, Self>
        ) -> Result<(), ScriptContextError>
        where
            Pk: MiniscriptKey
    , + fn check_global_policy_validity<Pk>(
            _ms: &Miniscript<Pk, Self>
        ) -> Result<(), ScriptContextError>
        where
            Pk: MiniscriptKey
    , { ... } -
    fn check_local_consensus_validity<Pk>(
            _ms: &Miniscript<Pk, Self>
        ) -> Result<(), ScriptContextError>
        where
            Pk: MiniscriptKey
    , + fn check_local_consensus_validity<Pk>(
            _ms: &Miniscript<Pk, Self>
        ) -> Result<(), ScriptContextError>
        where
            Pk: MiniscriptKey
    , { ... } -
    fn check_local_policy_validity<Pk>(
            _ms: &Miniscript<Pk, Self>
        ) -> Result<(), ScriptContextError>
        where
            Pk: MiniscriptKey
    , + fn check_local_policy_validity<Pk>(
            _ms: &Miniscript<Pk, Self>
        ) -> Result<(), ScriptContextError>
        where
            Pk: MiniscriptKey
    , { ... } -
    fn check_global_validity<Pk>(
            ms: &Miniscript<Pk, Self>
        ) -> Result<(), ScriptContextError>
        where
            Pk: MiniscriptKey
    , + fn check_global_validity<Pk>(
            ms: &Miniscript<Pk, Self>
        ) -> Result<(), ScriptContextError>
        where
            Pk: MiniscriptKey
    , { ... } -
    fn check_local_validity<Pk>(
            ms: &Miniscript<Pk, Self>
        ) -> Result<(), ScriptContextError>
        where
            Pk: MiniscriptKey
    , + fn check_local_validity<Pk>(
            ms: &Miniscript<Pk, Self>
        ) -> Result<(), ScriptContextError>
        where
            Pk: MiniscriptKey
    , { ... } -
    fn top_level_type_check<Pk>(ms: &Miniscript<Pk, Self>) -> Result<(), Error>
        where
            Pk: MiniscriptKey
    , + fn top_level_type_check<Pk>(ms: &Miniscript<Pk, Self>) -> Result<(), Error>
        where
            Pk: MiniscriptKey
    , { ... } -
    fn other_top_level_checks<Pk>(
            _ms: &Miniscript<Pk, Self>
        ) -> Result<(), Error>
        where
            Pk: MiniscriptKey
    , + fn other_top_level_checks<Pk>(
            _ms: &Miniscript<Pk, Self>
        ) -> Result<(), Error>
        where
            Pk: MiniscriptKey
    , { ... } -
    fn top_level_checks<Pk>(ms: &Miniscript<Pk, Self>) -> Result<(), Error>
        where
            Pk: MiniscriptKey
    , + fn top_level_checks<Pk>(ms: &Miniscript<Pk, Self>) -> Result<(), Error>
        where
            Pk: MiniscriptKey
    , { ... }
    }
    Expand description

    The ScriptContext for Miniscript. Additional type information associated with miniscript that is used for carrying out checks that dependent on the context under which the script is used. For example, disallowing uncompressed keys in Segwit context

    -

    Associated Types

    The consensus key associated with the type. Must be a parseable key

    -

    Required methods

    Depending on ScriptContext, fragments can be malleable. For Example, +

    Required Associated Types§

    The consensus key associated with the type. Must be a parseable key

    +

    Required Methods§

    Depending on ScriptContext, fragments can be malleable. For Example, under Legacy context, PkH is malleable because it is possible to estimate the cost of satisfaction because of compressed keys This is currently only used in compiler code for removing malleable @@ -47,17 +41,17 @@ compilations. This does NOT recursively check if the children of the fragment are valid or not. Since the compilation proceeds in a leaf to root fashion, a recursive check is unnecessary.

    -

    Depending on script context, the size of a satifaction witness may slightly differ.

    -

    The type of signature required for satisfaction

    -

    Get the len of public key when serialized based on context +

    Depending on script context, the size of a satifaction witness may slightly differ.

    +

    The type of signature required for satisfaction

    +

    Get the len of public key when serialized based on context Note that this includes the serialization prefix. Returns 34/66 for Bare/Legacy based on key compressedness 34 for Segwitv0, 33 for Tap

    -

    Local helper function to display error messages with context

    -

    Provided methods

    Check whether the given satisfaction is valid under the ScriptContext +

    Local helper function to display error messages with context

    +

    Provided Methods§

    Check whether the given satisfaction is valid under the ScriptContext For example, segwit satisfactions may fail if the witness len is more 3600 or number of stack elements are more than 100.

    -

    Depending on script Context, some of the Terminals might not +

    Depending on script Context, some of the Terminals might not be valid under the current consensus rules. Or some of the script resource limits may have been exceeded. These miniscripts would never be accepted by the Bitcoin network and hence @@ -67,7 +61,7 @@ uncompressed public keys are non-standard and thus invalid. In LegacyP2SH context, scripts above 520 bytes are invalid. Post Tapscript upgrade, this would have to consider other nodes. This does NOT recursively check the miniscript fragments.

    -

    Depending on script Context, some of the script resource limits +

    Depending on script Context, some of the script resource limits may have been exceeded under the current bitcoin core policy rules These miniscripts would never be accepted by the Bitcoin network and hence it is safe to discard them. (unless explicitly disabled by non-standard flag) @@ -75,21 +69,20 @@ For example, in Segwit Context with MiniscriptKey as bitcoin::PublicKey scripts over 3600 bytes are invalid. Post Tapscript upgrade, this would have to consider other nodes. This does NOT recursively check the miniscript fragments.

    -

    Consensus rules at the Miniscript satisfaction time. +

    Consensus rules at the Miniscript satisfaction time. It is possible that some paths of miniscript may exceed resource limits and our current satisfier and lifting analysis would not work correctly. For example, satisfaction path(Legacy/Segwitv0) may require more than 201 opcodes.

    -

    Policy rules at the Miniscript satisfaction time. +

    Policy rules at the Miniscript satisfaction time. It is possible that some paths of miniscript may exceed resource limits and our current satisfier and lifting analysis would not work correctly. For example, satisfaction path in Legacy context scriptSig more than 1650 bytes

    -

    Check the consensus + policy(if not disabled) rules that are not based +

    Check the consensus + policy(if not disabled) rules that are not based satisfaction

    -

    Check the consensus + policy(if not disabled) rules including the +

    Check the consensus + policy(if not disabled) rules including the ones for satisfaction

    -

    Check whether the top-level is type B

    -

    Other top level checks that are context specific

    -

    Check top level consensus rules.

    -

    Implementations on Foreign Types

    Implementors

    - \ No newline at end of file +

    Check whether the top-level is type B

    +

    Other top level checks that are context specific

    +

    Check top level consensus rules.

    +

    Implementors§

    \ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/keys/type.KeyMap.html b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/keys/type.KeyMap.html index 402d5e7fd1..a2e9d34d12 100644 --- a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/keys/type.KeyMap.html +++ b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/keys/type.KeyMap.html @@ -1,15 +1,7 @@ -KeyMap in bdk::keys - Rust - -
    -

    Type Definition bdk::keys::KeyMap

    []
    Expand description

    Alias type for a map of public key to secret key

    +KeyMap in bdk::keys - Rust

    Type Definition bdk::keys::KeyMap

    Expand description

    Alias type for a map of public key to secret key

    This map is returned whenever a descriptor that contains secrets is parsed using Descriptor::parse_descriptor, since the descriptor will always only contain public keys. This map allows looking up the corresponding secret key given a public key from the descriptor.

    -
    - \ No newline at end of file +
    \ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/keys/type.ValidNetworks.html b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/keys/type.ValidNetworks.html index 538d529c80..568181f2ce 100644 --- a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/keys/type.ValidNetworks.html +++ b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/keys/type.ValidNetworks.html @@ -1,11 +1,3 @@ -ValidNetworks in bdk::keys - Rust - -
    -

    Type Definition bdk::keys::ValidNetworks

    source · []
    pub type ValidNetworks = HashSet<Network>;
    Expand description

    Set of valid networks for a key

    -
    - \ No newline at end of file +ValidNetworks in bdk::keys - Rust

    Type Definition bdk::keys::ValidNetworks

    source ·
    pub type ValidNetworks = HashSet<Network>;
    Expand description

    Set of valid networks for a key

    +
    \ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/macro.descriptor.html b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/macro.descriptor.html index 8016c90972..308997fb8d 100644 --- a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/macro.descriptor.html +++ b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/macro.descriptor.html @@ -1,24 +1,17 @@ -descriptor in bdk - Rust - -
    -

    Macro bdk::descriptor

    source · []
    macro_rules! descriptor {
    -    ( bare ( $( $minisc:tt )* ) ) => { ... };
    -    ( sh ( wsh ( $( $minisc:tt )* ) ) ) => { ... };
    -    ( shwsh ( $( $minisc:tt )* ) ) => { ... };
    -    ( pk ( $key:expr ) ) => { ... };
    -    ( pkh ( $key:expr ) ) => { ... };
    -    ( wpkh ( $key:expr ) ) => { ... };
    -    ( sh ( wpkh ( $key:expr ) ) ) => { ... };
    -    ( shwpkh ( $key:expr ) ) => { ... };
    -    ( sh ( $( $minisc:tt )* ) ) => { ... };
    -    ( wsh ( $( $minisc:tt )* ) ) => { ... };
    -    ( tr ( $internal_key:expr ) ) => { ... };
    -    ( tr ( $internal_key:expr, $( $taptree:tt )* ) ) => { ... };
    +descriptor in bdk - Rust

    Macro bdk::descriptor

    source ·
    macro_rules! descriptor {
    +    ( bare ( $( $minisc:tt )* ) ) => { ... };
    +    ( sh ( wsh ( $( $minisc:tt )* ) ) ) => { ... };
    +    ( shwsh ( $( $minisc:tt )* ) ) => { ... };
    +    ( pk ( $key:expr ) ) => { ... };
    +    ( pkh ( $key:expr ) ) => { ... };
    +    ( wpkh ( $key:expr ) ) => { ... };
    +    ( sh ( wpkh ( $key:expr ) ) ) => { ... };
    +    ( shwpkh ( $key:expr ) ) => { ... };
    +    ( sh ( $( $minisc:tt )* ) ) => { ... };
    +    ( wsh ( $( $minisc:tt )* ) ) => { ... };
    +    ( tr ( $internal_key:expr ) ) => { ... };
    +    ( tr ( $internal_key:expr, $( $taptree:tt )* ) ) => { ... };
     }
    Expand description

    Macro to write full descriptors with code

    This macro expands to a Result of @@ -30,59 +23,58 @@ broken up to s:d:v:older(144).

    IntoDescriptorKey. This means that keys can also be written inline as strings, but in that case they must be wrapped in quotes, which is another difference compared to the standard descriptor syntax.

    -

    Example

    +

    Example

    Signature plus timelock descriptor:

    -
    let (my_descriptor, my_keys_map, networks) = bdk::descriptor!(sh(wsh(and_v(v:pk("cVt4o7BGAig1UXywgGSmARhxMdzP5qvQsxKkSsc1XEkw3tDTQFpy"),older(50)))))?;
    +
    let (my_descriptor, my_keys_map, networks) = bdk::descriptor!(sh(wsh(and_v(v:pk("cVt4o7BGAig1UXywgGSmARhxMdzP5qvQsxKkSsc1XEkw3tDTQFpy"),older(50)))))?;

    2-of-3 that becomes a 1-of-3 after a timelock has expired. Both descriptor_a and descriptor_b are equivalent: the first syntax is more suitable for a fixed number of items known at compile time, while the other accepts a Vec of items, which makes it more suitable for writing dynamic descriptors.

    They both produce the descriptor: wsh(thresh(2,pk(...),s:pk(...),sndv:older(...)))

    -
    let my_key_1 = bitcoin::PublicKey::from_str(
    +
    let my_key_1 = bitcoin::PublicKey::from_str(
         "02e96fe52ef0e22d2f131dd425ce1893073a3c6ad20e8cac36726393dfb4856a4c",
     )?;
    -let my_key_2 =
    -    bitcoin::PrivateKey::from_wif("cVt4o7BGAig1UXywgGSmARhxMdzP5qvQsxKkSsc1XEkw3tDTQFpy")?;
    -let my_timelock = 50;
    +let my_key_2 =
    +    bitcoin::PrivateKey::from_wif("cVt4o7BGAig1UXywgGSmARhxMdzP5qvQsxKkSsc1XEkw3tDTQFpy")?;
    +let my_timelock = 50;
     
    -let (descriptor_a, key_map_a, networks) = bdk::descriptor! {
    -    wsh (
    -        thresh(2, pk(my_key_1), s:pk(my_key_2), s:n:d:v:older(my_timelock))
    +let (descriptor_a, key_map_a, networks) = bdk::descriptor! {
    +    wsh (
    +        thresh(2, pk(my_key_1), s:pk(my_key_2), s:n:d:v:older(my_timelock))
         )
     }?;
     
    -#[rustfmt::skip]
    -let b_items = vec![
    -    bdk::fragment!(pk(my_key_1))?,
    -    bdk::fragment!(s:pk(my_key_2))?,
    -    bdk::fragment!(s:n:d:v:older(my_timelock))?,
    +#[rustfmt::skip]
    +let b_items = vec![
    +    bdk::fragment!(pk(my_key_1))?,
    +    bdk::fragment!(s:pk(my_key_2))?,
    +    bdk::fragment!(s:n:d:v:older(my_timelock))?,
     ];
    -let (descriptor_b, mut key_map_b, networks) = bdk::descriptor!(wsh(thresh_vec(2, b_items)))?;
    +let (descriptor_b, mut key_map_b, networks) = bdk::descriptor!(wsh(thresh_vec(2, b_items)))?;
     
    -assert_eq!(descriptor_a, descriptor_b);
    -assert_eq!(key_map_a.len(), key_map_b.len());
    +assert_eq!(descriptor_a, descriptor_b); +assert_eq!(key_map_a.len(), key_map_b.len());

    Simple 2-of-2 multi-signature, equivalent to: wsh(multi(2, ...))

    -
    let my_key_1 = bitcoin::PublicKey::from_str(
    +
    let my_key_1 = bitcoin::PublicKey::from_str(
         "02e96fe52ef0e22d2f131dd425ce1893073a3c6ad20e8cac36726393dfb4856a4c",
     )?;
    -let my_key_2 =
    -    bitcoin::PrivateKey::from_wif("cVt4o7BGAig1UXywgGSmARhxMdzP5qvQsxKkSsc1XEkw3tDTQFpy")?;
    +let my_key_2 =
    +    bitcoin::PrivateKey::from_wif("cVt4o7BGAig1UXywgGSmARhxMdzP5qvQsxKkSsc1XEkw3tDTQFpy")?;
     
    -let (descriptor, key_map, networks) = bdk::descriptor! {
    -    wsh (
    -        multi(2, my_key_1, my_key_2)
    +let (descriptor, key_map, networks) = bdk::descriptor! {
    +    wsh (
    +        multi(2, my_key_1, my_key_2)
         )
     }?;

    Native-Segwit single-sig, equivalent to: wpkh(...)

    -
    let my_key =
    -    bitcoin::PrivateKey::from_wif("cVt4o7BGAig1UXywgGSmARhxMdzP5qvQsxKkSsc1XEkw3tDTQFpy")?;
    +
    let my_key =
    +    bitcoin::PrivateKey::from_wif("cVt4o7BGAig1UXywgGSmARhxMdzP5qvQsxKkSsc1XEkw3tDTQFpy")?;
     
    -let (descriptor, key_map, networks) = bdk::descriptor!(wpkh(my_key))?;
    -
    - \ No newline at end of file +let (descriptor, key_map, networks) = bdk::descriptor!(wpkh(my_key))?;
    +
    \ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/macro.fragment.html b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/macro.fragment.html index 82c3a6ec02..964d8c119f 100644 --- a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/macro.fragment.html +++ b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/macro.fragment.html @@ -1,44 +1,36 @@ -fragment in bdk - Rust - -
    -

    Macro bdk::fragment

    source · []
    macro_rules! fragment {
    -    ( $modif:tt : $( $tail:tt )* ) => { ... };
    -    ( true ) => { ... };
    -    ( false ) => { ... };
    -    ( pk_k ( $key:expr ) ) => { ... };
    -    ( pk ( $key:expr ) ) => { ... };
    -    ( pk_h ( $key:expr ) ) => { ... };
    -    ( after ( $value:expr ) ) => { ... };
    -    ( older ( $value:expr ) ) => { ... };
    -    ( sha256 ( $hash:expr ) ) => { ... };
    -    ( hash256 ( $hash:expr ) ) => { ... };
    -    ( ripemd160 ( $hash:expr ) ) => { ... };
    -    ( hash160 ( $hash:expr ) ) => { ... };
    -    ( and_v ( $( $inner:tt )* ) ) => { ... };
    -    ( and_b ( $( $inner:tt )* ) ) => { ... };
    -    ( and_or ( $( $inner:tt )* ) ) => { ... };
    -    ( andor ( $( $inner:tt )* ) ) => { ... };
    -    ( or_b ( $( $inner:tt )* ) ) => { ... };
    -    ( or_d ( $( $inner:tt )* ) ) => { ... };
    -    ( or_c ( $( $inner:tt )* ) ) => { ... };
    -    ( or_i ( $( $inner:tt )* ) ) => { ... };
    -    ( thresh_vec ( $thresh:expr, $items:expr ) ) => { ... };
    -    ( thresh ( $thresh:expr, $( $inner:tt )* ) ) => { ... };
    -    ( multi_vec ( $thresh:expr, $keys:expr ) ) => { ... };
    -    ( multi ( $thresh:expr $(, $key:expr )+ ) ) => { ... };
    -    ( multi_a_vec ( $thresh:expr, $keys:expr ) ) => { ... };
    -    ( multi_a ( $thresh:expr $(, $key:expr )+ ) ) => { ... };
    -    ( sortedmulti ( $( $inner:tt )* ) ) => { ... };
    -    ( sortedmulti_vec ( $( $inner:tt )* ) ) => { ... };
    +fragment in bdk - Rust

    Macro bdk::fragment

    source ·
    macro_rules! fragment {
    +    ( $modif:tt : $( $tail:tt )* ) => { ... };
    +    ( true ) => { ... };
    +    ( false ) => { ... };
    +    ( pk_k ( $key:expr ) ) => { ... };
    +    ( pk ( $key:expr ) ) => { ... };
    +    ( pk_h ( $key:expr ) ) => { ... };
    +    ( after ( $value:expr ) ) => { ... };
    +    ( older ( $value:expr ) ) => { ... };
    +    ( sha256 ( $hash:expr ) ) => { ... };
    +    ( hash256 ( $hash:expr ) ) => { ... };
    +    ( ripemd160 ( $hash:expr ) ) => { ... };
    +    ( hash160 ( $hash:expr ) ) => { ... };
    +    ( and_v ( $( $inner:tt )* ) ) => { ... };
    +    ( and_b ( $( $inner:tt )* ) ) => { ... };
    +    ( and_or ( $( $inner:tt )* ) ) => { ... };
    +    ( andor ( $( $inner:tt )* ) ) => { ... };
    +    ( or_b ( $( $inner:tt )* ) ) => { ... };
    +    ( or_d ( $( $inner:tt )* ) ) => { ... };
    +    ( or_c ( $( $inner:tt )* ) ) => { ... };
    +    ( or_i ( $( $inner:tt )* ) ) => { ... };
    +    ( thresh_vec ( $thresh:expr, $items:expr ) ) => { ... };
    +    ( thresh ( $thresh:expr, $( $inner:tt )* ) ) => { ... };
    +    ( multi_vec ( $thresh:expr, $keys:expr ) ) => { ... };
    +    ( multi ( $thresh:expr $(, $key:expr )+ ) ) => { ... };
    +    ( multi_a_vec ( $thresh:expr, $keys:expr ) ) => { ... };
    +    ( multi_a ( $thresh:expr $(, $key:expr )+ ) ) => { ... };
    +    ( sortedmulti ( $( $inner:tt )* ) ) => { ... };
    +    ( sortedmulti_vec ( $( $inner:tt )* ) ) => { ... };
     }
    Expand description

    Macro to write descriptor fragments with code

    This macro will be expanded to an object of type Result<(Miniscript<DescriptorPublicKey, _>, KeyMap, ValidNetworks), DescriptorError>. It allows writing fragments of larger descriptors that can be pieced together using fragment!(thresh_vec(m, ...)).

    The syntax to write macro fragment is the same as documented for the descriptor macro.

    -
    - \ No newline at end of file +
    \ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/psbt/index.html b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/psbt/index.html index 443bb4473e..4ea6962910 100644 --- a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/psbt/index.html +++ b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/psbt/index.html @@ -1,13 +1,3 @@ -bdk::psbt - Rust - -
    -

    Module bdk::psbt

    source · []
    Expand description

    Additional functions on the rust-bitcoin PartiallySignedTransaction structure.

    -

    Traits

    -

    Trait to add functions to extract utxos and calculate fees.

    -
    - \ No newline at end of file +bdk::psbt - Rust

    Module bdk::psbt

    source ·
    Expand description

    Additional functions on the rust-bitcoin PartiallySignedTransaction structure.

    +

    Traits

    Trait to add functions to extract utxos and calculate fees.
    \ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/psbt/sidebar-items.js b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/psbt/sidebar-items.js index 042b9d55d0..3b7a144401 100644 --- a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/psbt/sidebar-items.js +++ b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/psbt/sidebar-items.js @@ -1 +1 @@ -initSidebarItems({"trait":[["PsbtUtils","Trait to add functions to extract utxos and calculate fees."]]}); \ No newline at end of file +window.SIDEBAR_ITEMS = {"trait":[["PsbtUtils","Trait to add functions to extract utxos and calculate fees."]]}; \ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/psbt/trait.PsbtUtils.html b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/psbt/trait.PsbtUtils.html index e549ebf313..f771c9a156 100644 --- a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/psbt/trait.PsbtUtils.html +++ b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/psbt/trait.PsbtUtils.html @@ -1,22 +1,14 @@ -PsbtUtils in bdk::psbt - Rust - -
    -

    Trait bdk::psbt::PsbtUtils

    source · []
    pub trait PsbtUtils {
    -    fn get_utxo_for(&self, input_index: usize) -> Option<TxOut>;
    -
    fn fee_amount(&self) -> Option<u64>; -
    fn fee_rate(&self) -> Option<FeeRate>; +PsbtUtils in bdk::psbt - Rust

    Trait bdk::psbt::PsbtUtils

    source ·
    pub trait PsbtUtils {
    +    fn get_utxo_for(&self, input_index: usize) -> Option<TxOut>;
    +    fn fee_amount(&self) -> Option<u64>;
    +    fn fee_rate(&self) -> Option<FeeRate>;
     }
    Expand description

    Trait to add functions to extract utxos and calculate fees.

    -

    Required methods

    Get the TxOut for the specified input index, if it doesn’t exist in the PSBT None is returned.

    -

    The total transaction fee amount, sum of input amounts minus sum of output amounts, in Sats. +

    Required Methods§

    Get the TxOut for the specified input index, if it doesn’t exist in the PSBT None is returned.

    +

    The total transaction fee amount, sum of input amounts minus sum of output amounts, in Sats. If the PSBT is missing a TxOut for an input returns None.

    -

    The transaction’s fee rate. This value will only be accurate if calculated AFTER the +

    The transaction’s fee rate. This value will only be accurate if calculated AFTER the PartiallySignedTransaction is finalized and all witness/signature data is added to the transaction. If the PSBT is missing a TxOut for an input returns None.

    -

    Implementations on Foreign Types

    Implementors

    - \ No newline at end of file +

    Implementations on Foreign Types§

    Implementors§

    \ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/sidebar-items.js b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/sidebar-items.js index e970e9c663..81a6afbae0 100644 --- a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/sidebar-items.js +++ b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/sidebar-items.js @@ -1 +1 @@ -initSidebarItems({"enum":[["Error","Errors that can be thrown by the `Wallet`"],["KeychainKind","Types of keychains"],["Utxo","An unspent transaction output (UTXO)."]],"externcrate":[["bitcoin",""],["bitcoincore_rpc",""],["electrum_client",""],["esplora_client",""],["hwi",""],["miniscript",""],["rusqlite",""],["sled",""]],"fn":[["version","Get the version of BDK at runtime"]],"macro":[["descriptor","Macro to write full descriptors with code"],["fragment","Macro to write descriptor fragments with code"]],"mod":[["blockchain","Blockchain backends"],["database","Database types"],["descriptor","Descriptors"],["keys","Key formats"],["psbt","Additional functions on the `rust-bitcoin` `PartiallySignedTransaction` structure."],["wallet","Wallet"]],"struct":[["Balance","Balance differentiated in various categories"],["BlockTime","Block height and timestamp of a block"],["FeeRate","Fee rate"],["LocalUtxo","An unspent output owned by a `Wallet`."],["TransactionDetails","A wallet transaction"],["WeightedUtxo","A [`Utxo`] with its `satisfaction_weight`."]],"trait":[["Vbytes","Trait implemented by types that can be used to measure weight units."]],"type":[["ConfirmationTime","DEPRECATED: Confirmation time of a transaction"]]}); \ No newline at end of file +window.SIDEBAR_ITEMS = {"enum":[["Error","Errors that can be thrown by the `Wallet`"],["KeychainKind","Types of keychains"],["Utxo","An unspent transaction output (UTXO)."]],"externcrate":[["bitcoin",""],["bitcoincore_rpc",""],["electrum_client",""],["esplora_client",""],["hwi",""],["miniscript",""],["rusqlite",""],["sled",""]],"fn":[["version","Get the version of BDK at runtime"]],"macro":[["descriptor","Macro to write full descriptors with code"],["fragment","Macro to write descriptor fragments with code"]],"mod":[["blockchain","Blockchain backends"],["database","Database types"],["descriptor","Descriptors"],["keys","Key formats"],["psbt","Additional functions on the `rust-bitcoin` `PartiallySignedTransaction` structure."],["wallet","Wallet"]],"struct":[["Balance","Balance differentiated in various categories"],["BlockTime","Block height and timestamp of a block"],["FeeRate","Fee rate"],["LocalUtxo","An unspent output owned by a `Wallet`."],["TransactionDetails","A wallet transaction"],["WeightedUtxo","A [`Utxo`] with its `satisfaction_weight`."]],"trait":[["Vbytes","Trait implemented by types that can be used to measure weight units."]],"type":[["ConfirmationTime","DEPRECATED: Confirmation time of a transaction"]]}; \ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/struct.Balance.html b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/struct.Balance.html index a9ae951c09..3a3c080a8c 100644 --- a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/struct.Balance.html +++ b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/struct.Balance.html @@ -1,55 +1,21 @@ -Balance in bdk - Rust - -
    -

    Struct bdk::Balance

    source · []
    pub struct Balance {
    +Balance in bdk - Rust

    Struct bdk::Balance

    source ·
    pub struct Balance {
         pub immature: u64,
         pub trusted_pending: u64,
         pub untrusted_pending: u64,
         pub confirmed: u64,
     }
    Expand description

    Balance differentiated in various categories

    -

    Fields

    immature: u64

    All coinbase outputs not yet matured

    -
    trusted_pending: u64

    Unconfirmed UTXOs generated by a wallet tx

    -
    untrusted_pending: u64

    Unconfirmed UTXOs received from an external wallet

    -
    confirmed: u64

    Confirmed and immediately spendable balance

    -

    Implementations

    Get sum of trusted_pending and confirmed coins

    -

    Get the whole balance visible to the wallet

    -

    Trait Implementations

    The resulting type after applying the + operator.

    -

    Performs the + operation. Read more

    -

    Returns a copy of the value. Read more

    -

    Performs copy-assignment from source. Read more

    -

    Formats the value using the given formatter. Read more

    -

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

    -

    Deserialize this value from the given Serde deserializer. Read more

    -

    Formats the value using the given formatter. Read more

    -

    This method tests for self and other values to be equal, and is used -by ==. Read more

    -

    This method tests for !=.

    -

    Serialize this value into the given Serde serializer. Read more

    -

    Method which takes an iterator and generates Self from the elements by -“summing up” the items. Read more

    -

    Auto Trait Implementations

    Blanket Implementations

    Gets the TypeId of self. Read more

    -

    Immutably borrows from an owned value. Read more

    -

    Mutably borrows from an owned value. Read more

    -

    Performs the conversion.

    -

    Performs the conversion.

    -

    The alignment of pointer.

    -

    The type for initializers.

    -

    Initializes a with the given initializer. Read more

    -

    Dereferences the given pointer. Read more

    -

    Mutably dereferences the given pointer. Read more

    -

    Drops the object pointed to by the given pointer. Read more

    -

    The resulting type after obtaining ownership.

    -

    Creates owned data from borrowed data, usually by cloning. Read more

    -
    🔬 This is a nightly-only experimental API. (toowned_clone_into)

    Uses borrowed data to replace owned data, usually by cloning. Read more

    -

    Converts the given value to a String. Read more

    -

    The type returned in the event of a conversion error.

    -

    Performs the conversion.

    -

    The type returned in the event of a conversion error.

    -

    Performs the conversion.

    -
    - \ No newline at end of file +

    Fields§

    §immature: u64

    All coinbase outputs not yet matured

    +
    §trusted_pending: u64

    Unconfirmed UTXOs generated by a wallet tx

    +
    §untrusted_pending: u64

    Unconfirmed UTXOs received from an external wallet

    +
    §confirmed: u64

    Confirmed and immediately spendable balance

    +

    Implementations§

    Get sum of trusted_pending and confirmed coins

    +

    Get the whole balance visible to the wallet

    +

    Trait Implementations§

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

    Auto Trait Implementations§

    Blanket Implementations§

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

    Returns the argument unchanged.

    +

    Calls U::from(self).

    +

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

    +
    The alignment of pointer.
    The type for initializers.
    Initializes a with the given initializer. Read more
    Dereferences the given pointer. Read more
    Mutably dereferences the given pointer. Read more
    Drops the object pointed to by the given pointer. Read more
    The resulting type after obtaining ownership.
    Creates owned data from borrowed data, usually by cloning. Read more
    Uses borrowed data to replace owned data, usually by cloning. Read more
    Converts the given value to a String. Read more
    The type returned in the event of a conversion error.
    Performs the conversion.
    The type returned in the event of a conversion error.
    Performs the conversion.
    \ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/struct.BlockTime.html b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/struct.BlockTime.html index e8497eb05a..6438bd7f61 100644 --- a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/struct.BlockTime.html +++ b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/struct.BlockTime.html @@ -1,45 +1,15 @@ -BlockTime in bdk - Rust - -
    -

    Struct bdk::BlockTime

    source · []
    pub struct BlockTime {
    +BlockTime in bdk - Rust

    Struct bdk::BlockTime

    source ·
    pub struct BlockTime {
         pub height: u32,
         pub timestamp: u64,
     }
    Expand description

    Block height and timestamp of a block

    -

    Fields

    height: u32

    confirmation block height

    -
    timestamp: u64

    confirmation block timestamp

    -

    Implementations

    Returns Some BlockTime if both height and timestamp are Some

    -

    Trait Implementations

    Returns a copy of the value. Read more

    -

    Performs copy-assignment from source. Read more

    -

    Formats the value using the given formatter. Read more

    -

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

    -

    Deserialize this value from the given Serde deserializer. Read more

    -

    Performs the conversion.

    -

    This method tests for self and other values to be equal, and is used -by ==. Read more

    -

    This method tests for !=.

    -

    Serialize this value into the given Serde serializer. Read more

    -

    Auto Trait Implementations

    Blanket Implementations

    Gets the TypeId of self. Read more

    -

    Immutably borrows from an owned value. Read more

    -

    Mutably borrows from an owned value. Read more

    -

    Performs the conversion.

    -

    Performs the conversion.

    -

    The alignment of pointer.

    -

    The type for initializers.

    -

    Initializes a with the given initializer. Read more

    -

    Dereferences the given pointer. Read more

    -

    Mutably dereferences the given pointer. Read more

    -

    Drops the object pointed to by the given pointer. Read more

    -

    The resulting type after obtaining ownership.

    -

    Creates owned data from borrowed data, usually by cloning. Read more

    -
    🔬 This is a nightly-only experimental API. (toowned_clone_into)

    Uses borrowed data to replace owned data, usually by cloning. Read more

    -

    The type returned in the event of a conversion error.

    -

    Performs the conversion.

    -

    The type returned in the event of a conversion error.

    -

    Performs the conversion.

    -
    - \ No newline at end of file +

    Fields§

    §height: u32

    confirmation block height

    +
    §timestamp: u64

    confirmation block timestamp

    +

    Implementations§

    Returns Some BlockTime if both height and timestamp are Some

    +

    Trait Implementations§

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

    Auto Trait Implementations§

    Blanket Implementations§

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

    Returns the argument unchanged.

    +

    Calls U::from(self).

    +

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

    +
    The alignment of pointer.
    The type for initializers.
    Initializes a with the given initializer. Read more
    Dereferences the given pointer. Read more
    Mutably dereferences the given pointer. Read more
    Drops the object pointed to by the given pointer. Read more
    The resulting type after obtaining ownership.
    Creates owned data from borrowed data, usually by cloning. Read more
    Uses borrowed data to replace owned data, usually by cloning. Read more
    The type returned in the event of a conversion error.
    Performs the conversion.
    The type returned in the event of a conversion error.
    Performs the conversion.
    \ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/struct.FeeRate.html b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/struct.FeeRate.html index ff17d6a65c..77057a6877 100644 --- a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/struct.FeeRate.html +++ b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/struct.FeeRate.html @@ -1,59 +1,25 @@ -FeeRate in bdk - Rust - -
    -

    Struct bdk::FeeRate

    source · []
    pub struct FeeRate(_);
    Expand description

    Fee rate

    -

    Implementations

    Create a new instance of FeeRate given a float fee rate in sats/kwu

    -

    Create a new instance of FeeRate given a float fee rate in sats/kvb

    -

    Create a new instance of FeeRate given a float fee rate in btc/kvbytes

    -
    Panics
    +FeeRate in bdk - Rust

    Struct bdk::FeeRate

    source ·
    pub struct FeeRate(_);
    Expand description

    Fee rate

    +

    Implementations§

    Create a new instance of FeeRate given a float fee rate in sats/kwu

    +

    Create a new instance of FeeRate given a float fee rate in sats/kvb

    +

    Create a new instance of FeeRate given a float fee rate in btc/kvbytes

    +
    Panics

    Panics if the value is not normal (except if it’s a positive zero) or negative.

    -

    Create a new instance of FeeRate given a float fee rate in satoshi/vbyte

    -
    Panics
    +

    Create a new instance of FeeRate given a float fee rate in satoshi/vbyte

    +
    Panics

    Panics if the value is not normal (except if it’s a positive zero) or negative.

    -

    Create a new FeeRate with the default min relay fee value

    -

    Calculate fee rate from fee and weight units (wu).

    -

    Calculate fee rate from fee and vbytes.

    -

    Return the value as satoshi/vbyte

    -

    Calculate absolute fee in Satoshis using size in weight units.

    -

    Calculate absolute fee in Satoshis using size in virtual bytes.

    -

    Trait Implementations

    Returns a copy of the value. Read more

    -

    Performs copy-assignment from source. Read more

    -

    Formats the value using the given formatter. Read more

    -

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

    -

    This method tests for self and other values to be equal, and is used -by ==. Read more

    -

    This method tests for !=.

    -

    This method returns an ordering between self and other values if one exists. Read more

    -

    This method tests less than (for self and other) and is used by the < operator. Read more

    -

    This method tests less than or equal to (for self and other) and is used by the <= -operator. Read more

    -

    This method tests greater than (for self and other) and is used by the > operator. Read more

    -

    This method tests greater than or equal to (for self and other) and is used by the >= -operator. Read more

    -

    The resulting type after applying the - operator.

    -

    Performs the - operation. Read more

    -

    Auto Trait Implementations

    Blanket Implementations

    Gets the TypeId of self. Read more

    -

    Immutably borrows from an owned value. Read more

    -

    Mutably borrows from an owned value. Read more

    -

    Performs the conversion.

    -

    Performs the conversion.

    -

    The alignment of pointer.

    -

    The type for initializers.

    -

    Initializes a with the given initializer. Read more

    -

    Dereferences the given pointer. Read more

    -

    Mutably dereferences the given pointer. Read more

    -

    Drops the object pointed to by the given pointer. Read more

    -

    The resulting type after obtaining ownership.

    -

    Creates owned data from borrowed data, usually by cloning. Read more

    -
    🔬 This is a nightly-only experimental API. (toowned_clone_into)

    Uses borrowed data to replace owned data, usually by cloning. Read more

    -

    The type returned in the event of a conversion error.

    -

    Performs the conversion.

    -

    The type returned in the event of a conversion error.

    -

    Performs the conversion.

    -
    - \ No newline at end of file +

    Create a new FeeRate with the default min relay fee value

    +

    Calculate fee rate from fee and weight units (wu).

    +

    Calculate fee rate from fee and vbytes.

    +

    Return the value as satoshi/vbyte

    +

    Calculate absolute fee in Satoshis using size in weight units.

    +

    Calculate absolute fee in Satoshis using size in virtual bytes.

    +

    Trait Implementations§

    Returns a copy of the value. Read more
    Performs copy-assignment from source. Read more
    Formats the value using the given formatter. Read more
    Returns the “default value” for a type. Read more
    This method tests for self and other values to be equal, and is used +by ==. Read more
    This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason. Read more
    This method returns an ordering between self and other values if one exists. Read more
    This method tests less than (for self and other) and is used by the < operator. Read more
    This method tests less than or equal to (for self and other) and is used by the <= +operator. Read more
    This method tests greater than (for self and other) and is used by the > operator. Read more
    This method tests greater than or equal to (for self and other) and is used by the >= +operator. Read more
    The resulting type after applying the - operator.
    Performs the - operation. Read more

    Auto Trait Implementations§

    Blanket Implementations§

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

    Returns the argument unchanged.

    +

    Calls U::from(self).

    +

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

    +
    The alignment of pointer.
    The type for initializers.
    Initializes a with the given initializer. Read more
    Dereferences the given pointer. Read more
    Mutably dereferences the given pointer. Read more
    Drops the object pointed to by the given pointer. Read more
    The resulting type after obtaining ownership.
    Creates owned data from borrowed data, usually by cloning. Read more
    Uses borrowed data to replace owned data, usually by cloning. Read more
    The type returned in the event of a conversion error.
    Performs the conversion.
    The type returned in the event of a conversion error.
    Performs the conversion.
    \ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/struct.LocalUtxo.html b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/struct.LocalUtxo.html index 7cddb7f95c..59ba8f683e 100644 --- a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/struct.LocalUtxo.html +++ b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/struct.LocalUtxo.html @@ -1,48 +1,18 @@ -LocalUtxo in bdk - Rust - -
    -

    Struct bdk::LocalUtxo

    source · []
    pub struct LocalUtxo {
    +LocalUtxo in bdk - Rust

    Struct bdk::LocalUtxo

    source ·
    pub struct LocalUtxo {
         pub outpoint: OutPoint,
         pub txout: TxOut,
         pub keychain: KeychainKind,
         pub is_spent: bool,
     }
    Expand description

    An unspent output owned by a Wallet.

    -

    Fields

    outpoint: OutPoint

    Reference to a transaction output

    -
    txout: TxOut

    Transaction output

    -
    keychain: KeychainKind

    Type of keychain

    -
    is_spent: bool

    Whether this UTXO is spent or not

    -

    Trait Implementations

    Returns a copy of the value. Read more

    -

    Performs copy-assignment from source. Read more

    -

    Formats the value using the given formatter. Read more

    -

    Deserialize this value from the given Serde deserializer. Read more

    -

    Feeds this value into the given Hasher. Read more

    -

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

    -

    This method tests for self and other values to be equal, and is used -by ==. Read more

    -

    This method tests for !=.

    -

    Serialize this value into the given Serde serializer. Read more

    -

    Auto Trait Implementations

    Blanket Implementations

    Gets the TypeId of self. Read more

    -

    Immutably borrows from an owned value. Read more

    -

    Mutably borrows from an owned value. Read more

    -

    Performs the conversion.

    -

    Performs the conversion.

    -

    The alignment of pointer.

    -

    The type for initializers.

    -

    Initializes a with the given initializer. Read more

    -

    Dereferences the given pointer. Read more

    -

    Mutably dereferences the given pointer. Read more

    -

    Drops the object pointed to by the given pointer. Read more

    -

    The resulting type after obtaining ownership.

    -

    Creates owned data from borrowed data, usually by cloning. Read more

    -
    🔬 This is a nightly-only experimental API. (toowned_clone_into)

    Uses borrowed data to replace owned data, usually by cloning. Read more

    -

    The type returned in the event of a conversion error.

    -

    Performs the conversion.

    -

    The type returned in the event of a conversion error.

    -

    Performs the conversion.

    -
    - \ No newline at end of file +

    Fields§

    §outpoint: OutPoint

    Reference to a transaction output

    +
    §txout: TxOut

    Transaction output

    +
    §keychain: KeychainKind

    Type of keychain

    +
    §is_spent: bool

    Whether this UTXO is spent or not

    +

    Trait Implementations§

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

    Auto Trait Implementations§

    Blanket Implementations§

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

    Returns the argument unchanged.

    +

    Calls U::from(self).

    +

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

    +
    The alignment of pointer.
    The type for initializers.
    Initializes a with the given initializer. Read more
    Dereferences the given pointer. Read more
    Mutably dereferences the given pointer. Read more
    Drops the object pointed to by the given pointer. Read more
    The resulting type after obtaining ownership.
    Creates owned data from borrowed data, usually by cloning. Read more
    Uses borrowed data to replace owned data, usually by cloning. Read more
    The type returned in the event of a conversion error.
    Performs the conversion.
    The type returned in the event of a conversion error.
    Performs the conversion.
    \ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/struct.TransactionDetails.html b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/struct.TransactionDetails.html index f362a04a98..dbb9f66856 100644 --- a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/struct.TransactionDetails.html +++ b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/struct.TransactionDetails.html @@ -1,12 +1,5 @@ -TransactionDetails in bdk - Rust - -
    pub struct TransactionDetails {
    +TransactionDetails in bdk - Rust

    Struct bdk::TransactionDetails

    source ·
    pub struct TransactionDetails {
         pub transaction: Option<Transaction>,
         pub txid: Txid,
         pub received: u64,
    @@ -14,43 +7,22 @@
         pub fee: Option<u64>,
         pub confirmation_time: Option<BlockTime>,
     }
    Expand description

    A wallet transaction

    -

    Fields

    transaction: Option<Transaction>

    Optional transaction

    -
    txid: Txid

    Transaction id

    -
    received: u64

    Received value (sats) +

    Fields§

    §transaction: Option<Transaction>

    Optional transaction

    +
    §txid: Txid

    Transaction id

    +
    §received: u64

    Received value (sats) Sum of owned outputs of this transaction.

    -
    sent: u64

    Sent value (sats) +

    §sent: u64

    Sent value (sats) Sum of owned inputs of this transaction.

    -
    fee: Option<u64>

    Fee value (sats) if confirmed. +

    §fee: Option<u64>

    Fee value (sats) if confirmed. The availability of the fee depends on the backend. It’s never None with an Electrum Server backend, but it could be None with a Bitcoin RPC node without txindex that receive funds while offline.

    -
    confirmation_time: Option<BlockTime>

    If the transaction is confirmed, contains height and timestamp of the block containing the +

    §confirmation_time: Option<BlockTime>

    If the transaction is confirmed, contains height and timestamp of the block containing the transaction, unconfirmed transaction contains None.

    -

    Trait Implementations

    Returns a copy of the value. Read more

    -

    Performs copy-assignment from source. Read more

    -

    Formats the value using the given formatter. Read more

    -

    Deserialize this value from the given Serde deserializer. Read more

    -

    This method tests for self and other values to be equal, and is used -by ==. Read more

    -

    This method tests for !=.

    -

    Serialize this value into the given Serde serializer. Read more

    -

    Auto Trait Implementations

    Blanket Implementations

    Gets the TypeId of self. Read more

    -

    Immutably borrows from an owned value. Read more

    -

    Mutably borrows from an owned value. Read more

    -

    Performs the conversion.

    -

    Performs the conversion.

    -

    The alignment of pointer.

    -

    The type for initializers.

    -

    Initializes a with the given initializer. Read more

    -

    Dereferences the given pointer. Read more

    -

    Mutably dereferences the given pointer. Read more

    -

    Drops the object pointed to by the given pointer. Read more

    -

    The resulting type after obtaining ownership.

    -

    Creates owned data from borrowed data, usually by cloning. Read more

    -
    🔬 This is a nightly-only experimental API. (toowned_clone_into)

    Uses borrowed data to replace owned data, usually by cloning. Read more

    -

    The type returned in the event of a conversion error.

    -

    Performs the conversion.

    -

    The type returned in the event of a conversion error.

    -

    Performs the conversion.

    -
    - \ No newline at end of file +

    Trait Implementations§

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

    Auto Trait Implementations§

    Blanket Implementations§

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

    Returns the argument unchanged.

    +

    Calls U::from(self).

    +

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

    +
    The alignment of pointer.
    The type for initializers.
    Initializes a with the given initializer. Read more
    Dereferences the given pointer. Read more
    Mutably dereferences the given pointer. Read more
    Drops the object pointed to by the given pointer. Read more
    The resulting type after obtaining ownership.
    Creates owned data from borrowed data, usually by cloning. Read more
    Uses borrowed data to replace owned data, usually by cloning. Read more
    The type returned in the event of a conversion error.
    Performs the conversion.
    The type returned in the event of a conversion error.
    Performs the conversion.
    \ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/struct.WeightedUtxo.html b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/struct.WeightedUtxo.html index 325d651853..32b8893c89 100644 --- a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/struct.WeightedUtxo.html +++ b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/struct.WeightedUtxo.html @@ -1,41 +1,15 @@ -WeightedUtxo in bdk - Rust - -
    -

    Struct bdk::WeightedUtxo

    source · []
    pub struct WeightedUtxo {
    +WeightedUtxo in bdk - Rust

    Struct bdk::WeightedUtxo

    source ·
    pub struct WeightedUtxo {
         pub satisfaction_weight: usize,
         pub utxo: Utxo,
     }
    Expand description

    A Utxo with its satisfaction_weight.

    -

    Fields

    satisfaction_weight: usize

    The weight of the witness data and scriptSig expressed in weight units. This is used to +

    Fields§

    §satisfaction_weight: usize

    The weight of the witness data and scriptSig expressed in weight units. This is used to properly maintain the feerate when adding this input to a transaction during coin selection.

    -
    utxo: Utxo

    The UTXO

    -

    Trait Implementations

    Returns a copy of the value. Read more

    -

    Performs copy-assignment from source. Read more

    -

    Formats the value using the given formatter. Read more

    -

    This method tests for self and other values to be equal, and is used -by ==. Read more

    -

    This method tests for !=.

    -

    Auto Trait Implementations

    Blanket Implementations

    Gets the TypeId of self. Read more

    -

    Immutably borrows from an owned value. Read more

    -

    Mutably borrows from an owned value. Read more

    -

    Performs the conversion.

    -

    Performs the conversion.

    -

    The alignment of pointer.

    -

    The type for initializers.

    -

    Initializes a with the given initializer. Read more

    -

    Dereferences the given pointer. Read more

    -

    Mutably dereferences the given pointer. Read more

    -

    Drops the object pointed to by the given pointer. Read more

    -

    The resulting type after obtaining ownership.

    -

    Creates owned data from borrowed data, usually by cloning. Read more

    -
    🔬 This is a nightly-only experimental API. (toowned_clone_into)

    Uses borrowed data to replace owned data, usually by cloning. Read more

    -

    The type returned in the event of a conversion error.

    -

    Performs the conversion.

    -

    The type returned in the event of a conversion error.

    -

    Performs the conversion.

    -
    - \ No newline at end of file +
    §utxo: Utxo

    The UTXO

    +

    Trait Implementations§

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

    Auto Trait Implementations§

    Blanket Implementations§

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

    Returns the argument unchanged.

    +

    Calls U::from(self).

    +

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

    +
    The alignment of pointer.
    The type for initializers.
    Initializes a with the given initializer. Read more
    Dereferences the given pointer. Read more
    Mutably dereferences the given pointer. Read more
    Drops the object pointed to by the given pointer. Read more
    The resulting type after obtaining ownership.
    Creates owned data from borrowed data, usually by cloning. Read more
    Uses borrowed data to replace owned data, usually by cloning. Read more
    The type returned in the event of a conversion error.
    Performs the conversion.
    The type returned in the event of a conversion error.
    Performs the conversion.
    \ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/trait.Vbytes.html b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/trait.Vbytes.html index 90fe219959..a788ecf07f 100644 --- a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/trait.Vbytes.html +++ b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/trait.Vbytes.html @@ -1,14 +1,6 @@ -Vbytes in bdk - Rust - -
    -

    Trait bdk::Vbytes

    source · []
    pub trait Vbytes {
    -    fn vbytes(self) -> usize;
    +Vbytes in bdk - Rust

    Trait bdk::Vbytes

    source ·
    pub trait Vbytes {
    +    fn vbytes(self) -> usize;
     }
    Expand description

    Trait implemented by types that can be used to measure weight units.

    -

    Required methods

    Convert weight units to virtual bytes.

    -

    Implementations on Foreign Types

    Implementors

    - \ No newline at end of file +

    Required Methods§

    Convert weight units to virtual bytes.

    +

    Implementations on Foreign Types§

    Implementors§

    \ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/type.ConfirmationTime.html b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/type.ConfirmationTime.html index 9454eb0869..9d7e3bf2cf 100644 --- a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/type.ConfirmationTime.html +++ b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/type.ConfirmationTime.html @@ -1,13 +1,4 @@ -ConfirmationTime in bdk - Rust - -
    -

    Type Definition bdk::ConfirmationTime

    source · []
    pub type ConfirmationTime = BlockTime;
    👎 Deprecated:

    This structure has been renamed to BlockTime

    -
    Expand description

    DEPRECATED: Confirmation time of a transaction

    +ConfirmationTime in bdk - Rust

    Type Definition bdk::ConfirmationTime

    source ·
    pub type ConfirmationTime = BlockTime;
    👎Deprecated: This structure has been renamed to BlockTime
    Expand description

    DEPRECATED: Confirmation time of a transaction

    The structure has been renamed to BlockTime

    -
    - \ No newline at end of file +
    \ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/wallet/coin_selection/enum.Excess.html b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/wallet/coin_selection/enum.Excess.html index d5b6baadc0..3cf8febb2c 100644 --- a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/wallet/coin_selection/enum.Excess.html +++ b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/wallet/coin_selection/enum.Excess.html @@ -1,12 +1,5 @@ -Excess in bdk::wallet::coin_selection - Rust - -
    pub enum Excess {
    +Excess in bdk::wallet::coin_selection - Rust
    pub enum Excess {
         NoChange {
             dust_threshold: u64,
             remaining_amount: u64,
    @@ -17,28 +10,15 @@
             fee: u64,
         },
     }
    Expand description

    Remaining amount after performing coin selection

    -

    Variants

    NoChange

    Fields

    dust_threshold: u64

    Threshold to consider amount as dust for this particular change script_pubkey

    -
    remaining_amount: u64

    Exceeding amount of current selection over outgoing value and fee costs

    -
    change_fee: u64

    The calculated fee for the drain TxOut with the selected script_pubkey

    +

    Variants§

    §

    NoChange

    Fields

    §dust_threshold: u64

    Threshold to consider amount as dust for this particular change script_pubkey

    +
    §remaining_amount: u64

    Exceeding amount of current selection over outgoing value and fee costs

    +
    §change_fee: u64

    The calculated fee for the drain TxOut with the selected script_pubkey

    It’s not possible to create spendable output from excess using the current drain output

    -

    Change

    Fields

    amount: u64

    Effective amount available to create change after deducting the change output fee

    -
    fee: u64

    The deducted change output fee

    +
    §

    Change

    Fields

    §amount: u64

    Effective amount available to create change after deducting the change output fee

    +
    §fee: u64

    The deducted change output fee

    It’s possible to create spendable output from excess using the current drain output

    -

    Trait Implementations

    Formats the value using the given formatter. Read more

    -

    Auto Trait Implementations

    Blanket Implementations

    Gets the TypeId of self. Read more

    -

    Immutably borrows from an owned value. Read more

    -

    Mutably borrows from an owned value. Read more

    -

    Performs the conversion.

    -

    Performs the conversion.

    -

    The alignment of pointer.

    -

    The type for initializers.

    -

    Initializes a with the given initializer. Read more

    -

    Dereferences the given pointer. Read more

    -

    Mutably dereferences the given pointer. Read more

    -

    Drops the object pointed to by the given pointer. Read more

    -

    The type returned in the event of a conversion error.

    -

    Performs the conversion.

    -

    The type returned in the event of a conversion error.

    -

    Performs the conversion.

    -
    - \ No newline at end of file +

    Trait Implementations§

    Formats the value using the given formatter. Read more

    Auto Trait Implementations§

    Blanket Implementations§

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

    Returns the argument unchanged.

    +

    Calls U::from(self).

    +

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

    +
    The alignment of pointer.
    The type for initializers.
    Initializes a with the given initializer. Read more
    Dereferences the given pointer. Read more
    Mutably dereferences the given pointer. Read more
    Drops the object pointed to by the given pointer. Read more
    The type returned in the event of a conversion error.
    Performs the conversion.
    The type returned in the event of a conversion error.
    Performs the conversion.
    \ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/wallet/coin_selection/fn.decide_change.html b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/wallet/coin_selection/fn.decide_change.html index 755b296865..94db309635 100644 --- a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/wallet/coin_selection/fn.decide_change.html +++ b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/wallet/coin_selection/fn.decide_change.html @@ -1,16 +1,8 @@ -decide_change in bdk::wallet::coin_selection - Rust - -
    pub fn decide_change(
        remaining_amount: u64,
        fee_rate: FeeRate,
        drain_script: &Script
    ) -> Excess
    Expand description

    Decide if change can be created

    +decide_change in bdk::wallet::coin_selection - Rust
    pub fn decide_change(
        remaining_amount: u64,
        fee_rate: FeeRate,
        drain_script: &Script
    ) -> Excess
    Expand description

    Decide if change can be created

    • remaining_amount: the amount in which the selected coins exceed the target amount
    • fee_rate: required fee rate for the current selection
    • drain_script: script to consider change creation
    -
    - \ No newline at end of file +
    \ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/wallet/coin_selection/index.html b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/wallet/coin_selection/index.html index 5342acbb26..83424c5cd3 100644 --- a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/wallet/coin_selection/index.html +++ b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/wallet/coin_selection/index.html @@ -1,90 +1,69 @@ -bdk::wallet::coin_selection - Rust - -
    Expand description

    Coin selection

    +bdk::wallet::coin_selection - Rust

    Module bdk::wallet::coin_selection

    source ·
    Expand description

    Coin selection

    This module provides the trait CoinSelectionAlgorithm that can be implemented to define custom coin selection algorithms.

    You can specify a custom coin selection algorithm through the coin_selection method on TxBuilder. DefaultCoinSelectionAlgorithm aliases the coin selection algorithm that will be used if it is not explicitly set.

    -

    Example

    -
    #[derive(Debug)]
    -struct AlwaysSpendEverything;
    +

    Example

    +
    #[derive(Debug)]
    +struct AlwaysSpendEverything;
     
    -impl<D: Database> CoinSelectionAlgorithm<D> for AlwaysSpendEverything {
    -    fn coin_select(
    +impl<D: Database> CoinSelectionAlgorithm<D> for AlwaysSpendEverything {
    +    fn coin_select(
             &self,
    -        database: &D,
    -        required_utxos: Vec<WeightedUtxo>,
    -        optional_utxos: Vec<WeightedUtxo>,
    -        fee_rate: FeeRate,
    -        target_amount: u64,
    -        drain_script: &Script,
    -    ) -> Result<CoinSelectionResult, bdk::Error> {
    -        let mut selected_amount = 0;
    -        let mut additional_weight = 0;
    -        let all_utxos_selected = required_utxos
    -            .into_iter()
    -            .chain(optional_utxos)
    -            .scan(
    -                (&mut selected_amount, &mut additional_weight),
    -                |(selected_amount, additional_weight), weighted_utxo| {
    -                    **selected_amount += weighted_utxo.utxo.txout().value;
    -                    **additional_weight += TXIN_BASE_WEIGHT + weighted_utxo.satisfaction_weight;
    -                    Some(weighted_utxo.utxo)
    +        database: &D,
    +        required_utxos: Vec<WeightedUtxo>,
    +        optional_utxos: Vec<WeightedUtxo>,
    +        fee_rate: FeeRate,
    +        target_amount: u64,
    +        drain_script: &Script,
    +    ) -> Result<CoinSelectionResult, bdk::Error> {
    +        let mut selected_amount = 0;
    +        let mut additional_weight = 0;
    +        let all_utxos_selected = required_utxos
    +            .into_iter()
    +            .chain(optional_utxos)
    +            .scan(
    +                (&mut selected_amount, &mut additional_weight),
    +                |(selected_amount, additional_weight), weighted_utxo| {
    +                    **selected_amount += weighted_utxo.utxo.txout().value;
    +                    **additional_weight += TXIN_BASE_WEIGHT + weighted_utxo.satisfaction_weight;
    +                    Some(weighted_utxo.utxo)
                     },
                 )
    -            .collect::<Vec<_>>();
    -        let additional_fees = fee_rate.fee_wu(additional_weight);
    -        let amount_needed_with_fees = additional_fees + target_amount;
    -        if selected_amount < amount_needed_with_fees {
    -            return Err(bdk::Error::InsufficientFunds {
    -                needed: amount_needed_with_fees,
    -                available: selected_amount,
    +            .collect::<Vec<_>>();
    +        let additional_fees = fee_rate.fee_wu(additional_weight);
    +        let amount_needed_with_fees = additional_fees + target_amount;
    +        if selected_amount < amount_needed_with_fees {
    +            return Err(bdk::Error::InsufficientFunds {
    +                needed: amount_needed_with_fees,
    +                available: selected_amount,
                 });
             }
     
    -        let remaining_amount = selected_amount - amount_needed_with_fees;
    +        let remaining_amount = selected_amount - amount_needed_with_fees;
     
    -        let excess = decide_change(remaining_amount, fee_rate, drain_script);
    +        let excess = decide_change(remaining_amount, fee_rate, drain_script);
     
    -        Ok(CoinSelectionResult {
    -            selected: all_utxos_selected,
    -            fee_amount: additional_fees,
    -            excess,
    +        Ok(CoinSelectionResult {
    +            selected: all_utxos_selected,
    +            fee_amount: additional_fees,
    +            excess,
             })
         }
     }
     
    -// create wallet, sync, ...
    +// create wallet, sync, ...
     
    -let to_address = Address::from_str("2N4eQYCbKUHCCTUjBJeHcJp9ok6J2GZsTDt").unwrap();
    -let (psbt, details) = {
    -    let mut builder = wallet.build_tx().coin_selection(AlwaysSpendEverything);
    -    builder.add_recipient(to_address.script_pubkey(), 50_000);
    -    builder.finish()?
    -};
    +let to_address = Address::from_str("2N4eQYCbKUHCCTUjBJeHcJp9ok6J2GZsTDt").unwrap();
    +let (psbt, details) = {
    +    let mut builder = wallet.build_tx().coin_selection(AlwaysSpendEverything);
    +    builder.add_recipient(to_address.script_pubkey(), 50_000);
    +    builder.finish()?
    +};
     
    -// inspect, sign, broadcast, ...
    -
    -

    Structs

    -

    Branch and bound coin selection

    -

    Result of a successful coin selection

    -

    Simple and dumb coin selection

    -

    OldestFirstCoinSelection always picks the utxo with the smallest blockheight to add to the selected coins next

    -

    Enums

    -

    Remaining amount after performing coin selection

    -

    Traits

    -

    Trait for generalized coin selection algorithms

    -

    Functions

    -

    Decide if change can be created

    -

    Type Definitions

    -

    Default coin selection algorithm used by TxBuilder if not -overridden

    -
    - \ No newline at end of file +// inspect, sign, broadcast, ... +
    +

    Structs

    Branch and bound coin selection
    Result of a successful coin selection
    Simple and dumb coin selection
    OldestFirstCoinSelection always picks the utxo with the smallest blockheight to add to the selected coins next

    Enums

    Remaining amount after performing coin selection

    Traits

    Trait for generalized coin selection algorithms

    Functions

    Decide if change can be created

    Type Definitions

    Default coin selection algorithm used by TxBuilder if not +overridden
    \ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/wallet/coin_selection/sidebar-items.js b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/wallet/coin_selection/sidebar-items.js index 4943ba67e8..7706d493e0 100644 --- a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/wallet/coin_selection/sidebar-items.js +++ b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/wallet/coin_selection/sidebar-items.js @@ -1 +1 @@ -initSidebarItems({"enum":[["Excess","Remaining amount after performing coin selection"]],"fn":[["decide_change","Decide if change can be created"]],"struct":[["BranchAndBoundCoinSelection","Branch and bound coin selection"],["CoinSelectionResult","Result of a successful coin selection"],["LargestFirstCoinSelection","Simple and dumb coin selection"],["OldestFirstCoinSelection","OldestFirstCoinSelection always picks the utxo with the smallest blockheight to add to the selected coins next"]],"trait":[["CoinSelectionAlgorithm","Trait for generalized coin selection algorithms"]],"type":[["DefaultCoinSelectionAlgorithm","Default coin selection algorithm used by `TxBuilder` if not overridden"]]}); \ No newline at end of file +window.SIDEBAR_ITEMS = {"enum":[["Excess","Remaining amount after performing coin selection"]],"fn":[["decide_change","Decide if change can be created"]],"struct":[["BranchAndBoundCoinSelection","Branch and bound coin selection"],["CoinSelectionResult","Result of a successful coin selection"],["LargestFirstCoinSelection","Simple and dumb coin selection"],["OldestFirstCoinSelection","OldestFirstCoinSelection always picks the utxo with the smallest blockheight to add to the selected coins next"]],"trait":[["CoinSelectionAlgorithm","Trait for generalized coin selection algorithms"]],"type":[["DefaultCoinSelectionAlgorithm","Default coin selection algorithm used by `TxBuilder` if not overridden"]]}; \ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/wallet/coin_selection/struct.BranchAndBoundCoinSelection.html b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/wallet/coin_selection/struct.BranchAndBoundCoinSelection.html index ef15844bea..b35430b406 100644 --- a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/wallet/coin_selection/struct.BranchAndBoundCoinSelection.html +++ b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/wallet/coin_selection/struct.BranchAndBoundCoinSelection.html @@ -1,31 +1,9 @@ -BranchAndBoundCoinSelection in bdk::wallet::coin_selection - Rust - -
    pub struct BranchAndBoundCoinSelection { /* private fields */ }
    Expand description

    Branch and bound coin selection

    +BranchAndBoundCoinSelection in bdk::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

    Create new instance with target size for change output

    -

    Trait Implementations

    Perform the coin selection Read more

    -

    Formats the value using the given formatter. Read more

    -

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

    -

    Auto Trait Implementations

    Blanket Implementations

    Gets the TypeId of self. Read more

    -

    Immutably borrows from an owned value. Read more

    -

    Mutably borrows from an owned value. Read more

    -

    Performs the conversion.

    -

    Performs the conversion.

    -

    The alignment of pointer.

    -

    The type for initializers.

    -

    Initializes a with the given initializer. Read more

    -

    Dereferences the given pointer. Read more

    -

    Mutably dereferences the given pointer. Read more

    -

    Drops the object pointed to by the given pointer. Read more

    -

    The type returned in the event of a conversion error.

    -

    Performs the conversion.

    -

    The type returned in the event of a conversion error.

    -

    Performs the conversion.

    -
    - \ No newline at end of file +

    Implementations§

    Create new instance with target size for change output

    +

    Trait Implementations§

    Perform the coin selection Read more
    Formats the value using the given formatter. Read more
    Returns the “default value” for a type. Read more

    Auto Trait Implementations§

    Blanket Implementations§

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

    Returns the argument unchanged.

    +

    Calls U::from(self).

    +

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

    +
    The alignment of pointer.
    The type for initializers.
    Initializes a with the given initializer. Read more
    Dereferences the given pointer. Read more
    Mutably dereferences the given pointer. Read more
    Drops the object pointed to by the given pointer. Read more
    The type returned in the event of a conversion error.
    Performs the conversion.
    The type returned in the event of a conversion error.
    Performs the conversion.
    \ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/wallet/coin_selection/struct.CoinSelectionResult.html b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/wallet/coin_selection/struct.CoinSelectionResult.html index 87fdd6a2d7..679507904d 100644 --- a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/wallet/coin_selection/struct.CoinSelectionResult.html +++ b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/wallet/coin_selection/struct.CoinSelectionResult.html @@ -1,36 +1,16 @@ -CoinSelectionResult in bdk::wallet::coin_selection - Rust - -
    pub struct CoinSelectionResult {
    +CoinSelectionResult in bdk::wallet::coin_selection - Rust
    pub struct CoinSelectionResult {
         pub selected: Vec<Utxo>,
         pub fee_amount: u64,
         pub excess: Excess,
     }
    Expand description

    Result of a successful coin selection

    -

    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

    The total value of the inputs selected.

    -

    The total value of the inputs selected from the local wallet.

    -

    Trait Implementations

    Formats the value using the given formatter. Read more

    -

    Auto Trait Implementations

    Blanket Implementations

    Gets the TypeId of self. Read more

    -

    Immutably borrows from an owned value. Read more

    -

    Mutably borrows from an owned value. Read more

    -

    Performs the conversion.

    -

    Performs the conversion.

    -

    The alignment of pointer.

    -

    The type for initializers.

    -

    Initializes a with the given initializer. Read more

    -

    Dereferences the given pointer. Read more

    -

    Mutably dereferences the given pointer. Read more

    -

    Drops the object pointed to by the given pointer. Read more

    -

    The type returned in the event of a conversion error.

    -

    Performs the conversion.

    -

    The type returned in the event of a conversion error.

    -

    Performs the conversion.

    -
    - \ No newline at end of file +

    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§

    The total value of the inputs selected.

    +

    The total value of the inputs selected from the local wallet.

    +

    Trait Implementations§

    Formats the value using the given formatter. Read more

    Auto Trait Implementations§

    Blanket Implementations§

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

    Returns the argument unchanged.

    +

    Calls U::from(self).

    +

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

    +
    The alignment of pointer.
    The type for initializers.
    Initializes a with the given initializer. Read more
    Dereferences the given pointer. Read more
    Mutably dereferences the given pointer. Read more
    Drops the object pointed to by the given pointer. Read more
    The type returned in the event of a conversion error.
    Performs the conversion.
    The type returned in the event of a conversion error.
    Performs the conversion.
    \ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/wallet/coin_selection/struct.LargestFirstCoinSelection.html b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/wallet/coin_selection/struct.LargestFirstCoinSelection.html index f9c9ade24b..39612b53c6 100644 --- a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/wallet/coin_selection/struct.LargestFirstCoinSelection.html +++ b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/wallet/coin_selection/struct.LargestFirstCoinSelection.html @@ -1,36 +1,9 @@ -LargestFirstCoinSelection in bdk::wallet::coin_selection - Rust - -
    pub struct LargestFirstCoinSelection;
    Expand description

    Simple and dumb coin selection

    +LargestFirstCoinSelection in bdk::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

    Returns a copy of the value. Read more

    -

    Performs copy-assignment from source. Read more

    -

    Perform the coin selection Read more

    -

    Formats the value using the given formatter. Read more

    -

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

    -

    Auto Trait Implementations

    Blanket Implementations

    Gets the TypeId of self. Read more

    -

    Immutably borrows from an owned value. Read more

    -

    Mutably borrows from an owned value. Read more

    -

    Performs the conversion.

    -

    Performs the conversion.

    -

    The alignment of pointer.

    -

    The type for initializers.

    -

    Initializes a with the given initializer. Read more

    -

    Dereferences the given pointer. Read more

    -

    Mutably dereferences the given pointer. Read more

    -

    Drops the object pointed to by the given pointer. Read more

    -

    The resulting type after obtaining ownership.

    -

    Creates owned data from borrowed data, usually by cloning. Read more

    -
    🔬 This is a nightly-only experimental API. (toowned_clone_into)

    Uses borrowed data to replace owned data, usually by cloning. Read more

    -

    The type returned in the event of a conversion error.

    -

    Performs the conversion.

    -

    The type returned in the event of a conversion error.

    -

    Performs the conversion.

    -
    - \ No newline at end of file +

    Trait Implementations§

    Returns a copy of the value. Read more
    Performs copy-assignment from source. Read more
    Perform the coin selection Read more
    Formats the value using the given formatter. Read more
    Returns the “default value” for a type. Read more

    Auto Trait Implementations§

    Blanket Implementations§

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

    Returns the argument unchanged.

    +

    Calls U::from(self).

    +

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

    +
    The alignment of pointer.
    The type for initializers.
    Initializes a with the given initializer. Read more
    Dereferences the given pointer. Read more
    Mutably dereferences the given pointer. Read more
    Drops the object pointed to by the given pointer. Read more
    The resulting type after obtaining ownership.
    Creates owned data from borrowed data, usually by cloning. Read more
    Uses borrowed data to replace owned data, usually by cloning. Read more
    The type returned in the event of a conversion error.
    Performs the conversion.
    The type returned in the event of a conversion error.
    Performs the conversion.
    \ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/wallet/coin_selection/struct.OldestFirstCoinSelection.html b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/wallet/coin_selection/struct.OldestFirstCoinSelection.html index b25e760ca2..68b86219a7 100644 --- a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/wallet/coin_selection/struct.OldestFirstCoinSelection.html +++ b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/wallet/coin_selection/struct.OldestFirstCoinSelection.html @@ -1,36 +1,9 @@ -OldestFirstCoinSelection in bdk::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::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

    Returns a copy of the value. Read more

    -

    Performs copy-assignment from source. Read more

    -

    Perform the coin selection Read more

    -

    Formats the value using the given formatter. Read more

    -

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

    -

    Auto Trait Implementations

    Blanket Implementations

    Gets the TypeId of self. Read more

    -

    Immutably borrows from an owned value. Read more

    -

    Mutably borrows from an owned value. Read more

    -

    Performs the conversion.

    -

    Performs the conversion.

    -

    The alignment of pointer.

    -

    The type for initializers.

    -

    Initializes a with the given initializer. Read more

    -

    Dereferences the given pointer. Read more

    -

    Mutably dereferences the given pointer. Read more

    -

    Drops the object pointed to by the given pointer. Read more

    -

    The resulting type after obtaining ownership.

    -

    Creates owned data from borrowed data, usually by cloning. Read more

    -
    🔬 This is a nightly-only experimental API. (toowned_clone_into)

    Uses borrowed data to replace owned data, usually by cloning. Read more

    -

    The type returned in the event of a conversion error.

    -

    Performs the conversion.

    -

    The type returned in the event of a conversion error.

    -

    Performs the conversion.

    -
    - \ No newline at end of file +

    Trait Implementations§

    Returns a copy of the value. Read more
    Performs copy-assignment from source. Read more
    Perform the coin selection Read more
    Formats the value using the given formatter. Read more
    Returns the “default value” for a type. Read more

    Auto Trait Implementations§

    Blanket Implementations§

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

    Returns the argument unchanged.

    +

    Calls U::from(self).

    +

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

    +
    The alignment of pointer.
    The type for initializers.
    Initializes a with the given initializer. Read more
    Dereferences the given pointer. Read more
    Mutably dereferences the given pointer. Read more
    Drops the object pointed to by the given pointer. Read more
    The resulting type after obtaining ownership.
    Creates owned data from borrowed data, usually by cloning. Read more
    Uses borrowed data to replace owned data, usually by cloning. Read more
    The type returned in the event of a conversion error.
    Performs the conversion.
    The type returned in the event of a conversion error.
    Performs the conversion.
    \ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/wallet/coin_selection/trait.CoinSelectionAlgorithm.html b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/wallet/coin_selection/trait.CoinSelectionAlgorithm.html index 16ffdf5158..3d7ab45330 100644 --- a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/wallet/coin_selection/trait.CoinSelectionAlgorithm.html +++ b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/wallet/coin_selection/trait.CoinSelectionAlgorithm.html @@ -1,18 +1,11 @@ -CoinSelectionAlgorithm in bdk::wallet::coin_selection - Rust - -
    pub trait CoinSelectionAlgorithm<D: Database>: Debug {
    -    fn coin_select(
            &self,
            database: &D,
            required_utxos: Vec<WeightedUtxo>,
            optional_utxos: Vec<WeightedUtxo>,
            fee_rate: FeeRate,
            target_amount: u64,
            drain_script: &Script
        ) -> Result<CoinSelectionResult, Error>; +CoinSelectionAlgorithm in bdk::wallet::coin_selection - Rust
    pub trait CoinSelectionAlgorithm<D: Database>: Debug {
    +    fn coin_select(
            &self,
            database: &D,
            required_utxos: Vec<WeightedUtxo>,
            optional_utxos: Vec<WeightedUtxo>,
            fee_rate: FeeRate,
            target_amount: u64,
            drain_script: &Script
        ) -> Result<CoinSelectionResult, Error>; }
    Expand description

    Trait for generalized coin selection algorithms

    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

    Perform the coin selection

    +

    Required Methods§

    Perform the coin selection

    • database: a reference to the wallet’s database that can be used to lookup additional details for a specific UTXO
    • @@ -25,5 +18,4 @@ weight cost 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/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/wallet/coin_selection/type.DefaultCoinSelectionAlgorithm.html b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/wallet/coin_selection/type.DefaultCoinSelectionAlgorithm.html index 29c394cf68..46d482c6dd 100644 --- a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/wallet/coin_selection/type.DefaultCoinSelectionAlgorithm.html +++ b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/wallet/coin_selection/type.DefaultCoinSelectionAlgorithm.html @@ -1,12 +1,4 @@ -DefaultCoinSelectionAlgorithm in bdk::wallet::coin_selection - Rust - -
    pub type DefaultCoinSelectionAlgorithm = BranchAndBoundCoinSelection;
    Expand description

    Default coin selection algorithm used by TxBuilder if not +DefaultCoinSelectionAlgorithm in bdk::wallet::coin_selection - Rust

    pub type DefaultCoinSelectionAlgorithm = BranchAndBoundCoinSelection;
    Expand description

    Default coin selection algorithm used by TxBuilder if not overridden

    -
    - \ No newline at end of file +
    \ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/wallet/enum.AddressIndex.html b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/wallet/enum.AddressIndex.html index 47482a14c3..c652ad6ad6 100644 --- a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/wallet/enum.AddressIndex.html +++ b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/wallet/enum.AddressIndex.html @@ -1,51 +1,31 @@ -AddressIndex in bdk::wallet - Rust - -
    pub enum AddressIndex {
    +AddressIndex in bdk::wallet - Rust

    Enum bdk::wallet::AddressIndex

    source ·
    pub enum AddressIndex {
         New,
         LastUnused,
         Peek(u32),
         Reset(u32),
     }
    Expand description

    The address index selection strategy to use to derived an address from the wallet’s external descriptor. See Wallet::get_address. If you’re unsure which one to use use WalletIndex::New.

    -

    Variants

    New

    Return a new address after incrementing the current descriptor index.

    -

    LastUnused

    Return the address for the current descriptor index if it has not been used in a received +

    Variants§

    §

    New

    Return a new address after incrementing the current descriptor index.

    +
    §

    LastUnused

    Return the address for the current descriptor index if it has not been used in a received transaction. Otherwise return a new address as with AddressIndex::New.

    Use with caution, if the wallet has not yet detected an address has been used it could return an already used address. This function is primarily meant for situations where the caller is untrusted; for example when deriving donation addresses on-demand for a public web page.

    -

    Peek(u32)

    Return the address for a specific descriptor index. Does not change the current descriptor +

    §

    Peek(u32)

    Return the address for a specific descriptor index. Does not change the current descriptor index used by AddressIndex::New and AddressIndex::LastUsed.

    Use with caution, if an index is given that is less than the current descriptor index then the returned address may have already been used.

    -

    Reset(u32)

    Return the address for a specific descriptor index and reset the current descriptor index +

    §

    Reset(u32)

    Return the address for a specific descriptor index and reset the current descriptor index used by AddressIndex::New and AddressIndex::LastUsed to this value.

    Use with caution, if an index is given that is less than the current descriptor index then the returned address and subsequent addresses returned by calls to AddressIndex::New and AddressIndex::LastUsed may have already been used. Also if the index is reset to a value earlier than the crate::blockchain::Blockchain stop_gap (default is 20) then a larger stop_gap should be used to monitor for all possibly used addresses.

    -

    Trait Implementations

    Formats the value using the given formatter. Read more

    -

    Auto Trait Implementations

    Blanket Implementations

    Gets the TypeId of self. Read more

    -

    Immutably borrows from an owned value. Read more

    -

    Mutably borrows from an owned value. Read more

    -

    Performs the conversion.

    -

    Performs the conversion.

    -

    The alignment of pointer.

    -

    The type for initializers.

    -

    Initializes a with the given initializer. Read more

    -

    Dereferences the given pointer. Read more

    -

    Mutably dereferences the given pointer. Read more

    -

    Drops the object pointed to by the given pointer. Read more

    -

    The type returned in the event of a conversion error.

    -

    Performs the conversion.

    -

    The type returned in the event of a conversion error.

    -

    Performs the conversion.

    -
    - \ No newline at end of file +

    Trait Implementations§

    Formats the value using the given formatter. Read more

    Auto Trait Implementations§

    Blanket Implementations§

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

    Returns the argument unchanged.

    +

    Calls U::from(self).

    +

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

    +
    The alignment of pointer.
    The type for initializers.
    Initializes a with the given initializer. Read more
    Dereferences the given pointer. Read more
    Mutably dereferences the given pointer. Read more
    Drops the object pointed to by the given pointer. Read more
    The type returned in the event of a conversion error.
    Performs the conversion.
    The type returned in the event of a conversion error.
    Performs the conversion.
    \ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/wallet/export/index.html b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/wallet/export/index.html index 88768d1a04..44ce4ea373 100644 --- a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/wallet/export/index.html +++ b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/wallet/export/index.html @@ -1,42 +1,30 @@ -bdk::wallet::export - Rust - -
    -

    Module bdk::wallet::export

    source · []
    Expand description

    Wallet export

    +bdk::wallet::export - Rust

    Module bdk::wallet::export

    source ·
    Expand description

    Wallet export

    This modules implements the wallet export format used by FullyNoded.

    -

    Examples

    Import from JSON

    -
    let import = r#"{
    +

    Examples

    Import from JSON

    +
    let import = r#"{
         "descriptor": "wpkh([c258d2e4\/84h\/1h\/0h]tpubDD3ynpHgJQW8VvWRzQ5WFDCrs4jqVFGHB3vLC3r49XHJSqP8bHKdK4AriuUKLccK68zfzowx7YhmDN8SiSkgCDENUFx9qVw65YyqM78vyVe\/0\/*)",
         "blockheight":1782088,
         "label":"testnet"
     }"#;
     
    -let import = FullyNodedExport::from_str(import)?;
    -let wallet = Wallet::new(
    -    &import.descriptor(),
    -    import.change_descriptor().as_ref(),
    -    Network::Testnet,
    -    MemoryDatabase::default(),
    +let import = FullyNodedExport::from_str(import)?;
    +let wallet = Wallet::new(
    +    &import.descriptor(),
    +    import.change_descriptor().as_ref(),
    +    Network::Testnet,
    +    MemoryDatabase::default(),
     )?;
    -

    Export a Wallet

    -
    let wallet = Wallet::new(
    +

    Export a Wallet

    +
    let wallet = Wallet::new(
         "wpkh([c258d2e4/84h/1h/0h]tpubDD3ynpHgJQW8VvWRzQ5WFDCrs4jqVFGHB3vLC3r49XHJSqP8bHKdK4AriuUKLccK68zfzowx7YhmDN8SiSkgCDENUFx9qVw65YyqM78vyVe/0/*)",
         Some("wpkh([c258d2e4/84h/1h/0h]tpubDD3ynpHgJQW8VvWRzQ5WFDCrs4jqVFGHB3vLC3r49XHJSqP8bHKdK4AriuUKLccK68zfzowx7YhmDN8SiSkgCDENUFx9qVw65YyqM78vyVe/1/*)"),
    -    Network::Testnet,
    -    MemoryDatabase::default()
    +    Network::Testnet,
    +    MemoryDatabase::default()
     )?;
    -let export = FullyNodedExport::export_wallet(&wallet, "exported wallet", true)
    -    .map_err(ToString::to_string)
    -    .map_err(bdk::Error::Generic)?;
    +let export = FullyNodedExport::export_wallet(&wallet, "exported wallet", true)
    +    .map_err(ToString::to_string)
    +    .map_err(bdk::Error::Generic)?;
     
    -println!("Exported: {}", export.to_string());
    -

    Structs

    -

    Structure that contains the export of a wallet

    -

    Type Definitions

    -
    WalletExportDeprecated

    Alias for FullyNodedExport

    -
    - \ No newline at end of file +println!("Exported: {}", export.to_string());
    +

    Structs

    Structure that contains the export of a wallet

    Type Definitions

    WalletExportDeprecated
    \ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/wallet/export/sidebar-items.js b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/wallet/export/sidebar-items.js index 7b5d4df89f..07ee950354 100644 --- a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/wallet/export/sidebar-items.js +++ b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/wallet/export/sidebar-items.js @@ -1 +1 @@ -initSidebarItems({"struct":[["FullyNodedExport","Structure that contains the export of a wallet"]],"type":[["WalletExport","Alias for [`FullyNodedExport`]"]]}); \ No newline at end of file +window.SIDEBAR_ITEMS = {"struct":[["FullyNodedExport","Structure that contains the export of a wallet"]],"type":[["WalletExport","Alias for [`FullyNodedExport`]"]]}; \ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/wallet/export/struct.FullyNodedExport.html b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/wallet/export/struct.FullyNodedExport.html index 55c3e243c7..acc861f402 100644 --- a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/wallet/export/struct.FullyNodedExport.html +++ b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/wallet/export/struct.FullyNodedExport.html @@ -1,20 +1,13 @@ -FullyNodedExport in bdk::wallet::export - Rust - -
    pub struct FullyNodedExport {
    +FullyNodedExport in bdk::wallet::export - Rust
    pub struct FullyNodedExport {
         pub blockheight: u32,
         pub label: String,
         /* private fields */
     }
    Expand description

    Structure that contains the export of a wallet

    For a usage example see this module’s documentation.

    -

    Fields

    blockheight: u32

    Earliest block to rescan when looking for the wallet’s transactions

    -
    label: String

    Arbitrary label for the wallet

    -

    Implementations

    Export a wallet

    +

    Fields§

    §blockheight: u32

    Earliest block to rescan when looking for the wallet’s transactions

    +
    §label: String

    Arbitrary label for the wallet

    +

    Implementations§

    Export a wallet

    This function returns an error if it determines that the wallet’s descriptor(s) are not supported by Bitcoin Core or don’t follow the standard derivation paths defined by BIP44 and others.

    @@ -22,28 +15,10 @@ and others.

    for the oldest transaction it knows and use that as the earliest block to rescan.

    If the database is empty or include_blockheight is false, the blockheight field returned will be 0.

    -

    Return the external descriptor

    -

    Return the internal descriptor, if present

    -

    Trait Implementations

    Formats the value using the given formatter. Read more

    -

    Deserialize this value from the given Serde deserializer. Read more

    -

    The associated error which can be returned from parsing.

    -

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

    -

    Serialize this value into the given Serde serializer. Read more

    -

    Converts the given value to a String. Read more

    -

    Auto Trait Implementations

    Blanket Implementations

    Gets the TypeId of self. Read more

    -

    Immutably borrows from an owned value. Read more

    -

    Mutably borrows from an owned value. Read more

    -

    Performs the conversion.

    -

    Performs the conversion.

    -

    The alignment of pointer.

    -

    The type for initializers.

    -

    Initializes a with the given initializer. Read more

    -

    Dereferences the given pointer. Read more

    -

    Mutably dereferences the given pointer. Read more

    -

    Drops the object pointed to by the given pointer. Read more

    -

    The type returned in the event of a conversion error.

    -

    Performs the conversion.

    -

    The type returned in the event of a conversion error.

    -

    Performs the conversion.

    -
    - \ No newline at end of file +

    Return the external descriptor

    +

    Return the internal descriptor, if present

    +

    Trait Implementations§

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

    Auto Trait Implementations§

    Blanket Implementations§

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

    Returns the argument unchanged.

    +

    Calls U::from(self).

    +

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

    +
    The alignment of pointer.
    The type for initializers.
    Initializes a with the given initializer. Read more
    Dereferences the given pointer. Read more
    Mutably dereferences the given pointer. Read more
    Drops the object pointed to by the given pointer. Read more
    The type returned in the event of a conversion error.
    Performs the conversion.
    The type returned in the event of a conversion error.
    Performs the conversion.
    \ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/wallet/export/type.WalletExport.html b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/wallet/export/type.WalletExport.html index 9d9dd1ea3b..c2c927378c 100644 --- a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/wallet/export/type.WalletExport.html +++ b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/wallet/export/type.WalletExport.html @@ -1,12 +1,3 @@ -WalletExport in bdk::wallet::export - Rust - -
    -

    Type Definition bdk::wallet::export::WalletExport

    source · []
    pub type WalletExport = FullyNodedExport;
    👎 Deprecated since 0.18.0:

    Please use [FullyNodedExport] instead

    -
    Expand description

    Alias for FullyNodedExport

    -
    - \ No newline at end of file +WalletExport in bdk::wallet::export - Rust

    Type Definition bdk::wallet::export::WalletExport

    source ·
    pub type WalletExport = FullyNodedExport;
    👎Deprecated since 0.18.0: Please use [FullyNodedExport] instead
    Expand description

    Alias for FullyNodedExport

    +
    \ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/wallet/fn.get_funded_wallet.html b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/wallet/fn.get_funded_wallet.html index 1335539642..a4d5a3ba30 100644 --- a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/wallet/fn.get_funded_wallet.html +++ b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/wallet/fn.get_funded_wallet.html @@ -1,11 +1,3 @@ -get_funded_wallet in bdk::wallet - Rust - -
    pub fn get_funded_wallet(
        descriptor: &str
    ) -> (Wallet<AnyDatabase>, (String, Option<String>), Txid)
    Expand description

    Return a fake wallet that appears to be funded for testing.

    -
    - \ No newline at end of file +get_funded_wallet in bdk::wallet - Rust

    Function bdk::wallet::get_funded_wallet

    source ·
    pub fn get_funded_wallet(
        descriptor: &str
    ) -> (Wallet<AnyDatabase>, (String, Option<String>), Txid)
    Expand description

    Return a fake wallet that appears to be funded for testing.

    +
    \ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/wallet/fn.wallet_name_from_descriptor.html b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/wallet/fn.wallet_name_from_descriptor.html index 207eca6b0d..f69d7d02f1 100644 --- a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/wallet/fn.wallet_name_from_descriptor.html +++ b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/wallet/fn.wallet_name_from_descriptor.html @@ -1,12 +1,4 @@ -wallet_name_from_descriptor in bdk::wallet - Rust - -
    pub fn wallet_name_from_descriptor<T>(
        descriptor: T,
        change_descriptor: Option<T>,
        network: Network,
        secp: &Secp256k1<All>
    ) -> Result<String, Error> where
        T: IntoWalletDescriptor
    Expand description

    Deterministically generate a unique name given the descriptors defining the wallet

    +wallet_name_from_descriptor in bdk::wallet - Rust
    pub fn wallet_name_from_descriptor<T>(
        descriptor: T,
        change_descriptor: Option<T>,
        network: Network,
        secp: &Secp256k1<All>
    ) -> Result<String, Error>where
        T: IntoWalletDescriptor,
    Expand description

    Deterministically generate a unique name given the descriptors defining the wallet

    Compatible with wallet_name_from_descriptor

    -
    - \ No newline at end of file +
    \ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/wallet/hardwaresigner/index.html b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/wallet/hardwaresigner/index.html index 3b705657b7..14bb3b316c 100644 --- a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/wallet/hardwaresigner/index.html +++ b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/wallet/hardwaresigner/index.html @@ -1,27 +1,17 @@ -bdk::wallet::hardwaresigner - Rust - -
    This is supported on crate feature hardware-signer only.
    Expand description

    HWI Signer

    +bdk::wallet::hardwaresigner - Rust

    Module bdk::wallet::hardwaresigner

    source ·
    Available on crate feature hardware-signer only.
    Expand description

    HWI Signer

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

    -
    let devices = HWIClient::enumerate()?;
    -let first_device = devices.first().expect("No devices found!");
    -let custom_signer = HWISigner::from_device(first_device, HWIChain::Test)?;
    +
    let devices = HWIClient::enumerate()?;
    +let first_device = devices.first().expect("No devices found!");
    +let custom_signer = HWISigner::from_device(first_device, HWIChain::Test)?;
     
    -// Adding the hardware signer to the BDK wallet
    -wallet.add_signer(
    -    KeychainKind::External,
    -    SignerOrdering(200),
    -    Arc::new(custom_signer),
    +// Adding the hardware signer to the BDK wallet
    +wallet.add_signer(
    +    KeychainKind::External,
    +    SignerOrdering(200),
    +    Arc::new(custom_signer),
     );
     
    -

    Structs

    -

    Custom signer for Hardware Wallets

    -
    - \ No newline at end of file +

    Structs

    Custom signer for Hardware Wallets
    \ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/wallet/hardwaresigner/sidebar-items.js b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/wallet/hardwaresigner/sidebar-items.js index 3fd6588450..1db16cc1ab 100644 --- a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/wallet/hardwaresigner/sidebar-items.js +++ b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/wallet/hardwaresigner/sidebar-items.js @@ -1 +1 @@ -initSidebarItems({"struct":[["HWISigner","Custom signer for Hardware Wallets"]]}); \ No newline at end of file +window.SIDEBAR_ITEMS = {"struct":[["HWISigner","Custom signer for Hardware Wallets"]]}; \ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/wallet/hardwaresigner/struct.HWISigner.html b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/wallet/hardwaresigner/struct.HWISigner.html index 3bc32a9ae0..a0eeb2904f 100644 --- a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/wallet/hardwaresigner/struct.HWISigner.html +++ b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/wallet/hardwaresigner/struct.HWISigner.html @@ -1,33 +1,10 @@ -HWISigner in bdk::wallet::hardwaresigner - Rust - -
    pub struct HWISigner { /* private fields */ }
    This is supported on crate feature hardware-signer only.
    Expand description

    Custom signer for Hardware Wallets

    +HWISigner in bdk::wallet::hardwaresigner - Rust
    pub struct HWISigner { /* private fields */ }
    Available on crate feature hardware-signer only.
    Expand description

    Custom signer for Hardware Wallets

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

    -

    Implementations

    Create a instance from the specified device and chain

    -

    Trait Implementations

    Formats the value using the given formatter. Read more

    -

    Return the SignerId for this signer Read more

    -

    Return the secret key for the signer Read more

    -

    This implementation ignores sign_options

    -

    Sign all the inputs of the psbt

    -

    Auto Trait Implementations

    Blanket Implementations

    Gets the TypeId of self. Read more

    -

    Immutably borrows from an owned value. Read more

    -

    Mutably borrows from an owned value. Read more

    -

    Performs the conversion.

    -

    Performs the conversion.

    -

    The alignment of pointer.

    -

    The type for initializers.

    -

    Initializes a with the given initializer. Read more

    -

    Dereferences the given pointer. Read more

    -

    Mutably dereferences the given pointer. Read more

    -

    Drops the object pointed to by the given pointer. Read more

    -

    The type returned in the event of a conversion error.

    -

    Performs the conversion.

    -

    The type returned in the event of a conversion error.

    -

    Performs the conversion.

    -
    - \ No newline at end of file +

    Implementations§

    Create a instance from the specified device and chain

    +

    Trait Implementations§

    Formats the value using the given formatter. Read more
    Return the SignerId for this signer Read more
    Return the secret key for the signer Read more

    This implementation ignores sign_options

    +
    Sign all the inputs of the psbt

    Auto Trait Implementations§

    Blanket Implementations§

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

    Returns the argument unchanged.

    +

    Calls U::from(self).

    +

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

    +
    The alignment of pointer.
    The type for initializers.
    Initializes a with the given initializer. Read more
    Dereferences the given pointer. Read more
    Mutably dereferences the given pointer. Read more
    Drops the object pointed to by the given pointer. Read more
    The type returned in the event of a conversion error.
    Performs the conversion.
    The type returned in the event of a conversion error.
    Performs the conversion.
    \ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/wallet/index.html b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/wallet/index.html index 0cb25d56b3..8d848ad8bd 100644 --- a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/wallet/index.html +++ b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/wallet/index.html @@ -1,35 +1,8 @@ -bdk::wallet - Rust - -
    -

    Module bdk::wallet

    source · []
    Expand description

    Wallet

    +bdk::wallet - Rust

    Module bdk::wallet

    source ·
    Expand description

    Wallet

    This module defines the Wallet structure.

    -

    Modules

    -

    Coin selection

    -

    Wallet export

    -
    hardwaresignerhardware-signer

    HWI Signer

    -

    Generalized signers

    -

    Cross-platform time

    -

    Transaction builder

    -
    verifyverify

    Verify transactions against the consensus rules

    -

    Structs

    -

    A derived address and the index it was found at -For convenience this automatically derefs to Address

    -

    Options to a sync.

    -

    A Bitcoin wallet

    -

    Enums

    -

    The address index selection strategy to use to derived an address from the wallet’s external -descriptor. See Wallet::get_address. If you’re unsure which one to use use WalletIndex::New.

    -

    Traits

    -

    Trait to check if a value is below the dust limit. +

    Modules

    Coin selection
    Wallet export
    hardwaresignerhardware-signer
    HWI Signer
    Generalized signers
    Cross-platform time
    Transaction builder
    verifyverify
    Verify transactions against the consensus rules

    Structs

    A derived address and the index it was found at +For convenience this automatically derefs to Address
    Options to a sync.
    A Bitcoin wallet

    Enums

    The address index selection strategy to use to derived an address from the wallet’s external +descriptor. See Wallet::get_address. If you’re unsure which one to use use WalletIndex::New.

    Traits

    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

    -

    Functions

    -

    Return a fake wallet that appears to be funded for testing.

    -

    Deterministically generate a unique name given the descriptors defining the wallet

    -
    - \ No newline at end of file +keep it compatible with network dust rate

    Functions

    Return a fake wallet that appears to be funded for testing.
    Deterministically generate a unique name given the descriptors defining the wallet
    \ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/wallet/sidebar-items.js b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/wallet/sidebar-items.js index 441045a7bb..ce79156216 100644 --- a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/wallet/sidebar-items.js +++ b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/wallet/sidebar-items.js @@ -1 +1 @@ -initSidebarItems({"enum":[["AddressIndex","The address index selection strategy to use to derived an address from the wallet’s external descriptor. See [`Wallet::get_address`]. If you’re unsure which one to use use `WalletIndex::New`."]],"fn":[["get_funded_wallet","Return a fake wallet that appears to be funded for testing."],["wallet_name_from_descriptor","Deterministically generate a unique name given the descriptors defining the wallet"]],"mod":[["coin_selection","Coin selection"],["export","Wallet export"],["hardwaresigner","HWI Signer"],["signer","Generalized signers"],["time","Cross-platform time"],["tx_builder","Transaction builder"],["verify","Verify transactions against the consensus rules"]],"struct":[["AddressInfo","A derived address and the index it was found at For convenience this automatically derefs to `Address`"],["SyncOptions","Options to a `sync`."],["Wallet","A Bitcoin wallet"]],"trait":[["IsDust","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"]]}); \ No newline at end of file +window.SIDEBAR_ITEMS = {"enum":[["AddressIndex","The address index selection strategy to use to derived an address from the wallet’s external descriptor. See [`Wallet::get_address`]. If you’re unsure which one to use use `WalletIndex::New`."]],"fn":[["get_funded_wallet","Return a fake wallet that appears to be funded for testing."],["wallet_name_from_descriptor","Deterministically generate a unique name given the descriptors defining the wallet"]],"mod":[["coin_selection","Coin selection"],["export","Wallet export"],["hardwaresigner","HWI Signer"],["signer","Generalized signers"],["time","Cross-platform time"],["tx_builder","Transaction builder"],["verify","Verify transactions against the consensus rules"]],"struct":[["AddressInfo","A derived address and the index it was found at For convenience this automatically derefs to `Address`"],["SyncOptions","Options to a `sync`."],["Wallet","A Bitcoin wallet"]],"trait":[["IsDust","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"]]}; \ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/wallet/signer/enum.SignerContext.html b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/wallet/signer/enum.SignerContext.html index 329499866e..ccfc74711d 100644 --- a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/wallet/signer/enum.SignerContext.html +++ b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/wallet/signer/enum.SignerContext.html @@ -1,12 +1,5 @@ -SignerContext in bdk::wallet::signer - Rust - -
    pub enum SignerContext {
    +SignerContext in bdk::wallet::signer - Rust
    pub enum SignerContext {
         Legacy,
         Segwitv0,
         Tap {
    @@ -14,33 +7,14 @@
         },
     }
    Expand description

    Signing context

    Used by our software signers to determine the type of signatures to make

    -

    Variants

    Legacy

    Legacy context

    -

    Segwitv0

    Segwit v0 context (BIP 143)

    -

    Tap

    Fields

    is_internal_key: bool

    Whether the signer can sign for the internal key or not

    +

    Variants§

    §

    Legacy

    Legacy context

    +
    §

    Segwitv0

    Segwit v0 context (BIP 143)

    +
    §

    Tap

    Fields

    §is_internal_key: bool

    Whether the signer can sign for the internal key or not

    Taproot context (BIP 340)

    -

    Trait Implementations

    Returns a copy of the value. Read more

    -

    Performs copy-assignment from source. Read more

    -

    Formats the value using the given formatter. Read more

    -

    This method tests for self and other values to be equal, and is used -by ==. Read more

    -

    This method tests for !=.

    -

    Auto Trait Implementations

    Blanket Implementations

    Gets the TypeId of self. Read more

    -

    Immutably borrows from an owned value. Read more

    -

    Mutably borrows from an owned value. Read more

    -

    Performs the conversion.

    -

    Performs the conversion.

    -

    The alignment of pointer.

    -

    The type for initializers.

    -

    Initializes a with the given initializer. Read more

    -

    Dereferences the given pointer. Read more

    -

    Mutably dereferences the given pointer. Read more

    -

    Drops the object pointed to by the given pointer. Read more

    -

    The resulting type after obtaining ownership.

    -

    Creates owned data from borrowed data, usually by cloning. Read more

    -
    🔬 This is a nightly-only experimental API. (toowned_clone_into)

    Uses borrowed data to replace owned data, usually by cloning. Read more

    -

    The type returned in the event of a conversion error.

    -

    Performs the conversion.

    -

    The type returned in the event of a conversion error.

    -

    Performs the conversion.

    -
    - \ No newline at end of file +

    Trait Implementations§

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

    Auto Trait Implementations§

    Blanket Implementations§

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

    Returns the argument unchanged.

    +

    Calls U::from(self).

    +

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

    +
    The alignment of pointer.
    The type for initializers.
    Initializes a with the given initializer. Read more
    Dereferences the given pointer. Read more
    Mutably dereferences the given pointer. Read more
    Drops the object pointed to by the given pointer. Read more
    The resulting type after obtaining ownership.
    Creates owned data from borrowed data, usually by cloning. Read more
    Uses borrowed data to replace owned data, usually by cloning. Read more
    The type returned in the event of a conversion error.
    Performs the conversion.
    The type returned in the event of a conversion error.
    Performs the conversion.
    \ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/wallet/signer/enum.SignerError.html b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/wallet/signer/enum.SignerError.html index ef7a742721..188eef18eb 100644 --- a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/wallet/signer/enum.SignerError.html +++ b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/wallet/signer/enum.SignerError.html @@ -1,12 +1,5 @@ -SignerError in bdk::wallet::signer - Rust - -
    pub enum SignerError {
    +SignerError in bdk::wallet::signer - Rust

    Enum bdk::wallet::signer::SignerError

    source ·
    pub enum SignerError {
     
    Show 13 variants MissingKey, InvalidKey, UserCanceled, @@ -21,54 +14,27 @@ SighashError(Error), HWIError(Error),
    }
    Expand description

    Signing error

    -

    Variants

    MissingKey

    The private key is missing for the required public key

    -

    InvalidKey

    The private key in use has the right fingerprint but derives differently than expected

    -

    UserCanceled

    The user canceled the operation

    -

    InputIndexOutOfRange

    Input index is out of range

    -

    MissingNonWitnessUtxo

    The non_witness_utxo field of the transaction is required to sign this input

    -

    InvalidNonWitnessUtxo

    The non_witness_utxo specified is invalid

    -

    MissingWitnessUtxo

    The witness_utxo field of the transaction is required to sign this input

    -

    MissingWitnessScript

    The witness_script field of the transaction is required to sign this input

    -

    MissingHdKeypath

    The fingerprint and derivation path are missing from the psbt input

    -

    NonStandardSighash

    The psbt contains a non-SIGHASH_ALL sighash in one of its input and the user hasn’t +

    Variants§

    §

    MissingKey

    The private key is missing for the required public key

    +
    §

    InvalidKey

    The private key in use has the right fingerprint but derives differently than expected

    +
    §

    UserCanceled

    The user canceled the operation

    +
    §

    InputIndexOutOfRange

    Input index is out of range

    +
    §

    MissingNonWitnessUtxo

    The non_witness_utxo field of the transaction is required to sign this input

    +
    §

    InvalidNonWitnessUtxo

    The non_witness_utxo specified is invalid

    +
    §

    MissingWitnessUtxo

    The witness_utxo field of the transaction is required to sign this input

    +
    §

    MissingWitnessScript

    The witness_script field of the transaction is required to sign this input

    +
    §

    MissingHdKeypath

    The fingerprint and derivation path are missing from the psbt input

    +
    §

    NonStandardSighash

    The psbt contains a non-SIGHASH_ALL sighash in one of its input and the user hasn’t explicitly allowed them

    To enable signing transactions with non-standard sighashes set SignOptions::allow_all_sighashes to true.

    -

    InvalidSighash

    Invalid SIGHASH for the signing context in use

    -

    SighashError(Error)

    Error while computing the hash to sign

    -

    HWIError(Error)

    Error while signing using hardware wallets

    -

    Trait Implementations

    Returns a copy of the value. Read more

    -

    Performs copy-assignment from source. Read more

    -

    Formats the value using the given formatter. Read more

    -

    Formats the value using the given formatter. Read more

    -

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

    -
    🔬 This is a nightly-only experimental API. (backtrace)

    Returns a stack backtrace, if available, of where this error occurred. Read more

    -
    👎 Deprecated since 1.42.0:

    use the Display impl or to_string()

    -
    👎 Deprecated since 1.33.0:

    replaced by Error::source, which can support downcasting

    -

    Performs the conversion.

    -

    Performs the conversion.

    -

    Performs the conversion.

    -

    This method tests for self and other values to be equal, and is used -by ==. Read more

    -

    This method tests for !=.

    -

    Auto Trait Implementations

    Blanket Implementations

    Gets the TypeId of self. Read more

    -

    Immutably borrows from an owned value. Read more

    -

    Mutably borrows from an owned value. Read more

    -

    Performs the conversion.

    -

    Performs the conversion.

    -

    The alignment of pointer.

    -

    The type for initializers.

    -

    Initializes a with the given initializer. Read more

    -

    Dereferences the given pointer. Read more

    -

    Mutably dereferences the given pointer. Read more

    -

    Drops the object pointed to by the given pointer. Read more

    -

    The resulting type after obtaining ownership.

    -

    Creates owned data from borrowed data, usually by cloning. Read more

    -
    🔬 This is a nightly-only experimental API. (toowned_clone_into)

    Uses borrowed data to replace owned data, usually by cloning. Read more

    -

    Converts the given value to a String. Read more

    -

    The type returned in the event of a conversion error.

    -

    Performs the conversion.

    -

    The type returned in the event of a conversion error.

    -

    Performs the conversion.

    -
    - \ No newline at end of file +
    §

    InvalidSighash

    Invalid SIGHASH for the signing context in use

    +
    §

    SighashError(Error)

    Error while computing the hash to sign

    +
    §

    HWIError(Error)

    Error while signing using hardware wallets

    +

    Trait Implementations§

    Returns a copy of the value. Read more
    Performs copy-assignment from source. Read more
    Formats the value using the given formatter. Read more
    Formats the value using the given formatter. Read more
    The lower-level source of this error, if any. Read more
    👎Deprecated since 1.42.0: use the Display impl or to_string()
    👎Deprecated since 1.33.0: replaced by Error::source, which can support downcasting
    🔬This is a nightly-only experimental API. (error_generic_member_access)
    Provides type based access to context intended for error reports. Read more
    Converts to this type from the input type.
    Converts to this type from the input type.
    Converts to this type from the input type.
    This method tests for self and other values to be equal, and is used +by ==. Read more
    This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason. Read more

    Auto Trait Implementations§

    Blanket Implementations§

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

    Returns the argument unchanged.

    +

    Calls U::from(self).

    +

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

    +
    The alignment of pointer.
    The type for initializers.
    Initializes a with the given initializer. Read more
    Dereferences the given pointer. Read more
    Mutably dereferences the given pointer. Read more
    Drops the object pointed to by the given pointer. Read more
    🔬This is a nightly-only experimental API. (provide_any)
    Data providers should implement this method to provide all values they are able to +provide by using demand. Read more
    The resulting type after obtaining ownership.
    Creates owned data from borrowed data, usually by cloning. Read more
    Uses borrowed data to replace owned data, usually by cloning. Read more
    Converts the given value to a String. Read more
    The type returned in the event of a conversion error.
    Performs the conversion.
    The type returned in the event of a conversion error.
    Performs the conversion.
    \ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/wallet/signer/enum.SignerId.html b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/wallet/signer/enum.SignerId.html index 7180358eed..b6559dfc35 100644 --- a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/wallet/signer/enum.SignerId.html +++ b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/wallet/signer/enum.SignerId.html @@ -1,58 +1,19 @@ -SignerId in bdk::wallet::signer - Rust - -
    pub enum SignerId {
    +SignerId in bdk::wallet::signer - Rust

    Enum bdk::wallet::signer::SignerId

    source ·
    pub enum SignerId {
         PkHash(Hash),
         Fingerprint(Fingerprint),
         Dummy(u64),
     }
    Expand description

    Identifier of a signer in the SignersContainers. Used as a key to find the right signer among multiple of them

    -

    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

    Returns a copy of the value. Read more

    -

    Performs copy-assignment from source. Read more

    -

    Formats the value using the given formatter. Read more

    -

    Performs the conversion.

    -

    Performs the conversion.

    -

    Feeds this value into the given Hasher. Read more

    -

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

    -

    This method returns an Ordering between self and other. Read more

    -

    Compares and returns the maximum of two values. Read more

    -

    Compares and returns the minimum of two values. Read more

    -

    Restrict a value to a certain interval. Read more

    -

    This method tests for self and other values to be equal, and is used -by ==. Read more

    -

    This method tests for !=.

    -

    This method returns an ordering between self and other values if one exists. Read more

    -

    This method tests less than (for self and other) and is used by the < operator. Read more

    -

    This method tests less than or equal to (for self and other) and is used by the <= -operator. Read more

    -

    This method tests greater than (for self and other) and is used by the > operator. Read more

    -

    This method tests greater than or equal to (for self and other) and is used by the >= -operator. Read more

    -

    Auto Trait Implementations

    Blanket Implementations

    Gets the TypeId of self. Read more

    -

    Immutably borrows from an owned value. Read more

    -

    Mutably borrows from an owned value. Read more

    -

    Performs the conversion.

    -

    Performs the conversion.

    -

    The alignment of pointer.

    -

    The type for initializers.

    -

    Initializes a with the given initializer. Read more

    -

    Dereferences the given pointer. Read more

    -

    Mutably dereferences the given pointer. Read more

    -

    Drops the object pointed to by the given pointer. Read more

    -

    The resulting type after obtaining ownership.

    -

    Creates owned data from borrowed data, usually by cloning. Read more

    -
    🔬 This is a nightly-only experimental API. (toowned_clone_into)

    Uses borrowed data to replace owned data, usually by cloning. Read more

    -

    The type returned in the event of a conversion error.

    -

    Performs the conversion.

    -

    The type returned in the event of a conversion error.

    -

    Performs the conversion.

    -
    - \ No newline at end of file +

    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§

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

    Auto Trait Implementations§

    Blanket Implementations§

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

    Returns the argument unchanged.

    +

    Calls U::from(self).

    +

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

    +
    The alignment of pointer.
    The type for initializers.
    Initializes a with the given initializer. Read more
    Dereferences the given pointer. Read more
    Mutably dereferences the given pointer. Read more
    Drops the object pointed to by the given pointer. Read more
    The resulting type after obtaining ownership.
    Creates owned data from borrowed data, usually by cloning. Read more
    Uses borrowed data to replace owned data, usually by cloning. Read more
    The type returned in the event of a conversion error.
    Performs the conversion.
    The type returned in the event of a conversion error.
    Performs the conversion.
    \ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/wallet/signer/enum.TapLeavesOptions.html b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/wallet/signer/enum.TapLeavesOptions.html index 0aea4a10ea..35c51f7b4c 100644 --- a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/wallet/signer/enum.TapLeavesOptions.html +++ b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/wallet/signer/enum.TapLeavesOptions.html @@ -1,46 +1,19 @@ -TapLeavesOptions in bdk::wallet::signer - Rust - -
    pub enum TapLeavesOptions {
    +TapLeavesOptions in bdk::wallet::signer - Rust
    pub enum TapLeavesOptions {
         All,
         Include(Vec<TapLeafHash>),
         Exclude(Vec<TapLeafHash>),
         None,
     }
    Expand description

    Customize which taproot script-path leaves the signer should sign.

    -

    Variants

    All

    The signer will sign all the leaves it has a key for.

    -

    Include(Vec<TapLeafHash>)

    The signer won’t sign leaves other than the ones specified. Note that it could still ignore +

    Variants§

    §

    All

    The signer will sign all the leaves it has a key for.

    +
    §

    Include(Vec<TapLeafHash>)

    The signer won’t sign leaves other than the ones specified. Note that it could still ignore some of the specified leaves, if it doesn’t have the right key to sign them.

    -

    Exclude(Vec<TapLeafHash>)

    The signer won’t sign the specified leaves.

    -

    None

    The signer won’t sign any leaf.

    -

    Trait Implementations

    Returns a copy of the value. Read more

    -

    Performs copy-assignment from source. Read more

    -

    Formats the value using the given formatter. Read more

    -

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

    -

    This method tests for self and other values to be equal, and is used -by ==. Read more

    -

    This method tests for !=.

    -

    Auto Trait Implementations

    Blanket Implementations

    Gets the TypeId of self. Read more

    -

    Immutably borrows from an owned value. Read more

    -

    Mutably borrows from an owned value. Read more

    -

    Performs the conversion.

    -

    Performs the conversion.

    -

    The alignment of pointer.

    -

    The type for initializers.

    -

    Initializes a with the given initializer. Read more

    -

    Dereferences the given pointer. Read more

    -

    Mutably dereferences the given pointer. Read more

    -

    Drops the object pointed to by the given pointer. Read more

    -

    The resulting type after obtaining ownership.

    -

    Creates owned data from borrowed data, usually by cloning. Read more

    -
    🔬 This is a nightly-only experimental API. (toowned_clone_into)

    Uses borrowed data to replace owned data, usually by cloning. Read more

    -

    The type returned in the event of a conversion error.

    -

    Performs the conversion.

    -

    The type returned in the event of a conversion error.

    -

    Performs the conversion.

    -
    - \ No newline at end of file +
    §

    Exclude(Vec<TapLeafHash>)

    The signer won’t sign the specified leaves.

    +
    §

    None

    The signer won’t sign any leaf.

    +

    Trait Implementations§

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

    Auto Trait Implementations§

    Blanket Implementations§

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

    Returns the argument unchanged.

    +

    Calls U::from(self).

    +

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

    +
    The alignment of pointer.
    The type for initializers.
    Initializes a with the given initializer. Read more
    Dereferences the given pointer. Read more
    Mutably dereferences the given pointer. Read more
    Drops the object pointed to by the given pointer. Read more
    The resulting type after obtaining ownership.
    Creates owned data from borrowed data, usually by cloning. Read more
    Uses borrowed data to replace owned data, usually by cloning. Read more
    The type returned in the event of a conversion error.
    Performs the conversion.
    The type returned in the event of a conversion error.
    Performs the conversion.
    \ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/wallet/signer/index.html b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/wallet/signer/index.html index c55881a027..66944dd0f9 100644 --- a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/wallet/signer/index.html +++ b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/wallet/signer/index.html @@ -1,70 +1,48 @@ -bdk::wallet::signer - Rust - -
    -

    Module bdk::wallet::signer

    source · []
    Expand description

    Generalized signers

    +bdk::wallet::signer - Rust

    Module bdk::wallet::signer

    source ·
    Expand description

    Generalized signers

    This module provides the ability to add customized signers to a Wallet through the Wallet::add_signer function.

    -
    #[derive(Debug)]
    -struct CustomSigner {
    -    device: CustomHSM,
    +
    #[derive(Debug)]
    +struct CustomSigner {
    +    device: CustomHSM,
     }
     
    -impl CustomSigner {
    -    fn connect() -> Self {
    -        CustomSigner { device: CustomHSM::connect() }
    +impl CustomSigner {
    +    fn connect() -> Self {
    +        CustomSigner { device: CustomHSM::connect() }
         }
     }
     
    -impl SignerCommon for CustomSigner {
    -    fn id(&self, _secp: &Secp256k1<All>) -> SignerId {
    -        self.device.get_id()
    +impl SignerCommon for CustomSigner {
    +    fn id(&self, _secp: &Secp256k1<All>) -> SignerId {
    +        self.device.get_id()
         }
     }
     
    -impl InputSigner for CustomSigner {
    -    fn sign_input(
    +impl InputSigner for CustomSigner {
    +    fn sign_input(
             &self,
    -        psbt: &mut psbt::PartiallySignedTransaction,
    -        input_index: usize,
    -        _sign_options: &SignOptions,
    -        _secp: &Secp256k1<All>,
    -    ) -> Result<(), SignerError> {
    -        self.device.hsm_sign_input(psbt, input_index)?;
    +        psbt: &mut psbt::PartiallySignedTransaction,
    +        input_index: usize,
    +        _sign_options: &SignOptions,
    +        _secp: &Secp256k1<All>,
    +    ) -> Result<(), SignerError> {
    +        self.device.hsm_sign_input(psbt, input_index)?;
     
             Ok(())
         }
     }
     
    -let custom_signer = CustomSigner::connect();
    +let custom_signer = CustomSigner::connect();
     
    -let descriptor = "wpkh(tpubD6NzVbkrYhZ4Xferm7Pz4VnjdcDPFyjVu5K4iZXQ4pVN8Cks4pHVowTBXBKRhX64pkRyJZJN5xAKj4UDNnLPb5p2sSKXhewoYx5GbTdUFWq/*)";
    -let mut wallet = Wallet::new(descriptor, None, Network::Testnet, MemoryDatabase::default())?;
    -wallet.add_signer(
    -    KeychainKind::External,
    -    SignerOrdering(200),
    -    Arc::new(custom_signer)
    +let descriptor = "wpkh(tpubD6NzVbkrYhZ4Xferm7Pz4VnjdcDPFyjVu5K4iZXQ4pVN8Cks4pHVowTBXBKRhX64pkRyJZJN5xAKj4UDNnLPb5p2sSKXhewoYx5GbTdUFWq/*)";
    +let mut wallet = Wallet::new(descriptor, None, Network::Testnet, MemoryDatabase::default())?;
    +wallet.add_signer(
    +    KeychainKind::External,
    +    SignerOrdering(200),
    +    Arc::new(custom_signer)
     );
     
    -

    Structs

    -

    Options for a software signer

    -

    Defines the order in which signers are called

    -

    Wrapper structure to pair a signer with its context

    -

    Container for multiple signers

    -

    Enums

    -

    Signing context

    -

    Signing error

    -

    Identifier of a signer in the SignersContainers. Used as a key to find the right signer among -multiple of them

    -

    Customize which taproot script-path leaves the signer should sign.

    -

    Traits

    -

    PSBT Input signer

    -

    Common signer methods

    -

    PSBT signer

    -
    - \ No newline at end of file +

    Structs

    Options for a software signer
    Defines the order in which signers are called
    Wrapper structure to pair a signer with its context
    Container for multiple signers

    Enums

    Signing context
    Signing error
    Identifier of a signer in the SignersContainers. Used as a key to find the right signer among +multiple of them
    Customize which taproot script-path leaves the signer should sign.

    Traits

    PSBT Input signer
    Common signer methods
    \ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/wallet/signer/sidebar-items.js b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/wallet/signer/sidebar-items.js index 618f3795af..60a5fa1bfb 100644 --- a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/wallet/signer/sidebar-items.js +++ b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/wallet/signer/sidebar-items.js @@ -1 +1 @@ -initSidebarItems({"enum":[["SignerContext","Signing context"],["SignerError","Signing error"],["SignerId","Identifier of a signer in the `SignersContainers`. Used as a key to find the right signer among multiple of them"],["TapLeavesOptions","Customize which taproot script-path leaves the signer should sign."]],"struct":[["SignOptions","Options for a software signer"],["SignerOrdering","Defines the order in which signers are called"],["SignerWrapper","Wrapper structure to pair a signer with its context"],["SignersContainer","Container for multiple signers"]],"trait":[["InputSigner","PSBT Input signer"],["SignerCommon","Common signer methods"],["TransactionSigner","PSBT signer"]]}); \ No newline at end of file +window.SIDEBAR_ITEMS = {"enum":[["SignerContext","Signing context"],["SignerError","Signing error"],["SignerId","Identifier of a signer in the `SignersContainers`. Used as a key to find the right signer among multiple of them"],["TapLeavesOptions","Customize which taproot script-path leaves the signer should sign."]],"struct":[["SignOptions","Options for a software signer"],["SignerOrdering","Defines the order in which signers are called"],["SignerWrapper","Wrapper structure to pair a signer with its context"],["SignersContainer","Container for multiple signers"]],"trait":[["InputSigner","PSBT Input signer"],["SignerCommon","Common signer methods"],["TransactionSigner","PSBT signer"]]}; \ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/wallet/signer/struct.SignOptions.html b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/wallet/signer/struct.SignOptions.html index 0c7c842dab..c335ce413e 100644 --- a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/wallet/signer/struct.SignOptions.html +++ b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/wallet/signer/struct.SignOptions.html @@ -1,12 +1,5 @@ -SignOptions in bdk::wallet::signer - Rust - -
    pub struct SignOptions {
    +SignOptions in bdk::wallet::signer - Rust

    Struct bdk::wallet::signer::SignOptions

    source ·
    pub struct SignOptions {
         pub trust_witness_utxo: bool,
         pub assume_height: Option<u32>,
         pub allow_all_sighashes: bool,
    @@ -17,7 +10,7 @@
         pub allow_grinding: bool,
     }
    Expand description

    Options for a software signer

    Adjust the behavior of our software signers and the way a transaction is finalized

    -

    Fields

    trust_witness_utxo: bool

    Whether the signer should trust the witness_utxo, if the non_witness_utxo hasn’t been +

    Fields§

    §trust_witness_utxo: bool

    Whether the signer should trust the witness_utxo, if the non_witness_utxo hasn’t been provided

    Defaults to false to mitigate the “SegWit bug” which chould trick the wallet into paying a fee larger than expected.

    @@ -26,48 +19,29 @@ SegWit transactions in the PSBT they generate: in those cases setting this to

    For more details see: https://blog.trezor.io/details-of-firmware-updates-for-trezor-one-version-1-9-1-and-trezor-model-t-version-2-3-1-1eba8f60f2dd

    -
    assume_height: Option<u32>

    Whether the wallet should assume a specific height has been reached when trying to finalize +

    §assume_height: Option<u32>

    Whether the wallet should assume a specific height has been reached when trying to finalize a transaction

    The wallet will only “use” a timelock to satisfy the spending policy of an input if the timelock height has already been reached. This option allows overriding the “current height” to let the wallet use timelocks in the future to spend a coin.

    -
    allow_all_sighashes: bool

    Whether the signer should use the sighash_type set in the PSBT when signing, no matter +

    §allow_all_sighashes: bool

    Whether the signer should use the sighash_type set in the PSBT when signing, no matter what its value is

    Defaults to false which will only allow signing using SIGHASH_ALL.

    -
    remove_partial_sigs: bool

    Whether to remove partial signatures from the PSBT inputs while finalizing PSBT.

    +
    §remove_partial_sigs: bool

    Whether to remove partial signatures from the PSBT inputs while finalizing PSBT.

    Defaults to true which will remove partial signatures during finalization.

    -
    try_finalize: bool

    Whether to try finalizing the PSBT after the inputs are signed.

    +
    §try_finalize: bool

    Whether to try finalizing the PSBT after the inputs are signed.

    Defaults to true which will try finalizing PSBT after inputs are signed.

    -
    tap_leaves_options: TapLeavesOptions

    Specifies which Taproot script-spend leaves we should sign for. This option is +

    §tap_leaves_options: TapLeavesOptions

    Specifies which Taproot script-spend leaves we should sign for. This option is ignored if we’re signing a non-taproot PSBT.

    Defaults to All, i.e., the wallet will sign all the leaves it has a key for.

    -
    sign_with_tap_internal_key: bool

    Whether we should try to sign a taproot transaction with the taproot internal key +

    §sign_with_tap_internal_key: bool

    Whether we should try to sign a taproot transaction with the taproot internal key or not. This option is ignored if we’re signing a non-taproot PSBT.

    Defaults to true, i.e., we always try to sign with the taproot internal key.

    -
    allow_grinding: bool

    Whether we should grind ECDSA signature to ensure signing with low r +

    §allow_grinding: bool

    Whether we should grind ECDSA signature to ensure signing with low r or not. Defaults to true, i.e., we always grind ECDSA signature to sign with low r.

    -

    Trait Implementations

    Returns a copy of the value. Read more

    -

    Performs copy-assignment from source. Read more

    -

    Formats the value using the given formatter. Read more

    -

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

    -

    Auto Trait Implementations

    Blanket Implementations

    Gets the TypeId of self. Read more

    -

    Immutably borrows from an owned value. Read more

    -

    Mutably borrows from an owned value. Read more

    -

    Performs the conversion.

    -

    Performs the conversion.

    -

    The alignment of pointer.

    -

    The type for initializers.

    -

    Initializes a with the given initializer. Read more

    -

    Dereferences the given pointer. Read more

    -

    Mutably dereferences the given pointer. Read more

    -

    Drops the object pointed to by the given pointer. Read more

    -

    The resulting type after obtaining ownership.

    -

    Creates owned data from borrowed data, usually by cloning. Read more

    -
    🔬 This is a nightly-only experimental API. (toowned_clone_into)

    Uses borrowed data to replace owned data, usually by cloning. Read more

    -

    The type returned in the event of a conversion error.

    -

    Performs the conversion.

    -

    The type returned in the event of a conversion error.

    -

    Performs the conversion.

    -
    - \ No newline at end of file +

    Trait Implementations§

    Returns a copy of the value. Read more
    Performs copy-assignment from source. Read more
    Formats the value using the given formatter. Read more
    Returns the “default value” for a type. Read more

    Auto Trait Implementations§

    Blanket Implementations§

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

    Returns the argument unchanged.

    +

    Calls U::from(self).

    +

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

    +
    The alignment of pointer.
    The type for initializers.
    Initializes a with the given initializer. Read more
    Dereferences the given pointer. Read more
    Mutably dereferences the given pointer. Read more
    Drops the object pointed to by the given pointer. Read more
    The resulting type after obtaining ownership.
    Creates owned data from borrowed data, usually by cloning. Read more
    Uses borrowed data to replace owned data, usually by cloning. Read more
    The type returned in the event of a conversion error.
    Performs the conversion.
    The type returned in the event of a conversion error.
    Performs the conversion.
    \ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/wallet/signer/struct.SignerOrdering.html b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/wallet/signer/struct.SignerOrdering.html index b59cf55320..b9976db064 100644 --- a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/wallet/signer/struct.SignerOrdering.html +++ b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/wallet/signer/struct.SignerOrdering.html @@ -1,50 +1,14 @@ -SignerOrdering in bdk::wallet::signer - Rust - -
    pub struct SignerOrdering(pub usize);
    Expand description

    Defines the order in which signers are called

    +SignerOrdering in bdk::wallet::signer - Rust

    Struct bdk::wallet::signer::SignerOrdering

    source ·
    pub struct SignerOrdering(pub usize);
    Expand description

    Defines the order in which signers are called

    The default value is 100. Signers with an ordering above that will be called later, and they will thus see the partial signatures added to the transaction once they get to sign themselves.

    -

    Tuple Fields

    0: usize

    Trait Implementations

    Returns a copy of the value. Read more

    -

    Performs copy-assignment from source. Read more

    -

    Formats the value using the given formatter. Read more

    -

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

    -

    This method returns an Ordering between self and other. Read more

    -

    Compares and returns the maximum of two values. Read more

    -

    Compares and returns the minimum of two values. Read more

    -

    Restrict a value to a certain interval. Read more

    -

    This method tests for self and other values to be equal, and is used -by ==. Read more

    -

    This method tests for !=.

    -

    This method returns an ordering between self and other values if one exists. Read more

    -

    This method tests less than (for self and other) and is used by the < operator. Read more

    -

    This method tests less than or equal to (for self and other) and is used by the <= -operator. Read more

    -

    This method tests greater than (for self and other) and is used by the > operator. Read more

    -

    This method tests greater than or equal to (for self and other) and is used by the >= -operator. Read more

    -

    Auto Trait Implementations

    Blanket Implementations

    Gets the TypeId of self. Read more

    -

    Immutably borrows from an owned value. Read more

    -

    Mutably borrows from an owned value. Read more

    -

    Performs the conversion.

    -

    Performs the conversion.

    -

    The alignment of pointer.

    -

    The type for initializers.

    -

    Initializes a with the given initializer. Read more

    -

    Dereferences the given pointer. Read more

    -

    Mutably dereferences the given pointer. Read more

    -

    Drops the object pointed to by the given pointer. Read more

    -

    The resulting type after obtaining ownership.

    -

    Creates owned data from borrowed data, usually by cloning. Read more

    -
    🔬 This is a nightly-only experimental API. (toowned_clone_into)

    Uses borrowed data to replace owned data, usually by cloning. Read more

    -

    The type returned in the event of a conversion error.

    -

    Performs the conversion.

    -

    The type returned in the event of a conversion error.

    -

    Performs the conversion.

    -
    - \ No newline at end of file +

    Tuple Fields§

    §0: usize

    Trait Implementations§

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

    Auto Trait Implementations§

    Blanket Implementations§

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

    Returns the argument unchanged.

    +

    Calls U::from(self).

    +

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

    +
    The alignment of pointer.
    The type for initializers.
    Initializes a with the given initializer. Read more
    Dereferences the given pointer. Read more
    Mutably dereferences the given pointer. Read more
    Drops the object pointed to by the given pointer. Read more
    The resulting type after obtaining ownership.
    Creates owned data from borrowed data, usually by cloning. Read more
    Uses borrowed data to replace owned data, usually by cloning. Read more
    The type returned in the event of a conversion error.
    Performs the conversion.
    The type returned in the event of a conversion error.
    Performs the conversion.
    \ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/wallet/signer/struct.SignerWrapper.html b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/wallet/signer/struct.SignerWrapper.html index b698b98d08..63a62b3244 100644 --- a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/wallet/signer/struct.SignerWrapper.html +++ b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/wallet/signer/struct.SignerWrapper.html @@ -1,42 +1,8 @@ -SignerWrapper in bdk::wallet::signer - Rust - -
    pub struct SignerWrapper<S: Sized + Debug + Clone> { /* private fields */ }
    Expand description

    Wrapper structure to pair a signer with its context

    -

    Implementations

    Create a wrapped signer from a signer and a context

    -

    Trait Implementations

    Returns a copy of the value. Read more

    -

    Performs copy-assignment from source. Read more

    -

    Formats the value using the given formatter. Read more

    -

    The resulting type after dereferencing.

    -

    Dereferences the value.

    -

    Sign a single psbt input

    -

    Sign a single psbt input

    -

    Return the SignerId for this signer Read more

    -

    Return the secret key for the signer Read more

    -

    Return the SignerId for this signer Read more

    -

    Return the secret key for the signer Read more

    -

    Auto Trait Implementations

    Blanket Implementations

    Gets the TypeId of self. Read more

    -

    Immutably borrows from an owned value. Read more

    -

    Mutably borrows from an owned value. Read more

    -

    Performs the conversion.

    -

    Performs the conversion.

    -

    The alignment of pointer.

    -

    The type for initializers.

    -

    Initializes a with the given initializer. Read more

    -

    Dereferences the given pointer. Read more

    -

    Mutably dereferences the given pointer. Read more

    -

    Drops the object pointed to by the given pointer. Read more

    -

    The resulting type after obtaining ownership.

    -

    Creates owned data from borrowed data, usually by cloning. Read more

    -
    🔬 This is a nightly-only experimental API. (toowned_clone_into)

    Uses borrowed data to replace owned data, usually by cloning. Read more

    -

    Sign all the inputs of the psbt

    -

    The type returned in the event of a conversion error.

    -

    Performs the conversion.

    -

    The type returned in the event of a conversion error.

    -

    Performs the conversion.

    -
    - \ No newline at end of file +SignerWrapper in bdk::wallet::signer - Rust

    Struct bdk::wallet::signer::SignerWrapper

    source ·
    pub struct SignerWrapper<S: Sized + Debug + Clone> { /* private fields */ }
    Expand description

    Wrapper structure to pair a signer with its context

    +

    Implementations§

    Create a wrapped signer from a signer and a context

    +

    Trait Implementations§

    Returns a copy of the value. Read more
    Performs copy-assignment from source. Read more
    Formats the value using the given formatter. Read more
    The resulting type after dereferencing.
    Dereferences the value.
    Sign a single psbt input
    Sign a single psbt input
    Return the SignerId for this signer Read more
    Return the secret key for the signer Read more
    Return the SignerId for this signer Read more
    Return the secret key for the signer Read more

    Auto Trait Implementations§

    Blanket Implementations§

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

    Returns the argument unchanged.

    +

    Calls U::from(self).

    +

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

    +
    The alignment of pointer.
    The type for initializers.
    Initializes a with the given initializer. Read more
    Dereferences the given pointer. Read more
    Mutably dereferences the given pointer. Read more
    Drops the object pointed to by the given pointer. Read more
    The resulting type after obtaining ownership.
    Creates owned data from borrowed data, usually by cloning. Read more
    Uses borrowed data to replace owned data, usually by cloning. Read more
    Sign all the inputs of the psbt
    The type returned in the event of a conversion error.
    Performs the conversion.
    The type returned in the event of a conversion error.
    Performs the conversion.
    \ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/wallet/signer/struct.SignersContainer.html b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/wallet/signer/struct.SignersContainer.html index 9953181e0a..0993d48292 100644 --- a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/wallet/signer/struct.SignersContainer.html +++ b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/wallet/signer/struct.SignersContainer.html @@ -1,44 +1,18 @@ -SignersContainer in bdk::wallet::signer - Rust - -
    pub struct SignersContainer(_);
    Expand description

    Container for multiple signers

    -

    Implementations

    Create a map of public keys to secret keys

    -

    Build a new signer container from a KeyMap

    +SignersContainer in bdk::wallet::signer - Rust
    pub struct SignersContainer(_);
    Expand description

    Container for multiple signers

    +

    Implementations§

    Create a map of public keys to secret keys

    +

    Build a new signer container from a KeyMap

    Also looks at the corresponding descriptor to determine the SignerContext to attach to the signers

    -

    Default constructor

    -

    Adds an external signer to the container for the specified id. Optionally returns the +

    Default constructor

    +

    Adds an external signer to the container for the specified id. Optionally returns the signer that was previously in the container, if any

    -

    Removes a signer from the container and returns it

    -

    Returns the list of identifiers of all the signers in the container

    -

    Returns the list of signers in the container, sorted by lowest to highest ordering

    -

    Finds the signer with lowest ordering for a given id in the container.

    -

    Trait Implementations

    Returns a copy of the value. Read more

    -

    Performs copy-assignment from source. Read more

    -

    Formats the value using the given formatter. Read more

    -

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

    -

    Auto Trait Implementations

    Blanket Implementations

    Gets the TypeId of self. Read more

    -

    Immutably borrows from an owned value. Read more

    -

    Mutably borrows from an owned value. Read more

    -

    Performs the conversion.

    -

    Performs the conversion.

    -

    The alignment of pointer.

    -

    The type for initializers.

    -

    Initializes a with the given initializer. Read more

    -

    Dereferences the given pointer. Read more

    -

    Mutably dereferences the given pointer. Read more

    -

    Drops the object pointed to by the given pointer. Read more

    -

    The resulting type after obtaining ownership.

    -

    Creates owned data from borrowed data, usually by cloning. Read more

    -
    🔬 This is a nightly-only experimental API. (toowned_clone_into)

    Uses borrowed data to replace owned data, usually by cloning. Read more

    -

    The type returned in the event of a conversion error.

    -

    Performs the conversion.

    -

    The type returned in the event of a conversion error.

    -

    Performs the conversion.

    -
    - \ No newline at end of file +

    Removes a signer from the container and returns it

    +

    Returns the list of identifiers of all the signers in the container

    +

    Returns the list of signers in the container, sorted by lowest to highest ordering

    +

    Finds the signer with lowest ordering for a given id in the container.

    +

    Trait Implementations§

    Returns a copy of the value. Read more
    Performs copy-assignment from source. Read more
    Formats the value using the given formatter. Read more
    Returns the “default value” for a type. Read more

    Auto Trait Implementations§

    Blanket Implementations§

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

    Returns the argument unchanged.

    +

    Calls U::from(self).

    +

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

    +
    The alignment of pointer.
    The type for initializers.
    Initializes a with the given initializer. Read more
    Dereferences the given pointer. Read more
    Mutably dereferences the given pointer. Read more
    Drops the object pointed to by the given pointer. Read more
    The resulting type after obtaining ownership.
    Creates owned data from borrowed data, usually by cloning. Read more
    Uses borrowed data to replace owned data, usually by cloning. Read more
    The type returned in the event of a conversion error.
    Performs the conversion.
    The type returned in the event of a conversion error.
    Performs the conversion.
    \ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/wallet/signer/trait.InputSigner.html b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/wallet/signer/trait.InputSigner.html index 32f4fef55f..0b108277a2 100644 --- a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/wallet/signer/trait.InputSigner.html +++ b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/wallet/signer/trait.InputSigner.html @@ -1,17 +1,9 @@ -InputSigner in bdk::wallet::signer - Rust - -
    pub trait InputSigner: SignerCommon {
    -    fn sign_input(
            &self,
            psbt: &mut PartiallySignedTransaction,
            input_index: usize,
            sign_options: &SignOptions,
            secp: &Secp256k1<All>
        ) -> Result<(), SignerError>; +InputSigner in bdk::wallet::signer - Rust

    Trait bdk::wallet::signer::InputSigner

    source ·
    pub trait InputSigner: SignerCommon {
    +    fn sign_input(
            &self,
            psbt: &mut PartiallySignedTransaction,
            input_index: usize,
            sign_options: &SignOptions,
            secp: &Secp256k1<All>
        ) -> Result<(), SignerError>; }
    Expand description

    PSBT Input signer

    This trait can be implemented to provide custom signers to the wallet. If the signer supports signing individual inputs, this trait should be implemented and BDK will provide automatically an implementation for TransactionSigner.

    -

    Required methods

    Sign a single psbt input

    -

    Implementors

    - \ No newline at end of file +

    Required Methods§

    Sign a single psbt input

    +

    Implementors§

    \ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/wallet/signer/trait.SignerCommon.html b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/wallet/signer/trait.SignerCommon.html index c9e8ee9cd4..3bb7f5ae78 100644 --- a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/wallet/signer/trait.SignerCommon.html +++ b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/wallet/signer/trait.SignerCommon.html @@ -1,22 +1,14 @@ -SignerCommon in bdk::wallet::signer - Rust - -
    pub trait SignerCommon: Debug + Send + Sync {
    -    fn id(&self, secp: &Secp256k1<All>) -> SignerId;
    +SignerCommon in bdk::wallet::signer - Rust

    Trait bdk::wallet::signer::SignerCommon

    source ·
    pub trait SignerCommon: Debug + Send + Sync {
    +    fn id(&self, secp: &Secp256k1<All>) -> SignerId;
     
    -    fn descriptor_secret_key(&self) -> Option<DescriptorSecretKey> { ... }
    +    fn descriptor_secret_key(&self) -> Option<DescriptorSecretKey> { ... }
     }
    Expand description

    Common signer methods

    -

    Required methods

    Return the SignerId for this signer

    +

    Required Methods§

    Return the SignerId for this signer

    The SignerId can be used to lookup a signer in the Wallet’s signers map or to compare two signers.

    -

    Provided methods

    Return the secret key for the signer

    +

    Provided Methods§

    Return the secret key for the signer

    This is used internally to reconstruct the original descriptor that may contain secrets. External signers that are meant to keep key isolated should just return None here (which is the default for this method, if not overridden).

    -

    Implementors

    - \ No newline at end of file +

    Implementors§

    \ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/wallet/signer/trait.TransactionSigner.html b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/wallet/signer/trait.TransactionSigner.html index 0de39708c2..0f635468ba 100644 --- a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/wallet/signer/trait.TransactionSigner.html +++ b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/wallet/signer/trait.TransactionSigner.html @@ -1,17 +1,9 @@ -TransactionSigner in bdk::wallet::signer - Rust - -
    pub trait TransactionSigner: SignerCommon {
    -    fn sign_transaction(
            &self,
            psbt: &mut PartiallySignedTransaction,
            sign_options: &SignOptions,
            secp: &Secp256k1<All>
        ) -> Result<(), SignerError>; +TransactionSigner in bdk::wallet::signer - Rust
    pub trait TransactionSigner: SignerCommon {
    +    fn sign_transaction(
            &self,
            psbt: &mut PartiallySignedTransaction,
            sign_options: &SignOptions,
            secp: &Secp256k1<All>
        ) -> Result<(), SignerError>; }
    Expand description

    PSBT signer

    This trait can be implemented when the signer can’t sign inputs individually, but signs the whole transaction at once.

    -

    Required methods

    Sign all the inputs of the psbt

    -

    Implementors

    This implementation ignores sign_options

    -
    - \ No newline at end of file +

    Required Methods§

    Sign all the inputs of the psbt

    +

    Implementors§

    This implementation ignores sign_options

    +
    \ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/wallet/struct.AddressInfo.html b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/wallet/struct.AddressInfo.html index 03a33aa136..c8b7bdc622 100644 --- a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/wallet/struct.AddressInfo.html +++ b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/wallet/struct.AddressInfo.html @@ -1,79 +1,54 @@ -AddressInfo in bdk::wallet - Rust - -
    pub struct AddressInfo {
    +AddressInfo in bdk::wallet - Rust

    Struct bdk::wallet::AddressInfo

    source ·
    pub struct AddressInfo {
         pub index: u32,
         pub address: Address,
         pub keychain: KeychainKind,
     }
    Expand description

    A derived address and the index it was found at For convenience this automatically derefs to Address

    -

    Fields

    index: u32

    Child index of this address

    -
    address: Address

    Address

    -
    keychain: KeychainKind

    Type of keychain

    -

    Methods from Deref<Target = Address>

    Gets the address type of the address.

    -
    Returns
    +

    Fields§

    §index: u32

    Child index of this address

    +
    §address: Address

    Address

    +
    §keychain: KeychainKind

    Type of keychain

    +

    Methods from Deref<Target = Address>§

    Gets the address type of the address.

    +
    Returns

    None if unknown, non-standard or related to the future witness version.

    -

    Checks whether or not the address is following Bitcoin standardness rules.

    +

    Checks whether or not the address is following Bitcoin standardness rules.

    SegWit addresses with unassigned witness versions or non-standard program sizes are considered non-standard.

    -

    Generates a script pubkey spending to this address.

    -

    Creates a URI string bitcoin:address optimized to be encoded in QR codes.

    +

    Generates a script pubkey spending to this address.

    +

    Creates a URI string bitcoin:address optimized to be encoded in QR codes.

    If the address is bech32, both the schema and the address become uppercase. If the address is base58, the schema is lowercase and the address is left mixed case.

    Quoting BIP 173 “inside QR codes uppercase SHOULD be used, as those permit the use of alphanumeric mode, which is 45% more compact than the normal byte mode.”

    -

    Parsed addresses do not always have one network. The problem is that legacy testnet, +

    Parsed addresses do not always have one network. The problem is that legacy testnet, regtest and signet addresse use the same prefix instead of multiple different ones. When parsing, such addresses are always assumed to be testnet addresses (the same is true for bech32 signet addresses). So if one wants to check if an address belongs to a certain network a simple comparison is not enough anymore. Instead this function can be used.

    -
    use bitcoin::{Address, Network};
    +
    use bitcoin::{Address, Network};
     
    -let address: Address = "2N83imGV3gPwBzKJQvWJ7cRUY2SpUyU6A5e".parse().unwrap();
    -assert!(address.is_valid_for_network(Network::Testnet));
    -assert!(address.is_valid_for_network(Network::Regtest));
    -assert!(address.is_valid_for_network(Network::Signet));
    +let address: Address = "2N83imGV3gPwBzKJQvWJ7cRUY2SpUyU6A5e".parse().unwrap();
    +assert!(address.is_valid_for_network(Network::Testnet));
    +assert!(address.is_valid_for_network(Network::Regtest));
    +assert!(address.is_valid_for_network(Network::Signet));
     
    -assert_eq!(address.is_valid_for_network(Network::Bitcoin), false);
    +assert_eq!(address.is_valid_for_network(Network::Bitcoin), false);
     
    -let address: Address = "32iVBEu4dxkUQk9dJbZUiBiQdmypcEyJRf".parse().unwrap();
    -assert!(address.is_valid_for_network(Network::Bitcoin));
    -assert_eq!(address.is_valid_for_network(Network::Testnet), false);
    -

    Returns true if the given pubkey is directly related to the address payload.

    +let address: Address = "32iVBEu4dxkUQk9dJbZUiBiQdmypcEyJRf".parse().unwrap(); +assert!(address.is_valid_for_network(Network::Bitcoin)); +assert_eq!(address.is_valid_for_network(Network::Testnet), false);
    +

    Returns true if the given pubkey is directly related to the address payload.

    This is determined by directly comparing the address payload with either the hash of the given public key or the segwit redeem hash generated from the given key. For taproot addresses, the supplied key is assumed to be tweaked

    -

    Returns true if the supplied xonly public key can be used to derive the address.

    +

    Returns true if the supplied xonly public key can be used to derive the address.

    This will only work for Taproot addresses. The Public Key is assumed to have already been tweaked.

    -

    Trait Implementations

    Formats the value using the given formatter. Read more

    -

    The resulting type after dereferencing.

    -

    Dereferences the value.

    -

    Formats the value using the given formatter. Read more

    -

    This method tests for self and other values to be equal, and is used -by ==. Read more

    -

    This method tests for !=.

    -

    Auto Trait Implementations

    Blanket Implementations

    Gets the TypeId of self. Read more

    -

    Immutably borrows from an owned value. Read more

    -

    Mutably borrows from an owned value. Read more

    -

    Performs the conversion.

    -

    Performs the conversion.

    -

    The alignment of pointer.

    -

    The type for initializers.

    -

    Initializes a with the given initializer. Read more

    -

    Dereferences the given pointer. Read more

    -

    Mutably dereferences the given pointer. Read more

    -

    Drops the object pointed to by the given pointer. Read more

    -

    Converts the given value to a String. Read more

    -

    The type returned in the event of a conversion error.

    -

    Performs the conversion.

    -

    The type returned in the event of a conversion error.

    -

    Performs the conversion.

    -
    - \ No newline at end of file +

    Trait Implementations§

    Formats the value using the given formatter. Read more
    The resulting type after dereferencing.
    Dereferences the value.
    Formats the value using the given formatter. Read more
    This method tests for self and other values to be equal, and is used +by ==. Read more
    This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason. Read more

    Auto Trait Implementations§

    Blanket Implementations§

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

    Returns the argument unchanged.

    +

    Calls U::from(self).

    +

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

    +
    The alignment of pointer.
    The type for initializers.
    Initializes a with the given initializer. Read more
    Dereferences the given pointer. Read more
    Mutably dereferences the given pointer. Read more
    Drops the object pointed to by the given pointer. Read more
    Converts the given value to a String. Read more
    The type returned in the event of a conversion error.
    Performs the conversion.
    The type returned in the event of a conversion error.
    Performs the conversion.
    \ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/wallet/struct.SyncOptions.html b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/wallet/struct.SyncOptions.html index c81cc541b1..d07235640a 100644 --- a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/wallet/struct.SyncOptions.html +++ b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/wallet/struct.SyncOptions.html @@ -1,31 +1,10 @@ -SyncOptions in bdk::wallet - Rust - -
    pub struct SyncOptions {
    +SyncOptions in bdk::wallet - Rust

    Struct bdk::wallet::SyncOptions

    source ·
    pub struct SyncOptions {
         pub progress: Option<Box<dyn Progress>>,
     }
    Expand description

    Options to a sync.

    -

    Fields

    progress: Option<Box<dyn Progress>>

    The progress tracker which may be informed when progress is made.

    -

    Trait Implementations

    Formats the value using the given formatter. Read more

    -

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

    -

    Auto Trait Implementations

    Blanket Implementations

    Gets the TypeId of self. Read more

    -

    Immutably borrows from an owned value. Read more

    -

    Mutably borrows from an owned value. Read more

    -

    Performs the conversion.

    -

    Performs the conversion.

    -

    The alignment of pointer.

    -

    The type for initializers.

    -

    Initializes a with the given initializer. Read more

    -

    Dereferences the given pointer. Read more

    -

    Mutably dereferences the given pointer. Read more

    -

    Drops the object pointed to by the given pointer. Read more

    -

    The type returned in the event of a conversion error.

    -

    Performs the conversion.

    -

    The type returned in the event of a conversion error.

    -

    Performs the conversion.

    -
    - \ No newline at end of file +

    Fields§

    §progress: Option<Box<dyn Progress>>

    The progress tracker which may be informed when progress is made.

    +

    Trait Implementations§

    Formats the value using the given formatter. Read more
    Returns the “default value” for a type. Read more

    Auto Trait Implementations§

    Blanket Implementations§

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

    Returns the argument unchanged.

    +

    Calls U::from(self).

    +

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

    +
    The alignment of pointer.
    The type for initializers.
    Initializes a with the given initializer. Read more
    Dereferences the given pointer. Read more
    Mutably dereferences the given pointer. Read more
    Drops the object pointed to by the given pointer. Read more
    The type returned in the event of a conversion error.
    Performs the conversion.
    The type returned in the event of a conversion error.
    Performs the conversion.
    \ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/wallet/struct.Wallet.html b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/wallet/struct.Wallet.html index 229587ff78..018191704d 100644 --- a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/wallet/struct.Wallet.html +++ b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/wallet/struct.Wallet.html @@ -1,12 +1,5 @@ -Wallet in bdk::wallet - Rust - -
    -

    Struct bdk::wallet::Wallet

    source · []
    pub struct Wallet<D> { /* private fields */ }
    Expand description

    A Bitcoin wallet

    +Wallet in bdk::wallet - Rust

    Struct bdk::wallet::Wallet

    source ·
    pub struct Wallet<D> { /* private fields */ }
    Expand description

    A Bitcoin wallet

    The Wallet struct acts as a way of coherently interfacing with output descriptors and related transactions. Its main components are:

      @@ -14,146 +7,132 @@ Its main components are:

    1. A Database where it tracks transactions and utxos related to the descriptors.
    2. signers that can contribute signatures to addresses instantiated from the descriptors.
    -

    Implementations

    👎 Deprecated:

    Just use Wallet::new – all wallets are offline now!

    -

    Create a new “offline” wallet

    -

    Create a wallet.

    +

    Implementations§

    👎Deprecated: Just use Wallet::new – all wallets are offline now!

    Create a new “offline” wallet

    +

    Create a wallet.

    The only way this can fail is if the descriptors passed in do not match the checksums in database.

    -

    Get the Bitcoin network the wallet is using.

    -

    Return a derived address using the external descriptor, see AddressIndex for +

    Get the Bitcoin network the wallet is using.

    +

    Return a derived address using the external descriptor, see AddressIndex for available address index selection strategies. If none of the keys in the descriptor are derivable (i.e. does not end with /*) then the same address will always be returned for any AddressIndex.

    -

    Return a derived address using the internal (change) descriptor.

    +

    Return a derived address using the internal (change) descriptor.

    If the wallet doesn’t have an internal descriptor it will use the external descriptor.

    see AddressIndex for available address index selection strategies. If none of the keys in the descriptor are derivable (i.e. does not end with /*) then the same address will always be returned for any AddressIndex.

    -

    Ensures that there are at least max_addresses addresses cached in the database if the +

    Ensures that there are at least max_addresses addresses cached in the database if the descriptor is derivable, or 1 address if it is not. Will return Ok(true) if there are new addresses generated (either external or internal), and Ok(false) if all the required addresses are already cached. This function is useful to explicitly cache addresses in a wallet to do things like check Wallet::is_mine on transaction output scripts.

    -

    Return whether or not a script is part of this wallet (either internal or external)

    -

    Return the list of unspent outputs of this wallet

    +

    Return whether or not a script is part of this wallet (either internal or external)

    +

    Return the list of unspent outputs of this wallet

    Note that this method only operates on the internal database, which first needs to be Wallet::sync manually.

    -

    Returns the UTXO owned by this wallet corresponding to outpoint if it exists in the +

    Returns the UTXO owned by this wallet corresponding to outpoint if it exists in the wallet’s database.

    -

    Return a single transactions made and received by the wallet

    +

    Return a single transactions made and received by the wallet

    Optionally fill the TransactionDetails::transaction field with the raw transaction if include_raw is true.

    Note that this method only operates on the internal database, which first needs to be Wallet::sync manually.

    -

    Return an unsorted list of transactions made and received by the wallet

    +

    Return an unsorted list of transactions made and received by the wallet

    Optionally fill the TransactionDetails::transaction field with the raw transaction if include_raw is true.

    To sort transactions, the following code can be used:

    -
    tx_list.sort_by(|a, b| {
    -    b.confirmation_time
    -        .as_ref()
    -        .map(|t| t.height)
    -        .cmp(&a.confirmation_time.as_ref().map(|t| t.height))
    +
    tx_list.sort_by(|a, b| {
    +    b.confirmation_time
    +        .as_ref()
    +        .map(|t| t.height)
    +        .cmp(&a.confirmation_time.as_ref().map(|t| t.height))
     });

    Note that this method only operates on the internal database, which first needs to be Wallet::sync manually.

    -

    Return the balance, separated into available, trusted-pending, untrusted-pending and immature +

    Return the balance, separated into available, trusted-pending, untrusted-pending and immature values.

    Note that this method only operates on the internal database, which first needs to be Wallet::sync manually.

    -

    Add an external signer

    +

    Add an external signer

    See the signer module for an example.

    -

    Get the signers

    -
    Example
    -
    let wallet = Wallet::new("wpkh(tprv8ZgxMBicQKsPe73PBRSmNbTfbcsZnwWhz5eVmhHpi31HW29Z7mc9B4cWGRQzopNUzZUT391DeDJxL2PefNunWyLgqCKRMDkU1s2s8bAfoSk/84'/0'/0'/0/*)", None, Network::Testnet, MemoryDatabase::new())?;
    -for secret_key in wallet.get_signers(KeychainKind::External).signers().iter().filter_map(|s| s.descriptor_secret_key()) {
    -    // secret_key: tprv8ZgxMBicQKsPe73PBRSmNbTfbcsZnwWhz5eVmhHpi31HW29Z7mc9B4cWGRQzopNUzZUT391DeDJxL2PefNunWyLgqCKRMDkU1s2s8bAfoSk/84'/0'/0'/0/*
    -    println!("secret_key: {}", secret_key);
    +

    Get the signers

    +
    Example
    +
    let wallet = Wallet::new("wpkh(tprv8ZgxMBicQKsPe73PBRSmNbTfbcsZnwWhz5eVmhHpi31HW29Z7mc9B4cWGRQzopNUzZUT391DeDJxL2PefNunWyLgqCKRMDkU1s2s8bAfoSk/84'/0'/0'/0/*)", None, Network::Testnet, MemoryDatabase::new())?;
    +for secret_key in wallet.get_signers(KeychainKind::External).signers().iter().filter_map(|s| s.descriptor_secret_key()) {
    +    // secret_key: tprv8ZgxMBicQKsPe73PBRSmNbTfbcsZnwWhz5eVmhHpi31HW29Z7mc9B4cWGRQzopNUzZUT391DeDJxL2PefNunWyLgqCKRMDkU1s2s8bAfoSk/84'/0'/0'/0/*
    +    println!("secret_key: {}", secret_key);
     }
     
    -Ok::<(), Box<dyn std::error::Error>>(())
    -

    Start building a transaction.

    +Ok::<(), Box<dyn std::error::Error>>(())
    +

    Start building a transaction.

    This returns a blank TxBuilder from which you can specify the parameters for the transaction.

    -
    Example
    -
    let (psbt, details) = {
    -   let mut builder =  wallet.build_tx();
    -   builder
    -       .add_recipient(to_address.script_pubkey(), 50_000);
    -   builder.finish()?
    -};
    +
    Example
    +
    let (psbt, details) = {
    +   let mut builder =  wallet.build_tx();
    +   builder
    +       .add_recipient(to_address.script_pubkey(), 50_000);
    +   builder.finish()?
    +};
     
     // sign and broadcast ...
    -

    Bump the fee of a transaction previously created with this wallet.

    +

    Bump the fee of a transaction previously created with this wallet.

    Returns an error if the transaction is already confirmed or doesn’t explicitly signal replace by fee (RBF). If the transaction can be fee bumped then it returns a TxBuilder pre-populated with the inputs and outputs of the original transaction.

    -
    Example
    -
    let (mut psbt, _) = {
    -    let mut builder = wallet.build_tx();
    -    builder
    -        .add_recipient(to_address.script_pubkey(), 50_000)
    -        .enable_rbf();
    -    builder.finish()?
    -};
    -let _ = wallet.sign(&mut psbt, SignOptions::default())?;
    -let tx = psbt.extract_tx();
    -// broadcast tx but it's taking too long to confirm so we want to bump the fee
    -let (mut psbt, _) =  {
    -    let mut builder = wallet.build_fee_bump(tx.txid())?;
    -    builder
    -        .fee_rate(FeeRate::from_sat_per_vb(5.0));
    -    builder.finish()?
    -};
    +
    Example
    +
    let (mut psbt, _) = {
    +    let mut builder = wallet.build_tx();
    +    builder
    +        .add_recipient(to_address.script_pubkey(), 50_000)
    +        .enable_rbf();
    +    builder.finish()?
    +};
    +let _ = wallet.sign(&mut psbt, SignOptions::default())?;
    +let tx = psbt.extract_tx();
    +// broadcast tx but it's taking too long to confirm so we want to bump the fee
    +let (mut psbt, _) =  {
    +    let mut builder = wallet.build_fee_bump(tx.txid())?;
    +    builder
    +        .fee_rate(FeeRate::from_sat_per_vb(5.0));
    +    builder.finish()?
    +};
     
    -let _ = wallet.sign(&mut psbt, SignOptions::default())?;
    -let fee_bumped_tx = psbt.extract_tx();
    +let _ = wallet.sign(&mut psbt, SignOptions::default())?;
    +let fee_bumped_tx = psbt.extract_tx();
     // broadcast fee_bumped_tx to replace original
    -

    Sign a transaction with all the wallet’s signers, in the order specified by every signer’s +

    Sign a transaction with all the wallet’s signers, in the order specified by every signer’s SignerOrdering

    The SignOptions can be used to tweak the behavior of the software signers, and the way the transaction is finalized at the end. Note that it can’t be guaranteed that every signers will follow the options, but the “software signers” (WIF keys and xprv) defined in this library will.

    -
    Example
    -
    let (mut psbt, _) = {
    -    let mut builder = wallet.build_tx();
    -    builder.add_recipient(to_address.script_pubkey(), 50_000);
    -    builder.finish()?
    -};
    -let  finalized = wallet.sign(&mut psbt, SignOptions::default())?;
    -assert!(finalized, "we should have signed all the inputs");
    -

    Return the spending policies for the wallet’s descriptor

    -

    Return the “public” version of the wallet’s descriptor, meaning a new descriptor that has +

    Example
    +
    let (mut psbt, _) = {
    +    let mut builder = wallet.build_tx();
    +    builder.add_recipient(to_address.script_pubkey(), 50_000);
    +    builder.finish()?
    +};
    +let  finalized = wallet.sign(&mut psbt, SignOptions::default())?;
    +assert!(finalized, "we should have signed all the inputs");
    +

    Return the spending policies for the wallet’s descriptor

    +

    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

    -

    Finalize a PSBT, i.e., for each input determine if sufficient data is available to pass +

    Finalize a PSBT, i.e., for each input determine if sufficient data is available to pass validation and construct the respective scriptSig or scriptWitness. Please refer to BIP174 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.

    -

    Return the secp256k1 context used for all signing operations

    -

    Returns the descriptor used to create addresses for a particular keychain.

    -

    get the corresponding PSBT Input for a LocalUtxo

    -

    Return an immutable reference to the internal database

    -

    Sync the internal database with the blockchain

    -

    Return the checksum of the public descriptor associated to keychain

    +

    Return the secp256k1 context used for all signing operations

    +

    Returns the descriptor used to create addresses for a particular keychain.

    +

    get the corresponding PSBT Input for a LocalUtxo

    +

    Return an immutable reference to the internal database

    +

    Sync the internal database with the blockchain

    +

    Return the checksum of the public descriptor associated to keychain

    Internally calls Self::get_descriptor_for_keychain to fetch the right descriptor

    -

    Trait Implementations

    Formats the value using the given formatter. Read more

    -

    Auto Trait Implementations

    Blanket Implementations

    Gets the TypeId of self. Read more

    -

    Immutably borrows from an owned value. Read more

    -

    Mutably borrows from an owned value. Read more

    -

    Performs the conversion.

    -

    Performs the conversion.

    -

    The alignment of pointer.

    -

    The type for initializers.

    -

    Initializes a with the given initializer. Read more

    -

    Dereferences the given pointer. Read more

    -

    Mutably dereferences the given pointer. Read more

    -

    Drops the object pointed to by the given pointer. Read more

    -

    The type returned in the event of a conversion error.

    -

    Performs the conversion.

    -

    The type returned in the event of a conversion error.

    -

    Performs the conversion.

    -
    - \ No newline at end of file +

    Trait Implementations§

    Formats the value using the given formatter. Read more

    Auto Trait Implementations§

    Blanket Implementations§

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

    Returns the argument unchanged.

    +

    Calls U::from(self).

    +

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

    +
    The alignment of pointer.
    The type for initializers.
    Initializes a with the given initializer. Read more
    Dereferences the given pointer. Read more
    Mutably dereferences the given pointer. Read more
    Drops the object pointed to by the given pointer. Read more
    The type returned in the event of a conversion error.
    Performs the conversion.
    The type returned in the event of a conversion error.
    Performs the conversion.
    \ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/wallet/time/fn.get_timestamp.html b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/wallet/time/fn.get_timestamp.html index 5e362f079f..b5fb0318df 100644 --- a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/wallet/time/fn.get_timestamp.html +++ b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/wallet/time/fn.get_timestamp.html @@ -1,11 +1,3 @@ -get_timestamp in bdk::wallet::time - Rust - -
    pub fn get_timestamp() -> u64
    Expand description

    Return the current timestamp in seconds

    -
    - \ No newline at end of file +get_timestamp in bdk::wallet::time - Rust

    Function bdk::wallet::time::get_timestamp

    source ·
    pub fn get_timestamp() -> u64
    Expand description

    Return the current timestamp in seconds

    +
    \ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/wallet/time/index.html b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/wallet/time/index.html index 086115e533..621edced2c 100644 --- a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/wallet/time/index.html +++ b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/wallet/time/index.html @@ -1,17 +1,7 @@ -bdk::wallet::time - Rust - -
    -

    Module bdk::wallet::time

    source · []
    Expand description

    Cross-platform time

    +bdk::wallet::time - Rust

    Module bdk::wallet::time

    source ·
    Expand description

    Cross-platform time

    This module provides a function to get the current timestamp that works on all the platforms supported by the library.

    It can be useful to compare it with the timestamps found in TransactionDetails.

    -

    Functions

    -

    Return the current timestamp in seconds

    -
    - \ No newline at end of file +

    Functions

    Return the current timestamp in seconds
    \ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/wallet/time/sidebar-items.js b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/wallet/time/sidebar-items.js index 22164ef49f..4568a098c6 100644 --- a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/wallet/time/sidebar-items.js +++ b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/wallet/time/sidebar-items.js @@ -1 +1 @@ -initSidebarItems({"fn":[["get_timestamp","Return the current timestamp in seconds"]]}); \ No newline at end of file +window.SIDEBAR_ITEMS = {"fn":[["get_timestamp","Return the current timestamp in seconds"]]}; \ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/wallet/trait.IsDust.html b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/wallet/trait.IsDust.html index 9d5d2db912..bb8fa958d5 100644 --- a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/wallet/trait.IsDust.html +++ b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/wallet/trait.IsDust.html @@ -1,16 +1,8 @@ -IsDust in bdk::wallet - Rust - -
    -

    Trait bdk::wallet::IsDust

    source · []
    pub trait IsDust {
    -    fn is_dust(&self, script: &Script) -> bool;
    +IsDust in bdk::wallet - Rust

    Trait bdk::wallet::IsDust

    source ·
    pub trait IsDust {
    +    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

    Check whether or not a value is below dust limit

    -

    Implementations on Foreign Types

    Implementors

    - \ No newline at end of file +

    Required Methods§

    Check whether or not a value is below dust limit

    +

    Implementations on Foreign Types§

    Implementors§

    \ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/wallet/tx_builder/enum.ChangeSpendPolicy.html b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/wallet/tx_builder/enum.ChangeSpendPolicy.html index b21b84b7f1..29b958a9d1 100644 --- a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/wallet/tx_builder/enum.ChangeSpendPolicy.html +++ b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/wallet/tx_builder/enum.ChangeSpendPolicy.html @@ -1,56 +1,18 @@ -ChangeSpendPolicy in bdk::wallet::tx_builder - Rust - -
    pub enum ChangeSpendPolicy {
    +ChangeSpendPolicy in bdk::wallet::tx_builder - Rust
    pub enum ChangeSpendPolicy {
         ChangeAllowed,
         OnlyChange,
         ChangeForbidden,
     }
    Expand description

    Policy regarding the use of change outputs when creating a transaction

    -

    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

    Returns a copy of the value. Read more

    -

    Performs copy-assignment from source. Read more

    -

    Formats the value using the given formatter. Read more

    -

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

    -

    Feeds this value into the given Hasher. Read more

    -

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

    -

    This method returns an Ordering between self and other. Read more

    -

    Compares and returns the maximum of two values. Read more

    -

    Compares and returns the minimum of two values. Read more

    -

    Restrict a value to a certain interval. Read more

    -

    This method tests for self and other values to be equal, and is used -by ==. Read more

    -

    This method tests for !=.

    -

    This method returns an ordering between self and other values if one exists. Read more

    -

    This method tests less than (for self and other) and is used by the < operator. Read more

    -

    This method tests less than or equal to (for self and other) and is used by the <= -operator. Read more

    -

    This method tests greater than (for self and other) and is used by the > operator. Read more

    -

    This method tests greater than or equal to (for self and other) and is used by the >= -operator. Read more

    -

    Auto Trait Implementations

    Blanket Implementations

    Gets the TypeId of self. Read more

    -

    Immutably borrows from an owned value. Read more

    -

    Mutably borrows from an owned value. Read more

    -

    Performs the conversion.

    -

    Performs the conversion.

    -

    The alignment of pointer.

    -

    The type for initializers.

    -

    Initializes a with the given initializer. Read more

    -

    Dereferences the given pointer. Read more

    -

    Mutably dereferences the given pointer. Read more

    -

    Drops the object pointed to by the given pointer. Read more

    -

    The resulting type after obtaining ownership.

    -

    Creates owned data from borrowed data, usually by cloning. Read more

    -
    🔬 This is a nightly-only experimental API. (toowned_clone_into)

    Uses borrowed data to replace owned data, usually by cloning. Read more

    -

    The type returned in the event of a conversion error.

    -

    Performs the conversion.

    -

    The type returned in the event of a conversion error.

    -

    Performs the conversion.

    -
    - \ No newline at end of file +

    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§

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

    Auto Trait Implementations§

    Blanket Implementations§

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

    Returns the argument unchanged.

    +

    Calls U::from(self).

    +

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

    +
    The alignment of pointer.
    The type for initializers.
    Initializes a with the given initializer. Read more
    Dereferences the given pointer. Read more
    Mutably dereferences the given pointer. Read more
    Drops the object pointed to by the given pointer. Read more
    The resulting type after obtaining ownership.
    Creates owned data from borrowed data, usually by cloning. Read more
    Uses borrowed data to replace owned data, usually by cloning. Read more
    The type returned in the event of a conversion error.
    Performs the conversion.
    The type returned in the event of a conversion error.
    Performs the conversion.
    \ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/wallet/tx_builder/enum.TxOrdering.html b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/wallet/tx_builder/enum.TxOrdering.html index ee8d315ed9..5b2de206bd 100644 --- a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/wallet/tx_builder/enum.TxOrdering.html +++ b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/wallet/tx_builder/enum.TxOrdering.html @@ -1,57 +1,19 @@ -TxOrdering in bdk::wallet::tx_builder - Rust - -
    pub enum TxOrdering {
    +TxOrdering in bdk::wallet::tx_builder - Rust
    pub enum TxOrdering {
         Shuffle,
         Untouched,
         Bip69Lexicographic,
     }
    Expand description

    Ordering of the transaction’s inputs and outputs

    -

    Variants

    Shuffle

    Randomized (default)

    -

    Untouched

    Unchanged

    -

    Bip69Lexicographic

    BIP69 / Lexicographic

    -

    Implementations

    Sort transaction inputs and outputs by TxOrdering variant

    -

    Trait Implementations

    Returns a copy of the value. Read more

    -

    Performs copy-assignment from source. Read more

    -

    Formats the value using the given formatter. Read more

    -

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

    -

    Feeds this value into the given Hasher. Read more

    -

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

    -

    This method returns an Ordering between self and other. Read more

    -

    Compares and returns the maximum of two values. Read more

    -

    Compares and returns the minimum of two values. Read more

    -

    Restrict a value to a certain interval. Read more

    -

    This method tests for self and other values to be equal, and is used -by ==. Read more

    -

    This method tests for !=.

    -

    This method returns an ordering between self and other values if one exists. Read more

    -

    This method tests less than (for self and other) and is used by the < operator. Read more

    -

    This method tests less than or equal to (for self and other) and is used by the <= -operator. Read more

    -

    This method tests greater than (for self and other) and is used by the > operator. Read more

    -

    This method tests greater than or equal to (for self and other) and is used by the >= -operator. Read more

    -

    Auto Trait Implementations

    Blanket Implementations

    Gets the TypeId of self. Read more

    -

    Immutably borrows from an owned value. Read more

    -

    Mutably borrows from an owned value. Read more

    -

    Performs the conversion.

    -

    Performs the conversion.

    -

    The alignment of pointer.

    -

    The type for initializers.

    -

    Initializes a with the given initializer. Read more

    -

    Dereferences the given pointer. Read more

    -

    Mutably dereferences the given pointer. Read more

    -

    Drops the object pointed to by the given pointer. Read more

    -

    The resulting type after obtaining ownership.

    -

    Creates owned data from borrowed data, usually by cloning. Read more

    -
    🔬 This is a nightly-only experimental API. (toowned_clone_into)

    Uses borrowed data to replace owned data, usually by cloning. Read more

    -

    The type returned in the event of a conversion error.

    -

    Performs the conversion.

    -

    The type returned in the event of a conversion error.

    -

    Performs the conversion.

    -
    - \ No newline at end of file +

    Variants§

    §

    Shuffle

    Randomized (default)

    +
    §

    Untouched

    Unchanged

    +
    §

    Bip69Lexicographic

    BIP69 / Lexicographic

    +

    Implementations§

    Sort transaction inputs and outputs by TxOrdering variant

    +

    Trait Implementations§

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

    Auto Trait Implementations§

    Blanket Implementations§

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

    Returns the argument unchanged.

    +

    Calls U::from(self).

    +

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

    +
    The alignment of pointer.
    The type for initializers.
    Initializes a with the given initializer. Read more
    Dereferences the given pointer. Read more
    Mutably dereferences the given pointer. Read more
    Drops the object pointed to by the given pointer. Read more
    The resulting type after obtaining ownership.
    Creates owned data from borrowed data, usually by cloning. Read more
    Uses borrowed data to replace owned data, usually by cloning. Read more
    The type returned in the event of a conversion error.
    Performs the conversion.
    The type returned in the event of a conversion error.
    Performs the conversion.
    \ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/wallet/tx_builder/index.html b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/wallet/tx_builder/index.html index 07e577b694..efde794e2f 100644 --- a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/wallet/tx_builder/index.html +++ b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/wallet/tx_builder/index.html @@ -1,35 +1,18 @@ -bdk::wallet::tx_builder - Rust - -
    -

    Module bdk::wallet::tx_builder

    source · []
    Expand description

    Transaction builder

    -

    Example

    -
    // create a TxBuilder from a wallet
    -let mut tx_builder = wallet.build_tx();
    +bdk::wallet::tx_builder - Rust

    Module bdk::wallet::tx_builder

    source ·
    Expand description

    Transaction builder

    +

    Example

    +
    // create a TxBuilder from a wallet
    +let mut tx_builder = wallet.build_tx();
     
    -tx_builder
    -    // Create a transaction with one output to `to_address` of 50_000 satoshi
    -    .add_recipient(to_address.script_pubkey(), 50_000)
    -    // With a custom fee rate of 5.0 satoshi/vbyte
    -    .fee_rate(FeeRate::from_sat_per_vb(5.0))
    -    // Only spend non-change outputs
    -    .do_not_spend_change()
    -    // Turn on RBF signaling
    -    .enable_rbf();
    -let (psbt, tx_details) = tx_builder.finish()?;
    -

    Structs

    -

    Marker type to indicate the TxBuilder is being used to bump the fee of an existing transaction.

    -

    Marker type to indicate the TxBuilder is being used to create a new transaction (as opposed -to bumping the fee of an existing one).

    -

    A transaction builder

    -

    Enums

    -

    Policy regarding the use of change outputs when creating a transaction

    -

    Ordering of the transaction’s inputs and outputs

    -

    Traits

    -

    Context in which the TxBuilder is valid

    -
    - \ No newline at end of file +tx_builder + // Create a transaction with one output to `to_address` of 50_000 satoshi + .add_recipient(to_address.script_pubkey(), 50_000) + // With a custom fee rate of 5.0 satoshi/vbyte + .fee_rate(FeeRate::from_sat_per_vb(5.0)) + // Only spend non-change outputs + .do_not_spend_change() + // Turn on RBF signaling + .enable_rbf(); +let (psbt, tx_details) = tx_builder.finish()?;
    +

    Structs

    Marker type to indicate the TxBuilder is being used to bump the fee of an existing transaction.
    Marker type to indicate the TxBuilder is being used to create a new transaction (as opposed +to bumping the fee of an existing one).
    A transaction builder

    Enums

    Policy regarding the use of change outputs when creating a transaction
    Ordering of the transaction’s inputs and outputs

    Traits

    Context in which the TxBuilder is valid
    \ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/wallet/tx_builder/sidebar-items.js b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/wallet/tx_builder/sidebar-items.js index dcd52e5dff..7d9ed1d51b 100644 --- a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/wallet/tx_builder/sidebar-items.js +++ b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/wallet/tx_builder/sidebar-items.js @@ -1 +1 @@ -initSidebarItems({"enum":[["ChangeSpendPolicy","Policy regarding the use of change outputs when creating a transaction"],["TxOrdering","Ordering of the transaction’s inputs and outputs"]],"struct":[["BumpFee","Marker type to indicate the [`TxBuilder`] is being used to bump the fee of an existing transaction."],["CreateTx","Marker type to indicate the [`TxBuilder`] is being used to create a new transaction (as opposed to bumping the fee of an existing one)."],["TxBuilder","A transaction builder"]],"trait":[["TxBuilderContext","Context in which the [`TxBuilder`] is valid"]]}); \ No newline at end of file +window.SIDEBAR_ITEMS = {"enum":[["ChangeSpendPolicy","Policy regarding the use of change outputs when creating a transaction"],["TxOrdering","Ordering of the transaction’s inputs and outputs"]],"struct":[["BumpFee","Marker type to indicate the [`TxBuilder`] is being used to bump the fee of an existing transaction."],["CreateTx","Marker type to indicate the [`TxBuilder`] is being used to create a new transaction (as opposed to bumping the fee of an existing one)."],["TxBuilder","A transaction builder"]],"trait":[["TxBuilderContext","Context in which the [`TxBuilder`] is valid"]]}; \ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/wallet/tx_builder/struct.BumpFee.html b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/wallet/tx_builder/struct.BumpFee.html index ca386919e3..f3477eed22 100644 --- a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/wallet/tx_builder/struct.BumpFee.html +++ b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/wallet/tx_builder/struct.BumpFee.html @@ -1,33 +1,7 @@ -BumpFee in bdk::wallet::tx_builder - Rust - -
    pub struct BumpFee;
    Expand description

    Marker type to indicate the TxBuilder is being used to bump the fee of an existing transaction.

    -

    Trait Implementations

    Returns a copy of the value. Read more

    -

    Performs copy-assignment from source. Read more

    -

    Formats the value using the given formatter. Read more

    -

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

    -

    Auto Trait Implementations

    Blanket Implementations

    Gets the TypeId of self. Read more

    -

    Immutably borrows from an owned value. Read more

    -

    Mutably borrows from an owned value. Read more

    -

    Performs the conversion.

    -

    Performs the conversion.

    -

    The alignment of pointer.

    -

    The type for initializers.

    -

    Initializes a with the given initializer. Read more

    -

    Dereferences the given pointer. Read more

    -

    Mutably dereferences the given pointer. Read more

    -

    Drops the object pointed to by the given pointer. Read more

    -

    The resulting type after obtaining ownership.

    -

    Creates owned data from borrowed data, usually by cloning. Read more

    -
    🔬 This is a nightly-only experimental API. (toowned_clone_into)

    Uses borrowed data to replace owned data, usually by cloning. Read more

    -

    The type returned in the event of a conversion error.

    -

    Performs the conversion.

    -

    The type returned in the event of a conversion error.

    -

    Performs the conversion.

    -
    - \ No newline at end of file +BumpFee in bdk::wallet::tx_builder - Rust

    Struct bdk::wallet::tx_builder::BumpFee

    source ·
    pub struct BumpFee;
    Expand description

    Marker type to indicate the TxBuilder is being used to bump the fee of an existing transaction.

    +

    Trait Implementations§

    Returns a copy of the value. Read more
    Performs copy-assignment from source. Read more
    Formats the value using the given formatter. Read more
    Returns the “default value” for a type. Read more

    Auto Trait Implementations§

    Blanket Implementations§

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

    Returns the argument unchanged.

    +

    Calls U::from(self).

    +

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

    +
    The alignment of pointer.
    The type for initializers.
    Initializes a with the given initializer. Read more
    Dereferences the given pointer. Read more
    Mutably dereferences the given pointer. Read more
    Drops the object pointed to by the given pointer. Read more
    The resulting type after obtaining ownership.
    Creates owned data from borrowed data, usually by cloning. Read more
    Uses borrowed data to replace owned data, usually by cloning. Read more
    The type returned in the event of a conversion error.
    Performs the conversion.
    The type returned in the event of a conversion error.
    Performs the conversion.
    \ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/wallet/tx_builder/struct.CreateTx.html b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/wallet/tx_builder/struct.CreateTx.html index fac1e51dee..5730fc311c 100644 --- a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/wallet/tx_builder/struct.CreateTx.html +++ b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/wallet/tx_builder/struct.CreateTx.html @@ -1,34 +1,8 @@ -CreateTx in bdk::wallet::tx_builder - Rust - -
    pub struct CreateTx;
    Expand description

    Marker type to indicate the TxBuilder is being used to create a new transaction (as opposed +CreateTx in bdk::wallet::tx_builder - Rust

    Struct bdk::wallet::tx_builder::CreateTx

    source ·
    pub struct CreateTx;
    Expand description

    Marker type to indicate the TxBuilder is being used to create a new transaction (as opposed to bumping the fee of an existing one).

    -

    Trait Implementations

    Returns a copy of the value. Read more

    -

    Performs copy-assignment from source. Read more

    -

    Formats the value using the given formatter. Read more

    -

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

    -

    Auto Trait Implementations

    Blanket Implementations

    Gets the TypeId of self. Read more

    -

    Immutably borrows from an owned value. Read more

    -

    Mutably borrows from an owned value. Read more

    -

    Performs the conversion.

    -

    Performs the conversion.

    -

    The alignment of pointer.

    -

    The type for initializers.

    -

    Initializes a with the given initializer. Read more

    -

    Dereferences the given pointer. Read more

    -

    Mutably dereferences the given pointer. Read more

    -

    Drops the object pointed to by the given pointer. Read more

    -

    The resulting type after obtaining ownership.

    -

    Creates owned data from borrowed data, usually by cloning. Read more

    -
    🔬 This is a nightly-only experimental API. (toowned_clone_into)

    Uses borrowed data to replace owned data, usually by cloning. Read more

    -

    The type returned in the event of a conversion error.

    -

    Performs the conversion.

    -

    The type returned in the event of a conversion error.

    -

    Performs the conversion.

    -
    - \ No newline at end of file +

    Trait Implementations§

    Returns a copy of the value. Read more
    Performs copy-assignment from source. Read more
    Formats the value using the given formatter. Read more
    Returns the “default value” for a type. Read more

    Auto Trait Implementations§

    Blanket Implementations§

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

    Returns the argument unchanged.

    +

    Calls U::from(self).

    +

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

    +
    The alignment of pointer.
    The type for initializers.
    Initializes a with the given initializer. Read more
    Dereferences the given pointer. Read more
    Mutably dereferences the given pointer. Read more
    Drops the object pointed to by the given pointer. Read more
    The resulting type after obtaining ownership.
    Creates owned data from borrowed data, usually by cloning. Read more
    Uses borrowed data to replace owned data, usually by cloning. Read more
    The type returned in the event of a conversion error.
    Performs the conversion.
    The type returned in the event of a conversion error.
    Performs the conversion.
    \ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/wallet/tx_builder/struct.TxBuilder.html b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/wallet/tx_builder/struct.TxBuilder.html index b9fc85c7d8..25c6744504 100644 --- a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/wallet/tx_builder/struct.TxBuilder.html +++ b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/wallet/tx_builder/struct.TxBuilder.html @@ -1,50 +1,43 @@ -TxBuilder in bdk::wallet::tx_builder - Rust - -
    pub struct TxBuilder<'a, D, Cs, Ctx> { /* private fields */ }
    Expand description

    A transaction builder

    +TxBuilder in bdk::wallet::tx_builder - Rust

    Struct bdk::wallet::tx_builder::TxBuilder

    source ·
    pub struct TxBuilder<'a, D, Cs, Ctx> { /* 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.

    Each option setting method on TxBuilder takes and returns &mut self so you can chain calls as in the following example:

    -
    // chaining
    -let (psbt1, details) = {
    -    let mut builder = wallet.build_tx();
    -    builder
    -        .ordering(TxOrdering::Untouched)
    -        .add_recipient(addr1.script_pubkey(), 50_000)
    -        .add_recipient(addr2.script_pubkey(), 50_000);
    -    builder.finish()?
    -};
    +
    // chaining
    +let (psbt1, details) = {
    +    let mut builder = wallet.build_tx();
    +    builder
    +        .ordering(TxOrdering::Untouched)
    +        .add_recipient(addr1.script_pubkey(), 50_000)
    +        .add_recipient(addr2.script_pubkey(), 50_000);
    +    builder.finish()?
    +};
     
    -// non-chaining
    -let (psbt2, details) = {
    -    let mut builder = wallet.build_tx();
    -    builder.ordering(TxOrdering::Untouched);
    -    for addr in &[addr1, addr2] {
    -        builder.add_recipient(addr.script_pubkey(), 50_000);
    +// non-chaining
    +let (psbt2, details) = {
    +    let mut builder = wallet.build_tx();
    +    builder.ordering(TxOrdering::Untouched);
    +    for addr in &[addr1, addr2] {
    +        builder.add_recipient(addr.script_pubkey(), 50_000);
         }
    -    builder.finish()?
    -};
    +    builder.finish()?
    +};
     
    -assert_eq!(psbt1.unsigned_tx.output[..2], psbt2.unsigned_tx.output[..2]);
    +assert_eq!(psbt1.unsigned_tx.output[..2], psbt2.unsigned_tx.output[..2]);

    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

    Set a custom fee rate

    -

    Set an absolute fee

    -

    Set the policy path to use while creating the transaction for a given keychain.

    +

    Implementations§

    Set a custom fee rate

    +

    Set an absolute fee

    +

    Set the policy path to use while creating the transaction for a given keychain.

    This method accepts a map where the key is the policy node id (see Policy::id) and the value is the list of the indexes of the items that are intended to be satisfied from the policy node (see SatisfiableItem::Thresh::items).

    -
    Example
    +
    Example

    An example of when the policy path is needed is the following descriptor: wsh(thresh(2,pk(A),sj:and_v(v:pk(B),n:older(6)),snj:and_v(v:pk(C),after(630000)))), derived from the miniscript policy thresh(2,pk(A),and(pk(B),older(6)),and(pk(C),after(630000))). @@ -75,22 +68,22 @@ used, in no particular order.

    If a particularly complex descriptor has multiple ambiguous thresholds in its structure, multiple entries can be added to the map, one for each node that requires an explicit path.

    -
    let mut path = BTreeMap::new();
    -path.insert("aabbccdd".to_string(), vec![0, 1]);
    +
    let mut path = BTreeMap::new();
    +path.insert("aabbccdd".to_string(), vec![0, 1]);
     
    -let builder = wallet
    -    .build_tx()
    -    .add_recipient(to_address.script_pubkey(), 50_000)
    -    .policy_path(path, KeychainKind::External);
    +let builder = wallet
    +    .build_tx()
    +    .add_recipient(to_address.script_pubkey(), 50_000)
    +    .policy_path(path, KeychainKind::External);
     
    -

    Add the list of outpoints to the internal list of UTXOs that must be spent.

    +

    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.

    -

    Add a utxo to the internal list of utxos that must be spent

    +

    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.

    -

    Add a foreign UTXO i.e. a UTXO not owned by this wallet.

    +

    Add a foreign UTXO i.e. a UTXO not owned by this wallet.

    At a minimum to add a foreign UTXO we need:

    1. outpoint: To add it to the raw transaction.
    2. @@ -113,7 +106,7 @@ of course check the real input weight matches the expected weight prior to broad psbt_input provide a miniscript descriptor for the input so you can check it against the script_pubkey and then ask it for the max_satisfaction_weight.

      This is an EXPERIMENTAL feature, API and other major changes are expected.

      -
      Errors
      +
      Errors

      This method returns errors in the following circumstances:

      1. The psbt_input does not contain a witness_utxo or non_witness_utxo.
      2. @@ -122,56 +115,56 @@ of course check the real input weight matches the expected weight prior to broad

        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.

        -

    Only spend utxos added by add_utxo.

    +

    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.

    -

    Replace the internal list of unspendable utxos with a new list

    +

    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.

    -

    Add a utxo to the internal list of unspendable utxos

    +

    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.

    -

    Sign with a specific sig hash

    +

    Sign with a specific sig hash

    Use this option very carefully

    -

    Choose the ordering for inputs and outputs of the transaction

    -

    Use a specific nLockTime while creating the transaction

    +

    Choose the ordering for inputs and outputs of the transaction

    +

    Use a specific nLockTime while creating the transaction

    This can cause conflicts if the wallet’s descriptors contain an “after” (OP_CLTV) operator.

    -

    Build a transaction with a specific version

    +

    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.

    -

    Do not spend change outputs

    +

    Do not spend change outputs

    This effectively adds all the change outputs to the “unspendable” list. See TxBuilder::unspendable.

    -

    Only spend change outputs

    +

    Only spend change outputs

    This effectively adds all the non-change outputs to the “unspendable” list. See TxBuilder::unspendable.

    -

    Only Fill-in the psbt::Input::witness_utxo field when spending from +

    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.

    -

    Fill-in the psbt::Output::redeem_script and +

    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.

    -

    Fill-in the PSBT_GLOBAL_XPUB field with the extended keys contained in both the external +

    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.

    -

    Spend all the available inputs. This respects filters like TxBuilder::unspendable and the change policy.

    -

    Choose the coin selection algorithm

    +

    Spend all the available inputs. This respects filters like TxBuilder::unspendable and the change policy.

    +

    Choose the coin selection algorithm

    Overrides the DefaultCoinSelectionAlgorithm.

    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.

    -

    Finish building the transaction.

    +

    Finish building the transaction.

    Returns the BIP174 “PSBT” and summary details about the transaction.

    -

    Enable signaling RBF

    +

    Enable signaling RBF

    This will use the default nSequence value of 0xFFFFFFFD.

    -

    Enable signaling RBF with a specific nSequence value

    +

    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.

    -

    Set the current blockchain height.

    +

    Set the current blockchain height.

    This will be used to:

    1. Set the nLockTime for preventing fee sniping. @@ -182,12 +175,12 @@ If you want to create a transaction that spends immature coinbase inputs, manual add them using TxBuilder::add_utxos.

    In both cases, if you don’t provide a current height, we use the last sync height.

    -

    Set whether or not the dust limit is checked.

    +

    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.

    -

    Replace the recipients already added with a new list

    -

    Add a recipient to the internal list

    -

    Add data as an output, using OP_RETURN

    -

    Sets the address to drain excess coins to.

    +

    Replace the recipients already added with a new list

    +

    Add a recipient to the internal list

    +

    Add data as an output, using OP_RETURN

    +

    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 @@ -198,21 +191,21 @@ with add_recipientadd_utxos, or set drain_wallet to spend all of them.

    When bumping the fees of a transaction made with this option, you probably want to use allow_shrinking to allow this output to be reduced to pay for the extra fees.

    -
    Example
    +
    Example

    drain_to is very useful for draining all the coins in a wallet with drain_wallet to a single address.

    -
    let mut tx_builder = wallet.build_tx();
    +
    let mut tx_builder = wallet.build_tx();
     
    -tx_builder
    -    // Spend all outputs in this wallet.
    -    .drain_wallet()
    -    // Send the excess (which is all the coins minus the fee) to this address.
    -    .drain_to(to_address.script_pubkey())
    -    .fee_rate(FeeRate::from_sat_per_vb(5.0))
    -    .enable_rbf();
    -let (psbt, tx_details) = tx_builder.finish()?;
    -

    Explicitly tells the wallet that it is allowed to reduce the amount of the output matching this +tx_builder + // Spend all outputs in this wallet. + .drain_wallet() + // Send the excess (which is all the coins minus the fee) to this address. + .drain_to(to_address.script_pubkey()) + .fee_rate(FeeRate::from_sat_per_vb(5.0)) + .enable_rbf(); +let (psbt, tx_details) = tx_builder.finish()?;

    +

    Explicitly tells the wallet that it is allowed to reduce the amount of the output matching this script_pubkey in order to bump the transaction fee. Without specifying this the wallet will attempt to find a change output to shrink instead.

    Note that the output may shrink to below the dust limit and therefore be removed. If it is @@ -220,26 +213,8 @@ preserved then it is currently not guaranteed to be in the same position as it w originally.

    Returns an Err if script_pubkey can’t be found among the recipients of the transaction we are bumping.

    -

    Trait Implementations

    Returns a copy of the value. Read more

    -

    Performs copy-assignment from source. Read more

    -

    Formats the value using the given formatter. Read more

    -

    Auto Trait Implementations

    Blanket Implementations

    Gets the TypeId of self. Read more

    -

    Immutably borrows from an owned value. Read more

    -

    Mutably borrows from an owned value. Read more

    -

    Performs the conversion.

    -

    Performs the conversion.

    -

    The alignment of pointer.

    -

    The type for initializers.

    -

    Initializes a with the given initializer. Read more

    -

    Dereferences the given pointer. Read more

    -

    Mutably dereferences the given pointer. Read more

    -

    Drops the object pointed to by the given pointer. Read more

    -

    The resulting type after obtaining ownership.

    -

    Creates owned data from borrowed data, usually by cloning. Read more

    -
    🔬 This is a nightly-only experimental API. (toowned_clone_into)

    Uses borrowed data to replace owned data, usually by cloning. Read more

    -

    The type returned in the event of a conversion error.

    -

    Performs the conversion.

    -

    The type returned in the event of a conversion error.

    -

    Performs the conversion.

    -
    - \ No newline at end of file +

    Trait Implementations§

    Returns a copy of the value. Read more
    Performs copy-assignment from source. Read more
    Formats the value using the given formatter. Read more

    Auto Trait Implementations§

    Blanket Implementations§

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

    Returns the argument unchanged.

    +

    Calls U::from(self).

    +

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

    +
    The alignment of pointer.
    The type for initializers.
    Initializes a with the given initializer. Read more
    Dereferences the given pointer. Read more
    Mutably dereferences the given pointer. Read more
    Drops the object pointed to by the given pointer. Read more
    The resulting type after obtaining ownership.
    Creates owned data from borrowed data, usually by cloning. Read more
    Uses borrowed data to replace owned data, usually by cloning. Read more
    The type returned in the event of a conversion error.
    Performs the conversion.
    The type returned in the event of a conversion error.
    Performs the conversion.
    \ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/wallet/tx_builder/trait.TxBuilderContext.html b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/wallet/tx_builder/trait.TxBuilderContext.html index c201e5a0a0..6d53cb45bd 100644 --- a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/wallet/tx_builder/trait.TxBuilderContext.html +++ b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/wallet/tx_builder/trait.TxBuilderContext.html @@ -1,11 +1,3 @@ -TxBuilderContext in bdk::wallet::tx_builder - Rust - -
    pub trait TxBuilderContext: Debug + Default + Clone { }
    Expand description

    Context in which the TxBuilder is valid

    -

    Implementors

    - \ No newline at end of file +TxBuilderContext in bdk::wallet::tx_builder - Rust
    pub trait TxBuilderContext: Debug + Default + Clone { }
    Expand description

    Context in which the TxBuilder is valid

    +

    Implementors§

    \ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/wallet/verify/enum.VerifyError.html b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/wallet/verify/enum.VerifyError.html index 5b15fda6f6..c8bfffd04e 100644 --- a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/wallet/verify/enum.VerifyError.html +++ b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/wallet/verify/enum.VerifyError.html @@ -1,46 +1,18 @@ -VerifyError in bdk::wallet::verify - Rust - -
    pub enum VerifyError {
    +VerifyError in bdk::wallet::verify - Rust

    Enum bdk::wallet::verify::VerifyError

    source ·
    pub enum VerifyError {
         MissingInputTx(Txid),
         InvalidInput(OutPoint),
         Consensus(Error),
         Global(Box<Error>),
    -}
    This is supported on crate feature verify only.
    Expand description

    Error during validation of a tx agains the consensus rules

    -

    Variants

    MissingInputTx(Txid)

    The transaction being spent is not available in the database or the blockchain client

    -

    InvalidInput(OutPoint)

    The transaction being spent doesn’t have the requested output

    -

    Consensus(Error)

    Consensus error

    -

    Global(Box<Error>)

    Generic error

    +}
    Available on crate feature verify only.
    Expand description

    Error during validation of a tx agains the consensus rules

    +

    Variants§

    §

    MissingInputTx(Txid)

    The transaction being spent is not available in the database or the blockchain client

    +
    §

    InvalidInput(OutPoint)

    The transaction being spent doesn’t have the requested output

    +
    §

    Consensus(Error)

    Consensus error

    +
    §

    Global(Box<Error>)

    Generic error

    It has to be wrapped in a Box since Error has a variant that contains this enum

    -

    Trait Implementations

    Formats the value using the given formatter. Read more

    -

    Formats the value using the given formatter. Read more

    -

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

    -
    🔬 This is a nightly-only experimental API. (backtrace)

    Returns a stack backtrace, if available, of where this error occurred. Read more

    -
    👎 Deprecated since 1.42.0:

    use the Display impl or to_string()

    -
    👎 Deprecated since 1.33.0:

    replaced by Error::source, which can support downcasting

    -

    Performs the conversion.

    -

    Performs the conversion.

    -

    Performs the conversion.

    -

    Auto Trait Implementations

    Blanket Implementations

    Gets the TypeId of self. Read more

    -

    Immutably borrows from an owned value. Read more

    -

    Mutably borrows from an owned value. Read more

    -

    Performs the conversion.

    -

    Performs the conversion.

    -

    The alignment of pointer.

    -

    The type for initializers.

    -

    Initializes a with the given initializer. Read more

    -

    Dereferences the given pointer. Read more

    -

    Mutably dereferences the given pointer. Read more

    -

    Drops the object pointed to by the given pointer. Read more

    -

    Converts the given value to a String. Read more

    -

    The type returned in the event of a conversion error.

    -

    Performs the conversion.

    -

    The type returned in the event of a conversion error.

    -

    Performs the conversion.

    -
    - \ No newline at end of file +

    Trait Implementations§

    Formats the value using the given formatter. Read more
    Formats the value using the given formatter. Read more
    The lower-level source of this error, if any. Read more
    👎Deprecated since 1.42.0: use the Display impl or to_string()
    👎Deprecated since 1.33.0: replaced by Error::source, which can support downcasting
    🔬This is a nightly-only experimental API. (error_generic_member_access)
    Provides type based access to context intended for error reports. Read more
    Converts to this type from the input type.
    Converts to this type from the input type.
    Converts to this type from the input type.

    Auto Trait Implementations§

    Blanket Implementations§

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

    Returns the argument unchanged.

    +

    Calls U::from(self).

    +

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

    +
    The alignment of pointer.
    The type for initializers.
    Initializes a with the given initializer. Read more
    Dereferences the given pointer. Read more
    Mutably dereferences the given pointer. Read more
    Drops the object pointed to by the given pointer. Read more
    🔬This is a nightly-only experimental API. (provide_any)
    Data providers should implement this method to provide all values they are able to +provide by using demand. Read more
    Converts the given value to a String. Read more
    The type returned in the event of a conversion error.
    Performs the conversion.
    The type returned in the event of a conversion error.
    Performs the conversion.
    \ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/wallet/verify/fn.verify_tx.html b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/wallet/verify/fn.verify_tx.html index 8a42ab9968..fbd973e17d 100644 --- a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/wallet/verify/fn.verify_tx.html +++ b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/wallet/verify/fn.verify_tx.html @@ -1,16 +1,8 @@ -verify_tx in bdk::wallet::verify - Rust - -
    -

    Function bdk::wallet::verify::verify_tx

    source · []
    pub fn verify_tx<D: Database, B: GetTx>(
        tx: &Transaction,
        database: &D,
        blockchain: &B
    ) -> Result<(), VerifyError>
    This is supported on crate feature verify only.
    Expand description

    Verify a transaction against the consensus rules

    +verify_tx in bdk::wallet::verify - Rust

    Function bdk::wallet::verify::verify_tx

    source ·
    pub fn verify_tx<D: Database, B: GetTx>(
        tx: &Transaction,
        database: &D,
        blockchain: &B
    ) -> Result<(), VerifyError>
    Available on crate feature verify only.
    Expand description

    Verify a transaction against the consensus rules

    This function uses [bitcoinconsensus] to verify transactions by fetching the required data either from the Database or using the Blockchain.

    Depending on the capabilities of the Blockchain backend, the method could fail when called with old “historical” transactions or with unconfirmed transactions that have been evicted from the backend’s memory.

    -
    - \ No newline at end of file +
    \ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/wallet/verify/index.html b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/wallet/verify/index.html index 57ef056a7f..4a90044725 100644 --- a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/wallet/verify/index.html +++ b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/wallet/verify/index.html @@ -1,15 +1,3 @@ -bdk::wallet::verify - Rust - -
    -

    Module bdk::wallet::verify

    source · []
    This is supported on crate feature verify only.
    Expand description

    Verify transactions against the consensus rules

    -

    Enums

    -

    Error during validation of a tx agains the consensus rules

    -

    Functions

    -

    Verify a transaction against the consensus rules

    -
    - \ No newline at end of file +bdk::wallet::verify - Rust

    Module bdk::wallet::verify

    source ·
    Available on crate feature verify only.
    Expand description

    Verify transactions against the consensus rules

    +

    Enums

    Error during validation of a tx agains the consensus rules

    Functions

    Verify a transaction against the consensus rules
    \ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/wallet/verify/sidebar-items.js b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/wallet/verify/sidebar-items.js index a5421696ad..c93f31eca0 100644 --- a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/wallet/verify/sidebar-items.js +++ b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/bdk/wallet/verify/sidebar-items.js @@ -1 +1 @@ -initSidebarItems({"enum":[["VerifyError","Error during validation of a tx agains the consensus rules"]],"fn":[["verify_tx","Verify a transaction against the consensus rules"]]}); \ No newline at end of file +window.SIDEBAR_ITEMS = {"enum":[["VerifyError","Error during validation of a tx agains the consensus rules"]],"fn":[["verify_tx","Verify a transaction against the consensus rules"]]}; \ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/brush.svg b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/brush.svg deleted file mode 100644 index ea266e856a..0000000000 --- a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/brush.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/clipboard.svg b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/clipboard.svg deleted file mode 100644 index 8adbd99630..0000000000 --- a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/clipboard.svg +++ /dev/null @@ -1 +0,0 @@ - diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/dark.css b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/dark.css deleted file mode 100644 index 896e07f470..0000000000 --- a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/dark.css +++ /dev/null @@ -1 +0,0 @@ -body{background-color:#353535;color:#ddd;}h1,h2,h3,h4{color:#ddd;}h1.fqn{border-bottom-color:#d2d2d2;}h2,h3,h4{border-bottom-color:#d2d2d2;}.in-band{background-color:#353535;}.invisible{background:rgba(0,0,0,0);}.docblock code,.docblock-short code{background-color:#2A2A2A;}pre,.rustdoc.source .example-wrap{background-color:#2A2A2A;}.sidebar,.mobile-topbar,.sidebar-menu-toggle{background-color:#505050;}.rust-logo{filter:drop-shadow(1px 0 0px #fff) drop-shadow(0 1px 0 #fff) drop-shadow(-1px 0 0 #fff) drop-shadow(0 -1px 0 #fff)}*{scrollbar-color:rgb(64,65,67) #717171;}.sidebar{scrollbar-color:rgba(32,34,37,.6) #5a5a5a;}::-webkit-scrollbar-track{background-color:#717171;}::-webkit-scrollbar-thumb{background-color:rgba(32,34,37,.6);}.sidebar::-webkit-scrollbar-track{background-color:#717171;}.sidebar::-webkit-scrollbar-thumb{background-color:rgba(32,34,37,.6);}.sidebar .current{background-color:#333;}.source .sidebar{background-color:#565656;}.block a:hover{background:#444;}.line-numbers span{color:#3B91E2;}.line-numbers .line-highlighted{background-color:#0a042f !important;}.docblock h1,.docblock h2,.docblock h3,.docblock h4,.docblock h5,.docblock h6{border-bottom-color:#DDD;}.docblock table td,.docblock table th{border-color:#ddd;}.content .method .where,.content .fn .where,.content .where.fmt-newline{color:#ddd;}.search-results a:hover{background-color:#777;}.search-results a:focus{color:#eee !important;background-color:#616161;}.search-results a:focus span{color:#eee !important;}a.result-trait:focus{background-color:#013191;}a.result-traitalias:focus{background-color:#013191;}a.result-mod:focus,a.result-externcrate:focus{background-color:#884719;}a.result-enum:focus{background-color:#194e9f;}a.result-struct:focus{background-color:#194e9f;}a.result-union:focus{background-color:#194e9f;}a.result-fn:focus,a.result-method:focus,a.result-tymethod:focus{background-color:#4950ed;}a.result-type:focus{background-color:#194e9f;}a.result-associatedtype:focus{background-color:#884719;}a.result-foreigntype:focus{background-color:#194e9f;}a.result-attr:focus,a.result-derive:focus,a.result-macro:focus{background-color:#217d1c;}a.result-constant:focus,a.result-static:focus{background-color:#884719;}a.result-primitive:focus{background-color:#194e9f;}a.result-keyword:focus{background-color:#884719;}.content .item-info::before{color:#ccc;}.content span.enum,.content a.enum,.block a.current.enum{color:#2dbfb8;}.content span.struct,.content a.struct,.block a.current.struct{color:#2dbfb8;}.content span.type,.content a.type,.block a.current.type{color:#2dbfb8;}.content span.associatedtype,.content a.associatedtype,.block a.current.associatedtype{color:#D2991D;}.content span.foreigntype,.content a.foreigntype,.block a.current.foreigntype{color:#2dbfb8;}.content span.attr,.content a.attr,.block a.current.attr,.content span.derive,.content a.derive,.block a.current.derive,.content span.macro,.content a.macro,.block a.current.macro{color:#09bd00;}.content span.union,.content a.union,.block a.current.union{color:#2dbfb8;}.content span.constant,.content a.constant,.block a.current.constant,.content span.static,.content a.static,.block a.current.static{color:#D2991D;}.content span.primitive,.content a.primitive,.block a.current.primitive{color:#2dbfb8;}.content span.externcrate,.content span.mod,.content a.mod,.block a.current.mod{color:#D2991D;}.content span.trait,.content a.trait,.block a.current.trait{color:#b78cf2;}.content span.traitalias,.content a.traitalias,.block a.current.traitalias{color:#b78cf2;}.content span.fn,.content a.fn,.block a.current.fn,.content span.method,.content a.method,.block a.current.method,.content span.tymethod,.content a.tymethod,.block a.current.tymethod,.content .fnname{color:#2BAB63;}.content span.keyword,.content a.keyword,.block a.current.keyword{color:#D2991D;}.sidebar a{color:#fdbf35;}.sidebar a.current.enum{color:#12ece2;}.sidebar a.current.struct{color:#12ece2;}.sidebar a.current.type{color:#12ece2;}.sidebar a.current.associatedtype{color:#fdbf35;}.sidebar a.current.foreigntype{color:#12ece2;}.sidebar a.current.attr,.sidebar a.current.derive,.sidebar a.current.macro{color:#0be900;}.sidebar a.current.union{color:#12ece2;}.sidebar a.current.constant .sidebar a.current.static{color:#fdbf35;}.sidebar a.current.primitive{color:#12ece2;}.sidebar a.current.externcrate .sidebar a.current.mod{color:#fdbf35;}.sidebar a.current.trait{color:#cca7ff;}.sidebar a.current.traitalias{color:#cca7ff;}.sidebar a.current.fn,.sidebar a.current.method,.sidebar a.current.tymethod{color:#32d479;}.sidebar a.current.keyword{color:#fdbf35;}pre.rust .comment{color:#8d8d8b;}pre.rust .doccomment{color:#8ca375;}nav.main .current{border-top-color:#eee;border-bottom-color:#eee;}nav.main .separator{border-color:#eee;}a{color:#D2991D;}a#toggle-all-docs,a.anchor,.small-section-header a,#source-sidebar a,pre.rust a,.sidebar h2 a,.sidebar h3 a,.in-band a{color:#ddd;}.search-results a{color:#ddd;}a.test-arrow{color:#dedede;}body.source .example-wrap pre.rust a{background:#333;}details.rustdoc-toggle>summary.hideme>span,details.rustdoc-toggle>summary::before,details.undocumented>summary::before{color:#999;}details.rustdoc-toggle>summary::before,details.undocumented>summary::before{filter:invert(100%);}#crate-search,.search-input{color:#111;background-color:#f0f0f0;border-color:#000;}.search-input{border-color:#e0e0e0;}.search-input:focus{border-color:#008dfd;}.module-item .stab,.import-item .stab{color:#ddd;}.stab.unstable{background:#FFF5D6;border-color:#FFC600;color:#2f2f2f;}.stab.deprecated{background:#ffc4c4;border-color:#db7b7b;color:#2f2f2f;}.stab.portability{background:#F3DFFF;border-color:#b07bdb;color:#2f2f2f;}.stab.portability>code{background:none;}#help>div{background:#4d4d4d;border-color:#bfbfbf;}#help span.bottom,#help span.top{border-color:#bfbfbf;}#help dt{border-color:#bfbfbf;background:rgba(0,0,0,0);}.rightside,.out-of-band{color:grey;}.result-name .primitive>i,.result-name .keyword>i{color:#ddd;}.line-numbers :target{background-color:transparent;}pre.rust .kw{color:#ab8ac1;}pre.rust .kw-2,pre.rust .prelude-ty{color:#769acb;}pre.rust .number,pre.rust .string{color:#83a300;}pre.rust .self,pre.rust .bool-val,pre.rust .prelude-val,pre.rust .attribute,pre.rust .attribute .ident{color:#ee6868;}pre.rust .macro,pre.rust .macro-nonterminal{color:#3E999F;}pre.rust .lifetime{color:#d97f26;}pre.rust .question-mark{color:#ff9011;}.example-wrap>pre.line-number{border-color:#4a4949;}a.test-arrow{background-color:rgba(78,139,202,0.2);}a.test-arrow:hover{background-color:#4e8bca;}.toggle-label,.code-attribute{color:#999;}:target{background-color:#494a3d;border-right:3px solid #bb7410;}pre.compile_fail{border-left:2px solid rgba(255,0,0,.8);}pre.compile_fail:hover,.information:hover+pre.compile_fail{border-left:2px solid #f00;}pre.should_panic{border-left:2px solid rgba(255,0,0,.8);}pre.should_panic:hover,.information:hover+pre.should_panic{border-left:2px solid #f00;}pre.ignore{border-left:2px solid rgba(255,142,0,.6);}pre.ignore:hover,.information:hover+pre.ignore{border-left:2px solid #ff9200;}.tooltip.compile_fail{color:rgba(255,0,0,.8);}.information>.compile_fail:hover{color:#f00;}.tooltip.should_panic{color:rgba(255,0,0,.8);}.information>.should_panic:hover{color:#f00;}.tooltip.ignore{color:rgba(255,142,0,.6);}.information>.ignore:hover{color:#ff9200;}.search-failed a{color:#0089ff;}.tooltip::after{background-color:#000;color:#fff;border-color:#000;}.tooltip::before{border-color:transparent black transparent transparent;}.notable-traits-tooltiptext{background-color:#111;border-color:#777;}.notable-traits-tooltiptext .notable{border-bottom-color:#d2d2d2;}#titles>button:not(.selected){background-color:#252525;border-top-color:#252525;}#titles>button:hover,#titles>button.selected{border-top-color:#0089ff;background-color:#353535;}#titles>button>div.count{color:#888;}@media (max-width:700px){.sidebar-menu{background-color:#505050;border-bottom-color:#e0e0e0;border-right-color:#e0e0e0;}.sidebar-elems{background-color:#505050;border-right-color:#000;}#sidebar-filler{background-color:#505050;border-bottom-color:#e0e0e0;}}kbd{color:#000;background-color:#fafbfc;border-color:#d1d5da;border-bottom-color:#c6cbd1;box-shadow-color:#c6cbd1;}#theme-picker,#settings-menu,#help-button{border-color:#e0e0e0;background:#f0f0f0;color:#000;}#theme-picker:hover,#theme-picker:focus,#settings-menu:hover,#settings-menu:focus,#help-button:hover,#help-button:focus{border-color:#ffb900;}#copy-path{color:#999;}#copy-path>img{filter:invert(50%);}#copy-path:hover>img{filter:invert(65%);}#theme-choices{border-color:#e0e0e0;background-color:#353535;}#theme-choices>button:not(:first-child){border-top-color:#e0e0e0;}#theme-choices>button:hover,#theme-choices>button:focus{background-color:#4e4e4e;}@media (max-width:700px){#theme-picker{background:#f0f0f0;}}.search-results .result-name span.alias{color:#fff;}.search-results .result-name span.grey{color:#ccc;}#sidebar-toggle{background-color:#565656;}#sidebar-toggle:hover{background-color:#676767;}#source-sidebar{background-color:#565656;}#source-sidebar>.title{border-bottom-color:#ccc;}div.files>a:hover,div.name:hover{background-color:#444;}div.files>.selected{background-color:#333;}.setting-line>.title{border-bottom-color:#ddd;}.scraped-example .example-wrap .rust span.highlight{background:rgb(91,59,1);}.scraped-example .example-wrap .rust span.highlight.focus{background:rgb(124,75,15);}.scraped-example:not(.expanded) .code-wrapper:before{background:linear-gradient(to bottom,rgba(53,53,53,1),rgba(53,53,53,0));}.scraped-example:not(.expanded) .code-wrapper:after{background:linear-gradient(to top,rgba(53,53,53,1),rgba(53,53,53,0));}.toggle-line-inner{background:#616161;}.toggle-line:hover .toggle-line-inner{background:##898989;} \ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/down-arrow.svg b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/down-arrow.svg deleted file mode 100644 index 35437e77a7..0000000000 --- a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/down-arrow.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/favicon-16x16.png b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/favicon-16x16.png deleted file mode 100644 index ea4b45cae1..0000000000 Binary files a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/favicon-16x16.png and /dev/null differ diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/favicon-32x32.png b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/favicon-32x32.png deleted file mode 100644 index 69b8613ce1..0000000000 Binary files a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/favicon-32x32.png and /dev/null differ diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/favicon.svg b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/favicon.svg deleted file mode 100644 index 8b34b51198..0000000000 --- a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/favicon.svg +++ /dev/null @@ -1,24 +0,0 @@ - - - - - diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/help.html b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/help.html new file mode 100644 index 0000000000..700c7c3d65 --- /dev/null +++ b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/help.html @@ -0,0 +1,2 @@ +Rustdoc help

    Rustdoc help

    Back
    \ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/implementors/alloc/string/trait.ToString.js b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/implementors/alloc/string/trait.ToString.js index 1abb3dab25..ff48cc6583 100644 --- a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/implementors/alloc/string/trait.ToString.js +++ b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/implementors/alloc/string/trait.ToString.js @@ -1,3 +1,3 @@ -(function() {var implementors = {}; -implementors["bdk"] = [{"text":"impl ToString for FullyNodedExport","synthetic":false,"types":["bdk::wallet::export::FullyNodedExport"]}]; -if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file +(function() {var implementors = { +"bdk":[["impl ToString for FullyNodedExport"]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/implementors/bdk/blockchain/trait.Blockchain.js b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/implementors/bdk/blockchain/trait.Blockchain.js index 8262d3bea5..bb0690bde5 100644 --- a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/implementors/bdk/blockchain/trait.Blockchain.js +++ b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/implementors/bdk/blockchain/trait.Blockchain.js @@ -1,3 +1,3 @@ -(function() {var implementors = {}; -implementors["bdk"] = []; -if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file +(function() {var implementors = { +"bdk":[] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/implementors/bdk/blockchain/trait.BlockchainFactory.js b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/implementors/bdk/blockchain/trait.BlockchainFactory.js index 8262d3bea5..bb0690bde5 100644 --- a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/implementors/bdk/blockchain/trait.BlockchainFactory.js +++ b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/implementors/bdk/blockchain/trait.BlockchainFactory.js @@ -1,3 +1,3 @@ -(function() {var implementors = {}; -implementors["bdk"] = []; -if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file +(function() {var implementors = { +"bdk":[] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/implementors/bdk/blockchain/trait.ConfigurableBlockchain.js b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/implementors/bdk/blockchain/trait.ConfigurableBlockchain.js index 8262d3bea5..bb0690bde5 100644 --- a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/implementors/bdk/blockchain/trait.ConfigurableBlockchain.js +++ b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/implementors/bdk/blockchain/trait.ConfigurableBlockchain.js @@ -1,3 +1,3 @@ -(function() {var implementors = {}; -implementors["bdk"] = []; -if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file +(function() {var implementors = { +"bdk":[] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/implementors/bdk/blockchain/trait.GetBlockHash.js b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/implementors/bdk/blockchain/trait.GetBlockHash.js index 8262d3bea5..bb0690bde5 100644 --- a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/implementors/bdk/blockchain/trait.GetBlockHash.js +++ b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/implementors/bdk/blockchain/trait.GetBlockHash.js @@ -1,3 +1,3 @@ -(function() {var implementors = {}; -implementors["bdk"] = []; -if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file +(function() {var implementors = { +"bdk":[] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/implementors/bdk/blockchain/trait.GetHeight.js b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/implementors/bdk/blockchain/trait.GetHeight.js index 8262d3bea5..bb0690bde5 100644 --- a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/implementors/bdk/blockchain/trait.GetHeight.js +++ b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/implementors/bdk/blockchain/trait.GetHeight.js @@ -1,3 +1,3 @@ -(function() {var implementors = {}; -implementors["bdk"] = []; -if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file +(function() {var implementors = { +"bdk":[] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/implementors/bdk/blockchain/trait.GetTx.js b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/implementors/bdk/blockchain/trait.GetTx.js index 8262d3bea5..bb0690bde5 100644 --- a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/implementors/bdk/blockchain/trait.GetTx.js +++ b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/implementors/bdk/blockchain/trait.GetTx.js @@ -1,3 +1,3 @@ -(function() {var implementors = {}; -implementors["bdk"] = []; -if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file +(function() {var implementors = { +"bdk":[] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/implementors/bdk/blockchain/trait.Progress.js b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/implementors/bdk/blockchain/trait.Progress.js index 8262d3bea5..bb0690bde5 100644 --- a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/implementors/bdk/blockchain/trait.Progress.js +++ b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/implementors/bdk/blockchain/trait.Progress.js @@ -1,3 +1,3 @@ -(function() {var implementors = {}; -implementors["bdk"] = []; -if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file +(function() {var implementors = { +"bdk":[] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/implementors/bdk/blockchain/trait.StatelessBlockchain.js b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/implementors/bdk/blockchain/trait.StatelessBlockchain.js index 8262d3bea5..bb0690bde5 100644 --- a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/implementors/bdk/blockchain/trait.StatelessBlockchain.js +++ b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/implementors/bdk/blockchain/trait.StatelessBlockchain.js @@ -1,3 +1,3 @@ -(function() {var implementors = {}; -implementors["bdk"] = []; -if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file +(function() {var implementors = { +"bdk":[] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/implementors/bdk/blockchain/trait.WalletSync.js b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/implementors/bdk/blockchain/trait.WalletSync.js index 8262d3bea5..bb0690bde5 100644 --- a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/implementors/bdk/blockchain/trait.WalletSync.js +++ b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/implementors/bdk/blockchain/trait.WalletSync.js @@ -1,3 +1,3 @@ -(function() {var implementors = {}; -implementors["bdk"] = []; -if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file +(function() {var implementors = { +"bdk":[] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/implementors/bdk/database/trait.BatchDatabase.js b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/implementors/bdk/database/trait.BatchDatabase.js index 8262d3bea5..bb0690bde5 100644 --- a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/implementors/bdk/database/trait.BatchDatabase.js +++ b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/implementors/bdk/database/trait.BatchDatabase.js @@ -1,3 +1,3 @@ -(function() {var implementors = {}; -implementors["bdk"] = []; -if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file +(function() {var implementors = { +"bdk":[] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/implementors/bdk/database/trait.BatchOperations.js b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/implementors/bdk/database/trait.BatchOperations.js index 8262d3bea5..bb0690bde5 100644 --- a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/implementors/bdk/database/trait.BatchOperations.js +++ b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/implementors/bdk/database/trait.BatchOperations.js @@ -1,3 +1,3 @@ -(function() {var implementors = {}; -implementors["bdk"] = []; -if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file +(function() {var implementors = { +"bdk":[] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/implementors/bdk/database/trait.ConfigurableDatabase.js b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/implementors/bdk/database/trait.ConfigurableDatabase.js index 8262d3bea5..bb0690bde5 100644 --- a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/implementors/bdk/database/trait.ConfigurableDatabase.js +++ b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/implementors/bdk/database/trait.ConfigurableDatabase.js @@ -1,3 +1,3 @@ -(function() {var implementors = {}; -implementors["bdk"] = []; -if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file +(function() {var implementors = { +"bdk":[] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/implementors/bdk/database/trait.Database.js b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/implementors/bdk/database/trait.Database.js index 8262d3bea5..bb0690bde5 100644 --- a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/implementors/bdk/database/trait.Database.js +++ b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/implementors/bdk/database/trait.Database.js @@ -1,3 +1,3 @@ -(function() {var implementors = {}; -implementors["bdk"] = []; -if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file +(function() {var implementors = { +"bdk":[] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/implementors/bdk/descriptor/template/trait.DescriptorTemplate.js b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/implementors/bdk/descriptor/template/trait.DescriptorTemplate.js index 8262d3bea5..bb0690bde5 100644 --- a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/implementors/bdk/descriptor/template/trait.DescriptorTemplate.js +++ b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/implementors/bdk/descriptor/template/trait.DescriptorTemplate.js @@ -1,3 +1,3 @@ -(function() {var implementors = {}; -implementors["bdk"] = []; -if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file +(function() {var implementors = { +"bdk":[] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/implementors/bdk/descriptor/trait.ExtractPolicy.js b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/implementors/bdk/descriptor/trait.ExtractPolicy.js index 8262d3bea5..bb0690bde5 100644 --- a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/implementors/bdk/descriptor/trait.ExtractPolicy.js +++ b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/implementors/bdk/descriptor/trait.ExtractPolicy.js @@ -1,3 +1,3 @@ -(function() {var implementors = {}; -implementors["bdk"] = []; -if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file +(function() {var implementors = { +"bdk":[] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/implementors/bdk/descriptor/trait.IntoWalletDescriptor.js b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/implementors/bdk/descriptor/trait.IntoWalletDescriptor.js index 8262d3bea5..bb0690bde5 100644 --- a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/implementors/bdk/descriptor/trait.IntoWalletDescriptor.js +++ b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/implementors/bdk/descriptor/trait.IntoWalletDescriptor.js @@ -1,3 +1,3 @@ -(function() {var implementors = {}; -implementors["bdk"] = []; -if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file +(function() {var implementors = { +"bdk":[] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/implementors/bdk/keys/trait.DerivableKey.js b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/implementors/bdk/keys/trait.DerivableKey.js index 8262d3bea5..bb0690bde5 100644 --- a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/implementors/bdk/keys/trait.DerivableKey.js +++ b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/implementors/bdk/keys/trait.DerivableKey.js @@ -1,3 +1,3 @@ -(function() {var implementors = {}; -implementors["bdk"] = []; -if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file +(function() {var implementors = { +"bdk":[] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/implementors/bdk/keys/trait.ExtScriptContext.js b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/implementors/bdk/keys/trait.ExtScriptContext.js index 8262d3bea5..bb0690bde5 100644 --- a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/implementors/bdk/keys/trait.ExtScriptContext.js +++ b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/implementors/bdk/keys/trait.ExtScriptContext.js @@ -1,3 +1,3 @@ -(function() {var implementors = {}; -implementors["bdk"] = []; -if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file +(function() {var implementors = { +"bdk":[] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/implementors/bdk/keys/trait.GeneratableDefaultOptions.js b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/implementors/bdk/keys/trait.GeneratableDefaultOptions.js index 8262d3bea5..bb0690bde5 100644 --- a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/implementors/bdk/keys/trait.GeneratableDefaultOptions.js +++ b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/implementors/bdk/keys/trait.GeneratableDefaultOptions.js @@ -1,3 +1,3 @@ -(function() {var implementors = {}; -implementors["bdk"] = []; -if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file +(function() {var implementors = { +"bdk":[] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/implementors/bdk/keys/trait.GeneratableKey.js b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/implementors/bdk/keys/trait.GeneratableKey.js index 8262d3bea5..bb0690bde5 100644 --- a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/implementors/bdk/keys/trait.GeneratableKey.js +++ b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/implementors/bdk/keys/trait.GeneratableKey.js @@ -1,3 +1,3 @@ -(function() {var implementors = {}; -implementors["bdk"] = []; -if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file +(function() {var implementors = { +"bdk":[] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/implementors/bdk/keys/trait.IntoDescriptorKey.js b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/implementors/bdk/keys/trait.IntoDescriptorKey.js index 8262d3bea5..bb0690bde5 100644 --- a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/implementors/bdk/keys/trait.IntoDescriptorKey.js +++ b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/implementors/bdk/keys/trait.IntoDescriptorKey.js @@ -1,3 +1,3 @@ -(function() {var implementors = {}; -implementors["bdk"] = []; -if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file +(function() {var implementors = { +"bdk":[] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/implementors/bdk/keys/trait.ScriptContext.js b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/implementors/bdk/keys/trait.ScriptContext.js deleted file mode 100644 index 8262d3bea5..0000000000 --- a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/implementors/bdk/keys/trait.ScriptContext.js +++ /dev/null @@ -1,3 +0,0 @@ -(function() {var implementors = {}; -implementors["bdk"] = []; -if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/implementors/bdk/psbt/trait.PsbtUtils.js b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/implementors/bdk/psbt/trait.PsbtUtils.js index 8262d3bea5..bb0690bde5 100644 --- a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/implementors/bdk/psbt/trait.PsbtUtils.js +++ b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/implementors/bdk/psbt/trait.PsbtUtils.js @@ -1,3 +1,3 @@ -(function() {var implementors = {}; -implementors["bdk"] = []; -if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file +(function() {var implementors = { +"bdk":[] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/implementors/bdk/trait.Vbytes.js b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/implementors/bdk/trait.Vbytes.js deleted file mode 100644 index 8262d3bea5..0000000000 --- a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/implementors/bdk/trait.Vbytes.js +++ /dev/null @@ -1,3 +0,0 @@ -(function() {var implementors = {}; -implementors["bdk"] = []; -if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/implementors/bdk/types/trait.Vbytes.js b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/implementors/bdk/types/trait.Vbytes.js new file mode 100644 index 0000000000..bb0690bde5 --- /dev/null +++ b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/implementors/bdk/types/trait.Vbytes.js @@ -0,0 +1,3 @@ +(function() {var implementors = { +"bdk":[] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/implementors/bdk/wallet/coin_selection/trait.CoinSelectionAlgorithm.js b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/implementors/bdk/wallet/coin_selection/trait.CoinSelectionAlgorithm.js index 8262d3bea5..bb0690bde5 100644 --- a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/implementors/bdk/wallet/coin_selection/trait.CoinSelectionAlgorithm.js +++ b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/implementors/bdk/wallet/coin_selection/trait.CoinSelectionAlgorithm.js @@ -1,3 +1,3 @@ -(function() {var implementors = {}; -implementors["bdk"] = []; -if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file +(function() {var implementors = { +"bdk":[] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/implementors/bdk/wallet/signer/trait.InputSigner.js b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/implementors/bdk/wallet/signer/trait.InputSigner.js index 8262d3bea5..bb0690bde5 100644 --- a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/implementors/bdk/wallet/signer/trait.InputSigner.js +++ b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/implementors/bdk/wallet/signer/trait.InputSigner.js @@ -1,3 +1,3 @@ -(function() {var implementors = {}; -implementors["bdk"] = []; -if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file +(function() {var implementors = { +"bdk":[] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/implementors/bdk/wallet/signer/trait.SignerCommon.js b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/implementors/bdk/wallet/signer/trait.SignerCommon.js index 8262d3bea5..bb0690bde5 100644 --- a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/implementors/bdk/wallet/signer/trait.SignerCommon.js +++ b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/implementors/bdk/wallet/signer/trait.SignerCommon.js @@ -1,3 +1,3 @@ -(function() {var implementors = {}; -implementors["bdk"] = []; -if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file +(function() {var implementors = { +"bdk":[] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/implementors/bdk/wallet/signer/trait.TransactionSigner.js b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/implementors/bdk/wallet/signer/trait.TransactionSigner.js index 8262d3bea5..bb0690bde5 100644 --- a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/implementors/bdk/wallet/signer/trait.TransactionSigner.js +++ b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/implementors/bdk/wallet/signer/trait.TransactionSigner.js @@ -1,3 +1,3 @@ -(function() {var implementors = {}; -implementors["bdk"] = []; -if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file +(function() {var implementors = { +"bdk":[] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/implementors/bdk/wallet/trait.IsDust.js b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/implementors/bdk/wallet/trait.IsDust.js deleted file mode 100644 index 8262d3bea5..0000000000 --- a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/implementors/bdk/wallet/trait.IsDust.js +++ /dev/null @@ -1,3 +0,0 @@ -(function() {var implementors = {}; -implementors["bdk"] = []; -if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/implementors/bdk/wallet/tx_builder/trait.TxBuilderContext.js b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/implementors/bdk/wallet/tx_builder/trait.TxBuilderContext.js index 8262d3bea5..bb0690bde5 100644 --- a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/implementors/bdk/wallet/tx_builder/trait.TxBuilderContext.js +++ b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/implementors/bdk/wallet/tx_builder/trait.TxBuilderContext.js @@ -1,3 +1,3 @@ -(function() {var implementors = {}; -implementors["bdk"] = []; -if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file +(function() {var implementors = { +"bdk":[] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/implementors/bdk/wallet/utils/trait.IsDust.js b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/implementors/bdk/wallet/utils/trait.IsDust.js new file mode 100644 index 0000000000..bb0690bde5 --- /dev/null +++ b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/implementors/bdk/wallet/utils/trait.IsDust.js @@ -0,0 +1,3 @@ +(function() {var implementors = { +"bdk":[] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/implementors/core/clone/trait.Clone.js b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/implementors/core/clone/trait.Clone.js index f53bcf3ca8..f9f37ca62e 100644 --- a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/implementors/core/clone/trait.Clone.js +++ b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/implementors/core/clone/trait.Clone.js @@ -1,3 +1,3 @@ -(function() {var implementors = {}; -implementors["bdk"] = [{"text":"impl Clone for AnyBlockchainConfig","synthetic":false,"types":["bdk::blockchain::any::AnyBlockchainConfig"]},{"text":"impl Clone for ElectrumBlockchainConfig","synthetic":false,"types":["bdk::blockchain::electrum::ElectrumBlockchainConfig"]},{"text":"impl Clone for RpcConfig","synthetic":false,"types":["bdk::blockchain::rpc::RpcConfig"]},{"text":"impl Clone for RpcSyncParams","synthetic":false,"types":["bdk::blockchain::rpc::RpcSyncParams"]},{"text":"impl Clone for Auth","synthetic":false,"types":["bdk::blockchain::rpc::Auth"]},{"text":"impl Clone for RpcBlockchainFactory","synthetic":false,"types":["bdk::blockchain::rpc::RpcBlockchainFactory"]},{"text":"impl Clone for EsploraBlockchainConfig","synthetic":false,"types":["bdk::blockchain::esplora::EsploraBlockchainConfig"]},{"text":"impl Clone for BitcoinPeerConfig","synthetic":false,"types":["bdk::blockchain::compact_filters::BitcoinPeerConfig"]},{"text":"impl Clone for CompactFiltersBlockchainConfig","synthetic":false,"types":["bdk::blockchain::compact_filters::CompactFiltersBlockchainConfig"]},{"text":"impl Clone for Capability","synthetic":false,"types":["bdk::blockchain::Capability"]},{"text":"impl Clone for NoopProgress","synthetic":false,"types":["bdk::blockchain::NoopProgress"]},{"text":"impl Clone for LogProgress","synthetic":false,"types":["bdk::blockchain::LogProgress"]},{"text":"impl Clone for SyncTime","synthetic":false,"types":["bdk::database::SyncTime"]},{"text":"impl Clone for PkOrF","synthetic":false,"types":["bdk::descriptor::policy::PkOrF"]},{"text":"impl Clone for SatisfiableItem","synthetic":false,"types":["bdk::descriptor::policy::SatisfiableItem"]},{"text":"impl Clone for Satisfaction","synthetic":false,"types":["bdk::descriptor::policy::Satisfaction"]},{"text":"impl Clone for Policy","synthetic":false,"types":["bdk::descriptor::policy::Policy"]},{"text":"impl Clone for Condition","synthetic":false,"types":["bdk::descriptor::policy::Condition"]},{"text":"impl<'a> Clone for BuildSatisfaction<'a>","synthetic":false,"types":["bdk::descriptor::policy::BuildSatisfaction"]},{"text":"impl Clone for ScriptContextEnum","synthetic":false,"types":["bdk::keys::ScriptContextEnum"]},{"text":"impl<K: Clone, Ctx: ScriptContext> Clone for GeneratedKey<K, Ctx>","synthetic":false,"types":["bdk::keys::GeneratedKey"]},{"text":"impl Clone for PrivateKeyGenerateOptions","synthetic":false,"types":["bdk::keys::PrivateKeyGenerateOptions"]},{"text":"impl Clone for KeychainKind","synthetic":false,"types":["bdk::types::KeychainKind"]},{"text":"impl Clone for FeeRate","synthetic":false,"types":["bdk::types::FeeRate"]},{"text":"impl Clone for LocalUtxo","synthetic":false,"types":["bdk::types::LocalUtxo"]},{"text":"impl Clone for WeightedUtxo","synthetic":false,"types":["bdk::types::WeightedUtxo"]},{"text":"impl Clone for Utxo","synthetic":false,"types":["bdk::types::Utxo"]},{"text":"impl Clone for TransactionDetails","synthetic":false,"types":["bdk::types::TransactionDetails"]},{"text":"impl Clone for BlockTime","synthetic":false,"types":["bdk::types::BlockTime"]},{"text":"impl Clone for Balance","synthetic":false,"types":["bdk::types::Balance"]},{"text":"impl Clone for LargestFirstCoinSelection","synthetic":false,"types":["bdk::wallet::coin_selection::LargestFirstCoinSelection"]},{"text":"impl Clone for OldestFirstCoinSelection","synthetic":false,"types":["bdk::wallet::coin_selection::OldestFirstCoinSelection"]},{"text":"impl Clone for SignerId","synthetic":false,"types":["bdk::wallet::signer::SignerId"]},{"text":"impl Clone for SignerError","synthetic":false,"types":["bdk::wallet::signer::SignerError"]},{"text":"impl Clone for SignerContext","synthetic":false,"types":["bdk::wallet::signer::SignerContext"]},{"text":"impl<S: Clone + Sized + Debug + Clone> Clone for SignerWrapper<S>","synthetic":false,"types":["bdk::wallet::signer::SignerWrapper"]},{"text":"impl Clone for SignerOrdering","synthetic":false,"types":["bdk::wallet::signer::SignerOrdering"]},{"text":"impl Clone for SignersContainer","synthetic":false,"types":["bdk::wallet::signer::SignersContainer"]},{"text":"impl Clone for SignOptions","synthetic":false,"types":["bdk::wallet::signer::SignOptions"]},{"text":"impl Clone for TapLeavesOptions","synthetic":false,"types":["bdk::wallet::signer::TapLeavesOptions"]},{"text":"impl Clone for CreateTx","synthetic":false,"types":["bdk::wallet::tx_builder::CreateTx"]},{"text":"impl Clone for BumpFee","synthetic":false,"types":["bdk::wallet::tx_builder::BumpFee"]},{"text":"impl<'a, Cs: Clone, Ctx, D> Clone for TxBuilder<'a, D, Cs, Ctx>","synthetic":false,"types":["bdk::wallet::tx_builder::TxBuilder"]},{"text":"impl Clone for TxOrdering","synthetic":false,"types":["bdk::wallet::tx_builder::TxOrdering"]},{"text":"impl Clone for ChangeSpendPolicy","synthetic":false,"types":["bdk::wallet::tx_builder::ChangeSpendPolicy"]}]; -if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file +(function() {var implementors = { +"bdk":[["impl Clone for AnyBlockchainConfig"],["impl Clone for ElectrumBlockchainConfig"],["impl Clone for RpcConfig"],["impl Clone for RpcSyncParams"],["impl Clone for Auth"],["impl Clone for RpcBlockchainFactory"],["impl Clone for EsploraBlockchainConfig"],["impl Clone for BitcoinPeerConfig"],["impl Clone for CompactFiltersBlockchainConfig"],["impl Clone for Capability"],["impl Clone for NoopProgress"],["impl Clone for LogProgress"],["impl Clone for SyncTime"],["impl Clone for PkOrF"],["impl Clone for SatisfiableItem"],["impl Clone for Satisfaction"],["impl Clone for Policy"],["impl Clone for Condition"],["impl<'a> Clone for BuildSatisfaction<'a>"],["impl Clone for ScriptContextEnum"],["impl<K: Clone, Ctx: ScriptContext> Clone for GeneratedKey<K, Ctx>"],["impl Clone for PrivateKeyGenerateOptions"],["impl Clone for KeychainKind"],["impl Clone for FeeRate"],["impl Clone for LocalUtxo"],["impl Clone for WeightedUtxo"],["impl Clone for Utxo"],["impl Clone for TransactionDetails"],["impl Clone for BlockTime"],["impl Clone for Balance"],["impl Clone for LargestFirstCoinSelection"],["impl Clone for OldestFirstCoinSelection"],["impl Clone for SignerId"],["impl Clone for SignerError"],["impl Clone for SignerContext"],["impl<S: Clone + Sized + Debug + Clone> Clone for SignerWrapper<S>"],["impl Clone for SignerOrdering"],["impl Clone for SignersContainer"],["impl Clone for SignOptions"],["impl Clone for TapLeavesOptions"],["impl Clone for CreateTx"],["impl Clone for BumpFee"],["impl<'a, Cs: Clone, Ctx, D> Clone for TxBuilder<'a, D, Cs, Ctx>"],["impl Clone for TxOrdering"],["impl Clone for ChangeSpendPolicy"]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/implementors/core/cmp/trait.Eq.js b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/implementors/core/cmp/trait.Eq.js index 00c422007a..aa829b0d15 100644 --- a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/implementors/core/cmp/trait.Eq.js +++ b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/implementors/core/cmp/trait.Eq.js @@ -1,3 +1,3 @@ -(function() {var implementors = {}; -implementors["bdk"] = [{"text":"impl Eq for AnyBlockchainConfig","synthetic":false,"types":["bdk::blockchain::any::AnyBlockchainConfig"]},{"text":"impl Eq for ElectrumBlockchainConfig","synthetic":false,"types":["bdk::blockchain::electrum::ElectrumBlockchainConfig"]},{"text":"impl Eq for RpcConfig","synthetic":false,"types":["bdk::blockchain::rpc::RpcConfig"]},{"text":"impl Eq for RpcSyncParams","synthetic":false,"types":["bdk::blockchain::rpc::RpcSyncParams"]},{"text":"impl Eq for Auth","synthetic":false,"types":["bdk::blockchain::rpc::Auth"]},{"text":"impl Eq for EsploraBlockchainConfig","synthetic":false,"types":["bdk::blockchain::esplora::EsploraBlockchainConfig"]},{"text":"impl Eq for BitcoinPeerConfig","synthetic":false,"types":["bdk::blockchain::compact_filters::BitcoinPeerConfig"]},{"text":"impl Eq for CompactFiltersBlockchainConfig","synthetic":false,"types":["bdk::blockchain::compact_filters::CompactFiltersBlockchainConfig"]},{"text":"impl Eq for Capability","synthetic":false,"types":["bdk::blockchain::Capability"]},{"text":"impl Eq for PkOrF","synthetic":false,"types":["bdk::descriptor::policy::PkOrF"]},{"text":"impl Eq for SatisfiableItem","synthetic":false,"types":["bdk::descriptor::policy::SatisfiableItem"]},{"text":"impl Eq for Satisfaction","synthetic":false,"types":["bdk::descriptor::policy::Satisfaction"]},{"text":"impl Eq for Policy","synthetic":false,"types":["bdk::descriptor::policy::Policy"]},{"text":"impl Eq for Condition","synthetic":false,"types":["bdk::descriptor::policy::Condition"]},{"text":"impl Eq for PolicyError","synthetic":false,"types":["bdk::descriptor::policy::PolicyError"]},{"text":"impl Eq for ScriptContextEnum","synthetic":false,"types":["bdk::keys::ScriptContextEnum"]},{"text":"impl Eq for KeychainKind","synthetic":false,"types":["bdk::types::KeychainKind"]},{"text":"impl Eq for LocalUtxo","synthetic":false,"types":["bdk::types::LocalUtxo"]},{"text":"impl Eq for WeightedUtxo","synthetic":false,"types":["bdk::types::WeightedUtxo"]},{"text":"impl Eq for Utxo","synthetic":false,"types":["bdk::types::Utxo"]},{"text":"impl Eq for TransactionDetails","synthetic":false,"types":["bdk::types::TransactionDetails"]},{"text":"impl Eq for BlockTime","synthetic":false,"types":["bdk::types::BlockTime"]},{"text":"impl Eq for Balance","synthetic":false,"types":["bdk::types::Balance"]},{"text":"impl Eq for SignerId","synthetic":false,"types":["bdk::wallet::signer::SignerId"]},{"text":"impl Eq for SignerError","synthetic":false,"types":["bdk::wallet::signer::SignerError"]},{"text":"impl Eq for SignerContext","synthetic":false,"types":["bdk::wallet::signer::SignerContext"]},{"text":"impl Eq for SignerOrdering","synthetic":false,"types":["bdk::wallet::signer::SignerOrdering"]},{"text":"impl Eq for TapLeavesOptions","synthetic":false,"types":["bdk::wallet::signer::TapLeavesOptions"]},{"text":"impl Eq for TxOrdering","synthetic":false,"types":["bdk::wallet::tx_builder::TxOrdering"]},{"text":"impl Eq for ChangeSpendPolicy","synthetic":false,"types":["bdk::wallet::tx_builder::ChangeSpendPolicy"]},{"text":"impl Eq for AddressInfo","synthetic":false,"types":["bdk::wallet::AddressInfo"]}]; -if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file +(function() {var implementors = { +"bdk":[["impl Eq for AnyBlockchainConfig"],["impl Eq for ElectrumBlockchainConfig"],["impl Eq for RpcConfig"],["impl Eq for RpcSyncParams"],["impl Eq for Auth"],["impl Eq for EsploraBlockchainConfig"],["impl Eq for BitcoinPeerConfig"],["impl Eq for CompactFiltersBlockchainConfig"],["impl Eq for Capability"],["impl Eq for PkOrF"],["impl Eq for SatisfiableItem"],["impl Eq for Satisfaction"],["impl Eq for Policy"],["impl Eq for Condition"],["impl Eq for PolicyError"],["impl Eq for ScriptContextEnum"],["impl Eq for KeychainKind"],["impl Eq for LocalUtxo"],["impl Eq for WeightedUtxo"],["impl Eq for Utxo"],["impl Eq for TransactionDetails"],["impl Eq for BlockTime"],["impl Eq for Balance"],["impl Eq for SignerId"],["impl Eq for SignerError"],["impl Eq for SignerContext"],["impl Eq for SignerOrdering"],["impl Eq for TapLeavesOptions"],["impl Eq for TxOrdering"],["impl Eq for ChangeSpendPolicy"],["impl Eq for AddressInfo"]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/implementors/core/cmp/trait.Ord.js b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/implementors/core/cmp/trait.Ord.js index 4d281f26e6..808a6ea512 100644 --- a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/implementors/core/cmp/trait.Ord.js +++ b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/implementors/core/cmp/trait.Ord.js @@ -1,3 +1,3 @@ -(function() {var implementors = {}; -implementors["bdk"] = [{"text":"impl Ord for Auth","synthetic":false,"types":["bdk::blockchain::rpc::Auth"]},{"text":"impl Ord for SignerId","synthetic":false,"types":["bdk::wallet::signer::SignerId"]},{"text":"impl Ord for SignerOrdering","synthetic":false,"types":["bdk::wallet::signer::SignerOrdering"]},{"text":"impl Ord for TxOrdering","synthetic":false,"types":["bdk::wallet::tx_builder::TxOrdering"]},{"text":"impl Ord for ChangeSpendPolicy","synthetic":false,"types":["bdk::wallet::tx_builder::ChangeSpendPolicy"]}]; -if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file +(function() {var implementors = { +"bdk":[["impl Ord for Auth"],["impl Ord for SignerId"],["impl Ord for SignerOrdering"],["impl Ord for TxOrdering"],["impl Ord for ChangeSpendPolicy"]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/implementors/core/cmp/trait.PartialEq.js b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/implementors/core/cmp/trait.PartialEq.js index d56485b2fd..c14ade9e8d 100644 --- a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/implementors/core/cmp/trait.PartialEq.js +++ b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/implementors/core/cmp/trait.PartialEq.js @@ -1,3 +1,3 @@ -(function() {var implementors = {}; -implementors["bdk"] = [{"text":"impl PartialEq<AnyBlockchainConfig> for AnyBlockchainConfig","synthetic":false,"types":["bdk::blockchain::any::AnyBlockchainConfig"]},{"text":"impl PartialEq<ElectrumBlockchainConfig> for ElectrumBlockchainConfig","synthetic":false,"types":["bdk::blockchain::electrum::ElectrumBlockchainConfig"]},{"text":"impl PartialEq<RpcConfig> for RpcConfig","synthetic":false,"types":["bdk::blockchain::rpc::RpcConfig"]},{"text":"impl PartialEq<RpcSyncParams> for RpcSyncParams","synthetic":false,"types":["bdk::blockchain::rpc::RpcSyncParams"]},{"text":"impl PartialEq<Auth> for Auth","synthetic":false,"types":["bdk::blockchain::rpc::Auth"]},{"text":"impl PartialEq<EsploraBlockchainConfig> for EsploraBlockchainConfig","synthetic":false,"types":["bdk::blockchain::esplora::EsploraBlockchainConfig"]},{"text":"impl PartialEq<BitcoinPeerConfig> for BitcoinPeerConfig","synthetic":false,"types":["bdk::blockchain::compact_filters::BitcoinPeerConfig"]},{"text":"impl PartialEq<CompactFiltersBlockchainConfig> for CompactFiltersBlockchainConfig","synthetic":false,"types":["bdk::blockchain::compact_filters::CompactFiltersBlockchainConfig"]},{"text":"impl PartialEq<Capability> for Capability","synthetic":false,"types":["bdk::blockchain::Capability"]},{"text":"impl PartialEq<PkOrF> for PkOrF","synthetic":false,"types":["bdk::descriptor::policy::PkOrF"]},{"text":"impl PartialEq<SatisfiableItem> for SatisfiableItem","synthetic":false,"types":["bdk::descriptor::policy::SatisfiableItem"]},{"text":"impl PartialEq<Satisfaction> for Satisfaction","synthetic":false,"types":["bdk::descriptor::policy::Satisfaction"]},{"text":"impl PartialEq<Policy> for Policy","synthetic":false,"types":["bdk::descriptor::policy::Policy"]},{"text":"impl PartialEq<Condition> for Condition","synthetic":false,"types":["bdk::descriptor::policy::Condition"]},{"text":"impl PartialEq<PolicyError> for PolicyError","synthetic":false,"types":["bdk::descriptor::policy::PolicyError"]},{"text":"impl PartialEq<ScriptContextEnum> for ScriptContextEnum","synthetic":false,"types":["bdk::keys::ScriptContextEnum"]},{"text":"impl PartialEq<KeychainKind> for KeychainKind","synthetic":false,"types":["bdk::types::KeychainKind"]},{"text":"impl PartialEq<FeeRate> for FeeRate","synthetic":false,"types":["bdk::types::FeeRate"]},{"text":"impl PartialEq<LocalUtxo> for LocalUtxo","synthetic":false,"types":["bdk::types::LocalUtxo"]},{"text":"impl PartialEq<WeightedUtxo> for WeightedUtxo","synthetic":false,"types":["bdk::types::WeightedUtxo"]},{"text":"impl PartialEq<Utxo> for Utxo","synthetic":false,"types":["bdk::types::Utxo"]},{"text":"impl PartialEq<TransactionDetails> for TransactionDetails","synthetic":false,"types":["bdk::types::TransactionDetails"]},{"text":"impl PartialEq<BlockTime> for BlockTime","synthetic":false,"types":["bdk::types::BlockTime"]},{"text":"impl PartialEq<Balance> for Balance","synthetic":false,"types":["bdk::types::Balance"]},{"text":"impl PartialEq<SignerId> for SignerId","synthetic":false,"types":["bdk::wallet::signer::SignerId"]},{"text":"impl PartialEq<SignerError> for SignerError","synthetic":false,"types":["bdk::wallet::signer::SignerError"]},{"text":"impl PartialEq<SignerContext> for SignerContext","synthetic":false,"types":["bdk::wallet::signer::SignerContext"]},{"text":"impl PartialEq<SignerOrdering> for SignerOrdering","synthetic":false,"types":["bdk::wallet::signer::SignerOrdering"]},{"text":"impl PartialEq<TapLeavesOptions> for TapLeavesOptions","synthetic":false,"types":["bdk::wallet::signer::TapLeavesOptions"]},{"text":"impl PartialEq<TxOrdering> for TxOrdering","synthetic":false,"types":["bdk::wallet::tx_builder::TxOrdering"]},{"text":"impl PartialEq<ChangeSpendPolicy> for ChangeSpendPolicy","synthetic":false,"types":["bdk::wallet::tx_builder::ChangeSpendPolicy"]},{"text":"impl PartialEq<AddressInfo> for AddressInfo","synthetic":false,"types":["bdk::wallet::AddressInfo"]}]; -if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file +(function() {var implementors = { +"bdk":[["impl PartialEq<AnyBlockchainConfig> for AnyBlockchainConfig"],["impl PartialEq<ElectrumBlockchainConfig> for ElectrumBlockchainConfig"],["impl PartialEq<RpcConfig> for RpcConfig"],["impl PartialEq<RpcSyncParams> for RpcSyncParams"],["impl PartialEq<Auth> for Auth"],["impl PartialEq<EsploraBlockchainConfig> for EsploraBlockchainConfig"],["impl PartialEq<BitcoinPeerConfig> for BitcoinPeerConfig"],["impl PartialEq<CompactFiltersBlockchainConfig> for CompactFiltersBlockchainConfig"],["impl PartialEq<Capability> for Capability"],["impl PartialEq<PkOrF> for PkOrF"],["impl PartialEq<SatisfiableItem> for SatisfiableItem"],["impl PartialEq<Satisfaction> for Satisfaction"],["impl PartialEq<Policy> for Policy"],["impl PartialEq<Condition> for Condition"],["impl PartialEq<PolicyError> for PolicyError"],["impl PartialEq<ScriptContextEnum> for ScriptContextEnum"],["impl PartialEq<KeychainKind> for KeychainKind"],["impl PartialEq<FeeRate> for FeeRate"],["impl PartialEq<LocalUtxo> for LocalUtxo"],["impl PartialEq<WeightedUtxo> for WeightedUtxo"],["impl PartialEq<Utxo> for Utxo"],["impl PartialEq<TransactionDetails> for TransactionDetails"],["impl PartialEq<BlockTime> for BlockTime"],["impl PartialEq<Balance> for Balance"],["impl PartialEq<SignerId> for SignerId"],["impl PartialEq<SignerError> for SignerError"],["impl PartialEq<SignerContext> for SignerContext"],["impl PartialEq<SignerOrdering> for SignerOrdering"],["impl PartialEq<TapLeavesOptions> for TapLeavesOptions"],["impl PartialEq<TxOrdering> for TxOrdering"],["impl PartialEq<ChangeSpendPolicy> for ChangeSpendPolicy"],["impl PartialEq<AddressInfo> for AddressInfo"]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/implementors/core/cmp/trait.PartialOrd.js b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/implementors/core/cmp/trait.PartialOrd.js index c42572b6ee..42c992cb49 100644 --- a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/implementors/core/cmp/trait.PartialOrd.js +++ b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/implementors/core/cmp/trait.PartialOrd.js @@ -1,3 +1,3 @@ -(function() {var implementors = {}; -implementors["bdk"] = [{"text":"impl PartialOrd<Auth> for Auth","synthetic":false,"types":["bdk::blockchain::rpc::Auth"]},{"text":"impl PartialOrd<Condition> for Condition","synthetic":false,"types":["bdk::descriptor::policy::Condition"]},{"text":"impl PartialOrd<FeeRate> for FeeRate","synthetic":false,"types":["bdk::types::FeeRate"]},{"text":"impl PartialOrd<SignerId> for SignerId","synthetic":false,"types":["bdk::wallet::signer::SignerId"]},{"text":"impl PartialOrd<SignerOrdering> for SignerOrdering","synthetic":false,"types":["bdk::wallet::signer::SignerOrdering"]},{"text":"impl PartialOrd<TxOrdering> for TxOrdering","synthetic":false,"types":["bdk::wallet::tx_builder::TxOrdering"]},{"text":"impl PartialOrd<ChangeSpendPolicy> for ChangeSpendPolicy","synthetic":false,"types":["bdk::wallet::tx_builder::ChangeSpendPolicy"]}]; -if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file +(function() {var implementors = { +"bdk":[["impl PartialOrd<Auth> for Auth"],["impl PartialOrd<Condition> for Condition"],["impl PartialOrd<FeeRate> for FeeRate"],["impl PartialOrd<SignerId> for SignerId"],["impl PartialOrd<SignerOrdering> for SignerOrdering"],["impl PartialOrd<TxOrdering> for TxOrdering"],["impl PartialOrd<ChangeSpendPolicy> for ChangeSpendPolicy"]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/implementors/core/convert/trait.AsRef.js b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/implementors/core/convert/trait.AsRef.js index cc88354e83..cfe2be8162 100644 --- a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/implementors/core/convert/trait.AsRef.js +++ b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/implementors/core/convert/trait.AsRef.js @@ -1,3 +1,3 @@ -(function() {var implementors = {}; -implementors["bdk"] = [{"text":"impl AsRef<[u8]> for KeychainKind","synthetic":false,"types":["bdk::types::KeychainKind"]}]; -if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file +(function() {var implementors = { +"bdk":[["impl AsRef<[u8]> for KeychainKind"]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/implementors/core/convert/trait.From.js b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/implementors/core/convert/trait.From.js index 44e200d82a..391d56cb14 100644 --- a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/implementors/core/convert/trait.From.js +++ b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/implementors/core/convert/trait.From.js @@ -1,3 +1,3 @@ -(function() {var implementors = {}; -implementors["bdk"] = [{"text":"impl From<Error> for Error","synthetic":false,"types":["bdk::error::Error"]},{"text":"impl From<PolicyError> for Error","synthetic":false,"types":["bdk::error::Error"]},{"text":"impl From<SignerError> for Error","synthetic":false,"types":["bdk::error::Error"]},{"text":"impl From<KeyError> for Error","synthetic":false,"types":["bdk::error::Error"]},{"text":"impl From<Error> for Error","synthetic":false,"types":["bdk::error::Error"]},{"text":"impl From<Error> for Error","synthetic":false,"types":["bdk::error::Error"]},{"text":"impl From<Error> for Error","synthetic":false,"types":["bdk::error::Error"]},{"text":"impl From<Error> for Error","synthetic":false,"types":["bdk::error::Error"]},{"text":"impl From<Error> for Error","synthetic":false,"types":["bdk::error::Error"]},{"text":"impl From<Error> for Error","synthetic":false,"types":["bdk::error::Error"]},{"text":"impl From<Error> for Error","synthetic":false,"types":["bdk::error::Error"]},{"text":"impl From<PsbtParseError> for Error","synthetic":false,"types":["bdk::error::Error"]},{"text":"impl From<Error> for Error","synthetic":false,"types":["bdk::error::Error"]},{"text":"impl From<Error> for Error","synthetic":false,"types":["bdk::error::Error"]},{"text":"impl From<Error> for Error","synthetic":false,"types":["bdk::error::Error"]},{"text":"impl From<Error> for Error","synthetic":false,"types":["bdk::error::Error"]},{"text":"impl From<CompactFiltersError> for Error","synthetic":false,"types":["bdk::error::Error"]},{"text":"impl From<VerifyError> for Error","synthetic":false,"types":["bdk::error::Error"]},{"text":"impl From<Error> for Error","synthetic":false,"types":["bdk::error::Error"]},{"text":"impl From<ElectrumBlockchain> for AnyBlockchain","synthetic":false,"types":["bdk::blockchain::any::AnyBlockchain"]},{"text":"impl From<EsploraBlockchain> for AnyBlockchain","synthetic":false,"types":["bdk::blockchain::any::AnyBlockchain"]},{"text":"impl From<CompactFiltersBlockchain> for AnyBlockchain","synthetic":false,"types":["bdk::blockchain::any::AnyBlockchain"]},{"text":"impl From<RpcBlockchain> for AnyBlockchain","synthetic":false,"types":["bdk::blockchain::any::AnyBlockchain"]},{"text":"impl From<ElectrumBlockchainConfig> for AnyBlockchainConfig","synthetic":false,"types":["bdk::blockchain::any::AnyBlockchainConfig"]},{"text":"impl From<EsploraBlockchainConfig> for AnyBlockchainConfig","synthetic":false,"types":["bdk::blockchain::any::AnyBlockchainConfig"]},{"text":"impl From<CompactFiltersBlockchainConfig> for AnyBlockchainConfig","synthetic":false,"types":["bdk::blockchain::any::AnyBlockchainConfig"]},{"text":"impl From<RpcConfig> for AnyBlockchainConfig","synthetic":false,"types":["bdk::blockchain::any::AnyBlockchainConfig"]},{"text":"impl From<Client> for ElectrumBlockchain","synthetic":false,"types":["bdk::blockchain::electrum::ElectrumBlockchain"]},{"text":"impl From<Auth> for RpcAuth","synthetic":false,"types":["bitcoincore_rpc::client::Auth"]},{"text":"impl From<BlockTime> for BlockTime","synthetic":false,"types":["bdk::types::BlockTime"]},{"text":"impl From<Error> for CompactFiltersError","synthetic":false,"types":["bdk::blockchain::compact_filters::CompactFiltersError"]},{"text":"impl From<Error> for CompactFiltersError","synthetic":false,"types":["bdk::blockchain::compact_filters::CompactFiltersError"]},{"text":"impl From<Error> for CompactFiltersError","synthetic":false,"types":["bdk::blockchain::compact_filters::CompactFiltersError"]},{"text":"impl From<SystemTimeError> for CompactFiltersError","synthetic":false,"types":["bdk::blockchain::compact_filters::CompactFiltersError"]},{"text":"impl From<Error> for CompactFiltersError","synthetic":false,"types":["bdk::blockchain::compact_filters::CompactFiltersError"]},{"text":"impl From<MemoryDatabase> for AnyDatabase","synthetic":false,"types":["bdk::database::any::AnyDatabase"]},{"text":"impl From<Tree> for AnyDatabase","synthetic":false,"types":["bdk::database::any::AnyDatabase"]},{"text":"impl From<SqliteDatabase> for AnyDatabase","synthetic":false,"types":["bdk::database::any::AnyDatabase"]},{"text":"impl From<<MemoryDatabase as BatchDatabase>::Batch> for AnyBatch","synthetic":false,"types":["bdk::database::any::AnyBatch"]},{"text":"impl From<<Tree as BatchDatabase>::Batch> for AnyBatch","synthetic":false,"types":["bdk::database::any::AnyBatch"]},{"text":"impl From<<SqliteDatabase as BatchDatabase>::Batch> for AnyBatch","synthetic":false,"types":["bdk::database::any::AnyBatch"]},{"text":"impl From<()> for AnyDatabaseConfig","synthetic":false,"types":["bdk::database::any::AnyDatabaseConfig"]},{"text":"impl From<SledDbConfiguration> for AnyDatabaseConfig","synthetic":false,"types":["bdk::database::any::AnyDatabaseConfig"]},{"text":"impl From<SqliteDbConfiguration> for AnyDatabaseConfig","synthetic":false,"types":["bdk::database::any::AnyDatabaseConfig"]},{"text":"impl From<KeyError> for Error","synthetic":false,"types":["bdk::descriptor::error::Error"]},{"text":"impl From<Error> for Error","synthetic":false,"types":["bdk::descriptor::error::Error"]},{"text":"impl From<Error> for Error","synthetic":false,"types":["bdk::descriptor::error::Error"]},{"text":"impl From<Error> for Error","synthetic":false,"types":["bdk::descriptor::error::Error"]},{"text":"impl From<Error> for Error","synthetic":false,"types":["bdk::descriptor::error::Error"]},{"text":"impl From<Error> for Error","synthetic":false,"types":["bdk::descriptor::error::Error"]},{"text":"impl From<PolicyError> for Error","synthetic":false,"types":["bdk::descriptor::error::Error"]},{"text":"impl From<bool> for Satisfaction","synthetic":false,"types":["bdk::descriptor::policy::Satisfaction"]},{"text":"impl From<SatisfiableItem> for Policy","synthetic":false,"types":["bdk::descriptor::policy::Policy"]},{"text":"impl<Ctx: ScriptContext> From<ExtendedPubKey> for ExtendedKey<Ctx>","synthetic":false,"types":["bdk::keys::ExtendedKey"]},{"text":"impl<Ctx: ScriptContext> From<ExtendedPrivKey> for ExtendedKey<Ctx>","synthetic":false,"types":["bdk::keys::ExtendedKey"]},{"text":"impl From<Error> for KeyError","synthetic":false,"types":["bdk::keys::KeyError"]},{"text":"impl From<Error> for KeyError","synthetic":false,"types":["bdk::keys::KeyError"]},{"text":"impl From<Hash> for SignerId","synthetic":false,"types":["bdk::wallet::signer::SignerId"]},{"text":"impl From<Fingerprint> for SignerId","synthetic":false,"types":["bdk::wallet::signer::SignerId"]},{"text":"impl From<Error> for SignerError","synthetic":false,"types":["bdk::wallet::signer::SignerError"]},{"text":"impl From<Error> for SignerError","synthetic":false,"types":["bdk::wallet::signer::SignerError"]},{"text":"impl From<Error> for VerifyError","synthetic":false,"types":["bdk::wallet::verify::VerifyError"]},{"text":"impl From<Error> for VerifyError","synthetic":false,"types":["bdk::wallet::verify::VerifyError"]}]; -if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file +(function() {var implementors = { +"bdk":[["impl From<Error> for Error"],["impl From<PolicyError> for Error"],["impl From<SignerError> for Error"],["impl From<KeyError> for Error"],["impl From<Error> for Error"],["impl From<Error> for Error"],["impl From<Error> for Error"],["impl From<Error> for Error"],["impl From<Error> for Error"],["impl From<Error> for Error"],["impl From<Error> for Error"],["impl From<PsbtParseError> for Error"],["impl From<Error> for Error"],["impl From<Error> for Error"],["impl From<Error> for Error"],["impl From<Error> for Error"],["impl From<CompactFiltersError> for Error"],["impl From<VerifyError> for Error"],["impl From<Error> for Error"],["impl From<ElectrumBlockchain> for AnyBlockchain"],["impl From<EsploraBlockchain> for AnyBlockchain"],["impl From<CompactFiltersBlockchain> for AnyBlockchain"],["impl From<RpcBlockchain> for AnyBlockchain"],["impl From<ElectrumBlockchainConfig> for AnyBlockchainConfig"],["impl From<EsploraBlockchainConfig> for AnyBlockchainConfig"],["impl From<CompactFiltersBlockchainConfig> for AnyBlockchainConfig"],["impl From<RpcConfig> for AnyBlockchainConfig"],["impl From<Client> for ElectrumBlockchain"],["impl From<Auth> for RpcAuth"],["impl From<BlockTime> for BlockTime"],["impl From<Error> for CompactFiltersError"],["impl From<Error> for CompactFiltersError"],["impl From<Error> for CompactFiltersError"],["impl From<SystemTimeError> for CompactFiltersError"],["impl From<Error> for CompactFiltersError"],["impl From<MemoryDatabase> for AnyDatabase"],["impl From<Tree> for AnyDatabase"],["impl From<SqliteDatabase> for AnyDatabase"],["impl From<<MemoryDatabase as BatchDatabase>::Batch> for AnyBatch"],["impl From<<Tree as BatchDatabase>::Batch> for AnyBatch"],["impl From<<SqliteDatabase as BatchDatabase>::Batch> for AnyBatch"],["impl From<()> for AnyDatabaseConfig"],["impl From<SledDbConfiguration> for AnyDatabaseConfig"],["impl From<SqliteDbConfiguration> for AnyDatabaseConfig"],["impl From<KeyError> for Error"],["impl From<Error> for Error"],["impl From<Error> for Error"],["impl From<Error> for Error"],["impl From<Error> for Error"],["impl From<Error> for Error"],["impl From<PolicyError> for Error"],["impl From<bool> for Satisfaction"],["impl From<SatisfiableItem> for Policy"],["impl<Ctx: ScriptContext> From<ExtendedPubKey> for ExtendedKey<Ctx>"],["impl<Ctx: ScriptContext> From<ExtendedPrivKey> for ExtendedKey<Ctx>"],["impl From<Error> for KeyError"],["impl From<Error> for KeyError"],["impl From<Hash> for SignerId"],["impl From<Fingerprint> for SignerId"],["impl From<Error> for SignerError"],["impl From<Error> for SignerError"],["impl From<Error> for VerifyError"],["impl From<Error> for VerifyError"]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/implementors/core/default/trait.Default.js b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/implementors/core/default/trait.Default.js index 4534113581..a17b9ff950 100644 --- a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/implementors/core/default/trait.Default.js +++ b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/implementors/core/default/trait.Default.js @@ -1,3 +1,3 @@ -(function() {var implementors = {}; -implementors["bdk"] = [{"text":"impl Default for RpcSyncParams","synthetic":false,"types":["bdk::blockchain::rpc::RpcSyncParams"]},{"text":"impl Default for Mempool","synthetic":false,"types":["bdk::blockchain::compact_filters::peer::Mempool"]},{"text":"impl Default for NoopProgress","synthetic":false,"types":["bdk::blockchain::NoopProgress"]},{"text":"impl Default for LogProgress","synthetic":false,"types":["bdk::blockchain::LogProgress"]},{"text":"impl Default for MemoryDatabase","synthetic":false,"types":["bdk::database::memory::MemoryDatabase"]},{"text":"impl Default for Condition","synthetic":false,"types":["bdk::descriptor::policy::Condition"]},{"text":"impl Default for PrivateKeyGenerateOptions","synthetic":false,"types":["bdk::keys::PrivateKeyGenerateOptions"]},{"text":"impl Default for FeeRate","synthetic":false,"types":["bdk::types::FeeRate"]},{"text":"impl Default for BlockTime","synthetic":false,"types":["bdk::types::BlockTime"]},{"text":"impl Default for Balance","synthetic":false,"types":["bdk::types::Balance"]},{"text":"impl Default for LargestFirstCoinSelection","synthetic":false,"types":["bdk::wallet::coin_selection::LargestFirstCoinSelection"]},{"text":"impl Default for OldestFirstCoinSelection","synthetic":false,"types":["bdk::wallet::coin_selection::OldestFirstCoinSelection"]},{"text":"impl Default for BranchAndBoundCoinSelection","synthetic":false,"types":["bdk::wallet::coin_selection::BranchAndBoundCoinSelection"]},{"text":"impl Default for SignerOrdering","synthetic":false,"types":["bdk::wallet::signer::SignerOrdering"]},{"text":"impl Default for SignersContainer","synthetic":false,"types":["bdk::wallet::signer::SignersContainer"]},{"text":"impl Default for TapLeavesOptions","synthetic":false,"types":["bdk::wallet::signer::TapLeavesOptions"]},{"text":"impl Default for SignOptions","synthetic":false,"types":["bdk::wallet::signer::SignOptions"]},{"text":"impl Default for CreateTx","synthetic":false,"types":["bdk::wallet::tx_builder::CreateTx"]},{"text":"impl Default for BumpFee","synthetic":false,"types":["bdk::wallet::tx_builder::BumpFee"]},{"text":"impl Default for TxOrdering","synthetic":false,"types":["bdk::wallet::tx_builder::TxOrdering"]},{"text":"impl Default for ChangeSpendPolicy","synthetic":false,"types":["bdk::wallet::tx_builder::ChangeSpendPolicy"]},{"text":"impl Default for SyncOptions","synthetic":false,"types":["bdk::wallet::SyncOptions"]}]; -if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file +(function() {var implementors = { +"bdk":[["impl Default for RpcSyncParams"],["impl Default for Mempool"],["impl Default for NoopProgress"],["impl Default for LogProgress"],["impl Default for MemoryDatabase"],["impl Default for Condition"],["impl Default for PrivateKeyGenerateOptions"],["impl Default for FeeRate"],["impl Default for BlockTime"],["impl Default for Balance"],["impl Default for LargestFirstCoinSelection"],["impl Default for OldestFirstCoinSelection"],["impl Default for BranchAndBoundCoinSelection"],["impl Default for SignerOrdering"],["impl Default for SignersContainer"],["impl Default for TapLeavesOptions"],["impl Default for SignOptions"],["impl Default for CreateTx"],["impl Default for BumpFee"],["impl Default for TxOrdering"],["impl Default for ChangeSpendPolicy"],["impl Default for SyncOptions"]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/implementors/core/error/trait.Error.js b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/implementors/core/error/trait.Error.js new file mode 100644 index 0000000000..4d50be53a6 --- /dev/null +++ b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/implementors/core/error/trait.Error.js @@ -0,0 +1,3 @@ +(function() {var implementors = { +"bdk":[["impl Error for Error"],["impl Error for CompactFiltersError"],["impl Error for Error"],["impl Error for PolicyError"],["impl Error for KeyError"],["impl Error for SignerError"],["impl Error for VerifyError"]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/implementors/core/fmt/trait.Debug.js b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/implementors/core/fmt/trait.Debug.js index d0d145af98..655ad24360 100644 --- a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/implementors/core/fmt/trait.Debug.js +++ b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/implementors/core/fmt/trait.Debug.js @@ -1,3 +1,3 @@ -(function() {var implementors = {}; -implementors["bdk"] = [{"text":"impl Debug for Error","synthetic":false,"types":["bdk::error::Error"]},{"text":"impl Debug for AnyBlockchainConfig","synthetic":false,"types":["bdk::blockchain::any::AnyBlockchainConfig"]},{"text":"impl Debug for ElectrumBlockchainConfig","synthetic":false,"types":["bdk::blockchain::electrum::ElectrumBlockchainConfig"]},{"text":"impl Debug for RpcBlockchain","synthetic":false,"types":["bdk::blockchain::rpc::RpcBlockchain"]},{"text":"impl Debug for RpcConfig","synthetic":false,"types":["bdk::blockchain::rpc::RpcConfig"]},{"text":"impl Debug for RpcSyncParams","synthetic":false,"types":["bdk::blockchain::rpc::RpcSyncParams"]},{"text":"impl Debug for Auth","synthetic":false,"types":["bdk::blockchain::rpc::Auth"]},{"text":"impl Debug for RpcBlockchainFactory","synthetic":false,"types":["bdk::blockchain::rpc::RpcBlockchainFactory"]},{"text":"impl Debug for EsploraBlockchain","synthetic":false,"types":["bdk::blockchain::esplora::blocking::EsploraBlockchain"]},{"text":"impl Debug for EsploraBlockchainConfig","synthetic":false,"types":["bdk::blockchain::esplora::EsploraBlockchainConfig"]},{"text":"impl Debug for Mempool","synthetic":false,"types":["bdk::blockchain::compact_filters::peer::Mempool"]},{"text":"impl Debug for Peer","synthetic":false,"types":["bdk::blockchain::compact_filters::peer::Peer"]},{"text":"impl Debug for CompactFiltersBlockchain","synthetic":false,"types":["bdk::blockchain::compact_filters::CompactFiltersBlockchain"]},{"text":"impl Debug for BitcoinPeerConfig","synthetic":false,"types":["bdk::blockchain::compact_filters::BitcoinPeerConfig"]},{"text":"impl Debug for CompactFiltersBlockchainConfig","synthetic":false,"types":["bdk::blockchain::compact_filters::CompactFiltersBlockchainConfig"]},{"text":"impl Debug for CompactFiltersError","synthetic":false,"types":["bdk::blockchain::compact_filters::CompactFiltersError"]},{"text":"impl Debug for Capability","synthetic":false,"types":["bdk::blockchain::Capability"]},{"text":"impl Debug for NoopProgress","synthetic":false,"types":["bdk::blockchain::NoopProgress"]},{"text":"impl Debug for LogProgress","synthetic":false,"types":["bdk::blockchain::LogProgress"]},{"text":"impl Debug for AnyDatabase","synthetic":false,"types":["bdk::database::any::AnyDatabase"]},{"text":"impl Debug for SledDbConfiguration","synthetic":false,"types":["bdk::database::any::SledDbConfiguration"]},{"text":"impl Debug for SqliteDbConfiguration","synthetic":false,"types":["bdk::database::any::SqliteDbConfiguration"]},{"text":"impl Debug for AnyDatabaseConfig","synthetic":false,"types":["bdk::database::any::AnyDatabaseConfig"]},{"text":"impl Debug for SqliteDatabase","synthetic":false,"types":["bdk::database::sqlite::SqliteDatabase"]},{"text":"impl Debug for MemoryDatabase","synthetic":false,"types":["bdk::database::memory::MemoryDatabase"]},{"text":"impl Debug for SyncTime","synthetic":false,"types":["bdk::database::SyncTime"]},{"text":"impl Debug for Error","synthetic":false,"types":["bdk::descriptor::error::Error"]},{"text":"impl Debug for PkOrF","synthetic":false,"types":["bdk::descriptor::policy::PkOrF"]},{"text":"impl Debug for SatisfiableItem","synthetic":false,"types":["bdk::descriptor::policy::SatisfiableItem"]},{"text":"impl Debug for Satisfaction","synthetic":false,"types":["bdk::descriptor::policy::Satisfaction"]},{"text":"impl Debug for Policy","synthetic":false,"types":["bdk::descriptor::policy::Policy"]},{"text":"impl Debug for Condition","synthetic":false,"types":["bdk::descriptor::policy::Condition"]},{"text":"impl Debug for PolicyError","synthetic":false,"types":["bdk::descriptor::policy::PolicyError"]},{"text":"impl<'a> Debug for BuildSatisfaction<'a>","synthetic":false,"types":["bdk::descriptor::policy::BuildSatisfaction"]},{"text":"impl<Ctx: Debug + ScriptContext> Debug for DescriptorKey<Ctx>","synthetic":false,"types":["bdk::keys::DescriptorKey"]},{"text":"impl Debug for ScriptContextEnum","synthetic":false,"types":["bdk::keys::ScriptContextEnum"]},{"text":"impl Debug for PrivateKeyGenerateOptions","synthetic":false,"types":["bdk::keys::PrivateKeyGenerateOptions"]},{"text":"impl Debug for KeyError","synthetic":false,"types":["bdk::keys::KeyError"]},{"text":"impl Debug for KeychainKind","synthetic":false,"types":["bdk::types::KeychainKind"]},{"text":"impl Debug for FeeRate","synthetic":false,"types":["bdk::types::FeeRate"]},{"text":"impl Debug for LocalUtxo","synthetic":false,"types":["bdk::types::LocalUtxo"]},{"text":"impl Debug for WeightedUtxo","synthetic":false,"types":["bdk::types::WeightedUtxo"]},{"text":"impl Debug for Utxo","synthetic":false,"types":["bdk::types::Utxo"]},{"text":"impl Debug for TransactionDetails","synthetic":false,"types":["bdk::types::TransactionDetails"]},{"text":"impl Debug for BlockTime","synthetic":false,"types":["bdk::types::BlockTime"]},{"text":"impl Debug for Balance","synthetic":false,"types":["bdk::types::Balance"]},{"text":"impl Debug for Excess","synthetic":false,"types":["bdk::wallet::coin_selection::Excess"]},{"text":"impl Debug for CoinSelectionResult","synthetic":false,"types":["bdk::wallet::coin_selection::CoinSelectionResult"]},{"text":"impl Debug for LargestFirstCoinSelection","synthetic":false,"types":["bdk::wallet::coin_selection::LargestFirstCoinSelection"]},{"text":"impl Debug for OldestFirstCoinSelection","synthetic":false,"types":["bdk::wallet::coin_selection::OldestFirstCoinSelection"]},{"text":"impl Debug for BranchAndBoundCoinSelection","synthetic":false,"types":["bdk::wallet::coin_selection::BranchAndBoundCoinSelection"]},{"text":"impl Debug for FullyNodedExport","synthetic":false,"types":["bdk::wallet::export::FullyNodedExport"]},{"text":"impl Debug for SignerId","synthetic":false,"types":["bdk::wallet::signer::SignerId"]},{"text":"impl Debug for SignerError","synthetic":false,"types":["bdk::wallet::signer::SignerError"]},{"text":"impl Debug for SignerContext","synthetic":false,"types":["bdk::wallet::signer::SignerContext"]},{"text":"impl<S: Debug + Sized + Debug + Clone> Debug for SignerWrapper<S>","synthetic":false,"types":["bdk::wallet::signer::SignerWrapper"]},{"text":"impl Debug for SignerOrdering","synthetic":false,"types":["bdk::wallet::signer::SignerOrdering"]},{"text":"impl Debug for SignersContainer","synthetic":false,"types":["bdk::wallet::signer::SignersContainer"]},{"text":"impl Debug for SignOptions","synthetic":false,"types":["bdk::wallet::signer::SignOptions"]},{"text":"impl Debug for TapLeavesOptions","synthetic":false,"types":["bdk::wallet::signer::TapLeavesOptions"]},{"text":"impl Debug for CreateTx","synthetic":false,"types":["bdk::wallet::tx_builder::CreateTx"]},{"text":"impl Debug for BumpFee","synthetic":false,"types":["bdk::wallet::tx_builder::BumpFee"]},{"text":"impl<'a, D: Debug, Cs: Debug, Ctx: Debug> Debug for TxBuilder<'a, D, Cs, Ctx>","synthetic":false,"types":["bdk::wallet::tx_builder::TxBuilder"]},{"text":"impl Debug for TxOrdering","synthetic":false,"types":["bdk::wallet::tx_builder::TxOrdering"]},{"text":"impl Debug for ChangeSpendPolicy","synthetic":false,"types":["bdk::wallet::tx_builder::ChangeSpendPolicy"]},{"text":"impl Debug for VerifyError","synthetic":false,"types":["bdk::wallet::verify::VerifyError"]},{"text":"impl Debug for HWISigner","synthetic":false,"types":["bdk::wallet::hardwaresigner::HWISigner"]},{"text":"impl<D: Debug> Debug for Wallet<D>","synthetic":false,"types":["bdk::wallet::Wallet"]},{"text":"impl Debug for AddressIndex","synthetic":false,"types":["bdk::wallet::AddressIndex"]},{"text":"impl Debug for AddressInfo","synthetic":false,"types":["bdk::wallet::AddressInfo"]},{"text":"impl Debug for SyncOptions","synthetic":false,"types":["bdk::wallet::SyncOptions"]}]; -if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file +(function() {var implementors = { +"bdk":[["impl Debug for Error"],["impl Debug for AnyBlockchainConfig"],["impl Debug for ElectrumBlockchainConfig"],["impl Debug for RpcBlockchain"],["impl Debug for RpcConfig"],["impl Debug for RpcSyncParams"],["impl Debug for Auth"],["impl Debug for RpcBlockchainFactory"],["impl Debug for EsploraBlockchain"],["impl Debug for EsploraBlockchainConfig"],["impl Debug for Mempool"],["impl Debug for Peer"],["impl Debug for CompactFiltersBlockchain"],["impl Debug for BitcoinPeerConfig"],["impl Debug for CompactFiltersBlockchainConfig"],["impl Debug for CompactFiltersError"],["impl Debug for Capability"],["impl Debug for NoopProgress"],["impl Debug for LogProgress"],["impl Debug for AnyDatabase"],["impl Debug for SledDbConfiguration"],["impl Debug for SqliteDbConfiguration"],["impl Debug for AnyDatabaseConfig"],["impl Debug for SqliteDatabase"],["impl Debug for MemoryDatabase"],["impl Debug for SyncTime"],["impl Debug for Error"],["impl Debug for PkOrF"],["impl Debug for SatisfiableItem"],["impl Debug for Satisfaction"],["impl Debug for Policy"],["impl Debug for Condition"],["impl Debug for PolicyError"],["impl<'a> Debug for BuildSatisfaction<'a>"],["impl<Ctx: Debug + ScriptContext> Debug for DescriptorKey<Ctx>"],["impl Debug for ScriptContextEnum"],["impl Debug for PrivateKeyGenerateOptions"],["impl Debug for KeyError"],["impl Debug for KeychainKind"],["impl Debug for FeeRate"],["impl Debug for LocalUtxo"],["impl Debug for WeightedUtxo"],["impl Debug for Utxo"],["impl Debug for TransactionDetails"],["impl Debug for BlockTime"],["impl Debug for Balance"],["impl Debug for Excess"],["impl Debug for CoinSelectionResult"],["impl Debug for LargestFirstCoinSelection"],["impl Debug for OldestFirstCoinSelection"],["impl Debug for BranchAndBoundCoinSelection"],["impl Debug for FullyNodedExport"],["impl Debug for SignerId"],["impl Debug for SignerError"],["impl Debug for SignerContext"],["impl<S: Debug + Sized + Debug + Clone> Debug for SignerWrapper<S>"],["impl Debug for SignerOrdering"],["impl Debug for SignersContainer"],["impl Debug for SignOptions"],["impl Debug for TapLeavesOptions"],["impl Debug for CreateTx"],["impl Debug for BumpFee"],["impl<'a, D: Debug, Cs: Debug, Ctx: Debug> Debug for TxBuilder<'a, D, Cs, Ctx>"],["impl Debug for TxOrdering"],["impl Debug for ChangeSpendPolicy"],["impl Debug for VerifyError"],["impl Debug for HWISigner"],["impl<D: Debug> Debug for Wallet<D>"],["impl Debug for AddressIndex"],["impl Debug for AddressInfo"],["impl Debug for SyncOptions"]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/implementors/core/fmt/trait.Display.js b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/implementors/core/fmt/trait.Display.js index 9b68ced2fe..a53371ee26 100644 --- a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/implementors/core/fmt/trait.Display.js +++ b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/implementors/core/fmt/trait.Display.js @@ -1,3 +1,3 @@ -(function() {var implementors = {}; -implementors["bdk"] = [{"text":"impl Display for Error","synthetic":false,"types":["bdk::error::Error"]},{"text":"impl Display for CompactFiltersError","synthetic":false,"types":["bdk::blockchain::compact_filters::CompactFiltersError"]},{"text":"impl Display for Error","synthetic":false,"types":["bdk::descriptor::error::Error"]},{"text":"impl Display for PolicyError","synthetic":false,"types":["bdk::descriptor::policy::PolicyError"]},{"text":"impl Display for KeyError","synthetic":false,"types":["bdk::keys::KeyError"]},{"text":"impl Display for Balance","synthetic":false,"types":["bdk::types::Balance"]},{"text":"impl Display for SignerError","synthetic":false,"types":["bdk::wallet::signer::SignerError"]},{"text":"impl Display for VerifyError","synthetic":false,"types":["bdk::wallet::verify::VerifyError"]},{"text":"impl Display for AddressInfo","synthetic":false,"types":["bdk::wallet::AddressInfo"]}]; -if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file +(function() {var implementors = { +"bdk":[["impl Display for Error"],["impl Display for CompactFiltersError"],["impl Display for Error"],["impl Display for PolicyError"],["impl Display for KeyError"],["impl Display for Balance"],["impl Display for SignerError"],["impl Display for VerifyError"],["impl Display for AddressInfo"]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/implementors/core/hash/trait.Hash.js b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/implementors/core/hash/trait.Hash.js index 6c0dadb18d..5777e71c6f 100644 --- a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/implementors/core/hash/trait.Hash.js +++ b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/implementors/core/hash/trait.Hash.js @@ -1,3 +1,3 @@ -(function() {var implementors = {}; -implementors["bdk"] = [{"text":"impl Hash for Auth","synthetic":false,"types":["bdk::blockchain::rpc::Auth"]},{"text":"impl Hash for Capability","synthetic":false,"types":["bdk::blockchain::Capability"]},{"text":"impl Hash for PkOrF","synthetic":false,"types":["bdk::descriptor::policy::PkOrF"]},{"text":"impl Hash for Condition","synthetic":false,"types":["bdk::descriptor::policy::Condition"]},{"text":"impl Hash for KeychainKind","synthetic":false,"types":["bdk::types::KeychainKind"]},{"text":"impl Hash for LocalUtxo","synthetic":false,"types":["bdk::types::LocalUtxo"]},{"text":"impl Hash for SignerId","synthetic":false,"types":["bdk::wallet::signer::SignerId"]},{"text":"impl Hash for TxOrdering","synthetic":false,"types":["bdk::wallet::tx_builder::TxOrdering"]},{"text":"impl Hash for ChangeSpendPolicy","synthetic":false,"types":["bdk::wallet::tx_builder::ChangeSpendPolicy"]}]; -if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file +(function() {var implementors = { +"bdk":[["impl Hash for Auth"],["impl Hash for Capability"],["impl Hash for PkOrF"],["impl Hash for Condition"],["impl Hash for KeychainKind"],["impl Hash for LocalUtxo"],["impl Hash for SignerId"],["impl Hash for TxOrdering"],["impl Hash for ChangeSpendPolicy"]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/implementors/core/iter/traits/accum/trait.Sum.js b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/implementors/core/iter/traits/accum/trait.Sum.js index defaa9e9d4..b140d668cc 100644 --- a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/implementors/core/iter/traits/accum/trait.Sum.js +++ b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/implementors/core/iter/traits/accum/trait.Sum.js @@ -1,3 +1,3 @@ -(function() {var implementors = {}; -implementors["bdk"] = [{"text":"impl Sum<Balance> for Balance","synthetic":false,"types":["bdk::types::Balance"]}]; -if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file +(function() {var implementors = { +"bdk":[["impl Sum<Balance> for Balance"]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/implementors/core/marker/trait.Copy.js b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/implementors/core/marker/trait.Copy.js index 75eb26e6bc..0226f2c234 100644 --- a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/implementors/core/marker/trait.Copy.js +++ b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/implementors/core/marker/trait.Copy.js @@ -1,3 +1,3 @@ -(function() {var implementors = {}; -implementors["bdk"] = [{"text":"impl Copy for Capability","synthetic":false,"types":["bdk::blockchain::Capability"]},{"text":"impl Copy for NoopProgress","synthetic":false,"types":["bdk::blockchain::NoopProgress"]},{"text":"impl Copy for LogProgress","synthetic":false,"types":["bdk::blockchain::LogProgress"]},{"text":"impl Copy for Condition","synthetic":false,"types":["bdk::descriptor::policy::Condition"]},{"text":"impl<'a> Copy for BuildSatisfaction<'a>","synthetic":false,"types":["bdk::descriptor::policy::BuildSatisfaction"]},{"text":"impl Copy for ScriptContextEnum","synthetic":false,"types":["bdk::keys::ScriptContextEnum"]},{"text":"impl Copy for PrivateKeyGenerateOptions","synthetic":false,"types":["bdk::keys::PrivateKeyGenerateOptions"]},{"text":"impl Copy for KeychainKind","synthetic":false,"types":["bdk::types::KeychainKind"]},{"text":"impl Copy for FeeRate","synthetic":false,"types":["bdk::types::FeeRate"]},{"text":"impl Copy for LargestFirstCoinSelection","synthetic":false,"types":["bdk::wallet::coin_selection::LargestFirstCoinSelection"]},{"text":"impl Copy for OldestFirstCoinSelection","synthetic":false,"types":["bdk::wallet::coin_selection::OldestFirstCoinSelection"]},{"text":"impl Copy for SignerContext","synthetic":false,"types":["bdk::wallet::signer::SignerContext"]},{"text":"impl Copy for TxOrdering","synthetic":false,"types":["bdk::wallet::tx_builder::TxOrdering"]},{"text":"impl Copy for ChangeSpendPolicy","synthetic":false,"types":["bdk::wallet::tx_builder::ChangeSpendPolicy"]}]; -if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file +(function() {var implementors = { +"bdk":[["impl Copy for Capability"],["impl Copy for NoopProgress"],["impl Copy for LogProgress"],["impl Copy for Condition"],["impl<'a> Copy for BuildSatisfaction<'a>"],["impl Copy for ScriptContextEnum"],["impl Copy for PrivateKeyGenerateOptions"],["impl Copy for KeychainKind"],["impl Copy for FeeRate"],["impl Copy for LargestFirstCoinSelection"],["impl Copy for OldestFirstCoinSelection"],["impl Copy for SignerContext"],["impl Copy for TxOrdering"],["impl Copy for ChangeSpendPolicy"]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/implementors/core/marker/trait.Freeze.js b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/implementors/core/marker/trait.Freeze.js index 6b91f091fc..83946b5b28 100644 --- a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/implementors/core/marker/trait.Freeze.js +++ b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/implementors/core/marker/trait.Freeze.js @@ -1,3 +1,3 @@ -(function() {var implementors = {}; -implementors["bdk"] = [{"text":"impl Freeze for Error","synthetic":true,"types":["bdk::error::Error"]},{"text":"impl Freeze for AnyBlockchain","synthetic":true,"types":["bdk::blockchain::any::AnyBlockchain"]},{"text":"impl Freeze for AnyBlockchainConfig","synthetic":true,"types":["bdk::blockchain::any::AnyBlockchainConfig"]},{"text":"impl !Freeze for ElectrumBlockchain","synthetic":true,"types":["bdk::blockchain::electrum::ElectrumBlockchain"]},{"text":"impl Freeze for ElectrumBlockchainConfig","synthetic":true,"types":["bdk::blockchain::electrum::ElectrumBlockchainConfig"]},{"text":"impl !Freeze for RpcBlockchain","synthetic":true,"types":["bdk::blockchain::rpc::RpcBlockchain"]},{"text":"impl Freeze for RpcConfig","synthetic":true,"types":["bdk::blockchain::rpc::RpcConfig"]},{"text":"impl Freeze for RpcSyncParams","synthetic":true,"types":["bdk::blockchain::rpc::RpcSyncParams"]},{"text":"impl Freeze for Auth","synthetic":true,"types":["bdk::blockchain::rpc::Auth"]},{"text":"impl Freeze for RpcBlockchainFactory","synthetic":true,"types":["bdk::blockchain::rpc::RpcBlockchainFactory"]},{"text":"impl Freeze for EsploraBlockchain","synthetic":true,"types":["bdk::blockchain::esplora::blocking::EsploraBlockchain"]},{"text":"impl Freeze for EsploraBlockchainConfig","synthetic":true,"types":["bdk::blockchain::esplora::EsploraBlockchainConfig"]},{"text":"impl !Freeze for Mempool","synthetic":true,"types":["bdk::blockchain::compact_filters::peer::Mempool"]},{"text":"impl Freeze for Peer","synthetic":true,"types":["bdk::blockchain::compact_filters::peer::Peer"]},{"text":"impl Freeze for CompactFiltersBlockchain","synthetic":true,"types":["bdk::blockchain::compact_filters::CompactFiltersBlockchain"]},{"text":"impl Freeze for BitcoinPeerConfig","synthetic":true,"types":["bdk::blockchain::compact_filters::BitcoinPeerConfig"]},{"text":"impl Freeze for CompactFiltersBlockchainConfig","synthetic":true,"types":["bdk::blockchain::compact_filters::CompactFiltersBlockchainConfig"]},{"text":"impl Freeze for CompactFiltersError","synthetic":true,"types":["bdk::blockchain::compact_filters::CompactFiltersError"]},{"text":"impl Freeze for Capability","synthetic":true,"types":["bdk::blockchain::Capability"]},{"text":"impl Freeze for NoopProgress","synthetic":true,"types":["bdk::blockchain::NoopProgress"]},{"text":"impl Freeze for LogProgress","synthetic":true,"types":["bdk::blockchain::LogProgress"]},{"text":"impl !Freeze for AnyDatabase","synthetic":true,"types":["bdk::database::any::AnyDatabase"]},{"text":"impl !Freeze for AnyBatch","synthetic":true,"types":["bdk::database::any::AnyBatch"]},{"text":"impl Freeze for SledDbConfiguration","synthetic":true,"types":["bdk::database::any::SledDbConfiguration"]},{"text":"impl Freeze for SqliteDbConfiguration","synthetic":true,"types":["bdk::database::any::SqliteDbConfiguration"]},{"text":"impl Freeze for AnyDatabaseConfig","synthetic":true,"types":["bdk::database::any::AnyDatabaseConfig"]},{"text":"impl !Freeze for SqliteDatabase","synthetic":true,"types":["bdk::database::sqlite::SqliteDatabase"]},{"text":"impl Freeze for MemoryDatabase","synthetic":true,"types":["bdk::database::memory::MemoryDatabase"]},{"text":"impl Freeze for SyncTime","synthetic":true,"types":["bdk::database::SyncTime"]},{"text":"impl Freeze for Error","synthetic":true,"types":["bdk::descriptor::error::Error"]},{"text":"impl Freeze for PkOrF","synthetic":true,"types":["bdk::descriptor::policy::PkOrF"]},{"text":"impl Freeze for SatisfiableItem","synthetic":true,"types":["bdk::descriptor::policy::SatisfiableItem"]},{"text":"impl Freeze for Satisfaction","synthetic":true,"types":["bdk::descriptor::policy::Satisfaction"]},{"text":"impl Freeze for Policy","synthetic":true,"types":["bdk::descriptor::policy::Policy"]},{"text":"impl Freeze for Condition","synthetic":true,"types":["bdk::descriptor::policy::Condition"]},{"text":"impl Freeze for PolicyError","synthetic":true,"types":["bdk::descriptor::policy::PolicyError"]},{"text":"impl<'a> Freeze for BuildSatisfaction<'a>","synthetic":true,"types":["bdk::descriptor::policy::BuildSatisfaction"]},{"text":"impl<K> Freeze for P2Pkh<K> where
        K: Freeze, 
    ","synthetic":true,"types":["bdk::descriptor::template::P2Pkh"]},{"text":"impl<K> Freeze for P2Wpkh_P2Sh<K> where
        K: Freeze, 
    ","synthetic":true,"types":["bdk::descriptor::template::P2Wpkh_P2Sh"]},{"text":"impl<K> Freeze for P2Wpkh<K> where
        K: Freeze, 
    ","synthetic":true,"types":["bdk::descriptor::template::P2Wpkh"]},{"text":"impl<K> Freeze for Bip44<K> where
        K: Freeze, 
    ","synthetic":true,"types":["bdk::descriptor::template::Bip44"]},{"text":"impl<K> Freeze for Bip44Public<K> where
        K: Freeze, 
    ","synthetic":true,"types":["bdk::descriptor::template::Bip44Public"]},{"text":"impl<K> Freeze for Bip49<K> where
        K: Freeze, 
    ","synthetic":true,"types":["bdk::descriptor::template::Bip49"]},{"text":"impl<K> Freeze for Bip49Public<K> where
        K: Freeze, 
    ","synthetic":true,"types":["bdk::descriptor::template::Bip49Public"]},{"text":"impl<K> Freeze for Bip84<K> where
        K: Freeze, 
    ","synthetic":true,"types":["bdk::descriptor::template::Bip84"]},{"text":"impl<K> Freeze for Bip84Public<K> where
        K: Freeze, 
    ","synthetic":true,"types":["bdk::descriptor::template::Bip84Public"]},{"text":"impl Freeze for WordCount","synthetic":true,"types":["bdk::keys::bip39::WordCount"]},{"text":"impl<Ctx> Freeze for DescriptorKey<Ctx>","synthetic":true,"types":["bdk::keys::DescriptorKey"]},{"text":"impl Freeze for ScriptContextEnum","synthetic":true,"types":["bdk::keys::ScriptContextEnum"]},{"text":"impl<Ctx> Freeze for ExtendedKey<Ctx>","synthetic":true,"types":["bdk::keys::ExtendedKey"]},{"text":"impl<K, Ctx> Freeze for GeneratedKey<K, Ctx> where
        K: Freeze, 
    ","synthetic":true,"types":["bdk::keys::GeneratedKey"]},{"text":"impl Freeze for PrivateKeyGenerateOptions","synthetic":true,"types":["bdk::keys::PrivateKeyGenerateOptions"]},{"text":"impl Freeze for KeyError","synthetic":true,"types":["bdk::keys::KeyError"]},{"text":"impl Freeze for KeychainKind","synthetic":true,"types":["bdk::types::KeychainKind"]},{"text":"impl Freeze for FeeRate","synthetic":true,"types":["bdk::types::FeeRate"]},{"text":"impl Freeze for LocalUtxo","synthetic":true,"types":["bdk::types::LocalUtxo"]},{"text":"impl Freeze for WeightedUtxo","synthetic":true,"types":["bdk::types::WeightedUtxo"]},{"text":"impl Freeze for Utxo","synthetic":true,"types":["bdk::types::Utxo"]},{"text":"impl Freeze for TransactionDetails","synthetic":true,"types":["bdk::types::TransactionDetails"]},{"text":"impl Freeze for BlockTime","synthetic":true,"types":["bdk::types::BlockTime"]},{"text":"impl Freeze for Balance","synthetic":true,"types":["bdk::types::Balance"]},{"text":"impl Freeze for Excess","synthetic":true,"types":["bdk::wallet::coin_selection::Excess"]},{"text":"impl Freeze for CoinSelectionResult","synthetic":true,"types":["bdk::wallet::coin_selection::CoinSelectionResult"]},{"text":"impl Freeze for LargestFirstCoinSelection","synthetic":true,"types":["bdk::wallet::coin_selection::LargestFirstCoinSelection"]},{"text":"impl Freeze for OldestFirstCoinSelection","synthetic":true,"types":["bdk::wallet::coin_selection::OldestFirstCoinSelection"]},{"text":"impl Freeze for BranchAndBoundCoinSelection","synthetic":true,"types":["bdk::wallet::coin_selection::BranchAndBoundCoinSelection"]},{"text":"impl Freeze for FullyNodedExport","synthetic":true,"types":["bdk::wallet::export::FullyNodedExport"]},{"text":"impl Freeze for SignerId","synthetic":true,"types":["bdk::wallet::signer::SignerId"]},{"text":"impl Freeze for SignerError","synthetic":true,"types":["bdk::wallet::signer::SignerError"]},{"text":"impl Freeze for SignerContext","synthetic":true,"types":["bdk::wallet::signer::SignerContext"]},{"text":"impl<S> Freeze for SignerWrapper<S> where
        S: Freeze, 
    ","synthetic":true,"types":["bdk::wallet::signer::SignerWrapper"]},{"text":"impl Freeze for SignerOrdering","synthetic":true,"types":["bdk::wallet::signer::SignerOrdering"]},{"text":"impl Freeze for SignersContainer","synthetic":true,"types":["bdk::wallet::signer::SignersContainer"]},{"text":"impl Freeze for SignOptions","synthetic":true,"types":["bdk::wallet::signer::SignOptions"]},{"text":"impl Freeze for TapLeavesOptions","synthetic":true,"types":["bdk::wallet::signer::TapLeavesOptions"]},{"text":"impl Freeze for CreateTx","synthetic":true,"types":["bdk::wallet::tx_builder::CreateTx"]},{"text":"impl Freeze for BumpFee","synthetic":true,"types":["bdk::wallet::tx_builder::BumpFee"]},{"text":"impl<'a, D, Cs, Ctx> Freeze for TxBuilder<'a, D, Cs, Ctx> where
        Cs: Freeze, 
    ","synthetic":true,"types":["bdk::wallet::tx_builder::TxBuilder"]},{"text":"impl Freeze for TxOrdering","synthetic":true,"types":["bdk::wallet::tx_builder::TxOrdering"]},{"text":"impl Freeze for ChangeSpendPolicy","synthetic":true,"types":["bdk::wallet::tx_builder::ChangeSpendPolicy"]},{"text":"impl Freeze for VerifyError","synthetic":true,"types":["bdk::wallet::verify::VerifyError"]},{"text":"impl Freeze for HWISigner","synthetic":true,"types":["bdk::wallet::hardwaresigner::HWISigner"]},{"text":"impl<D> !Freeze for Wallet<D>","synthetic":true,"types":["bdk::wallet::Wallet"]},{"text":"impl Freeze for AddressIndex","synthetic":true,"types":["bdk::wallet::AddressIndex"]},{"text":"impl Freeze for AddressInfo","synthetic":true,"types":["bdk::wallet::AddressInfo"]},{"text":"impl Freeze for SyncOptions","synthetic":true,"types":["bdk::wallet::SyncOptions"]}]; -if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file +(function() {var implementors = { +"bdk":[["impl Freeze for Error",1,["bdk::error::Error"]],["impl Freeze for AnyBlockchain",1,["bdk::blockchain::any::AnyBlockchain"]],["impl Freeze for AnyBlockchainConfig",1,["bdk::blockchain::any::AnyBlockchainConfig"]],["impl !Freeze for ElectrumBlockchain",1,["bdk::blockchain::electrum::ElectrumBlockchain"]],["impl Freeze for ElectrumBlockchainConfig",1,["bdk::blockchain::electrum::ElectrumBlockchainConfig"]],["impl !Freeze for RpcBlockchain",1,["bdk::blockchain::rpc::RpcBlockchain"]],["impl Freeze for RpcConfig",1,["bdk::blockchain::rpc::RpcConfig"]],["impl Freeze for RpcSyncParams",1,["bdk::blockchain::rpc::RpcSyncParams"]],["impl Freeze for Auth",1,["bdk::blockchain::rpc::Auth"]],["impl Freeze for RpcBlockchainFactory",1,["bdk::blockchain::rpc::RpcBlockchainFactory"]],["impl Freeze for EsploraBlockchain",1,["bdk::blockchain::esplora::blocking::EsploraBlockchain"]],["impl Freeze for EsploraBlockchainConfig",1,["bdk::blockchain::esplora::EsploraBlockchainConfig"]],["impl !Freeze for Mempool",1,["bdk::blockchain::compact_filters::peer::Mempool"]],["impl Freeze for Peer",1,["bdk::blockchain::compact_filters::peer::Peer"]],["impl Freeze for CompactFiltersBlockchain",1,["bdk::blockchain::compact_filters::CompactFiltersBlockchain"]],["impl Freeze for BitcoinPeerConfig",1,["bdk::blockchain::compact_filters::BitcoinPeerConfig"]],["impl Freeze for CompactFiltersBlockchainConfig",1,["bdk::blockchain::compact_filters::CompactFiltersBlockchainConfig"]],["impl Freeze for CompactFiltersError",1,["bdk::blockchain::compact_filters::CompactFiltersError"]],["impl Freeze for Capability",1,["bdk::blockchain::Capability"]],["impl Freeze for NoopProgress",1,["bdk::blockchain::NoopProgress"]],["impl Freeze for LogProgress",1,["bdk::blockchain::LogProgress"]],["impl !Freeze for AnyDatabase",1,["bdk::database::any::AnyDatabase"]],["impl !Freeze for AnyBatch",1,["bdk::database::any::AnyBatch"]],["impl Freeze for SledDbConfiguration",1,["bdk::database::any::SledDbConfiguration"]],["impl Freeze for SqliteDbConfiguration",1,["bdk::database::any::SqliteDbConfiguration"]],["impl Freeze for AnyDatabaseConfig",1,["bdk::database::any::AnyDatabaseConfig"]],["impl !Freeze for SqliteDatabase",1,["bdk::database::sqlite::SqliteDatabase"]],["impl Freeze for MemoryDatabase",1,["bdk::database::memory::MemoryDatabase"]],["impl Freeze for SyncTime",1,["bdk::database::SyncTime"]],["impl Freeze for Error",1,["bdk::descriptor::error::Error"]],["impl Freeze for PkOrF",1,["bdk::descriptor::policy::PkOrF"]],["impl Freeze for SatisfiableItem",1,["bdk::descriptor::policy::SatisfiableItem"]],["impl Freeze for Satisfaction",1,["bdk::descriptor::policy::Satisfaction"]],["impl Freeze for Policy",1,["bdk::descriptor::policy::Policy"]],["impl Freeze for Condition",1,["bdk::descriptor::policy::Condition"]],["impl Freeze for PolicyError",1,["bdk::descriptor::policy::PolicyError"]],["impl<'a> Freeze for BuildSatisfaction<'a>",1,["bdk::descriptor::policy::BuildSatisfaction"]],["impl<K> Freeze for P2Pkh<K>where
        K: Freeze,
    ",1,["bdk::descriptor::template::P2Pkh"]],["impl<K> Freeze for P2Wpkh_P2Sh<K>where
        K: Freeze,
    ",1,["bdk::descriptor::template::P2Wpkh_P2Sh"]],["impl<K> Freeze for P2Wpkh<K>where
        K: Freeze,
    ",1,["bdk::descriptor::template::P2Wpkh"]],["impl<K> Freeze for Bip44<K>where
        K: Freeze,
    ",1,["bdk::descriptor::template::Bip44"]],["impl<K> Freeze for Bip44Public<K>where
        K: Freeze,
    ",1,["bdk::descriptor::template::Bip44Public"]],["impl<K> Freeze for Bip49<K>where
        K: Freeze,
    ",1,["bdk::descriptor::template::Bip49"]],["impl<K> Freeze for Bip49Public<K>where
        K: Freeze,
    ",1,["bdk::descriptor::template::Bip49Public"]],["impl<K> Freeze for Bip84<K>where
        K: Freeze,
    ",1,["bdk::descriptor::template::Bip84"]],["impl<K> Freeze for Bip84Public<K>where
        K: Freeze,
    ",1,["bdk::descriptor::template::Bip84Public"]],["impl Freeze for WordCount",1,["bdk::keys::bip39::WordCount"]],["impl<Ctx> Freeze for DescriptorKey<Ctx>",1,["bdk::keys::DescriptorKey"]],["impl Freeze for ScriptContextEnum",1,["bdk::keys::ScriptContextEnum"]],["impl<Ctx> Freeze for ExtendedKey<Ctx>",1,["bdk::keys::ExtendedKey"]],["impl<K, Ctx> Freeze for GeneratedKey<K, Ctx>where
        K: Freeze,
    ",1,["bdk::keys::GeneratedKey"]],["impl Freeze for PrivateKeyGenerateOptions",1,["bdk::keys::PrivateKeyGenerateOptions"]],["impl Freeze for KeyError",1,["bdk::keys::KeyError"]],["impl Freeze for KeychainKind",1,["bdk::types::KeychainKind"]],["impl Freeze for FeeRate",1,["bdk::types::FeeRate"]],["impl Freeze for LocalUtxo",1,["bdk::types::LocalUtxo"]],["impl Freeze for WeightedUtxo",1,["bdk::types::WeightedUtxo"]],["impl Freeze for Utxo",1,["bdk::types::Utxo"]],["impl Freeze for TransactionDetails",1,["bdk::types::TransactionDetails"]],["impl Freeze for BlockTime",1,["bdk::types::BlockTime"]],["impl Freeze for Balance",1,["bdk::types::Balance"]],["impl Freeze for Excess",1,["bdk::wallet::coin_selection::Excess"]],["impl Freeze for CoinSelectionResult",1,["bdk::wallet::coin_selection::CoinSelectionResult"]],["impl Freeze for LargestFirstCoinSelection",1,["bdk::wallet::coin_selection::LargestFirstCoinSelection"]],["impl Freeze for OldestFirstCoinSelection",1,["bdk::wallet::coin_selection::OldestFirstCoinSelection"]],["impl Freeze for BranchAndBoundCoinSelection",1,["bdk::wallet::coin_selection::BranchAndBoundCoinSelection"]],["impl Freeze for FullyNodedExport",1,["bdk::wallet::export::FullyNodedExport"]],["impl Freeze for SignerId",1,["bdk::wallet::signer::SignerId"]],["impl Freeze for SignerError",1,["bdk::wallet::signer::SignerError"]],["impl Freeze for SignerContext",1,["bdk::wallet::signer::SignerContext"]],["impl<S> Freeze for SignerWrapper<S>where
        S: Freeze,
    ",1,["bdk::wallet::signer::SignerWrapper"]],["impl Freeze for SignerOrdering",1,["bdk::wallet::signer::SignerOrdering"]],["impl Freeze for SignersContainer",1,["bdk::wallet::signer::SignersContainer"]],["impl Freeze for SignOptions",1,["bdk::wallet::signer::SignOptions"]],["impl Freeze for TapLeavesOptions",1,["bdk::wallet::signer::TapLeavesOptions"]],["impl Freeze for CreateTx",1,["bdk::wallet::tx_builder::CreateTx"]],["impl Freeze for BumpFee",1,["bdk::wallet::tx_builder::BumpFee"]],["impl<'a, D, Cs, Ctx> Freeze for TxBuilder<'a, D, Cs, Ctx>where
        Cs: Freeze,
    ",1,["bdk::wallet::tx_builder::TxBuilder"]],["impl Freeze for TxOrdering",1,["bdk::wallet::tx_builder::TxOrdering"]],["impl Freeze for ChangeSpendPolicy",1,["bdk::wallet::tx_builder::ChangeSpendPolicy"]],["impl Freeze for VerifyError",1,["bdk::wallet::verify::VerifyError"]],["impl Freeze for HWISigner",1,["bdk::wallet::hardwaresigner::HWISigner"]],["impl<D> !Freeze for Wallet<D>",1,["bdk::wallet::Wallet"]],["impl Freeze for AddressIndex",1,["bdk::wallet::AddressIndex"]],["impl Freeze for AddressInfo",1,["bdk::wallet::AddressInfo"]],["impl Freeze for SyncOptions",1,["bdk::wallet::SyncOptions"]]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/implementors/core/marker/trait.Send.js b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/implementors/core/marker/trait.Send.js index b0f8293796..7c0843885b 100644 --- a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/implementors/core/marker/trait.Send.js +++ b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/implementors/core/marker/trait.Send.js @@ -1,3 +1,3 @@ -(function() {var implementors = {}; -implementors["bdk"] = [{"text":"impl Send for Error","synthetic":true,"types":["bdk::error::Error"]},{"text":"impl Send for AnyBlockchain","synthetic":true,"types":["bdk::blockchain::any::AnyBlockchain"]},{"text":"impl Send for AnyBlockchainConfig","synthetic":true,"types":["bdk::blockchain::any::AnyBlockchainConfig"]},{"text":"impl Send for ElectrumBlockchain","synthetic":true,"types":["bdk::blockchain::electrum::ElectrumBlockchain"]},{"text":"impl Send for ElectrumBlockchainConfig","synthetic":true,"types":["bdk::blockchain::electrum::ElectrumBlockchainConfig"]},{"text":"impl Send for RpcBlockchain","synthetic":true,"types":["bdk::blockchain::rpc::RpcBlockchain"]},{"text":"impl Send for RpcConfig","synthetic":true,"types":["bdk::blockchain::rpc::RpcConfig"]},{"text":"impl Send for RpcSyncParams","synthetic":true,"types":["bdk::blockchain::rpc::RpcSyncParams"]},{"text":"impl Send for Auth","synthetic":true,"types":["bdk::blockchain::rpc::Auth"]},{"text":"impl Send for RpcBlockchainFactory","synthetic":true,"types":["bdk::blockchain::rpc::RpcBlockchainFactory"]},{"text":"impl Send for EsploraBlockchain","synthetic":true,"types":["bdk::blockchain::esplora::blocking::EsploraBlockchain"]},{"text":"impl Send for EsploraBlockchainConfig","synthetic":true,"types":["bdk::blockchain::esplora::EsploraBlockchainConfig"]},{"text":"impl Send for Mempool","synthetic":true,"types":["bdk::blockchain::compact_filters::peer::Mempool"]},{"text":"impl Send for Peer","synthetic":true,"types":["bdk::blockchain::compact_filters::peer::Peer"]},{"text":"impl Send for CompactFiltersBlockchain","synthetic":true,"types":["bdk::blockchain::compact_filters::CompactFiltersBlockchain"]},{"text":"impl Send for BitcoinPeerConfig","synthetic":true,"types":["bdk::blockchain::compact_filters::BitcoinPeerConfig"]},{"text":"impl Send for CompactFiltersBlockchainConfig","synthetic":true,"types":["bdk::blockchain::compact_filters::CompactFiltersBlockchainConfig"]},{"text":"impl Send for CompactFiltersError","synthetic":true,"types":["bdk::blockchain::compact_filters::CompactFiltersError"]},{"text":"impl Send for Capability","synthetic":true,"types":["bdk::blockchain::Capability"]},{"text":"impl Send for NoopProgress","synthetic":true,"types":["bdk::blockchain::NoopProgress"]},{"text":"impl Send for LogProgress","synthetic":true,"types":["bdk::blockchain::LogProgress"]},{"text":"impl Send for AnyDatabase","synthetic":true,"types":["bdk::database::any::AnyDatabase"]},{"text":"impl Send for AnyBatch","synthetic":true,"types":["bdk::database::any::AnyBatch"]},{"text":"impl Send for SledDbConfiguration","synthetic":true,"types":["bdk::database::any::SledDbConfiguration"]},{"text":"impl Send for SqliteDbConfiguration","synthetic":true,"types":["bdk::database::any::SqliteDbConfiguration"]},{"text":"impl Send for AnyDatabaseConfig","synthetic":true,"types":["bdk::database::any::AnyDatabaseConfig"]},{"text":"impl Send for SqliteDatabase","synthetic":true,"types":["bdk::database::sqlite::SqliteDatabase"]},{"text":"impl Send for MemoryDatabase","synthetic":true,"types":["bdk::database::memory::MemoryDatabase"]},{"text":"impl Send for SyncTime","synthetic":true,"types":["bdk::database::SyncTime"]},{"text":"impl Send for Error","synthetic":true,"types":["bdk::descriptor::error::Error"]},{"text":"impl Send for PkOrF","synthetic":true,"types":["bdk::descriptor::policy::PkOrF"]},{"text":"impl Send for SatisfiableItem","synthetic":true,"types":["bdk::descriptor::policy::SatisfiableItem"]},{"text":"impl Send for Satisfaction","synthetic":true,"types":["bdk::descriptor::policy::Satisfaction"]},{"text":"impl Send for Policy","synthetic":true,"types":["bdk::descriptor::policy::Policy"]},{"text":"impl Send for Condition","synthetic":true,"types":["bdk::descriptor::policy::Condition"]},{"text":"impl Send for PolicyError","synthetic":true,"types":["bdk::descriptor::policy::PolicyError"]},{"text":"impl<'a> Send for BuildSatisfaction<'a>","synthetic":true,"types":["bdk::descriptor::policy::BuildSatisfaction"]},{"text":"impl<K> Send for P2Pkh<K> where
        K: Send
    ","synthetic":true,"types":["bdk::descriptor::template::P2Pkh"]},{"text":"impl<K> Send for P2Wpkh_P2Sh<K> where
        K: Send
    ","synthetic":true,"types":["bdk::descriptor::template::P2Wpkh_P2Sh"]},{"text":"impl<K> Send for P2Wpkh<K> where
        K: Send
    ","synthetic":true,"types":["bdk::descriptor::template::P2Wpkh"]},{"text":"impl<K> Send for Bip44<K> where
        K: Send
    ","synthetic":true,"types":["bdk::descriptor::template::Bip44"]},{"text":"impl<K> Send for Bip44Public<K> where
        K: Send
    ","synthetic":true,"types":["bdk::descriptor::template::Bip44Public"]},{"text":"impl<K> Send for Bip49<K> where
        K: Send
    ","synthetic":true,"types":["bdk::descriptor::template::Bip49"]},{"text":"impl<K> Send for Bip49Public<K> where
        K: Send
    ","synthetic":true,"types":["bdk::descriptor::template::Bip49Public"]},{"text":"impl<K> Send for Bip84<K> where
        K: Send
    ","synthetic":true,"types":["bdk::descriptor::template::Bip84"]},{"text":"impl<K> Send for Bip84Public<K> where
        K: Send
    ","synthetic":true,"types":["bdk::descriptor::template::Bip84Public"]},{"text":"impl Send for WordCount","synthetic":true,"types":["bdk::keys::bip39::WordCount"]},{"text":"impl<Ctx> Send for DescriptorKey<Ctx> where
        Ctx: Send
    ","synthetic":true,"types":["bdk::keys::DescriptorKey"]},{"text":"impl Send for ScriptContextEnum","synthetic":true,"types":["bdk::keys::ScriptContextEnum"]},{"text":"impl<Ctx> Send for ExtendedKey<Ctx> where
        Ctx: Send
    ","synthetic":true,"types":["bdk::keys::ExtendedKey"]},{"text":"impl<K, Ctx> Send for GeneratedKey<K, Ctx> where
        Ctx: Send,
        K: Send
    ","synthetic":true,"types":["bdk::keys::GeneratedKey"]},{"text":"impl Send for PrivateKeyGenerateOptions","synthetic":true,"types":["bdk::keys::PrivateKeyGenerateOptions"]},{"text":"impl Send for KeyError","synthetic":true,"types":["bdk::keys::KeyError"]},{"text":"impl Send for KeychainKind","synthetic":true,"types":["bdk::types::KeychainKind"]},{"text":"impl Send for FeeRate","synthetic":true,"types":["bdk::types::FeeRate"]},{"text":"impl Send for LocalUtxo","synthetic":true,"types":["bdk::types::LocalUtxo"]},{"text":"impl Send for WeightedUtxo","synthetic":true,"types":["bdk::types::WeightedUtxo"]},{"text":"impl Send for Utxo","synthetic":true,"types":["bdk::types::Utxo"]},{"text":"impl Send for TransactionDetails","synthetic":true,"types":["bdk::types::TransactionDetails"]},{"text":"impl Send for BlockTime","synthetic":true,"types":["bdk::types::BlockTime"]},{"text":"impl Send for Balance","synthetic":true,"types":["bdk::types::Balance"]},{"text":"impl Send for Excess","synthetic":true,"types":["bdk::wallet::coin_selection::Excess"]},{"text":"impl Send for CoinSelectionResult","synthetic":true,"types":["bdk::wallet::coin_selection::CoinSelectionResult"]},{"text":"impl Send for LargestFirstCoinSelection","synthetic":true,"types":["bdk::wallet::coin_selection::LargestFirstCoinSelection"]},{"text":"impl Send for OldestFirstCoinSelection","synthetic":true,"types":["bdk::wallet::coin_selection::OldestFirstCoinSelection"]},{"text":"impl Send for BranchAndBoundCoinSelection","synthetic":true,"types":["bdk::wallet::coin_selection::BranchAndBoundCoinSelection"]},{"text":"impl Send for FullyNodedExport","synthetic":true,"types":["bdk::wallet::export::FullyNodedExport"]},{"text":"impl Send for SignerId","synthetic":true,"types":["bdk::wallet::signer::SignerId"]},{"text":"impl Send for SignerError","synthetic":true,"types":["bdk::wallet::signer::SignerError"]},{"text":"impl Send for SignerContext","synthetic":true,"types":["bdk::wallet::signer::SignerContext"]},{"text":"impl<S> Send for SignerWrapper<S> where
        S: Send
    ","synthetic":true,"types":["bdk::wallet::signer::SignerWrapper"]},{"text":"impl Send for SignerOrdering","synthetic":true,"types":["bdk::wallet::signer::SignerOrdering"]},{"text":"impl Send for SignersContainer","synthetic":true,"types":["bdk::wallet::signer::SignersContainer"]},{"text":"impl Send for SignOptions","synthetic":true,"types":["bdk::wallet::signer::SignOptions"]},{"text":"impl Send for TapLeavesOptions","synthetic":true,"types":["bdk::wallet::signer::TapLeavesOptions"]},{"text":"impl Send for CreateTx","synthetic":true,"types":["bdk::wallet::tx_builder::CreateTx"]},{"text":"impl Send for BumpFee","synthetic":true,"types":["bdk::wallet::tx_builder::BumpFee"]},{"text":"impl<'a, D, Cs, Ctx> !Send for TxBuilder<'a, D, Cs, Ctx>","synthetic":true,"types":["bdk::wallet::tx_builder::TxBuilder"]},{"text":"impl Send for TxOrdering","synthetic":true,"types":["bdk::wallet::tx_builder::TxOrdering"]},{"text":"impl Send for ChangeSpendPolicy","synthetic":true,"types":["bdk::wallet::tx_builder::ChangeSpendPolicy"]},{"text":"impl Send for VerifyError","synthetic":true,"types":["bdk::wallet::verify::VerifyError"]},{"text":"impl Send for HWISigner","synthetic":true,"types":["bdk::wallet::hardwaresigner::HWISigner"]},{"text":"impl<D> Send for Wallet<D> where
        D: Send
    ","synthetic":true,"types":["bdk::wallet::Wallet"]},{"text":"impl Send for AddressIndex","synthetic":true,"types":["bdk::wallet::AddressIndex"]},{"text":"impl Send for AddressInfo","synthetic":true,"types":["bdk::wallet::AddressInfo"]},{"text":"impl Send for SyncOptions","synthetic":true,"types":["bdk::wallet::SyncOptions"]}]; -if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file +(function() {var implementors = { +"bdk":[["impl Send for Error",1,["bdk::error::Error"]],["impl Send for AnyBlockchain",1,["bdk::blockchain::any::AnyBlockchain"]],["impl Send for AnyBlockchainConfig",1,["bdk::blockchain::any::AnyBlockchainConfig"]],["impl Send for ElectrumBlockchain",1,["bdk::blockchain::electrum::ElectrumBlockchain"]],["impl Send for ElectrumBlockchainConfig",1,["bdk::blockchain::electrum::ElectrumBlockchainConfig"]],["impl Send for RpcBlockchain",1,["bdk::blockchain::rpc::RpcBlockchain"]],["impl Send for RpcConfig",1,["bdk::blockchain::rpc::RpcConfig"]],["impl Send for RpcSyncParams",1,["bdk::blockchain::rpc::RpcSyncParams"]],["impl Send for Auth",1,["bdk::blockchain::rpc::Auth"]],["impl Send for RpcBlockchainFactory",1,["bdk::blockchain::rpc::RpcBlockchainFactory"]],["impl Send for EsploraBlockchain",1,["bdk::blockchain::esplora::blocking::EsploraBlockchain"]],["impl Send for EsploraBlockchainConfig",1,["bdk::blockchain::esplora::EsploraBlockchainConfig"]],["impl Send for Mempool",1,["bdk::blockchain::compact_filters::peer::Mempool"]],["impl Send for Peer",1,["bdk::blockchain::compact_filters::peer::Peer"]],["impl Send for CompactFiltersBlockchain",1,["bdk::blockchain::compact_filters::CompactFiltersBlockchain"]],["impl Send for BitcoinPeerConfig",1,["bdk::blockchain::compact_filters::BitcoinPeerConfig"]],["impl Send for CompactFiltersBlockchainConfig",1,["bdk::blockchain::compact_filters::CompactFiltersBlockchainConfig"]],["impl Send for CompactFiltersError",1,["bdk::blockchain::compact_filters::CompactFiltersError"]],["impl Send for Capability",1,["bdk::blockchain::Capability"]],["impl Send for NoopProgress",1,["bdk::blockchain::NoopProgress"]],["impl Send for LogProgress",1,["bdk::blockchain::LogProgress"]],["impl Send for AnyDatabase",1,["bdk::database::any::AnyDatabase"]],["impl Send for AnyBatch",1,["bdk::database::any::AnyBatch"]],["impl Send for SledDbConfiguration",1,["bdk::database::any::SledDbConfiguration"]],["impl Send for SqliteDbConfiguration",1,["bdk::database::any::SqliteDbConfiguration"]],["impl Send for AnyDatabaseConfig",1,["bdk::database::any::AnyDatabaseConfig"]],["impl Send for SqliteDatabase",1,["bdk::database::sqlite::SqliteDatabase"]],["impl Send for MemoryDatabase",1,["bdk::database::memory::MemoryDatabase"]],["impl Send for SyncTime",1,["bdk::database::SyncTime"]],["impl Send for Error",1,["bdk::descriptor::error::Error"]],["impl Send for PkOrF",1,["bdk::descriptor::policy::PkOrF"]],["impl Send for SatisfiableItem",1,["bdk::descriptor::policy::SatisfiableItem"]],["impl Send for Satisfaction",1,["bdk::descriptor::policy::Satisfaction"]],["impl Send for Policy",1,["bdk::descriptor::policy::Policy"]],["impl Send for Condition",1,["bdk::descriptor::policy::Condition"]],["impl Send for PolicyError",1,["bdk::descriptor::policy::PolicyError"]],["impl<'a> Send for BuildSatisfaction<'a>",1,["bdk::descriptor::policy::BuildSatisfaction"]],["impl<K> Send for P2Pkh<K>where
        K: Send,
    ",1,["bdk::descriptor::template::P2Pkh"]],["impl<K> Send for P2Wpkh_P2Sh<K>where
        K: Send,
    ",1,["bdk::descriptor::template::P2Wpkh_P2Sh"]],["impl<K> Send for P2Wpkh<K>where
        K: Send,
    ",1,["bdk::descriptor::template::P2Wpkh"]],["impl<K> Send for Bip44<K>where
        K: Send,
    ",1,["bdk::descriptor::template::Bip44"]],["impl<K> Send for Bip44Public<K>where
        K: Send,
    ",1,["bdk::descriptor::template::Bip44Public"]],["impl<K> Send for Bip49<K>where
        K: Send,
    ",1,["bdk::descriptor::template::Bip49"]],["impl<K> Send for Bip49Public<K>where
        K: Send,
    ",1,["bdk::descriptor::template::Bip49Public"]],["impl<K> Send for Bip84<K>where
        K: Send,
    ",1,["bdk::descriptor::template::Bip84"]],["impl<K> Send for Bip84Public<K>where
        K: Send,
    ",1,["bdk::descriptor::template::Bip84Public"]],["impl Send for WordCount",1,["bdk::keys::bip39::WordCount"]],["impl<Ctx> Send for DescriptorKey<Ctx>where
        Ctx: Send,
    ",1,["bdk::keys::DescriptorKey"]],["impl Send for ScriptContextEnum",1,["bdk::keys::ScriptContextEnum"]],["impl<Ctx> Send for ExtendedKey<Ctx>where
        Ctx: Send,
    ",1,["bdk::keys::ExtendedKey"]],["impl<K, Ctx> Send for GeneratedKey<K, Ctx>where
        Ctx: Send,
        K: Send,
    ",1,["bdk::keys::GeneratedKey"]],["impl Send for PrivateKeyGenerateOptions",1,["bdk::keys::PrivateKeyGenerateOptions"]],["impl Send for KeyError",1,["bdk::keys::KeyError"]],["impl Send for KeychainKind",1,["bdk::types::KeychainKind"]],["impl Send for FeeRate",1,["bdk::types::FeeRate"]],["impl Send for LocalUtxo",1,["bdk::types::LocalUtxo"]],["impl Send for WeightedUtxo",1,["bdk::types::WeightedUtxo"]],["impl Send for Utxo",1,["bdk::types::Utxo"]],["impl Send for TransactionDetails",1,["bdk::types::TransactionDetails"]],["impl Send for BlockTime",1,["bdk::types::BlockTime"]],["impl Send for Balance",1,["bdk::types::Balance"]],["impl Send for Excess",1,["bdk::wallet::coin_selection::Excess"]],["impl Send for CoinSelectionResult",1,["bdk::wallet::coin_selection::CoinSelectionResult"]],["impl Send for LargestFirstCoinSelection",1,["bdk::wallet::coin_selection::LargestFirstCoinSelection"]],["impl Send for OldestFirstCoinSelection",1,["bdk::wallet::coin_selection::OldestFirstCoinSelection"]],["impl Send for BranchAndBoundCoinSelection",1,["bdk::wallet::coin_selection::BranchAndBoundCoinSelection"]],["impl Send for FullyNodedExport",1,["bdk::wallet::export::FullyNodedExport"]],["impl Send for SignerId",1,["bdk::wallet::signer::SignerId"]],["impl Send for SignerError",1,["bdk::wallet::signer::SignerError"]],["impl Send for SignerContext",1,["bdk::wallet::signer::SignerContext"]],["impl<S> Send for SignerWrapper<S>where
        S: Send,
    ",1,["bdk::wallet::signer::SignerWrapper"]],["impl Send for SignerOrdering",1,["bdk::wallet::signer::SignerOrdering"]],["impl Send for SignersContainer",1,["bdk::wallet::signer::SignersContainer"]],["impl Send for SignOptions",1,["bdk::wallet::signer::SignOptions"]],["impl Send for TapLeavesOptions",1,["bdk::wallet::signer::TapLeavesOptions"]],["impl Send for CreateTx",1,["bdk::wallet::tx_builder::CreateTx"]],["impl Send for BumpFee",1,["bdk::wallet::tx_builder::BumpFee"]],["impl<'a, D, Cs, Ctx> !Send for TxBuilder<'a, D, Cs, Ctx>",1,["bdk::wallet::tx_builder::TxBuilder"]],["impl Send for TxOrdering",1,["bdk::wallet::tx_builder::TxOrdering"]],["impl Send for ChangeSpendPolicy",1,["bdk::wallet::tx_builder::ChangeSpendPolicy"]],["impl Send for VerifyError",1,["bdk::wallet::verify::VerifyError"]],["impl Send for HWISigner",1,["bdk::wallet::hardwaresigner::HWISigner"]],["impl<D> Send for Wallet<D>where
        D: Send,
    ",1,["bdk::wallet::Wallet"]],["impl Send for AddressIndex",1,["bdk::wallet::AddressIndex"]],["impl Send for AddressInfo",1,["bdk::wallet::AddressInfo"]],["impl Send for SyncOptions",1,["bdk::wallet::SyncOptions"]]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/implementors/core/marker/trait.StructuralEq.js b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/implementors/core/marker/trait.StructuralEq.js index 9d449dceab..2a27a62d75 100644 --- a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/implementors/core/marker/trait.StructuralEq.js +++ b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/implementors/core/marker/trait.StructuralEq.js @@ -1,3 +1,3 @@ -(function() {var implementors = {}; -implementors["bdk"] = [{"text":"impl StructuralEq for AnyBlockchainConfig","synthetic":false,"types":["bdk::blockchain::any::AnyBlockchainConfig"]},{"text":"impl StructuralEq for ElectrumBlockchainConfig","synthetic":false,"types":["bdk::blockchain::electrum::ElectrumBlockchainConfig"]},{"text":"impl StructuralEq for RpcConfig","synthetic":false,"types":["bdk::blockchain::rpc::RpcConfig"]},{"text":"impl StructuralEq for RpcSyncParams","synthetic":false,"types":["bdk::blockchain::rpc::RpcSyncParams"]},{"text":"impl StructuralEq for Auth","synthetic":false,"types":["bdk::blockchain::rpc::Auth"]},{"text":"impl StructuralEq for EsploraBlockchainConfig","synthetic":false,"types":["bdk::blockchain::esplora::EsploraBlockchainConfig"]},{"text":"impl StructuralEq for BitcoinPeerConfig","synthetic":false,"types":["bdk::blockchain::compact_filters::BitcoinPeerConfig"]},{"text":"impl StructuralEq for CompactFiltersBlockchainConfig","synthetic":false,"types":["bdk::blockchain::compact_filters::CompactFiltersBlockchainConfig"]},{"text":"impl StructuralEq for Capability","synthetic":false,"types":["bdk::blockchain::Capability"]},{"text":"impl StructuralEq for PkOrF","synthetic":false,"types":["bdk::descriptor::policy::PkOrF"]},{"text":"impl StructuralEq for SatisfiableItem","synthetic":false,"types":["bdk::descriptor::policy::SatisfiableItem"]},{"text":"impl StructuralEq for Satisfaction","synthetic":false,"types":["bdk::descriptor::policy::Satisfaction"]},{"text":"impl StructuralEq for Policy","synthetic":false,"types":["bdk::descriptor::policy::Policy"]},{"text":"impl StructuralEq for Condition","synthetic":false,"types":["bdk::descriptor::policy::Condition"]},{"text":"impl StructuralEq for PolicyError","synthetic":false,"types":["bdk::descriptor::policy::PolicyError"]},{"text":"impl StructuralEq for ScriptContextEnum","synthetic":false,"types":["bdk::keys::ScriptContextEnum"]},{"text":"impl StructuralEq for KeychainKind","synthetic":false,"types":["bdk::types::KeychainKind"]},{"text":"impl StructuralEq for LocalUtxo","synthetic":false,"types":["bdk::types::LocalUtxo"]},{"text":"impl StructuralEq for WeightedUtxo","synthetic":false,"types":["bdk::types::WeightedUtxo"]},{"text":"impl StructuralEq for Utxo","synthetic":false,"types":["bdk::types::Utxo"]},{"text":"impl StructuralEq for TransactionDetails","synthetic":false,"types":["bdk::types::TransactionDetails"]},{"text":"impl StructuralEq for BlockTime","synthetic":false,"types":["bdk::types::BlockTime"]},{"text":"impl StructuralEq for Balance","synthetic":false,"types":["bdk::types::Balance"]},{"text":"impl StructuralEq for SignerId","synthetic":false,"types":["bdk::wallet::signer::SignerId"]},{"text":"impl StructuralEq for SignerError","synthetic":false,"types":["bdk::wallet::signer::SignerError"]},{"text":"impl StructuralEq for SignerContext","synthetic":false,"types":["bdk::wallet::signer::SignerContext"]},{"text":"impl StructuralEq for SignerOrdering","synthetic":false,"types":["bdk::wallet::signer::SignerOrdering"]},{"text":"impl StructuralEq for TapLeavesOptions","synthetic":false,"types":["bdk::wallet::signer::TapLeavesOptions"]},{"text":"impl StructuralEq for TxOrdering","synthetic":false,"types":["bdk::wallet::tx_builder::TxOrdering"]},{"text":"impl StructuralEq for ChangeSpendPolicy","synthetic":false,"types":["bdk::wallet::tx_builder::ChangeSpendPolicy"]},{"text":"impl StructuralEq for AddressInfo","synthetic":false,"types":["bdk::wallet::AddressInfo"]}]; -if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file +(function() {var implementors = { +"bdk":[["impl StructuralEq for AnyBlockchainConfig"],["impl StructuralEq for ElectrumBlockchainConfig"],["impl StructuralEq for RpcConfig"],["impl StructuralEq for RpcSyncParams"],["impl StructuralEq for Auth"],["impl StructuralEq for EsploraBlockchainConfig"],["impl StructuralEq for BitcoinPeerConfig"],["impl StructuralEq for CompactFiltersBlockchainConfig"],["impl StructuralEq for Capability"],["impl StructuralEq for PkOrF"],["impl StructuralEq for SatisfiableItem"],["impl StructuralEq for Satisfaction"],["impl StructuralEq for Policy"],["impl StructuralEq for Condition"],["impl StructuralEq for PolicyError"],["impl StructuralEq for ScriptContextEnum"],["impl StructuralEq for KeychainKind"],["impl StructuralEq for LocalUtxo"],["impl StructuralEq for WeightedUtxo"],["impl StructuralEq for Utxo"],["impl StructuralEq for TransactionDetails"],["impl StructuralEq for BlockTime"],["impl StructuralEq for Balance"],["impl StructuralEq for SignerId"],["impl StructuralEq for SignerError"],["impl StructuralEq for SignerContext"],["impl StructuralEq for SignerOrdering"],["impl StructuralEq for TapLeavesOptions"],["impl StructuralEq for TxOrdering"],["impl StructuralEq for ChangeSpendPolicy"],["impl StructuralEq for AddressInfo"]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/implementors/core/marker/trait.StructuralPartialEq.js b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/implementors/core/marker/trait.StructuralPartialEq.js index 7b87385cab..6a015c6511 100644 --- a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/implementors/core/marker/trait.StructuralPartialEq.js +++ b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/implementors/core/marker/trait.StructuralPartialEq.js @@ -1,3 +1,3 @@ -(function() {var implementors = {}; -implementors["bdk"] = [{"text":"impl StructuralPartialEq for AnyBlockchainConfig","synthetic":false,"types":["bdk::blockchain::any::AnyBlockchainConfig"]},{"text":"impl StructuralPartialEq for ElectrumBlockchainConfig","synthetic":false,"types":["bdk::blockchain::electrum::ElectrumBlockchainConfig"]},{"text":"impl StructuralPartialEq for RpcConfig","synthetic":false,"types":["bdk::blockchain::rpc::RpcConfig"]},{"text":"impl StructuralPartialEq for RpcSyncParams","synthetic":false,"types":["bdk::blockchain::rpc::RpcSyncParams"]},{"text":"impl StructuralPartialEq for Auth","synthetic":false,"types":["bdk::blockchain::rpc::Auth"]},{"text":"impl StructuralPartialEq for EsploraBlockchainConfig","synthetic":false,"types":["bdk::blockchain::esplora::EsploraBlockchainConfig"]},{"text":"impl StructuralPartialEq for BitcoinPeerConfig","synthetic":false,"types":["bdk::blockchain::compact_filters::BitcoinPeerConfig"]},{"text":"impl StructuralPartialEq for CompactFiltersBlockchainConfig","synthetic":false,"types":["bdk::blockchain::compact_filters::CompactFiltersBlockchainConfig"]},{"text":"impl StructuralPartialEq for Capability","synthetic":false,"types":["bdk::blockchain::Capability"]},{"text":"impl StructuralPartialEq for PkOrF","synthetic":false,"types":["bdk::descriptor::policy::PkOrF"]},{"text":"impl StructuralPartialEq for SatisfiableItem","synthetic":false,"types":["bdk::descriptor::policy::SatisfiableItem"]},{"text":"impl StructuralPartialEq for Satisfaction","synthetic":false,"types":["bdk::descriptor::policy::Satisfaction"]},{"text":"impl StructuralPartialEq for Policy","synthetic":false,"types":["bdk::descriptor::policy::Policy"]},{"text":"impl StructuralPartialEq for Condition","synthetic":false,"types":["bdk::descriptor::policy::Condition"]},{"text":"impl StructuralPartialEq for PolicyError","synthetic":false,"types":["bdk::descriptor::policy::PolicyError"]},{"text":"impl StructuralPartialEq for ScriptContextEnum","synthetic":false,"types":["bdk::keys::ScriptContextEnum"]},{"text":"impl StructuralPartialEq for KeychainKind","synthetic":false,"types":["bdk::types::KeychainKind"]},{"text":"impl StructuralPartialEq for FeeRate","synthetic":false,"types":["bdk::types::FeeRate"]},{"text":"impl StructuralPartialEq for LocalUtxo","synthetic":false,"types":["bdk::types::LocalUtxo"]},{"text":"impl StructuralPartialEq for WeightedUtxo","synthetic":false,"types":["bdk::types::WeightedUtxo"]},{"text":"impl StructuralPartialEq for Utxo","synthetic":false,"types":["bdk::types::Utxo"]},{"text":"impl StructuralPartialEq for TransactionDetails","synthetic":false,"types":["bdk::types::TransactionDetails"]},{"text":"impl StructuralPartialEq for BlockTime","synthetic":false,"types":["bdk::types::BlockTime"]},{"text":"impl StructuralPartialEq for Balance","synthetic":false,"types":["bdk::types::Balance"]},{"text":"impl StructuralPartialEq for SignerId","synthetic":false,"types":["bdk::wallet::signer::SignerId"]},{"text":"impl StructuralPartialEq for SignerError","synthetic":false,"types":["bdk::wallet::signer::SignerError"]},{"text":"impl StructuralPartialEq for SignerContext","synthetic":false,"types":["bdk::wallet::signer::SignerContext"]},{"text":"impl StructuralPartialEq for SignerOrdering","synthetic":false,"types":["bdk::wallet::signer::SignerOrdering"]},{"text":"impl StructuralPartialEq for TapLeavesOptions","synthetic":false,"types":["bdk::wallet::signer::TapLeavesOptions"]},{"text":"impl StructuralPartialEq for TxOrdering","synthetic":false,"types":["bdk::wallet::tx_builder::TxOrdering"]},{"text":"impl StructuralPartialEq for ChangeSpendPolicy","synthetic":false,"types":["bdk::wallet::tx_builder::ChangeSpendPolicy"]},{"text":"impl StructuralPartialEq for AddressInfo","synthetic":false,"types":["bdk::wallet::AddressInfo"]}]; -if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file +(function() {var implementors = { +"bdk":[["impl StructuralPartialEq for AnyBlockchainConfig"],["impl StructuralPartialEq for ElectrumBlockchainConfig"],["impl StructuralPartialEq for RpcConfig"],["impl StructuralPartialEq for RpcSyncParams"],["impl StructuralPartialEq for Auth"],["impl StructuralPartialEq for EsploraBlockchainConfig"],["impl StructuralPartialEq for BitcoinPeerConfig"],["impl StructuralPartialEq for CompactFiltersBlockchainConfig"],["impl StructuralPartialEq for Capability"],["impl StructuralPartialEq for PkOrF"],["impl StructuralPartialEq for SatisfiableItem"],["impl StructuralPartialEq for Satisfaction"],["impl StructuralPartialEq for Policy"],["impl StructuralPartialEq for Condition"],["impl StructuralPartialEq for PolicyError"],["impl StructuralPartialEq for ScriptContextEnum"],["impl StructuralPartialEq for KeychainKind"],["impl StructuralPartialEq for FeeRate"],["impl StructuralPartialEq for LocalUtxo"],["impl StructuralPartialEq for WeightedUtxo"],["impl StructuralPartialEq for Utxo"],["impl StructuralPartialEq for TransactionDetails"],["impl StructuralPartialEq for BlockTime"],["impl StructuralPartialEq for Balance"],["impl StructuralPartialEq for SignerId"],["impl StructuralPartialEq for SignerError"],["impl StructuralPartialEq for SignerContext"],["impl StructuralPartialEq for SignerOrdering"],["impl StructuralPartialEq for TapLeavesOptions"],["impl StructuralPartialEq for TxOrdering"],["impl StructuralPartialEq for ChangeSpendPolicy"],["impl StructuralPartialEq for AddressInfo"]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/implementors/core/marker/trait.Sync.js b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/implementors/core/marker/trait.Sync.js index bbba6b5781..2bd48a00b0 100644 --- a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/implementors/core/marker/trait.Sync.js +++ b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/implementors/core/marker/trait.Sync.js @@ -1,3 +1,3 @@ -(function() {var implementors = {}; -implementors["bdk"] = [{"text":"impl Sync for Error","synthetic":true,"types":["bdk::error::Error"]},{"text":"impl Sync for AnyBlockchain","synthetic":true,"types":["bdk::blockchain::any::AnyBlockchain"]},{"text":"impl Sync for AnyBlockchainConfig","synthetic":true,"types":["bdk::blockchain::any::AnyBlockchainConfig"]},{"text":"impl Sync for ElectrumBlockchain","synthetic":true,"types":["bdk::blockchain::electrum::ElectrumBlockchain"]},{"text":"impl Sync for ElectrumBlockchainConfig","synthetic":true,"types":["bdk::blockchain::electrum::ElectrumBlockchainConfig"]},{"text":"impl Sync for RpcBlockchain","synthetic":true,"types":["bdk::blockchain::rpc::RpcBlockchain"]},{"text":"impl Sync for RpcConfig","synthetic":true,"types":["bdk::blockchain::rpc::RpcConfig"]},{"text":"impl Sync for RpcSyncParams","synthetic":true,"types":["bdk::blockchain::rpc::RpcSyncParams"]},{"text":"impl Sync for Auth","synthetic":true,"types":["bdk::blockchain::rpc::Auth"]},{"text":"impl Sync for RpcBlockchainFactory","synthetic":true,"types":["bdk::blockchain::rpc::RpcBlockchainFactory"]},{"text":"impl Sync for EsploraBlockchain","synthetic":true,"types":["bdk::blockchain::esplora::blocking::EsploraBlockchain"]},{"text":"impl Sync for EsploraBlockchainConfig","synthetic":true,"types":["bdk::blockchain::esplora::EsploraBlockchainConfig"]},{"text":"impl Sync for Mempool","synthetic":true,"types":["bdk::blockchain::compact_filters::peer::Mempool"]},{"text":"impl Sync for Peer","synthetic":true,"types":["bdk::blockchain::compact_filters::peer::Peer"]},{"text":"impl Sync for CompactFiltersBlockchain","synthetic":true,"types":["bdk::blockchain::compact_filters::CompactFiltersBlockchain"]},{"text":"impl Sync for BitcoinPeerConfig","synthetic":true,"types":["bdk::blockchain::compact_filters::BitcoinPeerConfig"]},{"text":"impl Sync for CompactFiltersBlockchainConfig","synthetic":true,"types":["bdk::blockchain::compact_filters::CompactFiltersBlockchainConfig"]},{"text":"impl Sync for CompactFiltersError","synthetic":true,"types":["bdk::blockchain::compact_filters::CompactFiltersError"]},{"text":"impl Sync for Capability","synthetic":true,"types":["bdk::blockchain::Capability"]},{"text":"impl Sync for NoopProgress","synthetic":true,"types":["bdk::blockchain::NoopProgress"]},{"text":"impl Sync for LogProgress","synthetic":true,"types":["bdk::blockchain::LogProgress"]},{"text":"impl !Sync for AnyDatabase","synthetic":true,"types":["bdk::database::any::AnyDatabase"]},{"text":"impl !Sync for AnyBatch","synthetic":true,"types":["bdk::database::any::AnyBatch"]},{"text":"impl Sync for SledDbConfiguration","synthetic":true,"types":["bdk::database::any::SledDbConfiguration"]},{"text":"impl Sync for SqliteDbConfiguration","synthetic":true,"types":["bdk::database::any::SqliteDbConfiguration"]},{"text":"impl Sync for AnyDatabaseConfig","synthetic":true,"types":["bdk::database::any::AnyDatabaseConfig"]},{"text":"impl !Sync for SqliteDatabase","synthetic":true,"types":["bdk::database::sqlite::SqliteDatabase"]},{"text":"impl Sync for MemoryDatabase","synthetic":true,"types":["bdk::database::memory::MemoryDatabase"]},{"text":"impl Sync for SyncTime","synthetic":true,"types":["bdk::database::SyncTime"]},{"text":"impl Sync for Error","synthetic":true,"types":["bdk::descriptor::error::Error"]},{"text":"impl Sync for PkOrF","synthetic":true,"types":["bdk::descriptor::policy::PkOrF"]},{"text":"impl Sync for SatisfiableItem","synthetic":true,"types":["bdk::descriptor::policy::SatisfiableItem"]},{"text":"impl Sync for Satisfaction","synthetic":true,"types":["bdk::descriptor::policy::Satisfaction"]},{"text":"impl Sync for Policy","synthetic":true,"types":["bdk::descriptor::policy::Policy"]},{"text":"impl Sync for Condition","synthetic":true,"types":["bdk::descriptor::policy::Condition"]},{"text":"impl Sync for PolicyError","synthetic":true,"types":["bdk::descriptor::policy::PolicyError"]},{"text":"impl<'a> Sync for BuildSatisfaction<'a>","synthetic":true,"types":["bdk::descriptor::policy::BuildSatisfaction"]},{"text":"impl<K> Sync for P2Pkh<K> where
        K: Sync
    ","synthetic":true,"types":["bdk::descriptor::template::P2Pkh"]},{"text":"impl<K> Sync for P2Wpkh_P2Sh<K> where
        K: Sync
    ","synthetic":true,"types":["bdk::descriptor::template::P2Wpkh_P2Sh"]},{"text":"impl<K> Sync for P2Wpkh<K> where
        K: Sync
    ","synthetic":true,"types":["bdk::descriptor::template::P2Wpkh"]},{"text":"impl<K> Sync for Bip44<K> where
        K: Sync
    ","synthetic":true,"types":["bdk::descriptor::template::Bip44"]},{"text":"impl<K> Sync for Bip44Public<K> where
        K: Sync
    ","synthetic":true,"types":["bdk::descriptor::template::Bip44Public"]},{"text":"impl<K> Sync for Bip49<K> where
        K: Sync
    ","synthetic":true,"types":["bdk::descriptor::template::Bip49"]},{"text":"impl<K> Sync for Bip49Public<K> where
        K: Sync
    ","synthetic":true,"types":["bdk::descriptor::template::Bip49Public"]},{"text":"impl<K> Sync for Bip84<K> where
        K: Sync
    ","synthetic":true,"types":["bdk::descriptor::template::Bip84"]},{"text":"impl<K> Sync for Bip84Public<K> where
        K: Sync
    ","synthetic":true,"types":["bdk::descriptor::template::Bip84Public"]},{"text":"impl Sync for WordCount","synthetic":true,"types":["bdk::keys::bip39::WordCount"]},{"text":"impl<Ctx> Sync for DescriptorKey<Ctx> where
        Ctx: Sync
    ","synthetic":true,"types":["bdk::keys::DescriptorKey"]},{"text":"impl Sync for ScriptContextEnum","synthetic":true,"types":["bdk::keys::ScriptContextEnum"]},{"text":"impl<Ctx> Sync for ExtendedKey<Ctx> where
        Ctx: Sync
    ","synthetic":true,"types":["bdk::keys::ExtendedKey"]},{"text":"impl<K, Ctx> Sync for GeneratedKey<K, Ctx> where
        Ctx: Sync,
        K: Sync
    ","synthetic":true,"types":["bdk::keys::GeneratedKey"]},{"text":"impl Sync for PrivateKeyGenerateOptions","synthetic":true,"types":["bdk::keys::PrivateKeyGenerateOptions"]},{"text":"impl Sync for KeyError","synthetic":true,"types":["bdk::keys::KeyError"]},{"text":"impl Sync for KeychainKind","synthetic":true,"types":["bdk::types::KeychainKind"]},{"text":"impl Sync for FeeRate","synthetic":true,"types":["bdk::types::FeeRate"]},{"text":"impl Sync for LocalUtxo","synthetic":true,"types":["bdk::types::LocalUtxo"]},{"text":"impl Sync for WeightedUtxo","synthetic":true,"types":["bdk::types::WeightedUtxo"]},{"text":"impl Sync for Utxo","synthetic":true,"types":["bdk::types::Utxo"]},{"text":"impl Sync for TransactionDetails","synthetic":true,"types":["bdk::types::TransactionDetails"]},{"text":"impl Sync for BlockTime","synthetic":true,"types":["bdk::types::BlockTime"]},{"text":"impl Sync for Balance","synthetic":true,"types":["bdk::types::Balance"]},{"text":"impl Sync for Excess","synthetic":true,"types":["bdk::wallet::coin_selection::Excess"]},{"text":"impl Sync for CoinSelectionResult","synthetic":true,"types":["bdk::wallet::coin_selection::CoinSelectionResult"]},{"text":"impl Sync for LargestFirstCoinSelection","synthetic":true,"types":["bdk::wallet::coin_selection::LargestFirstCoinSelection"]},{"text":"impl Sync for OldestFirstCoinSelection","synthetic":true,"types":["bdk::wallet::coin_selection::OldestFirstCoinSelection"]},{"text":"impl Sync for BranchAndBoundCoinSelection","synthetic":true,"types":["bdk::wallet::coin_selection::BranchAndBoundCoinSelection"]},{"text":"impl Sync for FullyNodedExport","synthetic":true,"types":["bdk::wallet::export::FullyNodedExport"]},{"text":"impl Sync for SignerId","synthetic":true,"types":["bdk::wallet::signer::SignerId"]},{"text":"impl Sync for SignerError","synthetic":true,"types":["bdk::wallet::signer::SignerError"]},{"text":"impl Sync for SignerContext","synthetic":true,"types":["bdk::wallet::signer::SignerContext"]},{"text":"impl<S> Sync for SignerWrapper<S> where
        S: Sync
    ","synthetic":true,"types":["bdk::wallet::signer::SignerWrapper"]},{"text":"impl Sync for SignerOrdering","synthetic":true,"types":["bdk::wallet::signer::SignerOrdering"]},{"text":"impl Sync for SignersContainer","synthetic":true,"types":["bdk::wallet::signer::SignersContainer"]},{"text":"impl Sync for SignOptions","synthetic":true,"types":["bdk::wallet::signer::SignOptions"]},{"text":"impl Sync for TapLeavesOptions","synthetic":true,"types":["bdk::wallet::signer::TapLeavesOptions"]},{"text":"impl Sync for CreateTx","synthetic":true,"types":["bdk::wallet::tx_builder::CreateTx"]},{"text":"impl Sync for BumpFee","synthetic":true,"types":["bdk::wallet::tx_builder::BumpFee"]},{"text":"impl<'a, D, Cs, Ctx> !Sync for TxBuilder<'a, D, Cs, Ctx>","synthetic":true,"types":["bdk::wallet::tx_builder::TxBuilder"]},{"text":"impl Sync for TxOrdering","synthetic":true,"types":["bdk::wallet::tx_builder::TxOrdering"]},{"text":"impl Sync for ChangeSpendPolicy","synthetic":true,"types":["bdk::wallet::tx_builder::ChangeSpendPolicy"]},{"text":"impl Sync for VerifyError","synthetic":true,"types":["bdk::wallet::verify::VerifyError"]},{"text":"impl Sync for HWISigner","synthetic":true,"types":["bdk::wallet::hardwaresigner::HWISigner"]},{"text":"impl<D> !Sync for Wallet<D>","synthetic":true,"types":["bdk::wallet::Wallet"]},{"text":"impl Sync for AddressIndex","synthetic":true,"types":["bdk::wallet::AddressIndex"]},{"text":"impl Sync for AddressInfo","synthetic":true,"types":["bdk::wallet::AddressInfo"]},{"text":"impl !Sync for SyncOptions","synthetic":true,"types":["bdk::wallet::SyncOptions"]}]; -if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file +(function() {var implementors = { +"bdk":[["impl Sync for Error",1,["bdk::error::Error"]],["impl Sync for AnyBlockchain",1,["bdk::blockchain::any::AnyBlockchain"]],["impl Sync for AnyBlockchainConfig",1,["bdk::blockchain::any::AnyBlockchainConfig"]],["impl Sync for ElectrumBlockchain",1,["bdk::blockchain::electrum::ElectrumBlockchain"]],["impl Sync for ElectrumBlockchainConfig",1,["bdk::blockchain::electrum::ElectrumBlockchainConfig"]],["impl Sync for RpcBlockchain",1,["bdk::blockchain::rpc::RpcBlockchain"]],["impl Sync for RpcConfig",1,["bdk::blockchain::rpc::RpcConfig"]],["impl Sync for RpcSyncParams",1,["bdk::blockchain::rpc::RpcSyncParams"]],["impl Sync for Auth",1,["bdk::blockchain::rpc::Auth"]],["impl Sync for RpcBlockchainFactory",1,["bdk::blockchain::rpc::RpcBlockchainFactory"]],["impl Sync for EsploraBlockchain",1,["bdk::blockchain::esplora::blocking::EsploraBlockchain"]],["impl Sync for EsploraBlockchainConfig",1,["bdk::blockchain::esplora::EsploraBlockchainConfig"]],["impl Sync for Mempool",1,["bdk::blockchain::compact_filters::peer::Mempool"]],["impl Sync for Peer",1,["bdk::blockchain::compact_filters::peer::Peer"]],["impl Sync for CompactFiltersBlockchain",1,["bdk::blockchain::compact_filters::CompactFiltersBlockchain"]],["impl Sync for BitcoinPeerConfig",1,["bdk::blockchain::compact_filters::BitcoinPeerConfig"]],["impl Sync for CompactFiltersBlockchainConfig",1,["bdk::blockchain::compact_filters::CompactFiltersBlockchainConfig"]],["impl Sync for CompactFiltersError",1,["bdk::blockchain::compact_filters::CompactFiltersError"]],["impl Sync for Capability",1,["bdk::blockchain::Capability"]],["impl Sync for NoopProgress",1,["bdk::blockchain::NoopProgress"]],["impl Sync for LogProgress",1,["bdk::blockchain::LogProgress"]],["impl !Sync for AnyDatabase",1,["bdk::database::any::AnyDatabase"]],["impl !Sync for AnyBatch",1,["bdk::database::any::AnyBatch"]],["impl Sync for SledDbConfiguration",1,["bdk::database::any::SledDbConfiguration"]],["impl Sync for SqliteDbConfiguration",1,["bdk::database::any::SqliteDbConfiguration"]],["impl Sync for AnyDatabaseConfig",1,["bdk::database::any::AnyDatabaseConfig"]],["impl !Sync for SqliteDatabase",1,["bdk::database::sqlite::SqliteDatabase"]],["impl Sync for MemoryDatabase",1,["bdk::database::memory::MemoryDatabase"]],["impl Sync for SyncTime",1,["bdk::database::SyncTime"]],["impl Sync for Error",1,["bdk::descriptor::error::Error"]],["impl Sync for PkOrF",1,["bdk::descriptor::policy::PkOrF"]],["impl Sync for SatisfiableItem",1,["bdk::descriptor::policy::SatisfiableItem"]],["impl Sync for Satisfaction",1,["bdk::descriptor::policy::Satisfaction"]],["impl Sync for Policy",1,["bdk::descriptor::policy::Policy"]],["impl Sync for Condition",1,["bdk::descriptor::policy::Condition"]],["impl Sync for PolicyError",1,["bdk::descriptor::policy::PolicyError"]],["impl<'a> Sync for BuildSatisfaction<'a>",1,["bdk::descriptor::policy::BuildSatisfaction"]],["impl<K> Sync for P2Pkh<K>where
        K: Sync,
    ",1,["bdk::descriptor::template::P2Pkh"]],["impl<K> Sync for P2Wpkh_P2Sh<K>where
        K: Sync,
    ",1,["bdk::descriptor::template::P2Wpkh_P2Sh"]],["impl<K> Sync for P2Wpkh<K>where
        K: Sync,
    ",1,["bdk::descriptor::template::P2Wpkh"]],["impl<K> Sync for Bip44<K>where
        K: Sync,
    ",1,["bdk::descriptor::template::Bip44"]],["impl<K> Sync for Bip44Public<K>where
        K: Sync,
    ",1,["bdk::descriptor::template::Bip44Public"]],["impl<K> Sync for Bip49<K>where
        K: Sync,
    ",1,["bdk::descriptor::template::Bip49"]],["impl<K> Sync for Bip49Public<K>where
        K: Sync,
    ",1,["bdk::descriptor::template::Bip49Public"]],["impl<K> Sync for Bip84<K>where
        K: Sync,
    ",1,["bdk::descriptor::template::Bip84"]],["impl<K> Sync for Bip84Public<K>where
        K: Sync,
    ",1,["bdk::descriptor::template::Bip84Public"]],["impl Sync for WordCount",1,["bdk::keys::bip39::WordCount"]],["impl<Ctx> Sync for DescriptorKey<Ctx>where
        Ctx: Sync,
    ",1,["bdk::keys::DescriptorKey"]],["impl Sync for ScriptContextEnum",1,["bdk::keys::ScriptContextEnum"]],["impl<Ctx> Sync for ExtendedKey<Ctx>where
        Ctx: Sync,
    ",1,["bdk::keys::ExtendedKey"]],["impl<K, Ctx> Sync for GeneratedKey<K, Ctx>where
        Ctx: Sync,
        K: Sync,
    ",1,["bdk::keys::GeneratedKey"]],["impl Sync for PrivateKeyGenerateOptions",1,["bdk::keys::PrivateKeyGenerateOptions"]],["impl Sync for KeyError",1,["bdk::keys::KeyError"]],["impl Sync for KeychainKind",1,["bdk::types::KeychainKind"]],["impl Sync for FeeRate",1,["bdk::types::FeeRate"]],["impl Sync for LocalUtxo",1,["bdk::types::LocalUtxo"]],["impl Sync for WeightedUtxo",1,["bdk::types::WeightedUtxo"]],["impl Sync for Utxo",1,["bdk::types::Utxo"]],["impl Sync for TransactionDetails",1,["bdk::types::TransactionDetails"]],["impl Sync for BlockTime",1,["bdk::types::BlockTime"]],["impl Sync for Balance",1,["bdk::types::Balance"]],["impl Sync for Excess",1,["bdk::wallet::coin_selection::Excess"]],["impl Sync for CoinSelectionResult",1,["bdk::wallet::coin_selection::CoinSelectionResult"]],["impl Sync for LargestFirstCoinSelection",1,["bdk::wallet::coin_selection::LargestFirstCoinSelection"]],["impl Sync for OldestFirstCoinSelection",1,["bdk::wallet::coin_selection::OldestFirstCoinSelection"]],["impl Sync for BranchAndBoundCoinSelection",1,["bdk::wallet::coin_selection::BranchAndBoundCoinSelection"]],["impl Sync for FullyNodedExport",1,["bdk::wallet::export::FullyNodedExport"]],["impl Sync for SignerId",1,["bdk::wallet::signer::SignerId"]],["impl Sync for SignerError",1,["bdk::wallet::signer::SignerError"]],["impl Sync for SignerContext",1,["bdk::wallet::signer::SignerContext"]],["impl<S> Sync for SignerWrapper<S>where
        S: Sync,
    ",1,["bdk::wallet::signer::SignerWrapper"]],["impl Sync for SignerOrdering",1,["bdk::wallet::signer::SignerOrdering"]],["impl Sync for SignersContainer",1,["bdk::wallet::signer::SignersContainer"]],["impl Sync for SignOptions",1,["bdk::wallet::signer::SignOptions"]],["impl Sync for TapLeavesOptions",1,["bdk::wallet::signer::TapLeavesOptions"]],["impl Sync for CreateTx",1,["bdk::wallet::tx_builder::CreateTx"]],["impl Sync for BumpFee",1,["bdk::wallet::tx_builder::BumpFee"]],["impl<'a, D, Cs, Ctx> !Sync for TxBuilder<'a, D, Cs, Ctx>",1,["bdk::wallet::tx_builder::TxBuilder"]],["impl Sync for TxOrdering",1,["bdk::wallet::tx_builder::TxOrdering"]],["impl Sync for ChangeSpendPolicy",1,["bdk::wallet::tx_builder::ChangeSpendPolicy"]],["impl Sync for VerifyError",1,["bdk::wallet::verify::VerifyError"]],["impl Sync for HWISigner",1,["bdk::wallet::hardwaresigner::HWISigner"]],["impl<D> !Sync for Wallet<D>",1,["bdk::wallet::Wallet"]],["impl Sync for AddressIndex",1,["bdk::wallet::AddressIndex"]],["impl Sync for AddressInfo",1,["bdk::wallet::AddressInfo"]],["impl !Sync for SyncOptions",1,["bdk::wallet::SyncOptions"]]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/implementors/core/marker/trait.Unpin.js b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/implementors/core/marker/trait.Unpin.js index f6b9f5180d..881ca7c9dd 100644 --- a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/implementors/core/marker/trait.Unpin.js +++ b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/implementors/core/marker/trait.Unpin.js @@ -1,3 +1,3 @@ -(function() {var implementors = {}; -implementors["bdk"] = [{"text":"impl Unpin for Error","synthetic":true,"types":["bdk::error::Error"]},{"text":"impl Unpin for AnyBlockchain","synthetic":true,"types":["bdk::blockchain::any::AnyBlockchain"]},{"text":"impl Unpin for AnyBlockchainConfig","synthetic":true,"types":["bdk::blockchain::any::AnyBlockchainConfig"]},{"text":"impl Unpin for ElectrumBlockchain","synthetic":true,"types":["bdk::blockchain::electrum::ElectrumBlockchain"]},{"text":"impl Unpin for ElectrumBlockchainConfig","synthetic":true,"types":["bdk::blockchain::electrum::ElectrumBlockchainConfig"]},{"text":"impl Unpin for RpcBlockchain","synthetic":true,"types":["bdk::blockchain::rpc::RpcBlockchain"]},{"text":"impl Unpin for RpcConfig","synthetic":true,"types":["bdk::blockchain::rpc::RpcConfig"]},{"text":"impl Unpin for RpcSyncParams","synthetic":true,"types":["bdk::blockchain::rpc::RpcSyncParams"]},{"text":"impl Unpin for Auth","synthetic":true,"types":["bdk::blockchain::rpc::Auth"]},{"text":"impl Unpin for RpcBlockchainFactory","synthetic":true,"types":["bdk::blockchain::rpc::RpcBlockchainFactory"]},{"text":"impl Unpin for EsploraBlockchain","synthetic":true,"types":["bdk::blockchain::esplora::blocking::EsploraBlockchain"]},{"text":"impl Unpin for EsploraBlockchainConfig","synthetic":true,"types":["bdk::blockchain::esplora::EsploraBlockchainConfig"]},{"text":"impl Unpin for Mempool","synthetic":true,"types":["bdk::blockchain::compact_filters::peer::Mempool"]},{"text":"impl Unpin for Peer","synthetic":true,"types":["bdk::blockchain::compact_filters::peer::Peer"]},{"text":"impl Unpin for CompactFiltersBlockchain","synthetic":true,"types":["bdk::blockchain::compact_filters::CompactFiltersBlockchain"]},{"text":"impl Unpin for BitcoinPeerConfig","synthetic":true,"types":["bdk::blockchain::compact_filters::BitcoinPeerConfig"]},{"text":"impl Unpin for CompactFiltersBlockchainConfig","synthetic":true,"types":["bdk::blockchain::compact_filters::CompactFiltersBlockchainConfig"]},{"text":"impl Unpin for CompactFiltersError","synthetic":true,"types":["bdk::blockchain::compact_filters::CompactFiltersError"]},{"text":"impl Unpin for Capability","synthetic":true,"types":["bdk::blockchain::Capability"]},{"text":"impl Unpin for NoopProgress","synthetic":true,"types":["bdk::blockchain::NoopProgress"]},{"text":"impl Unpin for LogProgress","synthetic":true,"types":["bdk::blockchain::LogProgress"]},{"text":"impl Unpin for AnyDatabase","synthetic":true,"types":["bdk::database::any::AnyDatabase"]},{"text":"impl Unpin for AnyBatch","synthetic":true,"types":["bdk::database::any::AnyBatch"]},{"text":"impl Unpin for SledDbConfiguration","synthetic":true,"types":["bdk::database::any::SledDbConfiguration"]},{"text":"impl Unpin for SqliteDbConfiguration","synthetic":true,"types":["bdk::database::any::SqliteDbConfiguration"]},{"text":"impl Unpin for AnyDatabaseConfig","synthetic":true,"types":["bdk::database::any::AnyDatabaseConfig"]},{"text":"impl Unpin for SqliteDatabase","synthetic":true,"types":["bdk::database::sqlite::SqliteDatabase"]},{"text":"impl Unpin for MemoryDatabase","synthetic":true,"types":["bdk::database::memory::MemoryDatabase"]},{"text":"impl Unpin for SyncTime","synthetic":true,"types":["bdk::database::SyncTime"]},{"text":"impl Unpin for Error","synthetic":true,"types":["bdk::descriptor::error::Error"]},{"text":"impl Unpin for PkOrF","synthetic":true,"types":["bdk::descriptor::policy::PkOrF"]},{"text":"impl Unpin for SatisfiableItem","synthetic":true,"types":["bdk::descriptor::policy::SatisfiableItem"]},{"text":"impl Unpin for Satisfaction","synthetic":true,"types":["bdk::descriptor::policy::Satisfaction"]},{"text":"impl Unpin for Policy","synthetic":true,"types":["bdk::descriptor::policy::Policy"]},{"text":"impl Unpin for Condition","synthetic":true,"types":["bdk::descriptor::policy::Condition"]},{"text":"impl Unpin for PolicyError","synthetic":true,"types":["bdk::descriptor::policy::PolicyError"]},{"text":"impl<'a> Unpin for BuildSatisfaction<'a>","synthetic":true,"types":["bdk::descriptor::policy::BuildSatisfaction"]},{"text":"impl<K> Unpin for P2Pkh<K> where
        K: Unpin
    ","synthetic":true,"types":["bdk::descriptor::template::P2Pkh"]},{"text":"impl<K> Unpin for P2Wpkh_P2Sh<K> where
        K: Unpin
    ","synthetic":true,"types":["bdk::descriptor::template::P2Wpkh_P2Sh"]},{"text":"impl<K> Unpin for P2Wpkh<K> where
        K: Unpin
    ","synthetic":true,"types":["bdk::descriptor::template::P2Wpkh"]},{"text":"impl<K> Unpin for Bip44<K> where
        K: Unpin
    ","synthetic":true,"types":["bdk::descriptor::template::Bip44"]},{"text":"impl<K> Unpin for Bip44Public<K> where
        K: Unpin
    ","synthetic":true,"types":["bdk::descriptor::template::Bip44Public"]},{"text":"impl<K> Unpin for Bip49<K> where
        K: Unpin
    ","synthetic":true,"types":["bdk::descriptor::template::Bip49"]},{"text":"impl<K> Unpin for Bip49Public<K> where
        K: Unpin
    ","synthetic":true,"types":["bdk::descriptor::template::Bip49Public"]},{"text":"impl<K> Unpin for Bip84<K> where
        K: Unpin
    ","synthetic":true,"types":["bdk::descriptor::template::Bip84"]},{"text":"impl<K> Unpin for Bip84Public<K> where
        K: Unpin
    ","synthetic":true,"types":["bdk::descriptor::template::Bip84Public"]},{"text":"impl Unpin for WordCount","synthetic":true,"types":["bdk::keys::bip39::WordCount"]},{"text":"impl<Ctx> Unpin for DescriptorKey<Ctx> where
        Ctx: Unpin
    ","synthetic":true,"types":["bdk::keys::DescriptorKey"]},{"text":"impl Unpin for ScriptContextEnum","synthetic":true,"types":["bdk::keys::ScriptContextEnum"]},{"text":"impl<Ctx> Unpin for ExtendedKey<Ctx> where
        Ctx: Unpin
    ","synthetic":true,"types":["bdk::keys::ExtendedKey"]},{"text":"impl<K, Ctx> Unpin for GeneratedKey<K, Ctx> where
        Ctx: Unpin,
        K: Unpin
    ","synthetic":true,"types":["bdk::keys::GeneratedKey"]},{"text":"impl Unpin for PrivateKeyGenerateOptions","synthetic":true,"types":["bdk::keys::PrivateKeyGenerateOptions"]},{"text":"impl Unpin for KeyError","synthetic":true,"types":["bdk::keys::KeyError"]},{"text":"impl Unpin for KeychainKind","synthetic":true,"types":["bdk::types::KeychainKind"]},{"text":"impl Unpin for FeeRate","synthetic":true,"types":["bdk::types::FeeRate"]},{"text":"impl Unpin for LocalUtxo","synthetic":true,"types":["bdk::types::LocalUtxo"]},{"text":"impl Unpin for WeightedUtxo","synthetic":true,"types":["bdk::types::WeightedUtxo"]},{"text":"impl Unpin for Utxo","synthetic":true,"types":["bdk::types::Utxo"]},{"text":"impl Unpin for TransactionDetails","synthetic":true,"types":["bdk::types::TransactionDetails"]},{"text":"impl Unpin for BlockTime","synthetic":true,"types":["bdk::types::BlockTime"]},{"text":"impl Unpin for Balance","synthetic":true,"types":["bdk::types::Balance"]},{"text":"impl Unpin for Excess","synthetic":true,"types":["bdk::wallet::coin_selection::Excess"]},{"text":"impl Unpin for CoinSelectionResult","synthetic":true,"types":["bdk::wallet::coin_selection::CoinSelectionResult"]},{"text":"impl Unpin for LargestFirstCoinSelection","synthetic":true,"types":["bdk::wallet::coin_selection::LargestFirstCoinSelection"]},{"text":"impl Unpin for OldestFirstCoinSelection","synthetic":true,"types":["bdk::wallet::coin_selection::OldestFirstCoinSelection"]},{"text":"impl Unpin for BranchAndBoundCoinSelection","synthetic":true,"types":["bdk::wallet::coin_selection::BranchAndBoundCoinSelection"]},{"text":"impl Unpin for FullyNodedExport","synthetic":true,"types":["bdk::wallet::export::FullyNodedExport"]},{"text":"impl Unpin for SignerId","synthetic":true,"types":["bdk::wallet::signer::SignerId"]},{"text":"impl Unpin for SignerError","synthetic":true,"types":["bdk::wallet::signer::SignerError"]},{"text":"impl Unpin for SignerContext","synthetic":true,"types":["bdk::wallet::signer::SignerContext"]},{"text":"impl<S> Unpin for SignerWrapper<S> where
        S: Unpin
    ","synthetic":true,"types":["bdk::wallet::signer::SignerWrapper"]},{"text":"impl Unpin for SignerOrdering","synthetic":true,"types":["bdk::wallet::signer::SignerOrdering"]},{"text":"impl Unpin for SignersContainer","synthetic":true,"types":["bdk::wallet::signer::SignersContainer"]},{"text":"impl Unpin for SignOptions","synthetic":true,"types":["bdk::wallet::signer::SignOptions"]},{"text":"impl Unpin for TapLeavesOptions","synthetic":true,"types":["bdk::wallet::signer::TapLeavesOptions"]},{"text":"impl Unpin for CreateTx","synthetic":true,"types":["bdk::wallet::tx_builder::CreateTx"]},{"text":"impl Unpin for BumpFee","synthetic":true,"types":["bdk::wallet::tx_builder::BumpFee"]},{"text":"impl<'a, D, Cs, Ctx> Unpin for TxBuilder<'a, D, Cs, Ctx> where
        Cs: Unpin,
        Ctx: Unpin
    ","synthetic":true,"types":["bdk::wallet::tx_builder::TxBuilder"]},{"text":"impl Unpin for TxOrdering","synthetic":true,"types":["bdk::wallet::tx_builder::TxOrdering"]},{"text":"impl Unpin for ChangeSpendPolicy","synthetic":true,"types":["bdk::wallet::tx_builder::ChangeSpendPolicy"]},{"text":"impl Unpin for VerifyError","synthetic":true,"types":["bdk::wallet::verify::VerifyError"]},{"text":"impl Unpin for HWISigner","synthetic":true,"types":["bdk::wallet::hardwaresigner::HWISigner"]},{"text":"impl<D> Unpin for Wallet<D> where
        D: Unpin
    ","synthetic":true,"types":["bdk::wallet::Wallet"]},{"text":"impl Unpin for AddressIndex","synthetic":true,"types":["bdk::wallet::AddressIndex"]},{"text":"impl Unpin for AddressInfo","synthetic":true,"types":["bdk::wallet::AddressInfo"]},{"text":"impl Unpin for SyncOptions","synthetic":true,"types":["bdk::wallet::SyncOptions"]}]; -if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file +(function() {var implementors = { +"bdk":[["impl Unpin for Error",1,["bdk::error::Error"]],["impl Unpin for AnyBlockchain",1,["bdk::blockchain::any::AnyBlockchain"]],["impl Unpin for AnyBlockchainConfig",1,["bdk::blockchain::any::AnyBlockchainConfig"]],["impl Unpin for ElectrumBlockchain",1,["bdk::blockchain::electrum::ElectrumBlockchain"]],["impl Unpin for ElectrumBlockchainConfig",1,["bdk::blockchain::electrum::ElectrumBlockchainConfig"]],["impl Unpin for RpcBlockchain",1,["bdk::blockchain::rpc::RpcBlockchain"]],["impl Unpin for RpcConfig",1,["bdk::blockchain::rpc::RpcConfig"]],["impl Unpin for RpcSyncParams",1,["bdk::blockchain::rpc::RpcSyncParams"]],["impl Unpin for Auth",1,["bdk::blockchain::rpc::Auth"]],["impl Unpin for RpcBlockchainFactory",1,["bdk::blockchain::rpc::RpcBlockchainFactory"]],["impl Unpin for EsploraBlockchain",1,["bdk::blockchain::esplora::blocking::EsploraBlockchain"]],["impl Unpin for EsploraBlockchainConfig",1,["bdk::blockchain::esplora::EsploraBlockchainConfig"]],["impl Unpin for Mempool",1,["bdk::blockchain::compact_filters::peer::Mempool"]],["impl Unpin for Peer",1,["bdk::blockchain::compact_filters::peer::Peer"]],["impl Unpin for CompactFiltersBlockchain",1,["bdk::blockchain::compact_filters::CompactFiltersBlockchain"]],["impl Unpin for BitcoinPeerConfig",1,["bdk::blockchain::compact_filters::BitcoinPeerConfig"]],["impl Unpin for CompactFiltersBlockchainConfig",1,["bdk::blockchain::compact_filters::CompactFiltersBlockchainConfig"]],["impl Unpin for CompactFiltersError",1,["bdk::blockchain::compact_filters::CompactFiltersError"]],["impl Unpin for Capability",1,["bdk::blockchain::Capability"]],["impl Unpin for NoopProgress",1,["bdk::blockchain::NoopProgress"]],["impl Unpin for LogProgress",1,["bdk::blockchain::LogProgress"]],["impl Unpin for AnyDatabase",1,["bdk::database::any::AnyDatabase"]],["impl Unpin for AnyBatch",1,["bdk::database::any::AnyBatch"]],["impl Unpin for SledDbConfiguration",1,["bdk::database::any::SledDbConfiguration"]],["impl Unpin for SqliteDbConfiguration",1,["bdk::database::any::SqliteDbConfiguration"]],["impl Unpin for AnyDatabaseConfig",1,["bdk::database::any::AnyDatabaseConfig"]],["impl Unpin for SqliteDatabase",1,["bdk::database::sqlite::SqliteDatabase"]],["impl Unpin for MemoryDatabase",1,["bdk::database::memory::MemoryDatabase"]],["impl Unpin for SyncTime",1,["bdk::database::SyncTime"]],["impl Unpin for Error",1,["bdk::descriptor::error::Error"]],["impl Unpin for PkOrF",1,["bdk::descriptor::policy::PkOrF"]],["impl Unpin for SatisfiableItem",1,["bdk::descriptor::policy::SatisfiableItem"]],["impl Unpin for Satisfaction",1,["bdk::descriptor::policy::Satisfaction"]],["impl Unpin for Policy",1,["bdk::descriptor::policy::Policy"]],["impl Unpin for Condition",1,["bdk::descriptor::policy::Condition"]],["impl Unpin for PolicyError",1,["bdk::descriptor::policy::PolicyError"]],["impl<'a> Unpin for BuildSatisfaction<'a>",1,["bdk::descriptor::policy::BuildSatisfaction"]],["impl<K> Unpin for P2Pkh<K>where
        K: Unpin,
    ",1,["bdk::descriptor::template::P2Pkh"]],["impl<K> Unpin for P2Wpkh_P2Sh<K>where
        K: Unpin,
    ",1,["bdk::descriptor::template::P2Wpkh_P2Sh"]],["impl<K> Unpin for P2Wpkh<K>where
        K: Unpin,
    ",1,["bdk::descriptor::template::P2Wpkh"]],["impl<K> Unpin for Bip44<K>where
        K: Unpin,
    ",1,["bdk::descriptor::template::Bip44"]],["impl<K> Unpin for Bip44Public<K>where
        K: Unpin,
    ",1,["bdk::descriptor::template::Bip44Public"]],["impl<K> Unpin for Bip49<K>where
        K: Unpin,
    ",1,["bdk::descriptor::template::Bip49"]],["impl<K> Unpin for Bip49Public<K>where
        K: Unpin,
    ",1,["bdk::descriptor::template::Bip49Public"]],["impl<K> Unpin for Bip84<K>where
        K: Unpin,
    ",1,["bdk::descriptor::template::Bip84"]],["impl<K> Unpin for Bip84Public<K>where
        K: Unpin,
    ",1,["bdk::descriptor::template::Bip84Public"]],["impl Unpin for WordCount",1,["bdk::keys::bip39::WordCount"]],["impl<Ctx> Unpin for DescriptorKey<Ctx>where
        Ctx: Unpin,
    ",1,["bdk::keys::DescriptorKey"]],["impl Unpin for ScriptContextEnum",1,["bdk::keys::ScriptContextEnum"]],["impl<Ctx> Unpin for ExtendedKey<Ctx>where
        Ctx: Unpin,
    ",1,["bdk::keys::ExtendedKey"]],["impl<K, Ctx> Unpin for GeneratedKey<K, Ctx>where
        Ctx: Unpin,
        K: Unpin,
    ",1,["bdk::keys::GeneratedKey"]],["impl Unpin for PrivateKeyGenerateOptions",1,["bdk::keys::PrivateKeyGenerateOptions"]],["impl Unpin for KeyError",1,["bdk::keys::KeyError"]],["impl Unpin for KeychainKind",1,["bdk::types::KeychainKind"]],["impl Unpin for FeeRate",1,["bdk::types::FeeRate"]],["impl Unpin for LocalUtxo",1,["bdk::types::LocalUtxo"]],["impl Unpin for WeightedUtxo",1,["bdk::types::WeightedUtxo"]],["impl Unpin for Utxo",1,["bdk::types::Utxo"]],["impl Unpin for TransactionDetails",1,["bdk::types::TransactionDetails"]],["impl Unpin for BlockTime",1,["bdk::types::BlockTime"]],["impl Unpin for Balance",1,["bdk::types::Balance"]],["impl Unpin for Excess",1,["bdk::wallet::coin_selection::Excess"]],["impl Unpin for CoinSelectionResult",1,["bdk::wallet::coin_selection::CoinSelectionResult"]],["impl Unpin for LargestFirstCoinSelection",1,["bdk::wallet::coin_selection::LargestFirstCoinSelection"]],["impl Unpin for OldestFirstCoinSelection",1,["bdk::wallet::coin_selection::OldestFirstCoinSelection"]],["impl Unpin for BranchAndBoundCoinSelection",1,["bdk::wallet::coin_selection::BranchAndBoundCoinSelection"]],["impl Unpin for FullyNodedExport",1,["bdk::wallet::export::FullyNodedExport"]],["impl Unpin for SignerId",1,["bdk::wallet::signer::SignerId"]],["impl Unpin for SignerError",1,["bdk::wallet::signer::SignerError"]],["impl Unpin for SignerContext",1,["bdk::wallet::signer::SignerContext"]],["impl<S> Unpin for SignerWrapper<S>where
        S: Unpin,
    ",1,["bdk::wallet::signer::SignerWrapper"]],["impl Unpin for SignerOrdering",1,["bdk::wallet::signer::SignerOrdering"]],["impl Unpin for SignersContainer",1,["bdk::wallet::signer::SignersContainer"]],["impl Unpin for SignOptions",1,["bdk::wallet::signer::SignOptions"]],["impl Unpin for TapLeavesOptions",1,["bdk::wallet::signer::TapLeavesOptions"]],["impl Unpin for CreateTx",1,["bdk::wallet::tx_builder::CreateTx"]],["impl Unpin for BumpFee",1,["bdk::wallet::tx_builder::BumpFee"]],["impl<'a, D, Cs, Ctx> Unpin for TxBuilder<'a, D, Cs, Ctx>where
        Cs: Unpin,
        Ctx: Unpin,
    ",1,["bdk::wallet::tx_builder::TxBuilder"]],["impl Unpin for TxOrdering",1,["bdk::wallet::tx_builder::TxOrdering"]],["impl Unpin for ChangeSpendPolicy",1,["bdk::wallet::tx_builder::ChangeSpendPolicy"]],["impl Unpin for VerifyError",1,["bdk::wallet::verify::VerifyError"]],["impl Unpin for HWISigner",1,["bdk::wallet::hardwaresigner::HWISigner"]],["impl<D> Unpin for Wallet<D>where
        D: Unpin,
    ",1,["bdk::wallet::Wallet"]],["impl Unpin for AddressIndex",1,["bdk::wallet::AddressIndex"]],["impl Unpin for AddressInfo",1,["bdk::wallet::AddressInfo"]],["impl Unpin for SyncOptions",1,["bdk::wallet::SyncOptions"]]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/implementors/core/ops/arith/trait.Add.js b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/implementors/core/ops/arith/trait.Add.js index 7edd923cd7..4f08fd7f53 100644 --- a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/implementors/core/ops/arith/trait.Add.js +++ b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/implementors/core/ops/arith/trait.Add.js @@ -1,3 +1,3 @@ -(function() {var implementors = {}; -implementors["bdk"] = [{"text":"impl Add<Balance> for Balance","synthetic":false,"types":["bdk::types::Balance"]}]; -if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file +(function() {var implementors = { +"bdk":[["impl Add<Balance> for Balance"]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/implementors/core/ops/arith/trait.Sub.js b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/implementors/core/ops/arith/trait.Sub.js index 0527a76602..2862389d5d 100644 --- a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/implementors/core/ops/arith/trait.Sub.js +++ b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/implementors/core/ops/arith/trait.Sub.js @@ -1,3 +1,3 @@ -(function() {var implementors = {}; -implementors["bdk"] = [{"text":"impl Sub<FeeRate> for FeeRate","synthetic":false,"types":["bdk::types::FeeRate"]}]; -if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file +(function() {var implementors = { +"bdk":[["impl Sub<FeeRate> for FeeRate"]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/implementors/core/ops/deref/trait.Deref.js b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/implementors/core/ops/deref/trait.Deref.js index 9baafac1a1..50fa85e102 100644 --- a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/implementors/core/ops/deref/trait.Deref.js +++ b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/implementors/core/ops/deref/trait.Deref.js @@ -1,3 +1,3 @@ -(function() {var implementors = {}; -implementors["bdk"] = [{"text":"impl Deref for ElectrumBlockchain","synthetic":false,"types":["bdk::blockchain::electrum::ElectrumBlockchain"]},{"text":"impl Deref for RpcBlockchain","synthetic":false,"types":["bdk::blockchain::rpc::RpcBlockchain"]},{"text":"impl Deref for EsploraBlockchain","synthetic":false,"types":["bdk::blockchain::esplora::blocking::EsploraBlockchain"]},{"text":"impl<K, Ctx: ScriptContext> Deref for GeneratedKey<K, Ctx>","synthetic":false,"types":["bdk::keys::GeneratedKey"]},{"text":"impl<S: Sized + Debug + Clone> Deref for SignerWrapper<S>","synthetic":false,"types":["bdk::wallet::signer::SignerWrapper"]},{"text":"impl Deref for AddressInfo","synthetic":false,"types":["bdk::wallet::AddressInfo"]}]; -if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file +(function() {var implementors = { +"bdk":[["impl Deref for ElectrumBlockchain"],["impl Deref for RpcBlockchain"],["impl Deref for EsploraBlockchain"],["impl<K, Ctx: ScriptContext> Deref for GeneratedKey<K, Ctx>"],["impl<S: Sized + Debug + Clone> Deref for SignerWrapper<S>"],["impl Deref for AddressInfo"]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/implementors/core/panic/unwind_safe/trait.RefUnwindSafe.js b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/implementors/core/panic/unwind_safe/trait.RefUnwindSafe.js index a50687fdf6..8a71cae767 100644 --- a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/implementors/core/panic/unwind_safe/trait.RefUnwindSafe.js +++ b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/implementors/core/panic/unwind_safe/trait.RefUnwindSafe.js @@ -1,3 +1,3 @@ -(function() {var implementors = {}; -implementors["bdk"] = [{"text":"impl !RefUnwindSafe for Error","synthetic":true,"types":["bdk::error::Error"]},{"text":"impl !RefUnwindSafe for AnyBlockchain","synthetic":true,"types":["bdk::blockchain::any::AnyBlockchain"]},{"text":"impl RefUnwindSafe for AnyBlockchainConfig","synthetic":true,"types":["bdk::blockchain::any::AnyBlockchainConfig"]},{"text":"impl RefUnwindSafe for ElectrumBlockchain","synthetic":true,"types":["bdk::blockchain::electrum::ElectrumBlockchain"]},{"text":"impl RefUnwindSafe for ElectrumBlockchainConfig","synthetic":true,"types":["bdk::blockchain::electrum::ElectrumBlockchainConfig"]},{"text":"impl !RefUnwindSafe for RpcBlockchain","synthetic":true,"types":["bdk::blockchain::rpc::RpcBlockchain"]},{"text":"impl RefUnwindSafe for RpcConfig","synthetic":true,"types":["bdk::blockchain::rpc::RpcConfig"]},{"text":"impl RefUnwindSafe for RpcSyncParams","synthetic":true,"types":["bdk::blockchain::rpc::RpcSyncParams"]},{"text":"impl RefUnwindSafe for Auth","synthetic":true,"types":["bdk::blockchain::rpc::Auth"]},{"text":"impl RefUnwindSafe for RpcBlockchainFactory","synthetic":true,"types":["bdk::blockchain::rpc::RpcBlockchainFactory"]},{"text":"impl !RefUnwindSafe for EsploraBlockchain","synthetic":true,"types":["bdk::blockchain::esplora::blocking::EsploraBlockchain"]},{"text":"impl RefUnwindSafe for EsploraBlockchainConfig","synthetic":true,"types":["bdk::blockchain::esplora::EsploraBlockchainConfig"]},{"text":"impl RefUnwindSafe for Mempool","synthetic":true,"types":["bdk::blockchain::compact_filters::peer::Mempool"]},{"text":"impl !RefUnwindSafe for Peer","synthetic":true,"types":["bdk::blockchain::compact_filters::peer::Peer"]},{"text":"impl !RefUnwindSafe for CompactFiltersBlockchain","synthetic":true,"types":["bdk::blockchain::compact_filters::CompactFiltersBlockchain"]},{"text":"impl RefUnwindSafe for BitcoinPeerConfig","synthetic":true,"types":["bdk::blockchain::compact_filters::BitcoinPeerConfig"]},{"text":"impl RefUnwindSafe for CompactFiltersBlockchainConfig","synthetic":true,"types":["bdk::blockchain::compact_filters::CompactFiltersBlockchainConfig"]},{"text":"impl !RefUnwindSafe for CompactFiltersError","synthetic":true,"types":["bdk::blockchain::compact_filters::CompactFiltersError"]},{"text":"impl RefUnwindSafe for Capability","synthetic":true,"types":["bdk::blockchain::Capability"]},{"text":"impl RefUnwindSafe for NoopProgress","synthetic":true,"types":["bdk::blockchain::NoopProgress"]},{"text":"impl RefUnwindSafe for LogProgress","synthetic":true,"types":["bdk::blockchain::LogProgress"]},{"text":"impl !RefUnwindSafe for AnyDatabase","synthetic":true,"types":["bdk::database::any::AnyDatabase"]},{"text":"impl !RefUnwindSafe for AnyBatch","synthetic":true,"types":["bdk::database::any::AnyBatch"]},{"text":"impl RefUnwindSafe for SledDbConfiguration","synthetic":true,"types":["bdk::database::any::SledDbConfiguration"]},{"text":"impl RefUnwindSafe for SqliteDbConfiguration","synthetic":true,"types":["bdk::database::any::SqliteDbConfiguration"]},{"text":"impl RefUnwindSafe for AnyDatabaseConfig","synthetic":true,"types":["bdk::database::any::AnyDatabaseConfig"]},{"text":"impl !RefUnwindSafe for SqliteDatabase","synthetic":true,"types":["bdk::database::sqlite::SqliteDatabase"]},{"text":"impl !RefUnwindSafe for MemoryDatabase","synthetic":true,"types":["bdk::database::memory::MemoryDatabase"]},{"text":"impl RefUnwindSafe for SyncTime","synthetic":true,"types":["bdk::database::SyncTime"]},{"text":"impl RefUnwindSafe for Error","synthetic":true,"types":["bdk::descriptor::error::Error"]},{"text":"impl RefUnwindSafe for PkOrF","synthetic":true,"types":["bdk::descriptor::policy::PkOrF"]},{"text":"impl RefUnwindSafe for SatisfiableItem","synthetic":true,"types":["bdk::descriptor::policy::SatisfiableItem"]},{"text":"impl RefUnwindSafe for Satisfaction","synthetic":true,"types":["bdk::descriptor::policy::Satisfaction"]},{"text":"impl RefUnwindSafe for Policy","synthetic":true,"types":["bdk::descriptor::policy::Policy"]},{"text":"impl RefUnwindSafe for Condition","synthetic":true,"types":["bdk::descriptor::policy::Condition"]},{"text":"impl RefUnwindSafe for PolicyError","synthetic":true,"types":["bdk::descriptor::policy::PolicyError"]},{"text":"impl<'a> RefUnwindSafe for BuildSatisfaction<'a>","synthetic":true,"types":["bdk::descriptor::policy::BuildSatisfaction"]},{"text":"impl<K> RefUnwindSafe for P2Pkh<K> where
        K: RefUnwindSafe
    ","synthetic":true,"types":["bdk::descriptor::template::P2Pkh"]},{"text":"impl<K> RefUnwindSafe for P2Wpkh_P2Sh<K> where
        K: RefUnwindSafe
    ","synthetic":true,"types":["bdk::descriptor::template::P2Wpkh_P2Sh"]},{"text":"impl<K> RefUnwindSafe for P2Wpkh<K> where
        K: RefUnwindSafe
    ","synthetic":true,"types":["bdk::descriptor::template::P2Wpkh"]},{"text":"impl<K> RefUnwindSafe for Bip44<K> where
        K: RefUnwindSafe
    ","synthetic":true,"types":["bdk::descriptor::template::Bip44"]},{"text":"impl<K> RefUnwindSafe for Bip44Public<K> where
        K: RefUnwindSafe
    ","synthetic":true,"types":["bdk::descriptor::template::Bip44Public"]},{"text":"impl<K> RefUnwindSafe for Bip49<K> where
        K: RefUnwindSafe
    ","synthetic":true,"types":["bdk::descriptor::template::Bip49"]},{"text":"impl<K> RefUnwindSafe for Bip49Public<K> where
        K: RefUnwindSafe
    ","synthetic":true,"types":["bdk::descriptor::template::Bip49Public"]},{"text":"impl<K> RefUnwindSafe for Bip84<K> where
        K: RefUnwindSafe
    ","synthetic":true,"types":["bdk::descriptor::template::Bip84"]},{"text":"impl<K> RefUnwindSafe for Bip84Public<K> where
        K: RefUnwindSafe
    ","synthetic":true,"types":["bdk::descriptor::template::Bip84Public"]},{"text":"impl RefUnwindSafe for WordCount","synthetic":true,"types":["bdk::keys::bip39::WordCount"]},{"text":"impl<Ctx> RefUnwindSafe for DescriptorKey<Ctx> where
        Ctx: RefUnwindSafe
    ","synthetic":true,"types":["bdk::keys::DescriptorKey"]},{"text":"impl RefUnwindSafe for ScriptContextEnum","synthetic":true,"types":["bdk::keys::ScriptContextEnum"]},{"text":"impl<Ctx> RefUnwindSafe for ExtendedKey<Ctx> where
        Ctx: RefUnwindSafe
    ","synthetic":true,"types":["bdk::keys::ExtendedKey"]},{"text":"impl<K, Ctx> RefUnwindSafe for GeneratedKey<K, Ctx> where
        Ctx: RefUnwindSafe,
        K: RefUnwindSafe
    ","synthetic":true,"types":["bdk::keys::GeneratedKey"]},{"text":"impl RefUnwindSafe for PrivateKeyGenerateOptions","synthetic":true,"types":["bdk::keys::PrivateKeyGenerateOptions"]},{"text":"impl RefUnwindSafe for KeyError","synthetic":true,"types":["bdk::keys::KeyError"]},{"text":"impl RefUnwindSafe for KeychainKind","synthetic":true,"types":["bdk::types::KeychainKind"]},{"text":"impl RefUnwindSafe for FeeRate","synthetic":true,"types":["bdk::types::FeeRate"]},{"text":"impl RefUnwindSafe for LocalUtxo","synthetic":true,"types":["bdk::types::LocalUtxo"]},{"text":"impl RefUnwindSafe for WeightedUtxo","synthetic":true,"types":["bdk::types::WeightedUtxo"]},{"text":"impl RefUnwindSafe for Utxo","synthetic":true,"types":["bdk::types::Utxo"]},{"text":"impl RefUnwindSafe for TransactionDetails","synthetic":true,"types":["bdk::types::TransactionDetails"]},{"text":"impl RefUnwindSafe for BlockTime","synthetic":true,"types":["bdk::types::BlockTime"]},{"text":"impl RefUnwindSafe for Balance","synthetic":true,"types":["bdk::types::Balance"]},{"text":"impl RefUnwindSafe for Excess","synthetic":true,"types":["bdk::wallet::coin_selection::Excess"]},{"text":"impl RefUnwindSafe for CoinSelectionResult","synthetic":true,"types":["bdk::wallet::coin_selection::CoinSelectionResult"]},{"text":"impl RefUnwindSafe for LargestFirstCoinSelection","synthetic":true,"types":["bdk::wallet::coin_selection::LargestFirstCoinSelection"]},{"text":"impl RefUnwindSafe for OldestFirstCoinSelection","synthetic":true,"types":["bdk::wallet::coin_selection::OldestFirstCoinSelection"]},{"text":"impl RefUnwindSafe for BranchAndBoundCoinSelection","synthetic":true,"types":["bdk::wallet::coin_selection::BranchAndBoundCoinSelection"]},{"text":"impl RefUnwindSafe for FullyNodedExport","synthetic":true,"types":["bdk::wallet::export::FullyNodedExport"]},{"text":"impl RefUnwindSafe for SignerId","synthetic":true,"types":["bdk::wallet::signer::SignerId"]},{"text":"impl RefUnwindSafe for SignerError","synthetic":true,"types":["bdk::wallet::signer::SignerError"]},{"text":"impl RefUnwindSafe for SignerContext","synthetic":true,"types":["bdk::wallet::signer::SignerContext"]},{"text":"impl<S> RefUnwindSafe for SignerWrapper<S> where
        S: RefUnwindSafe
    ","synthetic":true,"types":["bdk::wallet::signer::SignerWrapper"]},{"text":"impl RefUnwindSafe for SignerOrdering","synthetic":true,"types":["bdk::wallet::signer::SignerOrdering"]},{"text":"impl !RefUnwindSafe for SignersContainer","synthetic":true,"types":["bdk::wallet::signer::SignersContainer"]},{"text":"impl RefUnwindSafe for SignOptions","synthetic":true,"types":["bdk::wallet::signer::SignOptions"]},{"text":"impl RefUnwindSafe for TapLeavesOptions","synthetic":true,"types":["bdk::wallet::signer::TapLeavesOptions"]},{"text":"impl RefUnwindSafe for CreateTx","synthetic":true,"types":["bdk::wallet::tx_builder::CreateTx"]},{"text":"impl RefUnwindSafe for BumpFee","synthetic":true,"types":["bdk::wallet::tx_builder::BumpFee"]},{"text":"impl<'a, D, Cs, Ctx> !RefUnwindSafe for TxBuilder<'a, D, Cs, Ctx>","synthetic":true,"types":["bdk::wallet::tx_builder::TxBuilder"]},{"text":"impl RefUnwindSafe for TxOrdering","synthetic":true,"types":["bdk::wallet::tx_builder::TxOrdering"]},{"text":"impl RefUnwindSafe for ChangeSpendPolicy","synthetic":true,"types":["bdk::wallet::tx_builder::ChangeSpendPolicy"]},{"text":"impl !RefUnwindSafe for VerifyError","synthetic":true,"types":["bdk::wallet::verify::VerifyError"]},{"text":"impl !RefUnwindSafe for HWISigner","synthetic":true,"types":["bdk::wallet::hardwaresigner::HWISigner"]},{"text":"impl<D> !RefUnwindSafe for Wallet<D>","synthetic":true,"types":["bdk::wallet::Wallet"]},{"text":"impl RefUnwindSafe for AddressIndex","synthetic":true,"types":["bdk::wallet::AddressIndex"]},{"text":"impl RefUnwindSafe for AddressInfo","synthetic":true,"types":["bdk::wallet::AddressInfo"]},{"text":"impl !RefUnwindSafe for SyncOptions","synthetic":true,"types":["bdk::wallet::SyncOptions"]}]; -if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file +(function() {var implementors = { +"bdk":[["impl !RefUnwindSafe for Error",1,["bdk::error::Error"]],["impl !RefUnwindSafe for AnyBlockchain",1,["bdk::blockchain::any::AnyBlockchain"]],["impl RefUnwindSafe for AnyBlockchainConfig",1,["bdk::blockchain::any::AnyBlockchainConfig"]],["impl RefUnwindSafe for ElectrumBlockchain",1,["bdk::blockchain::electrum::ElectrumBlockchain"]],["impl RefUnwindSafe for ElectrumBlockchainConfig",1,["bdk::blockchain::electrum::ElectrumBlockchainConfig"]],["impl !RefUnwindSafe for RpcBlockchain",1,["bdk::blockchain::rpc::RpcBlockchain"]],["impl RefUnwindSafe for RpcConfig",1,["bdk::blockchain::rpc::RpcConfig"]],["impl RefUnwindSafe for RpcSyncParams",1,["bdk::blockchain::rpc::RpcSyncParams"]],["impl RefUnwindSafe for Auth",1,["bdk::blockchain::rpc::Auth"]],["impl RefUnwindSafe for RpcBlockchainFactory",1,["bdk::blockchain::rpc::RpcBlockchainFactory"]],["impl !RefUnwindSafe for EsploraBlockchain",1,["bdk::blockchain::esplora::blocking::EsploraBlockchain"]],["impl RefUnwindSafe for EsploraBlockchainConfig",1,["bdk::blockchain::esplora::EsploraBlockchainConfig"]],["impl RefUnwindSafe for Mempool",1,["bdk::blockchain::compact_filters::peer::Mempool"]],["impl !RefUnwindSafe for Peer",1,["bdk::blockchain::compact_filters::peer::Peer"]],["impl !RefUnwindSafe for CompactFiltersBlockchain",1,["bdk::blockchain::compact_filters::CompactFiltersBlockchain"]],["impl RefUnwindSafe for BitcoinPeerConfig",1,["bdk::blockchain::compact_filters::BitcoinPeerConfig"]],["impl RefUnwindSafe for CompactFiltersBlockchainConfig",1,["bdk::blockchain::compact_filters::CompactFiltersBlockchainConfig"]],["impl !RefUnwindSafe for CompactFiltersError",1,["bdk::blockchain::compact_filters::CompactFiltersError"]],["impl RefUnwindSafe for Capability",1,["bdk::blockchain::Capability"]],["impl RefUnwindSafe for NoopProgress",1,["bdk::blockchain::NoopProgress"]],["impl RefUnwindSafe for LogProgress",1,["bdk::blockchain::LogProgress"]],["impl !RefUnwindSafe for AnyDatabase",1,["bdk::database::any::AnyDatabase"]],["impl !RefUnwindSafe for AnyBatch",1,["bdk::database::any::AnyBatch"]],["impl RefUnwindSafe for SledDbConfiguration",1,["bdk::database::any::SledDbConfiguration"]],["impl RefUnwindSafe for SqliteDbConfiguration",1,["bdk::database::any::SqliteDbConfiguration"]],["impl RefUnwindSafe for AnyDatabaseConfig",1,["bdk::database::any::AnyDatabaseConfig"]],["impl !RefUnwindSafe for SqliteDatabase",1,["bdk::database::sqlite::SqliteDatabase"]],["impl !RefUnwindSafe for MemoryDatabase",1,["bdk::database::memory::MemoryDatabase"]],["impl RefUnwindSafe for SyncTime",1,["bdk::database::SyncTime"]],["impl RefUnwindSafe for Error",1,["bdk::descriptor::error::Error"]],["impl RefUnwindSafe for PkOrF",1,["bdk::descriptor::policy::PkOrF"]],["impl RefUnwindSafe for SatisfiableItem",1,["bdk::descriptor::policy::SatisfiableItem"]],["impl RefUnwindSafe for Satisfaction",1,["bdk::descriptor::policy::Satisfaction"]],["impl RefUnwindSafe for Policy",1,["bdk::descriptor::policy::Policy"]],["impl RefUnwindSafe for Condition",1,["bdk::descriptor::policy::Condition"]],["impl RefUnwindSafe for PolicyError",1,["bdk::descriptor::policy::PolicyError"]],["impl<'a> RefUnwindSafe for BuildSatisfaction<'a>",1,["bdk::descriptor::policy::BuildSatisfaction"]],["impl<K> RefUnwindSafe for P2Pkh<K>where
        K: RefUnwindSafe,
    ",1,["bdk::descriptor::template::P2Pkh"]],["impl<K> RefUnwindSafe for P2Wpkh_P2Sh<K>where
        K: RefUnwindSafe,
    ",1,["bdk::descriptor::template::P2Wpkh_P2Sh"]],["impl<K> RefUnwindSafe for P2Wpkh<K>where
        K: RefUnwindSafe,
    ",1,["bdk::descriptor::template::P2Wpkh"]],["impl<K> RefUnwindSafe for Bip44<K>where
        K: RefUnwindSafe,
    ",1,["bdk::descriptor::template::Bip44"]],["impl<K> RefUnwindSafe for Bip44Public<K>where
        K: RefUnwindSafe,
    ",1,["bdk::descriptor::template::Bip44Public"]],["impl<K> RefUnwindSafe for Bip49<K>where
        K: RefUnwindSafe,
    ",1,["bdk::descriptor::template::Bip49"]],["impl<K> RefUnwindSafe for Bip49Public<K>where
        K: RefUnwindSafe,
    ",1,["bdk::descriptor::template::Bip49Public"]],["impl<K> RefUnwindSafe for Bip84<K>where
        K: RefUnwindSafe,
    ",1,["bdk::descriptor::template::Bip84"]],["impl<K> RefUnwindSafe for Bip84Public<K>where
        K: RefUnwindSafe,
    ",1,["bdk::descriptor::template::Bip84Public"]],["impl RefUnwindSafe for WordCount",1,["bdk::keys::bip39::WordCount"]],["impl<Ctx> RefUnwindSafe for DescriptorKey<Ctx>where
        Ctx: RefUnwindSafe,
    ",1,["bdk::keys::DescriptorKey"]],["impl RefUnwindSafe for ScriptContextEnum",1,["bdk::keys::ScriptContextEnum"]],["impl<Ctx> RefUnwindSafe for ExtendedKey<Ctx>where
        Ctx: RefUnwindSafe,
    ",1,["bdk::keys::ExtendedKey"]],["impl<K, Ctx> RefUnwindSafe for GeneratedKey<K, Ctx>where
        Ctx: RefUnwindSafe,
        K: RefUnwindSafe,
    ",1,["bdk::keys::GeneratedKey"]],["impl RefUnwindSafe for PrivateKeyGenerateOptions",1,["bdk::keys::PrivateKeyGenerateOptions"]],["impl RefUnwindSafe for KeyError",1,["bdk::keys::KeyError"]],["impl RefUnwindSafe for KeychainKind",1,["bdk::types::KeychainKind"]],["impl RefUnwindSafe for FeeRate",1,["bdk::types::FeeRate"]],["impl RefUnwindSafe for LocalUtxo",1,["bdk::types::LocalUtxo"]],["impl RefUnwindSafe for WeightedUtxo",1,["bdk::types::WeightedUtxo"]],["impl RefUnwindSafe for Utxo",1,["bdk::types::Utxo"]],["impl RefUnwindSafe for TransactionDetails",1,["bdk::types::TransactionDetails"]],["impl RefUnwindSafe for BlockTime",1,["bdk::types::BlockTime"]],["impl RefUnwindSafe for Balance",1,["bdk::types::Balance"]],["impl RefUnwindSafe for Excess",1,["bdk::wallet::coin_selection::Excess"]],["impl RefUnwindSafe for CoinSelectionResult",1,["bdk::wallet::coin_selection::CoinSelectionResult"]],["impl RefUnwindSafe for LargestFirstCoinSelection",1,["bdk::wallet::coin_selection::LargestFirstCoinSelection"]],["impl RefUnwindSafe for OldestFirstCoinSelection",1,["bdk::wallet::coin_selection::OldestFirstCoinSelection"]],["impl RefUnwindSafe for BranchAndBoundCoinSelection",1,["bdk::wallet::coin_selection::BranchAndBoundCoinSelection"]],["impl RefUnwindSafe for FullyNodedExport",1,["bdk::wallet::export::FullyNodedExport"]],["impl RefUnwindSafe for SignerId",1,["bdk::wallet::signer::SignerId"]],["impl RefUnwindSafe for SignerError",1,["bdk::wallet::signer::SignerError"]],["impl RefUnwindSafe for SignerContext",1,["bdk::wallet::signer::SignerContext"]],["impl<S> RefUnwindSafe for SignerWrapper<S>where
        S: RefUnwindSafe,
    ",1,["bdk::wallet::signer::SignerWrapper"]],["impl RefUnwindSafe for SignerOrdering",1,["bdk::wallet::signer::SignerOrdering"]],["impl !RefUnwindSafe for SignersContainer",1,["bdk::wallet::signer::SignersContainer"]],["impl RefUnwindSafe for SignOptions",1,["bdk::wallet::signer::SignOptions"]],["impl RefUnwindSafe for TapLeavesOptions",1,["bdk::wallet::signer::TapLeavesOptions"]],["impl RefUnwindSafe for CreateTx",1,["bdk::wallet::tx_builder::CreateTx"]],["impl RefUnwindSafe for BumpFee",1,["bdk::wallet::tx_builder::BumpFee"]],["impl<'a, D, Cs, Ctx> !RefUnwindSafe for TxBuilder<'a, D, Cs, Ctx>",1,["bdk::wallet::tx_builder::TxBuilder"]],["impl RefUnwindSafe for TxOrdering",1,["bdk::wallet::tx_builder::TxOrdering"]],["impl RefUnwindSafe for ChangeSpendPolicy",1,["bdk::wallet::tx_builder::ChangeSpendPolicy"]],["impl !RefUnwindSafe for VerifyError",1,["bdk::wallet::verify::VerifyError"]],["impl !RefUnwindSafe for HWISigner",1,["bdk::wallet::hardwaresigner::HWISigner"]],["impl<D> !RefUnwindSafe for Wallet<D>",1,["bdk::wallet::Wallet"]],["impl RefUnwindSafe for AddressIndex",1,["bdk::wallet::AddressIndex"]],["impl RefUnwindSafe for AddressInfo",1,["bdk::wallet::AddressInfo"]],["impl !RefUnwindSafe for SyncOptions",1,["bdk::wallet::SyncOptions"]]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/implementors/core/panic/unwind_safe/trait.UnwindSafe.js b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/implementors/core/panic/unwind_safe/trait.UnwindSafe.js index 6f3ceafb89..f3af7c52f6 100644 --- a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/implementors/core/panic/unwind_safe/trait.UnwindSafe.js +++ b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/implementors/core/panic/unwind_safe/trait.UnwindSafe.js @@ -1,3 +1,3 @@ -(function() {var implementors = {}; -implementors["bdk"] = [{"text":"impl !UnwindSafe for Error","synthetic":true,"types":["bdk::error::Error"]},{"text":"impl !UnwindSafe for AnyBlockchain","synthetic":true,"types":["bdk::blockchain::any::AnyBlockchain"]},{"text":"impl UnwindSafe for AnyBlockchainConfig","synthetic":true,"types":["bdk::blockchain::any::AnyBlockchainConfig"]},{"text":"impl UnwindSafe for ElectrumBlockchain","synthetic":true,"types":["bdk::blockchain::electrum::ElectrumBlockchain"]},{"text":"impl UnwindSafe for ElectrumBlockchainConfig","synthetic":true,"types":["bdk::blockchain::electrum::ElectrumBlockchainConfig"]},{"text":"impl !UnwindSafe for RpcBlockchain","synthetic":true,"types":["bdk::blockchain::rpc::RpcBlockchain"]},{"text":"impl UnwindSafe for RpcConfig","synthetic":true,"types":["bdk::blockchain::rpc::RpcConfig"]},{"text":"impl UnwindSafe for RpcSyncParams","synthetic":true,"types":["bdk::blockchain::rpc::RpcSyncParams"]},{"text":"impl UnwindSafe for Auth","synthetic":true,"types":["bdk::blockchain::rpc::Auth"]},{"text":"impl UnwindSafe for RpcBlockchainFactory","synthetic":true,"types":["bdk::blockchain::rpc::RpcBlockchainFactory"]},{"text":"impl !UnwindSafe for EsploraBlockchain","synthetic":true,"types":["bdk::blockchain::esplora::blocking::EsploraBlockchain"]},{"text":"impl UnwindSafe for EsploraBlockchainConfig","synthetic":true,"types":["bdk::blockchain::esplora::EsploraBlockchainConfig"]},{"text":"impl UnwindSafe for Mempool","synthetic":true,"types":["bdk::blockchain::compact_filters::peer::Mempool"]},{"text":"impl !UnwindSafe for Peer","synthetic":true,"types":["bdk::blockchain::compact_filters::peer::Peer"]},{"text":"impl !UnwindSafe for CompactFiltersBlockchain","synthetic":true,"types":["bdk::blockchain::compact_filters::CompactFiltersBlockchain"]},{"text":"impl UnwindSafe for BitcoinPeerConfig","synthetic":true,"types":["bdk::blockchain::compact_filters::BitcoinPeerConfig"]},{"text":"impl UnwindSafe for CompactFiltersBlockchainConfig","synthetic":true,"types":["bdk::blockchain::compact_filters::CompactFiltersBlockchainConfig"]},{"text":"impl !UnwindSafe for CompactFiltersError","synthetic":true,"types":["bdk::blockchain::compact_filters::CompactFiltersError"]},{"text":"impl UnwindSafe for Capability","synthetic":true,"types":["bdk::blockchain::Capability"]},{"text":"impl UnwindSafe for NoopProgress","synthetic":true,"types":["bdk::blockchain::NoopProgress"]},{"text":"impl UnwindSafe for LogProgress","synthetic":true,"types":["bdk::blockchain::LogProgress"]},{"text":"impl !UnwindSafe for AnyDatabase","synthetic":true,"types":["bdk::database::any::AnyDatabase"]},{"text":"impl !UnwindSafe for AnyBatch","synthetic":true,"types":["bdk::database::any::AnyBatch"]},{"text":"impl UnwindSafe for SledDbConfiguration","synthetic":true,"types":["bdk::database::any::SledDbConfiguration"]},{"text":"impl UnwindSafe for SqliteDbConfiguration","synthetic":true,"types":["bdk::database::any::SqliteDbConfiguration"]},{"text":"impl UnwindSafe for AnyDatabaseConfig","synthetic":true,"types":["bdk::database::any::AnyDatabaseConfig"]},{"text":"impl !UnwindSafe for SqliteDatabase","synthetic":true,"types":["bdk::database::sqlite::SqliteDatabase"]},{"text":"impl !UnwindSafe for MemoryDatabase","synthetic":true,"types":["bdk::database::memory::MemoryDatabase"]},{"text":"impl UnwindSafe for SyncTime","synthetic":true,"types":["bdk::database::SyncTime"]},{"text":"impl UnwindSafe for Error","synthetic":true,"types":["bdk::descriptor::error::Error"]},{"text":"impl UnwindSafe for PkOrF","synthetic":true,"types":["bdk::descriptor::policy::PkOrF"]},{"text":"impl UnwindSafe for SatisfiableItem","synthetic":true,"types":["bdk::descriptor::policy::SatisfiableItem"]},{"text":"impl UnwindSafe for Satisfaction","synthetic":true,"types":["bdk::descriptor::policy::Satisfaction"]},{"text":"impl UnwindSafe for Policy","synthetic":true,"types":["bdk::descriptor::policy::Policy"]},{"text":"impl UnwindSafe for Condition","synthetic":true,"types":["bdk::descriptor::policy::Condition"]},{"text":"impl UnwindSafe for PolicyError","synthetic":true,"types":["bdk::descriptor::policy::PolicyError"]},{"text":"impl<'a> UnwindSafe for BuildSatisfaction<'a>","synthetic":true,"types":["bdk::descriptor::policy::BuildSatisfaction"]},{"text":"impl<K> UnwindSafe for P2Pkh<K> where
        K: UnwindSafe
    ","synthetic":true,"types":["bdk::descriptor::template::P2Pkh"]},{"text":"impl<K> UnwindSafe for P2Wpkh_P2Sh<K> where
        K: UnwindSafe
    ","synthetic":true,"types":["bdk::descriptor::template::P2Wpkh_P2Sh"]},{"text":"impl<K> UnwindSafe for P2Wpkh<K> where
        K: UnwindSafe
    ","synthetic":true,"types":["bdk::descriptor::template::P2Wpkh"]},{"text":"impl<K> UnwindSafe for Bip44<K> where
        K: UnwindSafe
    ","synthetic":true,"types":["bdk::descriptor::template::Bip44"]},{"text":"impl<K> UnwindSafe for Bip44Public<K> where
        K: UnwindSafe
    ","synthetic":true,"types":["bdk::descriptor::template::Bip44Public"]},{"text":"impl<K> UnwindSafe for Bip49<K> where
        K: UnwindSafe
    ","synthetic":true,"types":["bdk::descriptor::template::Bip49"]},{"text":"impl<K> UnwindSafe for Bip49Public<K> where
        K: UnwindSafe
    ","synthetic":true,"types":["bdk::descriptor::template::Bip49Public"]},{"text":"impl<K> UnwindSafe for Bip84<K> where
        K: UnwindSafe
    ","synthetic":true,"types":["bdk::descriptor::template::Bip84"]},{"text":"impl<K> UnwindSafe for Bip84Public<K> where
        K: UnwindSafe
    ","synthetic":true,"types":["bdk::descriptor::template::Bip84Public"]},{"text":"impl UnwindSafe for WordCount","synthetic":true,"types":["bdk::keys::bip39::WordCount"]},{"text":"impl<Ctx> UnwindSafe for DescriptorKey<Ctx> where
        Ctx: UnwindSafe
    ","synthetic":true,"types":["bdk::keys::DescriptorKey"]},{"text":"impl UnwindSafe for ScriptContextEnum","synthetic":true,"types":["bdk::keys::ScriptContextEnum"]},{"text":"impl<Ctx> UnwindSafe for ExtendedKey<Ctx> where
        Ctx: UnwindSafe
    ","synthetic":true,"types":["bdk::keys::ExtendedKey"]},{"text":"impl<K, Ctx> UnwindSafe for GeneratedKey<K, Ctx> where
        Ctx: UnwindSafe,
        K: UnwindSafe
    ","synthetic":true,"types":["bdk::keys::GeneratedKey"]},{"text":"impl UnwindSafe for PrivateKeyGenerateOptions","synthetic":true,"types":["bdk::keys::PrivateKeyGenerateOptions"]},{"text":"impl UnwindSafe for KeyError","synthetic":true,"types":["bdk::keys::KeyError"]},{"text":"impl UnwindSafe for KeychainKind","synthetic":true,"types":["bdk::types::KeychainKind"]},{"text":"impl UnwindSafe for FeeRate","synthetic":true,"types":["bdk::types::FeeRate"]},{"text":"impl UnwindSafe for LocalUtxo","synthetic":true,"types":["bdk::types::LocalUtxo"]},{"text":"impl UnwindSafe for WeightedUtxo","synthetic":true,"types":["bdk::types::WeightedUtxo"]},{"text":"impl UnwindSafe for Utxo","synthetic":true,"types":["bdk::types::Utxo"]},{"text":"impl UnwindSafe for TransactionDetails","synthetic":true,"types":["bdk::types::TransactionDetails"]},{"text":"impl UnwindSafe for BlockTime","synthetic":true,"types":["bdk::types::BlockTime"]},{"text":"impl UnwindSafe for Balance","synthetic":true,"types":["bdk::types::Balance"]},{"text":"impl UnwindSafe for Excess","synthetic":true,"types":["bdk::wallet::coin_selection::Excess"]},{"text":"impl UnwindSafe for CoinSelectionResult","synthetic":true,"types":["bdk::wallet::coin_selection::CoinSelectionResult"]},{"text":"impl UnwindSafe for LargestFirstCoinSelection","synthetic":true,"types":["bdk::wallet::coin_selection::LargestFirstCoinSelection"]},{"text":"impl UnwindSafe for OldestFirstCoinSelection","synthetic":true,"types":["bdk::wallet::coin_selection::OldestFirstCoinSelection"]},{"text":"impl UnwindSafe for BranchAndBoundCoinSelection","synthetic":true,"types":["bdk::wallet::coin_selection::BranchAndBoundCoinSelection"]},{"text":"impl UnwindSafe for FullyNodedExport","synthetic":true,"types":["bdk::wallet::export::FullyNodedExport"]},{"text":"impl UnwindSafe for SignerId","synthetic":true,"types":["bdk::wallet::signer::SignerId"]},{"text":"impl UnwindSafe for SignerError","synthetic":true,"types":["bdk::wallet::signer::SignerError"]},{"text":"impl UnwindSafe for SignerContext","synthetic":true,"types":["bdk::wallet::signer::SignerContext"]},{"text":"impl<S> UnwindSafe for SignerWrapper<S> where
        S: UnwindSafe
    ","synthetic":true,"types":["bdk::wallet::signer::SignerWrapper"]},{"text":"impl UnwindSafe for SignerOrdering","synthetic":true,"types":["bdk::wallet::signer::SignerOrdering"]},{"text":"impl !UnwindSafe for SignersContainer","synthetic":true,"types":["bdk::wallet::signer::SignersContainer"]},{"text":"impl UnwindSafe for SignOptions","synthetic":true,"types":["bdk::wallet::signer::SignOptions"]},{"text":"impl UnwindSafe for TapLeavesOptions","synthetic":true,"types":["bdk::wallet::signer::TapLeavesOptions"]},{"text":"impl UnwindSafe for CreateTx","synthetic":true,"types":["bdk::wallet::tx_builder::CreateTx"]},{"text":"impl UnwindSafe for BumpFee","synthetic":true,"types":["bdk::wallet::tx_builder::BumpFee"]},{"text":"impl<'a, D, Cs, Ctx> !UnwindSafe for TxBuilder<'a, D, Cs, Ctx>","synthetic":true,"types":["bdk::wallet::tx_builder::TxBuilder"]},{"text":"impl UnwindSafe for TxOrdering","synthetic":true,"types":["bdk::wallet::tx_builder::TxOrdering"]},{"text":"impl UnwindSafe for ChangeSpendPolicy","synthetic":true,"types":["bdk::wallet::tx_builder::ChangeSpendPolicy"]},{"text":"impl !UnwindSafe for VerifyError","synthetic":true,"types":["bdk::wallet::verify::VerifyError"]},{"text":"impl UnwindSafe for HWISigner","synthetic":true,"types":["bdk::wallet::hardwaresigner::HWISigner"]},{"text":"impl<D> !UnwindSafe for Wallet<D>","synthetic":true,"types":["bdk::wallet::Wallet"]},{"text":"impl UnwindSafe for AddressIndex","synthetic":true,"types":["bdk::wallet::AddressIndex"]},{"text":"impl UnwindSafe for AddressInfo","synthetic":true,"types":["bdk::wallet::AddressInfo"]},{"text":"impl !UnwindSafe for SyncOptions","synthetic":true,"types":["bdk::wallet::SyncOptions"]}]; -if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file +(function() {var implementors = { +"bdk":[["impl !UnwindSafe for Error",1,["bdk::error::Error"]],["impl !UnwindSafe for AnyBlockchain",1,["bdk::blockchain::any::AnyBlockchain"]],["impl UnwindSafe for AnyBlockchainConfig",1,["bdk::blockchain::any::AnyBlockchainConfig"]],["impl UnwindSafe for ElectrumBlockchain",1,["bdk::blockchain::electrum::ElectrumBlockchain"]],["impl UnwindSafe for ElectrumBlockchainConfig",1,["bdk::blockchain::electrum::ElectrumBlockchainConfig"]],["impl !UnwindSafe for RpcBlockchain",1,["bdk::blockchain::rpc::RpcBlockchain"]],["impl UnwindSafe for RpcConfig",1,["bdk::blockchain::rpc::RpcConfig"]],["impl UnwindSafe for RpcSyncParams",1,["bdk::blockchain::rpc::RpcSyncParams"]],["impl UnwindSafe for Auth",1,["bdk::blockchain::rpc::Auth"]],["impl UnwindSafe for RpcBlockchainFactory",1,["bdk::blockchain::rpc::RpcBlockchainFactory"]],["impl !UnwindSafe for EsploraBlockchain",1,["bdk::blockchain::esplora::blocking::EsploraBlockchain"]],["impl UnwindSafe for EsploraBlockchainConfig",1,["bdk::blockchain::esplora::EsploraBlockchainConfig"]],["impl UnwindSafe for Mempool",1,["bdk::blockchain::compact_filters::peer::Mempool"]],["impl !UnwindSafe for Peer",1,["bdk::blockchain::compact_filters::peer::Peer"]],["impl !UnwindSafe for CompactFiltersBlockchain",1,["bdk::blockchain::compact_filters::CompactFiltersBlockchain"]],["impl UnwindSafe for BitcoinPeerConfig",1,["bdk::blockchain::compact_filters::BitcoinPeerConfig"]],["impl UnwindSafe for CompactFiltersBlockchainConfig",1,["bdk::blockchain::compact_filters::CompactFiltersBlockchainConfig"]],["impl !UnwindSafe for CompactFiltersError",1,["bdk::blockchain::compact_filters::CompactFiltersError"]],["impl UnwindSafe for Capability",1,["bdk::blockchain::Capability"]],["impl UnwindSafe for NoopProgress",1,["bdk::blockchain::NoopProgress"]],["impl UnwindSafe for LogProgress",1,["bdk::blockchain::LogProgress"]],["impl !UnwindSafe for AnyDatabase",1,["bdk::database::any::AnyDatabase"]],["impl !UnwindSafe for AnyBatch",1,["bdk::database::any::AnyBatch"]],["impl UnwindSafe for SledDbConfiguration",1,["bdk::database::any::SledDbConfiguration"]],["impl UnwindSafe for SqliteDbConfiguration",1,["bdk::database::any::SqliteDbConfiguration"]],["impl UnwindSafe for AnyDatabaseConfig",1,["bdk::database::any::AnyDatabaseConfig"]],["impl !UnwindSafe for SqliteDatabase",1,["bdk::database::sqlite::SqliteDatabase"]],["impl !UnwindSafe for MemoryDatabase",1,["bdk::database::memory::MemoryDatabase"]],["impl UnwindSafe for SyncTime",1,["bdk::database::SyncTime"]],["impl UnwindSafe for Error",1,["bdk::descriptor::error::Error"]],["impl UnwindSafe for PkOrF",1,["bdk::descriptor::policy::PkOrF"]],["impl UnwindSafe for SatisfiableItem",1,["bdk::descriptor::policy::SatisfiableItem"]],["impl UnwindSafe for Satisfaction",1,["bdk::descriptor::policy::Satisfaction"]],["impl UnwindSafe for Policy",1,["bdk::descriptor::policy::Policy"]],["impl UnwindSafe for Condition",1,["bdk::descriptor::policy::Condition"]],["impl UnwindSafe for PolicyError",1,["bdk::descriptor::policy::PolicyError"]],["impl<'a> UnwindSafe for BuildSatisfaction<'a>",1,["bdk::descriptor::policy::BuildSatisfaction"]],["impl<K> UnwindSafe for P2Pkh<K>where
        K: UnwindSafe,
    ",1,["bdk::descriptor::template::P2Pkh"]],["impl<K> UnwindSafe for P2Wpkh_P2Sh<K>where
        K: UnwindSafe,
    ",1,["bdk::descriptor::template::P2Wpkh_P2Sh"]],["impl<K> UnwindSafe for P2Wpkh<K>where
        K: UnwindSafe,
    ",1,["bdk::descriptor::template::P2Wpkh"]],["impl<K> UnwindSafe for Bip44<K>where
        K: UnwindSafe,
    ",1,["bdk::descriptor::template::Bip44"]],["impl<K> UnwindSafe for Bip44Public<K>where
        K: UnwindSafe,
    ",1,["bdk::descriptor::template::Bip44Public"]],["impl<K> UnwindSafe for Bip49<K>where
        K: UnwindSafe,
    ",1,["bdk::descriptor::template::Bip49"]],["impl<K> UnwindSafe for Bip49Public<K>where
        K: UnwindSafe,
    ",1,["bdk::descriptor::template::Bip49Public"]],["impl<K> UnwindSafe for Bip84<K>where
        K: UnwindSafe,
    ",1,["bdk::descriptor::template::Bip84"]],["impl<K> UnwindSafe for Bip84Public<K>where
        K: UnwindSafe,
    ",1,["bdk::descriptor::template::Bip84Public"]],["impl UnwindSafe for WordCount",1,["bdk::keys::bip39::WordCount"]],["impl<Ctx> UnwindSafe for DescriptorKey<Ctx>where
        Ctx: UnwindSafe,
    ",1,["bdk::keys::DescriptorKey"]],["impl UnwindSafe for ScriptContextEnum",1,["bdk::keys::ScriptContextEnum"]],["impl<Ctx> UnwindSafe for ExtendedKey<Ctx>where
        Ctx: UnwindSafe,
    ",1,["bdk::keys::ExtendedKey"]],["impl<K, Ctx> UnwindSafe for GeneratedKey<K, Ctx>where
        Ctx: UnwindSafe,
        K: UnwindSafe,
    ",1,["bdk::keys::GeneratedKey"]],["impl UnwindSafe for PrivateKeyGenerateOptions",1,["bdk::keys::PrivateKeyGenerateOptions"]],["impl UnwindSafe for KeyError",1,["bdk::keys::KeyError"]],["impl UnwindSafe for KeychainKind",1,["bdk::types::KeychainKind"]],["impl UnwindSafe for FeeRate",1,["bdk::types::FeeRate"]],["impl UnwindSafe for LocalUtxo",1,["bdk::types::LocalUtxo"]],["impl UnwindSafe for WeightedUtxo",1,["bdk::types::WeightedUtxo"]],["impl UnwindSafe for Utxo",1,["bdk::types::Utxo"]],["impl UnwindSafe for TransactionDetails",1,["bdk::types::TransactionDetails"]],["impl UnwindSafe for BlockTime",1,["bdk::types::BlockTime"]],["impl UnwindSafe for Balance",1,["bdk::types::Balance"]],["impl UnwindSafe for Excess",1,["bdk::wallet::coin_selection::Excess"]],["impl UnwindSafe for CoinSelectionResult",1,["bdk::wallet::coin_selection::CoinSelectionResult"]],["impl UnwindSafe for LargestFirstCoinSelection",1,["bdk::wallet::coin_selection::LargestFirstCoinSelection"]],["impl UnwindSafe for OldestFirstCoinSelection",1,["bdk::wallet::coin_selection::OldestFirstCoinSelection"]],["impl UnwindSafe for BranchAndBoundCoinSelection",1,["bdk::wallet::coin_selection::BranchAndBoundCoinSelection"]],["impl UnwindSafe for FullyNodedExport",1,["bdk::wallet::export::FullyNodedExport"]],["impl UnwindSafe for SignerId",1,["bdk::wallet::signer::SignerId"]],["impl UnwindSafe for SignerError",1,["bdk::wallet::signer::SignerError"]],["impl UnwindSafe for SignerContext",1,["bdk::wallet::signer::SignerContext"]],["impl<S> UnwindSafe for SignerWrapper<S>where
        S: UnwindSafe,
    ",1,["bdk::wallet::signer::SignerWrapper"]],["impl UnwindSafe for SignerOrdering",1,["bdk::wallet::signer::SignerOrdering"]],["impl !UnwindSafe for SignersContainer",1,["bdk::wallet::signer::SignersContainer"]],["impl UnwindSafe for SignOptions",1,["bdk::wallet::signer::SignOptions"]],["impl UnwindSafe for TapLeavesOptions",1,["bdk::wallet::signer::TapLeavesOptions"]],["impl UnwindSafe for CreateTx",1,["bdk::wallet::tx_builder::CreateTx"]],["impl UnwindSafe for BumpFee",1,["bdk::wallet::tx_builder::BumpFee"]],["impl<'a, D, Cs, Ctx> !UnwindSafe for TxBuilder<'a, D, Cs, Ctx>",1,["bdk::wallet::tx_builder::TxBuilder"]],["impl UnwindSafe for TxOrdering",1,["bdk::wallet::tx_builder::TxOrdering"]],["impl UnwindSafe for ChangeSpendPolicy",1,["bdk::wallet::tx_builder::ChangeSpendPolicy"]],["impl !UnwindSafe for VerifyError",1,["bdk::wallet::verify::VerifyError"]],["impl UnwindSafe for HWISigner",1,["bdk::wallet::hardwaresigner::HWISigner"]],["impl<D> !UnwindSafe for Wallet<D>",1,["bdk::wallet::Wallet"]],["impl UnwindSafe for AddressIndex",1,["bdk::wallet::AddressIndex"]],["impl UnwindSafe for AddressInfo",1,["bdk::wallet::AddressInfo"]],["impl !UnwindSafe for SyncOptions",1,["bdk::wallet::SyncOptions"]]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/implementors/core/str/traits/trait.FromStr.js b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/implementors/core/str/traits/trait.FromStr.js index 1d1171e17f..ce96fcb022 100644 --- a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/implementors/core/str/traits/trait.FromStr.js +++ b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/implementors/core/str/traits/trait.FromStr.js @@ -1,3 +1,3 @@ -(function() {var implementors = {}; -implementors["bdk"] = [{"text":"impl FromStr for FullyNodedExport","synthetic":false,"types":["bdk::wallet::export::FullyNodedExport"]}]; -if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file +(function() {var implementors = { +"bdk":[["impl FromStr for FullyNodedExport"]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/implementors/miniscript/miniscript/context/trait.ScriptContext.js b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/implementors/miniscript/miniscript/context/trait.ScriptContext.js new file mode 100644 index 0000000000..bb0690bde5 --- /dev/null +++ b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/implementors/miniscript/miniscript/context/trait.ScriptContext.js @@ -0,0 +1,3 @@ +(function() {var implementors = { +"bdk":[] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/implementors/serde/de/trait.Deserialize.js b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/implementors/serde/de/trait.Deserialize.js index 465047d48d..dbaf2798b7 100644 --- a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/implementors/serde/de/trait.Deserialize.js +++ b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/implementors/serde/de/trait.Deserialize.js @@ -1,3 +1,3 @@ -(function() {var implementors = {}; -implementors["bdk"] = [{"text":"impl<'de> Deserialize<'de> for AnyBlockchainConfig","synthetic":false,"types":["bdk::blockchain::any::AnyBlockchainConfig"]},{"text":"impl<'de> Deserialize<'de> for ElectrumBlockchainConfig","synthetic":false,"types":["bdk::blockchain::electrum::ElectrumBlockchainConfig"]},{"text":"impl<'de> Deserialize<'de> for RpcConfig","synthetic":false,"types":["bdk::blockchain::rpc::RpcConfig"]},{"text":"impl<'de> Deserialize<'de> for RpcSyncParams","synthetic":false,"types":["bdk::blockchain::rpc::RpcSyncParams"]},{"text":"impl<'de> Deserialize<'de> for Auth","synthetic":false,"types":["bdk::blockchain::rpc::Auth"]},{"text":"impl<'de> Deserialize<'de> for EsploraBlockchainConfig","synthetic":false,"types":["bdk::blockchain::esplora::EsploraBlockchainConfig"]},{"text":"impl<'de> Deserialize<'de> for BitcoinPeerConfig","synthetic":false,"types":["bdk::blockchain::compact_filters::BitcoinPeerConfig"]},{"text":"impl<'de> Deserialize<'de> for CompactFiltersBlockchainConfig","synthetic":false,"types":["bdk::blockchain::compact_filters::CompactFiltersBlockchainConfig"]},{"text":"impl<'de> Deserialize<'de> for SledDbConfiguration","synthetic":false,"types":["bdk::database::any::SledDbConfiguration"]},{"text":"impl<'de> Deserialize<'de> for SqliteDbConfiguration","synthetic":false,"types":["bdk::database::any::SqliteDbConfiguration"]},{"text":"impl<'de> Deserialize<'de> for AnyDatabaseConfig","synthetic":false,"types":["bdk::database::any::AnyDatabaseConfig"]},{"text":"impl<'de> Deserialize<'de> for SyncTime","synthetic":false,"types":["bdk::database::SyncTime"]},{"text":"impl<'de> Deserialize<'de> for KeychainKind","synthetic":false,"types":["bdk::types::KeychainKind"]},{"text":"impl<'de> Deserialize<'de> for LocalUtxo","synthetic":false,"types":["bdk::types::LocalUtxo"]},{"text":"impl<'de> Deserialize<'de> for TransactionDetails","synthetic":false,"types":["bdk::types::TransactionDetails"]},{"text":"impl<'de> Deserialize<'de> for BlockTime","synthetic":false,"types":["bdk::types::BlockTime"]},{"text":"impl<'de> Deserialize<'de> for Balance","synthetic":false,"types":["bdk::types::Balance"]},{"text":"impl<'de> Deserialize<'de> for FullyNodedExport","synthetic":false,"types":["bdk::wallet::export::FullyNodedExport"]}]; -if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file +(function() {var implementors = { +"bdk":[["impl<'de> Deserialize<'de> for AnyBlockchainConfig"],["impl<'de> Deserialize<'de> for ElectrumBlockchainConfig"],["impl<'de> Deserialize<'de> for RpcConfig"],["impl<'de> Deserialize<'de> for RpcSyncParams"],["impl<'de> Deserialize<'de> for Auth"],["impl<'de> Deserialize<'de> for EsploraBlockchainConfig"],["impl<'de> Deserialize<'de> for BitcoinPeerConfig"],["impl<'de> Deserialize<'de> for CompactFiltersBlockchainConfig"],["impl<'de> Deserialize<'de> for SledDbConfiguration"],["impl<'de> Deserialize<'de> for SqliteDbConfiguration"],["impl<'de> Deserialize<'de> for AnyDatabaseConfig"],["impl<'de> Deserialize<'de> for SyncTime"],["impl<'de> Deserialize<'de> for KeychainKind"],["impl<'de> Deserialize<'de> for LocalUtxo"],["impl<'de> Deserialize<'de> for TransactionDetails"],["impl<'de> Deserialize<'de> for BlockTime"],["impl<'de> Deserialize<'de> for Balance"],["impl<'de> Deserialize<'de> for FullyNodedExport"]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/implementors/serde/ser/trait.Serialize.js b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/implementors/serde/ser/trait.Serialize.js index 233582de77..e897cc0fc9 100644 --- a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/implementors/serde/ser/trait.Serialize.js +++ b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/implementors/serde/ser/trait.Serialize.js @@ -1,3 +1,3 @@ -(function() {var implementors = {}; -implementors["bdk"] = [{"text":"impl Serialize for AnyBlockchainConfig","synthetic":false,"types":["bdk::blockchain::any::AnyBlockchainConfig"]},{"text":"impl Serialize for ElectrumBlockchainConfig","synthetic":false,"types":["bdk::blockchain::electrum::ElectrumBlockchainConfig"]},{"text":"impl Serialize for RpcConfig","synthetic":false,"types":["bdk::blockchain::rpc::RpcConfig"]},{"text":"impl Serialize for RpcSyncParams","synthetic":false,"types":["bdk::blockchain::rpc::RpcSyncParams"]},{"text":"impl Serialize for Auth","synthetic":false,"types":["bdk::blockchain::rpc::Auth"]},{"text":"impl Serialize for EsploraBlockchainConfig","synthetic":false,"types":["bdk::blockchain::esplora::EsploraBlockchainConfig"]},{"text":"impl Serialize for BitcoinPeerConfig","synthetic":false,"types":["bdk::blockchain::compact_filters::BitcoinPeerConfig"]},{"text":"impl Serialize for CompactFiltersBlockchainConfig","synthetic":false,"types":["bdk::blockchain::compact_filters::CompactFiltersBlockchainConfig"]},{"text":"impl Serialize for SledDbConfiguration","synthetic":false,"types":["bdk::database::any::SledDbConfiguration"]},{"text":"impl Serialize for SqliteDbConfiguration","synthetic":false,"types":["bdk::database::any::SqliteDbConfiguration"]},{"text":"impl Serialize for AnyDatabaseConfig","synthetic":false,"types":["bdk::database::any::AnyDatabaseConfig"]},{"text":"impl Serialize for SyncTime","synthetic":false,"types":["bdk::database::SyncTime"]},{"text":"impl Serialize for PkOrF","synthetic":false,"types":["bdk::descriptor::policy::PkOrF"]},{"text":"impl Serialize for SatisfiableItem","synthetic":false,"types":["bdk::descriptor::policy::SatisfiableItem"]},{"text":"impl Serialize for Satisfaction","synthetic":false,"types":["bdk::descriptor::policy::Satisfaction"]},{"text":"impl Serialize for Policy","synthetic":false,"types":["bdk::descriptor::policy::Policy"]},{"text":"impl Serialize for Condition","synthetic":false,"types":["bdk::descriptor::policy::Condition"]},{"text":"impl Serialize for KeychainKind","synthetic":false,"types":["bdk::types::KeychainKind"]},{"text":"impl Serialize for LocalUtxo","synthetic":false,"types":["bdk::types::LocalUtxo"]},{"text":"impl Serialize for TransactionDetails","synthetic":false,"types":["bdk::types::TransactionDetails"]},{"text":"impl Serialize for BlockTime","synthetic":false,"types":["bdk::types::BlockTime"]},{"text":"impl Serialize for Balance","synthetic":false,"types":["bdk::types::Balance"]},{"text":"impl Serialize for FullyNodedExport","synthetic":false,"types":["bdk::wallet::export::FullyNodedExport"]}]; -if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file +(function() {var implementors = { +"bdk":[["impl Serialize for AnyBlockchainConfig"],["impl Serialize for ElectrumBlockchainConfig"],["impl Serialize for RpcConfig"],["impl Serialize for RpcSyncParams"],["impl Serialize for Auth"],["impl Serialize for EsploraBlockchainConfig"],["impl Serialize for BitcoinPeerConfig"],["impl Serialize for CompactFiltersBlockchainConfig"],["impl Serialize for SledDbConfiguration"],["impl Serialize for SqliteDbConfiguration"],["impl Serialize for AnyDatabaseConfig"],["impl Serialize for SyncTime"],["impl Serialize for PkOrF"],["impl Serialize for SatisfiableItem"],["impl Serialize for Satisfaction"],["impl Serialize for Policy"],["impl Serialize for Condition"],["impl Serialize for KeychainKind"],["impl Serialize for LocalUtxo"],["impl Serialize for TransactionDetails"],["impl Serialize for BlockTime"],["impl Serialize for Balance"],["impl Serialize for FullyNodedExport"]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/implementors/std/error/trait.Error.js b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/implementors/std/error/trait.Error.js deleted file mode 100644 index 6bc915b9df..0000000000 --- a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/implementors/std/error/trait.Error.js +++ /dev/null @@ -1,3 +0,0 @@ -(function() {var implementors = {}; -implementors["bdk"] = [{"text":"impl Error for Error","synthetic":false,"types":["bdk::error::Error"]},{"text":"impl Error for CompactFiltersError","synthetic":false,"types":["bdk::blockchain::compact_filters::CompactFiltersError"]},{"text":"impl Error for Error","synthetic":false,"types":["bdk::descriptor::error::Error"]},{"text":"impl Error for PolicyError","synthetic":false,"types":["bdk::descriptor::policy::PolicyError"]},{"text":"impl Error for KeyError","synthetic":false,"types":["bdk::keys::KeyError"]},{"text":"impl Error for SignerError","synthetic":false,"types":["bdk::wallet::signer::SignerError"]},{"text":"impl Error for VerifyError","synthetic":false,"types":["bdk::wallet::verify::VerifyError"]}]; -if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/light.css b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/light.css deleted file mode 100644 index 4891ff50e0..0000000000 --- a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/light.css +++ /dev/null @@ -1 +0,0 @@ - body{background-color:white;color:black;}h1,h2,h3,h4{color:black;}h1.fqn{border-bottom-color:#DDDDDD;}h2,h3,h4{border-bottom-color:#DDDDDD;}.in-band{background-color:white;}.invisible{background:rgba(0,0,0,0);}.docblock code,.docblock-short code{background-color:#F5F5F5;}pre,.rustdoc.source .example-wrap{background-color:#F5F5F5;}.sidebar,.mobile-topbar,.sidebar-menu-toggle{background-color:#F5F5F5;}*{scrollbar-color:rgba(36,37,39,0.6) #e6e6e6;}.sidebar{scrollbar-color:rgba(36,37,39,0.6) #d9d9d9;}.rust-logo{}::-webkit-scrollbar-track{background-color:#ecebeb;}::-webkit-scrollbar-thumb{background-color:rgba(36,37,39,0.6);}.sidebar::-webkit-scrollbar-track{background-color:#dcdcdc;}.sidebar::-webkit-scrollbar-thumb{background-color:rgba(36,37,39,0.6);}.sidebar .current{background-color:#fff;}.source .sidebar{background-color:#f1f1f1;}.block a:hover{background:#F5F5F5;}.line-numbers span{color:#c67e2d;}.line-numbers .line-highlighted{background-color:#FDFFD3 !important;}.docblock h1,.docblock h2,.docblock h3,.docblock h4,.docblock h5,.docblock h6{border-bottom-color:#ddd;}.docblock table td,.docblock table th{border-color:#ddd;}.content .method .where,.content .fn .where,.content .where.fmt-newline{color:#4E4C4C;}.search-results a:hover{background-color:#ddd;}.search-results a:focus{color:#000 !important;background-color:#ccc;}.search-results a:focus span{color:#000 !important;}a.result-trait:focus{background-color:#c7b6ff;}a.result-traitalias:focus{background-color:#c7b6ff;}a.result-mod:focus,a.result-externcrate:focus{background-color:#afc6e4;}a.result-enum:focus{background-color:#e7b1a0;}a.result-struct:focus{background-color:#e7b1a0;}a.result-union:focus{background-color:#e7b1a0;}a.result-fn:focus,a.result-method:focus,a.result-tymethod:focus{background-color:#c6afb3;}a.result-type:focus{background-color:#e7b1a0;}a.result-associatedtype:focus{background-color:#afc6e4;}a.result-foreigntype:focus{background-color:#e7b1a0;}a.result-attr:focus,a.result-derive:focus,a.result-macro:focus{background-color:#8ce488;}a.result-constant:focus,a.result-static:focus{background-color:#afc6e4;}a.result-primitive:focus{background-color:#e7b1a0;}a.result-keyword:focus{background-color:#afc6e4;}.content .item-info::before{color:#ccc;}.content span.enum,.content a.enum,.block a.current.enum{color:#AD378A;}.content span.struct,.content a.struct,.block a.current.struct{color:#AD378A;}.content span.type,.content a.type,.block a.current.type{color:#AD378A;}.content span.foreigntype,.content a.foreigntype,.block a.current.foreigntype{color:#3873AD;}.content span.associatedtype,.content a.associatedtype,.block a.current.associatedtype{color:#3873AD;}.content span.attr,.content a.attr,.block a.current.attr,.content span.derive,.content a.derive,.block a.current.derive,.content span.macro,.content a.macro,.block a.current.macro{color:#068000;}.content span.union,.content a.union,.block a.current.union{color:#AD378A;}.content span.constant,.content a.constant,.block a.current.constant,.content span.static,.content a.static,.block a.current.static{color:#3873AD;}.content span.primitive,.content a.primitive,.block a.current.primitive{color:#AD378A;}.content span.externcrate,.content span.mod,.content a.mod,.block a.current.mod{color:#3873AD;}.content span.trait,.content a.trait,.block a.current.trait{color:#6E4FC9;}.content span.traitalias,.content a.traitalias,.block a.current.traitalias{color:#5137AD;}.content span.fn,.content a.fn,.block a.current.fn,.content span.method,.content a.method,.block a.current.method,.content span.tymethod,.content a.tymethod,.block a.current.tymethod,.content .fnname{color:#AD7C37;}.content span.keyword,.content a.keyword,.block a.current.keyword{color:#3873AD;}.sidebar a{color:#356da4;}.sidebar a.current.enum{color:#a63283;}.sidebar a.current.struct{color:#a63283;}.sidebar a.current.type{color:#a63283;}.sidebar a.current.associatedtype{color:#356da4;}.sidebar a.current.foreigntype{color:#356da4;}.sidebar a.current.attr,.sidebar a.current.derive,.sidebar a.current.macro{color:#067901;}.sidebar a.current.union{color:#a63283;}.sidebar a.current.constant .sidebar a.current.static{color:#356da4;}.sidebar a.current.primitive{color:#a63283;}.sidebar a.current.externcrate .sidebar a.current.mod{color:#356da4;}.sidebar a.current.trait{color:#6849c3;}.sidebar a.current.traitalias{color:#4b349e;}.sidebar a.current.fn,.sidebar a.current.method,.sidebar a.current.tymethod{color:#32d479;}.sidebar a.current.keyword{color:#356da4;}nav.main .current{border-top-color:#000;border-bottom-color:#000;}nav.main .separator{border:1px solid #000;}a{color:#3873AD;}a#toggle-all-docs,a.anchor,.small-section-header a,#source-sidebar a,pre.rust a,.sidebar h2 a,.sidebar h3 a,.in-band a{color:#000;}.search-results a{color:initial;}a.test-arrow{color:#f5f5f5;}body.source .example-wrap pre.rust a{background:#eee;}details.rustdoc-toggle>summary.hideme>span,details.rustdoc-toggle>summary::before,details.undocumented>summary::before{color:#999;}#crate-search,.search-input{color:#555;background-color:white;border-color:#e0e0e0;}.search-input:focus{border-color:#66afe9;}.module-item .stab,.import-item .stab{color:#000;}.stab.unstable{background:#FFF5D6;border-color:#FFC600;}.stab.deprecated{background:#ffc4c4;border-color:#db7b7b;}.stab.portability{background:#F3DFFF;border-color:#b07bdb;}.stab.portability>code{background:none;}#help>div{background:#e9e9e9;border-color:#bfbfbf;}#help span.bottom,#help span.top{border-color:#bfbfbf;}.rightside,.out-of-band{color:grey;}.result-name .primitive>i,.result-name .keyword>i{color:black;}.line-numbers :target{background-color:transparent;}pre.rust .kw{color:#8959A8;}pre.rust .kw-2,pre.rust .prelude-ty{color:#4271AE;}pre.rust .number,pre.rust .string{color:#718C00;}pre.rust .self,pre.rust .bool-val,pre.rust .prelude-val,pre.rust .attribute,pre.rust .attribute .ident{color:#C82829;}pre.rust .comment{color:#8E908C;}pre.rust .doccomment{color:#4D4D4C;}pre.rust .macro,pre.rust .macro-nonterminal{color:#3E999F;}pre.rust .lifetime{color:#B76514;}pre.rust .question-mark{color:#ff9011;}.example-wrap>pre.line-number{border-color:#c7c7c7;}a.test-arrow{background-color:rgb(78,139,202,0.2);}a.test-arrow:hover{background-color:#4e8bca;}.toggle-label,.code-attribute{color:#999;}:target{background:#FDFFD3;border-right:3px solid #AD7C37;}pre.compile_fail{border-left:2px solid rgba(255,0,0,.5);}pre.compile_fail:hover,.information:hover+pre.compile_fail{border-left:2px solid #f00;}pre.should_panic{border-left:2px solid rgba(255,0,0,.5);}pre.should_panic:hover,.information:hover+pre.should_panic{border-left:2px solid #f00;}pre.ignore{border-left:2px solid rgba(255,142,0,.6);}pre.ignore:hover,.information:hover+pre.ignore{border-left:2px solid #ff9200;}.tooltip.compile_fail{color:rgba(255,0,0,.5);}.information>.compile_fail:hover{color:#f00;}.tooltip.should_panic{color:rgba(255,0,0,.5);}.information>.should_panic:hover{color:#f00;}.tooltip.ignore{color:rgba(255,142,0,.6);}.information>.ignore:hover{color:#ff9200;}.search-failed a{color:#3873AD;}.tooltip::after{background-color:#000;color:#fff;}.tooltip::before{border-color:transparent black transparent transparent;}.notable-traits-tooltiptext{background-color:#eee;border-color:#999;}.notable-traits-tooltiptext .notable{border-bottom-color:#DDDDDD;}#titles>button:not(.selected){background-color:#e6e6e6;border-top-color:#e6e6e6;}#titles>button:hover,#titles>button.selected{background-color:#ffffff;border-top-color:#0089ff;}#titles>button>div.count{color:#888;}@media (max-width:700px){.sidebar-menu{background-color:#F5F5F5;border-bottom-color:#e0e0e0;border-right-color:#e0e0e0;}.sidebar-elems{background-color:#F5F5F5;border-right-color:#000;}#sidebar-filler{background-color:#F5F5F5;border-bottom-color:#e0e0e0;}}kbd{color:#000;background-color:#fafbfc;border-color:#d1d5da;border-bottom-color:#c6cbd1;box-shadow-color:#c6cbd1;}#theme-picker,#settings-menu,#help-button{border-color:#e0e0e0;background-color:#fff;}#theme-picker:hover,#theme-picker:focus,#settings-menu:hover,#settings-menu:focus,#help-button:hover,#help-button:focus{border-color:#717171;}#copy-path{color:#999;}#copy-path>img{filter:invert(50%);}#copy-path:hover>img{filter:invert(35%);}#theme-choices{border-color:#ccc;background-color:#fff;}#theme-choices>button:not(:first-child){border-top-color:#e0e0e0;}#theme-choices>button:hover,#theme-choices>button:focus{background-color:#eee;}@media (max-width:700px){#theme-picker{background:#fff;}}.search-results .result-name span.alias{color:#000;}.search-results .result-name span.grey{color:#999;}#sidebar-toggle{background-color:#F5F5F5;}#sidebar-toggle:hover{background-color:#E0E0E0;}#source-sidebar{background-color:#F5F5F5;}#source-sidebar>.title{border-bottom-color:#ccc;}div.files>a:hover,div.name:hover{background-color:#E0E0E0;}div.files>.selected{background-color:#fff;}.setting-line>.title{border-bottom-color:#D5D5D5;} \ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/main.js b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/main.js deleted file mode 100644 index 635f56fb6f..0000000000 --- a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/main.js +++ /dev/null @@ -1,8 +0,0 @@ -if(!String.prototype.startsWith){String.prototype.startsWith=function(searchString,position){position=position||0;return this.indexOf(searchString,position)===position}}if(!String.prototype.endsWith){String.prototype.endsWith=function(suffix,length){var l=length||this.length;return this.indexOf(suffix,l-suffix.length)!==-1}}if(!DOMTokenList.prototype.add){DOMTokenList.prototype.add=function(className){if(className&&!hasClass(this,className)){if(this.className&&this.className.length>0){this.className+=" "+className}else{this.className=className}}}}if(!DOMTokenList.prototype.remove){DOMTokenList.prototype.remove=function(className){if(className&&this.className){this.className=(" "+this.className+" ").replace(" "+className+" "," ").trim()}}}function getVar(name){var el=document.getElementById("rustdoc-vars");if(el){return el.attributes["data-"+name].value}else{return null}}function resourcePath(basename,extension){return getVar("root-path")+basename+getVar("resource-suffix")+extension}(function(){window.rootPath=getVar("root-path");window.currentCrate=getVar("current-crate");window.searchJS=resourcePath("search",".js");window.searchIndexJS=resourcePath("search-index",".js");var sidebarVars=document.getElementById("sidebar-vars");if(sidebarVars){window.sidebarCurrent={name:sidebarVars.attributes["data-name"].value,ty:sidebarVars.attributes["data-ty"].value,relpath:sidebarVars.attributes["data-relpath"].value,};var mobileLocationTitle=document.querySelector(".mobile-topbar h2.location");var locationTitle=document.querySelector(".sidebar h2.location");if(mobileLocationTitle&&locationTitle){mobileLocationTitle.innerText=locationTitle.innerText}}}());function getVirtualKey(ev){if("key"in ev&&typeof ev.key!="undefined"){return ev.key}var c=ev.charCode||ev.keyCode;if(c==27){return"Escape"}return String.fromCharCode(c)}var THEME_PICKER_ELEMENT_ID="theme-picker";var THEMES_ELEMENT_ID="theme-choices";var MAIN_ID="main-content";function getThemesElement(){return document.getElementById(THEMES_ELEMENT_ID)}function getThemePickerElement(){return document.getElementById(THEME_PICKER_ELEMENT_ID)}function getNakedUrl(){return window.location.href.split("?")[0].split("#")[0]}function showThemeButtonState(){var themePicker=getThemePickerElement();var themeChoices=getThemesElement();themeChoices.style.display="block";themePicker.style.borderBottomRightRadius="0";themePicker.style.borderBottomLeftRadius="0"}function hideThemeButtonState(){var themePicker=getThemePickerElement();var themeChoices=getThemesElement();themeChoices.style.display="none";themePicker.style.borderBottomRightRadius="3px";themePicker.style.borderBottomLeftRadius="3px"}(function(){if(!document.location.href.startsWith("file:///")){return}var themeChoices=getThemesElement();var themePicker=getThemePickerElement();var availableThemes=getVar("themes").split(",");removeClass(themeChoices.parentElement,"hidden");function switchThemeButtonState(){if(themeChoices.style.display==="block"){hideThemeButtonState()}else{showThemeButtonState()}}function handleThemeButtonsBlur(e){var active=document.activeElement;var related=e.relatedTarget;if(active.id!==THEME_PICKER_ELEMENT_ID&&(!active.parentNode||active.parentNode.id!==THEMES_ELEMENT_ID)&&(!related||(related.id!==THEME_PICKER_ELEMENT_ID&&(!related.parentNode||related.parentNode.id!==THEMES_ELEMENT_ID)))){hideThemeButtonState()}}themePicker.onclick=switchThemeButtonState;themePicker.onblur=handleThemeButtonsBlur;availableThemes.forEach(function(item){var but=document.createElement("button");but.textContent=item;but.onclick=function(){switchTheme(window.currentTheme,window.mainTheme,item,true);useSystemTheme(false)};but.onblur=handleThemeButtonsBlur;themeChoices.appendChild(but)})}());(function(){"use strict";window.searchState={loadingText:"Loading search results...",input:document.getElementsByClassName("search-input")[0],outputElement:function(){return document.getElementById("search")},title:document.title,titleBeforeSearch:document.title,timeout:null,currentTab:0,focusedByTab:[null,null,null],clearInputTimeout:function(){if(searchState.timeout!==null){clearTimeout(searchState.timeout);searchState.timeout=null}},focus:function(){searchState.input.focus()},defocus:function(){searchState.input.blur()},showResults:function(search){if(search===null||typeof search==='undefined'){search=searchState.outputElement()}addClass(main,"hidden");removeClass(search,"hidden");searchState.mouseMovedAfterSearch=false;document.title=searchState.title},hideResults:function(search){if(search===null||typeof search==='undefined'){search=searchState.outputElement()}addClass(search,"hidden");removeClass(main,"hidden");document.title=searchState.titleBeforeSearch;if(searchState.browserSupportsHistoryApi()){history.replaceState("",window.currentCrate+" - Rust",getNakedUrl()+window.location.hash)}},getQueryStringParams:function(){var params={};window.location.search.substring(1).split("&").map(function(s){var pair=s.split("=");params[decodeURIComponent(pair[0])]=typeof pair[1]==="undefined"?null:decodeURIComponent(pair[1])});return params},putBackSearch:function(search_input){var search=searchState.outputElement();if(search_input.value!==""&&hasClass(search,"hidden")){searchState.showResults(search);if(searchState.browserSupportsHistoryApi()){var extra="?search="+encodeURIComponent(search_input.value);history.replaceState(search_input.value,"",getNakedUrl()+extra+window.location.hash)}document.title=searchState.title}},browserSupportsHistoryApi:function(){return window.history&&typeof window.history.pushState==="function"},setup:function(){var search_input=searchState.input;if(!searchState.input){return}function loadScript(url){var script=document.createElement('script');script.src=url;document.head.append(script)}var searchLoaded=false;function loadSearch(){if(!searchLoaded){searchLoaded=true;loadScript(window.searchJS);loadScript(window.searchIndexJS)}}search_input.addEventListener("focus",function(){searchState.putBackSearch(this);search_input.origPlaceholder=searchState.input.placeholder;search_input.placeholder="Type your search here.";loadSearch()});search_input.addEventListener("blur",function(){search_input.placeholder=searchState.input.origPlaceholder});if(search_input.value!=''){loadSearch()}var params=searchState.getQueryStringParams();if(params.search!==undefined){var search=searchState.outputElement();search.innerHTML="

    "+searchState.loadingText+"

    ";searchState.showResults(search);loadSearch()}},};function getPageId(){if(window.location.hash){var tmp=window.location.hash.replace(/^#/,"");if(tmp.length>0){return tmp}}return null}var toggleAllDocsId="toggle-all-docs";var main=document.getElementById(MAIN_ID);var savedHash="";function handleHashes(ev){var elem;var search=searchState.outputElement();if(ev!==null&&search&&!hasClass(search,"hidden")&&ev.newURL){searchState.hideResults(search);var hash=ev.newURL.slice(ev.newURL.indexOf("#")+1);if(searchState.browserSupportsHistoryApi()){history.replaceState(hash,"",getNakedUrl()+window.location.search+"#"+hash)}elem=document.getElementById(hash);if(elem){elem.scrollIntoView()}}if(savedHash!==window.location.hash){savedHash=window.location.hash;if(savedHash.length===0){return}expandSection(savedHash.slice(1))}}function onHashChange(ev){var sidebar=document.getElementsByClassName("sidebar")[0];removeClass(sidebar,"shown");handleHashes(ev)}function openParentDetails(elem){while(elem){if(elem.tagName==="DETAILS"){elem.open=true}elem=elem.parentNode}}function expandSection(id){openParentDetails(document.getElementById(id))}function getHelpElement(build){if(build){buildHelperPopup()}return document.getElementById("help")}function displayHelp(display,ev,help){if(display){help=help?help:getHelpElement(true);if(hasClass(help,"hidden")){ev.preventDefault();removeClass(help,"hidden");addClass(document.body,"blur")}}else{help=help?help:getHelpElement(false);if(help&&!hasClass(help,"hidden")){ev.preventDefault();addClass(help,"hidden");removeClass(document.body,"blur")}}}function handleEscape(ev){var help=getHelpElement(false);var search=searchState.outputElement();if(help&&!hasClass(help,"hidden")){displayHelp(false,ev,help)}else if(search&&!hasClass(search,"hidden")){searchState.clearInputTimeout();ev.preventDefault();searchState.hideResults(search)}searchState.defocus();hideThemeButtonState()}var disableShortcuts=getSettingValue("disable-shortcuts")==="true";function handleShortcut(ev){if(ev.ctrlKey||ev.altKey||ev.metaKey||disableShortcuts){return}if(document.activeElement.tagName==="INPUT"){switch(getVirtualKey(ev)){case"Escape":handleEscape(ev);break}}else{switch(getVirtualKey(ev)){case"Escape":handleEscape(ev);break;case"s":case"S":displayHelp(false,ev);ev.preventDefault();searchState.focus();break;case"+":case"-":ev.preventDefault();toggleAllDocs();break;case"?":displayHelp(true,ev);break;case"t":case"T":displayHelp(false,ev);ev.preventDefault();var themePicker=getThemePickerElement();themePicker.click();themePicker.focus();break;default:if(getThemePickerElement().parentNode.contains(ev.target)){handleThemeKeyDown(ev)}}}}function handleThemeKeyDown(ev){var active=document.activeElement;var themes=getThemesElement();switch(getVirtualKey(ev)){case"ArrowUp":ev.preventDefault();if(active.previousElementSibling&&ev.target.id!==THEME_PICKER_ELEMENT_ID){active.previousElementSibling.focus()}else{showThemeButtonState();themes.lastElementChild.focus()}break;case"ArrowDown":ev.preventDefault();if(active.nextElementSibling&&ev.target.id!==THEME_PICKER_ELEMENT_ID){active.nextElementSibling.focus()}else{showThemeButtonState();themes.firstElementChild.focus()}break;case"Enter":case"Return":case"Space":if(ev.target.id===THEME_PICKER_ELEMENT_ID&&themes.style.display==="none"){ev.preventDefault();showThemeButtonState();themes.firstElementChild.focus()}break;case"Home":ev.preventDefault();themes.firstElementChild.focus();break;case"End":ev.preventDefault();themes.lastElementChild.focus();break}}document.addEventListener("keypress",handleShortcut);document.addEventListener("keydown",handleShortcut);(function(){var x=document.getElementsByClassName("version-selector");if(x.length>0){x[0].onchange=function(){var i,match,url=document.location.href,stripped="",len=window.rootPath.match(/\.\.\//g).length+1;for(i=0;i .in-band > .trait").textContent;var baseIdName="impl-"+traitName+"-";var libs=Object.getOwnPropertyNames(imp);for(var i=0,llength=libs.length;i summary:not(.hideme)"),function(el){el.addEventListener("click",function(e){if(e.target.tagName!="SUMMARY"&&e.target.tagName!="A"){e.preventDefault()}})});onEachLazy(document.getElementsByClassName("notable-traits"),function(e){e.onclick=function(){this.getElementsByClassName('notable-traits-tooltiptext')[0].classList.toggle("force-tooltip")}});var sidebar_menu_toggle=document.getElementsByClassName("sidebar-menu-toggle")[0];if(sidebar_menu_toggle){sidebar_menu_toggle.addEventListener("click",function(){var sidebar=document.getElementsByClassName("sidebar")[0];if(!hasClass(sidebar,"shown")){addClass(sidebar,"shown")}else{removeClass(sidebar,"shown")}})}var buildHelperPopup=function(){var popup=document.createElement("aside");addClass(popup,"hidden");popup.id="help";popup.addEventListener("click",function(ev){if(ev.target===popup){displayHelp(false,ev)}});var book_info=document.createElement("span");book_info.className="top";book_info.innerHTML="You can find more information in \ - the rustdoc book.";var container=document.createElement("div");var shortcuts=[["?","Show this help dialog"],["S","Focus the search field"],["T","Focus the theme picker menu"],["↑","Move up in search results"],["↓","Move down in search results"],["← / →","Switch result tab (when results focused)"],["⏎","Go to active search result"],["+","Expand all sections"],["-","Collapse all sections"],].map(function(x){return"
    "+x[0].split(" ").map(function(y,index){return(index&1)===0?""+y+"":" "+y+" "}).join("")+"
    "+x[1]+"
    "}).join("");var div_shortcuts=document.createElement("div");addClass(div_shortcuts,"shortcuts");div_shortcuts.innerHTML="

    Keyboard Shortcuts

    "+shortcuts+"
    ";var infos=["Prefix searches with a type followed by a colon (e.g., fn:) to \ - restrict the search to a given item kind.","Accepted kinds are: fn, mod, struct, \ - enum, trait, type, macro, \ - and const.","Search functions by type signature (e.g., vec -> usize or \ - * -> vec)","Search multiple things at once by splitting your query with comma (e.g., \ - str,u8 or String,struct:Vec,test)","You can look for items with an exact name by putting double quotes around \ - your request: \"string\"","Look for items inside another one by searching for a path: vec::Vec",].map(function(x){return"

    "+x+"

    "}).join("");var div_infos=document.createElement("div");addClass(div_infos,"infos");div_infos.innerHTML="

    Search Tricks

    "+infos;container.appendChild(book_info);container.appendChild(div_shortcuts);container.appendChild(div_infos);var rustdoc_version=document.createElement("span");rustdoc_version.className="bottom";var rustdoc_version_code=document.createElement("code");rustdoc_version_code.innerText="rustdoc "+getVar("rustdoc-version");rustdoc_version.appendChild(rustdoc_version_code);container.appendChild(rustdoc_version);popup.appendChild(container);insertAfter(popup,document.querySelector("main"));buildHelperPopup=function(){}};onHashChange(null);window.addEventListener("hashchange",onHashChange);searchState.setup()}());(function(){var reset_button_timeout=null;window.copy_path=function(but){var parent=but.parentElement;var path=[];onEach(parent.childNodes,function(child){if(child.tagName==='A'){path.push(child.textContent)}});var el=document.createElement('textarea');el.value=path.join('::');el.setAttribute('readonly','');el.style.position='absolute';el.style.left='-9999px';document.body.appendChild(el);el.select();document.execCommand('copy');document.body.removeChild(el);but.children[0].style.display='none';var tmp;if(but.childNodes.length<2){tmp=document.createTextNode('✓');but.appendChild(tmp)}else{onEachLazy(but.childNodes,function(e){if(e.nodeType===Node.TEXT_NODE){tmp=e;return true}});tmp.textContent='✓'}if(reset_button_timeout!==null){window.clearTimeout(reset_button_timeout)}function reset_button(){tmp.textContent='';reset_button_timeout=null;but.children[0].style.display=""}reset_button_timeout=window.setTimeout(reset_button,1000)}}()) \ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/normalize.css b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/normalize.css deleted file mode 100644 index 469959f137..0000000000 --- a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/normalize.css +++ /dev/null @@ -1,2 +0,0 @@ - /*! normalize.css v8.0.1 | MIT License | github.com/necolas/normalize.css */ -html{line-height:1.15;-webkit-text-size-adjust:100%}body{margin:0}main{display:block}h1{font-size:2em;margin:0.67em 0}hr{box-sizing:content-box;height:0;overflow:visible}pre{font-family:monospace,monospace;font-size:1em}a{background-color:transparent}abbr[title]{border-bottom:none;text-decoration:underline;text-decoration:underline dotted}b,strong{font-weight:bolder}code,kbd,samp{font-family:monospace,monospace;font-size:1em}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sub{bottom:-0.25em}sup{top:-0.5em}img{border-style:none}button,input,optgroup,select,textarea{font-family:inherit;font-size:100%;line-height:1.15;margin:0}button,input{overflow:visible}button,select{text-transform:none}[type="button"],[type="reset"],[type="submit"],button{-webkit-appearance:button}[type="button"]::-moz-focus-inner,[type="reset"]::-moz-focus-inner,[type="submit"]::-moz-focus-inner,button::-moz-focus-inner{border-style:none;padding:0}[type="button"]:-moz-focusring,[type="reset"]:-moz-focusring,[type="submit"]:-moz-focusring,button:-moz-focusring{outline:1px dotted ButtonText}fieldset{padding:0.35em 0.75em 0.625em}legend{box-sizing:border-box;color:inherit;display:table;max-width:100%;padding:0;white-space:normal}progress{vertical-align:baseline}textarea{overflow:auto}[type="checkbox"],[type="radio"]{box-sizing:border-box;padding:0}[type="number"]::-webkit-inner-spin-button,[type="number"]::-webkit-outer-spin-button{height:auto}[type="search"]{-webkit-appearance:textfield;outline-offset:-2px}[type="search"]::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}details{display:block}summary{display:list-item}template{display:none}[hidden]{display:none} \ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/noscript.css b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/noscript.css deleted file mode 100644 index 8ad88640ab..0000000000 --- a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/noscript.css +++ /dev/null @@ -1 +0,0 @@ - #main-content .attributes{margin-left:0 !important;}#copy-path{display:none;}.sub{display:none;}#theme-picker{display:none;} \ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/rustdoc.css b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/rustdoc.css deleted file mode 100644 index 36ae99c16d..0000000000 --- a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/rustdoc.css +++ /dev/null @@ -1 +0,0 @@ - @font-face {font-family:'Fira Sans';font-style:normal;font-weight:400;src:local('Fira Sans'),url("FiraSans-Regular.woff2") format("woff2"),url("FiraSans-Regular.woff") format('woff');font-display:swap;}@font-face {font-family:'Fira Sans';font-style:normal;font-weight:500;src:local('Fira Sans Medium'),url("FiraSans-Medium.woff2") format("woff2"),url("FiraSans-Medium.woff") format('woff');font-display:swap;}@font-face {font-family:'Source Serif 4';font-style:normal;font-weight:400;src:local('Source Serif 4'),url("SourceSerif4-Regular.ttf.woff2") format("woff2"),url("SourceSerif4-Regular.ttf.woff") format("woff");font-display:swap;}@font-face {font-family:'Source Serif 4';font-style:italic;font-weight:400;src:local('Source Serif 4 Italic'),url("SourceSerif4-It.ttf.woff2") format("woff2"),url("SourceSerif4-It.ttf.woff") format("woff");font-display:swap;}@font-face {font-family:'Source Serif 4';font-style:normal;font-weight:700;src:local('Source Serif 4 Bold'),url("SourceSerif4-Bold.ttf.woff2") format("woff2"),url("SourceSerif4-Bold.ttf.woff") format("woff");font-display:swap;}@font-face {font-family:'Source Code Pro';font-style:normal;font-weight:400;src:url("SourceCodePro-Regular.ttf.woff2") format("woff2"),url("SourceCodePro-Regular.ttf.woff") format("woff");font-display:swap;}@font-face {font-family:'Source Code Pro';font-style:italic;font-weight:400;src:url("SourceCodePro-It.ttf.woff2") format("woff2"),url("SourceCodePro-It.ttf.woff") format("woff");font-display:swap;}@font-face {font-family:'Source Code Pro';font-style:normal;font-weight:600;src:url("SourceCodePro-Semibold.ttf.woff2") format("woff2"),url("SourceCodePro-Semibold.ttf.woff") format("woff");font-display:swap;}@font-face {font-family:'NanumBarunGothic';src:url("NanumBarunGothic.ttf.woff2") format("woff2"),url("NanumBarunGothic.ttf.woff") format("woff");font-display:swap;unicode-range:U+AC00-D7AF,U+1100-11FF,U+3130-318F,U+A960-A97F,U+D7B0-D7FF;}*{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;}html{content:"";}@media (prefers-color-scheme:light){html{content:"light";}}@media (prefers-color-scheme:dark){html{content:"dark";}}body{font:1rem/1.4 "Source Serif 4",NanumBarunGothic,serif;margin:0;position:relative;overflow-wrap:break-word;overflow-wrap:anywhere;-webkit-font-feature-settings:"kern","liga";-moz-font-feature-settings:"kern","liga";font-feature-settings:"kern","liga";}h1{font-size:1.5rem;}h2{font-size:1.4rem;}h3{font-size:1.3rem;}h1,h2,h3,h4,h5,h6{font-weight:500;}h1,h2,h3,h4{margin:20px 0 15px 0;padding-bottom:6px;}.docblock h3,.docblock h4,h5,h6{margin:15px 0 5px 0;}h1.fqn{margin:0;padding:0;}.main-heading{display:flex;flex-wrap:wrap;justify-content:space-between;padding-bottom:6px;margin-bottom:15px;}.main-heading a:hover{text-decoration:underline;}#toggle-all-docs{text-decoration:none;}h2,.top-doc h3,.top-doc h4{border-bottom:1px solid;}h3.code-header{font-size:1.1rem;}h4.code-header{font-size:1rem;}h3.code-header,h4.code-header{font-weight:600;border-bottom-style:none;padding:0;margin:0;}.impl,.impl-items .method,.methods .method,.impl-items .type,.methods .type,.impl-items .associatedconstant,.methods .associatedconstant,.impl-items .associatedtype,.methods .associatedtype{flex-basis:100%;font-weight:600;margin-top:16px;margin-bottom:10px;position:relative;}div.impl-items>div{padding-left:0;}h1,h2,h3,h4,h5,h6,.sidebar,.mobile-topbar,a.source,.search-input,.search-results .result-name,.content table td:first-child>a,.item-left>a,.out-of-band,span.since,#source-sidebar,#sidebar-toggle,details.rustdoc-toggle>summary::before,div.impl-items>div:not(.docblock):not(.item-info),.content ul.crate a.crate,a.srclink,#main-content>ul.docblock>li>a{font-family:"Fira Sans",Arial,NanumBarunGothic,sans-serif;}.content ul.crate a.crate{font-size:1rem/1.6;}ol,ul{padding-left:25px;}ul ul,ol ul,ul ol,ol ol{margin-bottom:.6em;}p{margin:0 0 .6em 0;}summary{outline:none;}td,th{padding:0;}table{border-collapse:collapse;}button,input,optgroup,select,textarea{color:inherit;font:inherit;margin:0;}button{padding:1px 6px;}.rustdoc{display:flex;flex-direction:row;flex-wrap:nowrap;}main{position:relative;flex-grow:1;padding:10px 15px 40px 45px;min-width:0;}.source main{padding:15px;}.width-limiter{max-width:960px;margin-right:auto;}.source .width-limiter{max-width:unset;}details:not(.rustdoc-toggle) summary{margin-bottom:.6em;}code,pre,a.test-arrow,.code-header{font-family:"Source Code Pro",monospace;}.docblock code,.docblock-short code{border-radius:3px;padding:0 0.1em;}.docblock pre code,.docblock-short pre code{padding:0;}pre{padding:14px;}.docblock.item-decl{margin-left:0;}.item-decl pre{overflow-x:auto;}.source .content pre{padding:20px;}img{max-width:100%;}li{position:relative;}.source .content{max-width:none;overflow:visible;margin-left:0px;}nav.sub{position:relative;font-size:1rem;text-transform:uppercase;}.sub-container{display:flex;flex-direction:row;flex-wrap:nowrap;}.sub-logo-container{display:none;margin-right:20px;}.source .sub-logo-container{display:block;}.source .sub-logo-container>img{height:60px;width:60px;object-fit:contain;}.sidebar{font-size:0.9rem;width:250px;min-width:200px;overflow-y:scroll;position:sticky;height:100vh;top:0;left:0;}.sidebar-elems,.sidebar>.location{padding-left:24px;}.sidebar .location{overflow-wrap:anywhere;}.rustdoc.source .sidebar{width:50px;min-width:0px;max-width:300px;flex-grow:0;flex-shrink:0;flex-basis:auto;border-right:1px solid;overflow-x:hidden;overflow-y:hidden;}.source .sidebar>*:not(:first-child){transition:opacity 0.5s;opacity:0;visibility:hidden;}.source .sidebar.expanded{overflow-y:auto;}.source .sidebar.expanded>*{opacity:1;visibility:visible;}#all-types{margin-top:1em;}*{scrollbar-width:initial;}.sidebar{scrollbar-width:thin;}::-webkit-scrollbar{width:12px;}.sidebar::-webkit-scrollbar{width:8px;}::-webkit-scrollbar-track{-webkit-box-shadow:inset 0;}.hidden{display:none !important;}.sidebar .logo-container{display:flex;margin-top:10px;margin-bottom:10px;justify-content:center;}.version{overflow-wrap:break-word;}.logo-container>img{height:100px;width:100px;}.location:empty{border:none;}.location a:first-of-type{font-weight:500;}.location a:hover{text-decoration:underline;}.block{padding:0;}.block ul,.block li{padding:0;list-style:none;}.block a{display:block;padding:0.3em;margin-left:-0.3em;text-overflow:ellipsis;overflow:hidden;}.sidebar h2{border-bottom:none;font-weight:500;padding:0;margin:0;margin-top:1rem;margin-bottom:1rem;}.sidebar h3{font-size:1.1rem;font-weight:500;padding:0;margin:0;margin-top:0.5rem;margin-bottom:0.25rem;}.sidebar-links,.block{margin-bottom:2em;}.mobile-topbar{display:none;}.source .content pre.rust{white-space:pre;overflow:auto;padding-left:0;}.rustdoc .example-wrap{display:inline-flex;margin-bottom:10px;}.example-wrap{position:relative;width:100%;}.example-wrap>pre.line-number{overflow:initial;border:1px solid;padding:13px 8px;text-align:right;border-top-left-radius:5px;border-bottom-left-radius:5px;}.example-wrap>pre.rust a:hover{text-decoration:underline;}.rustdoc:not(.source) .example-wrap>pre:not(.line-number){width:100%;overflow-x:auto;}.rustdoc:not(.source) .example-wrap>pre.line-numbers{width:auto;overflow-x:visible;}.rustdoc .example-wrap>pre{margin:0;}#search{position:relative;}.search-loading{text-align:center;}#results>table{width:100%;table-layout:fixed;}.content>.example-wrap pre.line-numbers{position:relative;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;}.line-numbers span{cursor:pointer;}.docblock-short{overflow-wrap:break-word;overflow-wrap:anywhere;}.docblock-short p{display:inline;}.docblock-short p{overflow:hidden;text-overflow:ellipsis;margin:0;}.docblock>:not(pre)>code,.docblock-short>:not(pre)>code{white-space:pre-wrap;}.top-doc .docblock h2{font-size:1.3rem;}.top-doc .docblock h3{font-size:1.15rem;}.top-doc .docblock h4,.top-doc .docblock h5{font-size:1.1rem;}.top-doc .docblock h6{font-size:1rem;}.docblock h5{font-size:1rem;}.docblock h6{font-size:0.95rem;}.docblock{margin-left:24px;position:relative;}.docblock>:not(.information){max-width:100%;overflow-x:auto;}.content .out-of-band{flex-grow:0;font-size:1.15rem;font-weight:normal;float:right;}.method>.code-header,.trait-impl>.code-header,.invisible>.code-header{max-width:calc(100% - 41px);display:block;}.invisible{width:100%;display:inline-block;}.content .in-band{flex-grow:1;margin:0px;padding:0px;overflow-wrap:break-word;overflow-wrap:anywhere;}.in-band>code,.in-band>.code-header{display:inline-block;}#main-content{position:relative;}#main-content>.since{top:inherit;font-family:"Fira Sans",Arial,sans-serif;}.content table:not(.table-display){border-spacing:0 5px;}.content td{vertical-align:top;}.content td:first-child{padding-right:20px;}.content td p:first-child{margin-top:0;}.content td h1,.content td h2{margin-left:0;font-size:1.1rem;}.content tr:first-child td{border-top:0;}.docblock table{margin:.5em 0;width:calc(100% - 2px);overflow-x:auto;display:block;}.docblock table td{padding:.5em;border:1px dashed;}.docblock table th{padding:.5em;text-align:left;border:1px solid;}.fields+table{margin-bottom:1em;}.content .item-list{list-style-type:none;padding:0;}.content .multi-column{-moz-column-count:5;-moz-column-gap:2.5em;-webkit-column-count:5;-webkit-column-gap:2.5em;column-count:5;column-gap:2.5em;}.content .multi-column li{width:100%;display:inline-block;}.content>.methods>.method{font-size:1rem;position:relative;}.content .method .where,.content .fn .where,.content .where.fmt-newline{display:block;font-size:0.8rem;}.content .methods>div:not(.notable-traits):not(.method){margin-left:40px;margin-bottom:15px;}.content .docblock>.impl-items{margin-left:20px;margin-top:-34px;}.content .docblock>.impl-items .table-display{margin:0;}.content .docblock>.impl-items table td{padding:0;}.content .docblock>.impl-items .table-display,.impl-items table td{border:none;}.content .item-info code{font-size:0.81rem;}.content .item-info{position:relative;margin-left:33px;}.sub-variant>div>.item-info{margin-top:initial;}.content .item-info::before{content:'⬑';font-size:1.5625rem;position:absolute;top:-6px;left:-19px;}.content .impl-items .docblock,.content .impl-items .item-info{margin-bottom:.6em;}.content .impl-items>.item-info{margin-left:40px;}.methods>.item-info,.content .impl-items>.item-info{margin-top:-8px;}.impl-items{flex-basis:100%;}#main-content>.item-info{margin-top:0;}nav.sub{flex-grow:1;margin-bottom:25px;}.source nav.sub{margin-left:32px;}nav.main{padding:20px 0;text-align:center;}nav.main .current{border-top:1px solid;border-bottom:1px solid;}nav.main .separator{border:1px solid;display:inline-block;height:23px;margin:0 20px;}nav.sum{text-align:right;}nav.sub form{display:inline;}a{text-decoration:none;background:transparent;}.small-section-header{display:flex;justify-content:space-between;position:relative;}.small-section-header:hover>.anchor{display:initial;}.in-band:hover>.anchor,.impl:hover>.anchor,.method.trait-impl:hover>.anchor,.type.trait-impl:hover>.anchor,.associatedconstant.trait-impl:hover>.anchor,.associatedtype.trait-impl:hover>.anchor{display:inline-block;position:absolute;}.anchor{display:none;position:absolute;left:-0.5em;background:none !important;}.anchor.field{left:-5px;}.small-section-header>.anchor{left:-15px;padding-right:8px;}h2.small-section-header>.anchor{padding-right:6px;}.anchor::before{content:'§';}.docblock a:not(.srclink):not(.test-arrow):hover,.docblock-short a:not(.srclink):not(.test-arrow):hover,.item-info a{text-decoration:underline;}.invisible>.srclink,.method>.code-header+.srclink{position:absolute;top:0;right:0;font-size:1.0625rem;font-weight:normal;}.block a.current.crate{font-weight:500;}table,.item-table{overflow-wrap:break-word;}.item-table{display:table;}.item-row{display:table-row;}.item-left,.item-right{display:table-cell;}.item-left{padding-right:1.2rem;}.search-container{position:relative;display:flex;height:34px;}.search-container>*{height:100%;}.search-results-title{display:inline;}#search-settings{font-size:1.5rem;font-weight:500;margin-bottom:20px;}#crate-search{min-width:115px;margin-top:5px;margin-left:0.2em;padding-left:0.3em;padding-right:23px;border:0;border-radius:4px;outline:none;cursor:pointer;-moz-appearance:none;-webkit-appearance:none;text-indent:0.01px;text-overflow:"";background-repeat:no-repeat;background-color:transparent;background-size:20px;background-position:calc(100% - 1px) 56%;background-image:url("down-arrow.svg");}.search-container{margin-top:4px;}.search-input{-webkit-appearance:none;-moz-box-sizing:border-box !important;box-sizing:border-box !important;outline:none;border:1px solid;border-radius:2px;padding:5px 8px;font-size:1.0625rem;transition:border-color 300ms ease;width:100%;}.search-results{display:none;padding-bottom:2em;}.search-results.active{display:block;clear:both;}.search-results .desc>span{white-space:nowrap;text-overflow:ellipsis;overflow:hidden;display:block;}.search-results>a{display:block;width:100%;margin-left:2px;margin-right:2px;border-bottom:1px solid #aaa3;}.search-results>a>div{display:flex;flex-flow:row wrap;}.search-results .result-name,.search-results div.desc,.search-results .result-description{width:50%;}.search-results .result-name{padding-right:1em;}.search-results .result-name>span{display:inline-block;margin:0;font-weight:normal;}body.blur>:not(#help){filter:blur(8px);-webkit-filter:blur(8px);opacity:.7;}#help{width:100%;height:100vh;position:fixed;top:0;left:0;display:flex;justify-content:center;align-items:center;}#help>div{flex:0 0 auto;box-shadow:0 0 6px rgba(0,0,0,.2);width:550px;height:auto;border:1px solid;}#help dt{float:left;clear:left;display:block;margin-right:0.5rem;}#help span.top,#help span.bottom{text-align:center;display:block;font-size:1.125rem;}#help span.top{text-align:center;display:block;margin:10px 0;border-bottom:1px solid;padding-bottom:4px;margin-bottom:6px;}#help span.bottom{clear:both;border-top:1px solid;}#help dd{margin:5px 35px;}#help .infos{padding-left:0;}#help h1,#help h2{margin-top:0;}#help>div div{width:50%;float:left;padding:0 20px 20px 17px;;}.item-info .stab{display:table;}.stab{padding:3px;margin-bottom:5px;font-size:0.9rem;font-weight:normal;}.stab p{display:inline;}.stab .emoji{font-size:1.2rem;}.emoji{text-shadow:1px 0 0 black,-1px 0 0 black,0 1px 0 black,0 -1px 0 black;}.module-item .stab,.import-item .stab{border-radius:3px;display:inline-block;font-size:0.8rem;line-height:1.2;margin-bottom:0;margin-left:.3em;padding:2px;vertical-align:text-bottom;}.module-item.unstable,.import-item.unstable{opacity:0.65;}.since{font-weight:normal;font-size:initial;}.rightside{padding-left:12px;padding-right:2px;position:initial;}.impl-items .srclink,.impl .srclink,.methods .srclink{font-weight:normal;font-size:1rem;}.impl .srclink{font-size:1.0625rem;}.rightside{float:right;}.has-srclink{font-size:1rem;margin-bottom:12px;justify-content:space-between;}.variants_table{width:100%;}.variants_table tbody tr td:first-child{width:1%;}td.summary-column{width:100%;}.summary{padding-right:0px;}pre.rust .question-mark{font-weight:bold;}a.test-arrow{display:inline-block;visibility:hidden;position:absolute;padding:5px 10px 5px 10px;border-radius:5px;font-size:1.3rem;top:5px;right:5px;z-index:1;}.example-wrap:hover .test-arrow{visibility:visible;}a.test-arrow:hover{text-decoration:none;}.section-header:hover a:before{position:absolute;left:-25px;padding-right:10px;content:'\2002\00a7\2002';}.section-header:hover a{text-decoration:none;}.code-attribute{font-weight:300;}.item-spacer{width:100%;height:12px;}.out-of-band>span.since{position:initial;font-size:1.25rem;}h3.variant{font-weight:600;font-size:1.1rem;margin-bottom:10px;border-bottom:none;}.sub-variant h4{font-size:1rem;font-weight:400;border-bottom:none;margin-top:0;margin-bottom:0;}.sub-variant{margin-left:24px;margin-bottom:40px;}.sub-variant>.sub-variant-field{margin-left:24px;}.toggle-label{display:inline-block;margin-left:4px;margin-top:3px;}.top-doc .docblock>.section-header:first-child{margin-left:15px;}.top-doc .docblock>.section-header:first-child:hover>a:before{left:-10px;}.docblock>.section-header:first-child{margin-top:0;}:target>code,:target>.code-header{opacity:1;}:target{padding-right:3px;}.information{position:absolute;left:-25px;margin-top:7px;z-index:1;}.tooltip{position:relative;display:inline-block;cursor:pointer;}.tooltip::after{display:none;text-align:center;padding:5px 3px 3px 3px;border-radius:6px;margin-left:5px;font-size:1rem;}.tooltip.ignore::after{content:"This example is not tested";}.tooltip.compile_fail::after{content:"This example deliberately fails to compile";}.tooltip.should_panic::after{content:"This example panics";}.tooltip.edition::after{content:"This code runs with edition " attr(data-edition);}.tooltip::before{content:" ";position:absolute;top:50%;left:16px;margin-top:-5px;border-width:5px;border-style:solid;display:none;}.tooltip:hover::before,.tooltip:hover::after{display:inline;}.tooltip.compile_fail,.tooltip.should_panic,.tooltip.ignore{font-weight:bold;font-size:1.25rem;}.notable-traits-tooltip{display:inline-block;cursor:pointer;}.notable-traits:hover .notable-traits-tooltiptext,.notable-traits .notable-traits-tooltiptext.force-tooltip{display:inline-block;}.notable-traits .notable-traits-tooltiptext{display:none;padding:5px 3px 3px 3px;border-radius:6px;margin-left:5px;z-index:10;font-size:1rem;cursor:default;position:absolute;border:1px solid;}.notable-traits-tooltip::after{content:"\00a0\00a0\00a0";}.notable-traits .notable,.notable-traits .docblock{margin:0;}.notable-traits .notable{margin:0;margin-bottom:13px;font-size:1.1875rem;font-weight:600;}.notable-traits .docblock code.content{margin:0;padding:0;font-size:1.25rem;}pre.rust.rust-example-rendered{position:relative;}pre.rust{tab-size:4;-moz-tab-size:4;}.search-failed{text-align:center;margin-top:20px;display:none;}.search-failed.active{display:block;}.search-failed>ul{text-align:left;max-width:570px;margin-left:auto;margin-right:auto;}#titles{height:35px;}#titles>button{float:left;width:33.3%;text-align:center;font-size:1.125rem;cursor:pointer;border:0;border-top:2px solid;}#titles>button:not(:last-child){margin-right:1px;width:calc(33.3% - 1px);}#titles>button>div.count{display:inline-block;font-size:1rem;}.notable-traits{cursor:pointer;z-index:2;margin-left:5px;}#sidebar-toggle{position:sticky;top:0;left:0;cursor:pointer;font-weight:bold;font-size:1.2rem;border-bottom:1px solid;display:flex;height:40px;justify-content:center;align-items:center;z-index:10;}#source-sidebar{width:100%;z-index:1;overflow:auto;}#source-sidebar>.title{font-size:1.5rem;text-align:center;border-bottom:1px solid;margin-bottom:6px;}.theme-picker{position:absolute;left:-38px;top:4px;}.theme-picker button{outline:none;}#settings-menu,#help-button{margin-left:4px;outline:none;}#theme-picker,#copy-path{height:34px;}#theme-picker,#settings-menu,#help-button,#copy-path{padding:5px;width:33px;border:1px solid;border-radius:2px;cursor:pointer;}#help-button{font-family:"Fira Sans",Arial,sans-serif;text-align:center;font-size:20px;padding-top:2px;}#copy-path{background:initial;margin-left:10px;padding:0;padding-left:2px;border:0;}#theme-choices{display:none;position:absolute;left:0;top:28px;border:1px solid;border-radius:3px;z-index:1;cursor:pointer;}#theme-choices>button{border:none;width:100%;padding:4px 8px;text-align:center;background:rgba(0,0,0,0);overflow-wrap:normal;}#theme-choices>button:not(:first-child){border-top:1px solid;}kbd{display:inline-block;padding:3px 5px;font:15px monospace;line-height:10px;vertical-align:middle;border:solid 1px;border-radius:3px;box-shadow:inset 0 -1px 0;cursor:default;}.hidden-by-impl-hider,.hidden-by-usual-hider{display:none !important;}#implementations-list>h3>span.in-band{width:100%;}.table-display{width:100%;border:0;border-collapse:collapse;border-spacing:0;font-size:1rem;}.table-display tr td:first-child{padding-right:0;}.table-display tr td:last-child{float:right;}.table-display .out-of-band{position:relative;font-size:1.1875rem;display:block;}#implementors-list>.impl-items .table-display .out-of-band{font-size:1.0625rem;}.table-display td:hover .anchor{display:block;top:2px;left:-5px;}#main-content>ul{padding-left:10px;}#main-content>ul>li{list-style:none;}.non-exhaustive{margin-bottom:1em;}div.children{padding-left:27px;display:none;}div.name{cursor:pointer;position:relative;margin-left:16px;}div.files>a{display:block;padding:0 3px;}div.files>a:hover,div.name:hover{background-color:#a14b4b;}div.name.expand+.children{display:block;}div.name::before{content:"\25B6";padding-left:4px;font-size:0.7rem;position:absolute;left:-16px;top:4px;}div.name.expand::before{transform:rotate(90deg);left:-15px;top:2px;}details.rustdoc-toggle>summary.hideme{cursor:pointer;}details.rustdoc-toggle>summary{list-style:none;}details.rustdoc-toggle>summary::-webkit-details-marker,details.rustdoc-toggle>summary::marker{display:none;}details.rustdoc-toggle>summary.hideme>span{margin-left:9px;}details.rustdoc-toggle>summary::before{content:"";cursor:pointer;width:17px;height:max(17px,1.1em);background-repeat:no-repeat;background-position:top left;display:inline-block;vertical-align:middle;opacity:.5;}details.rustdoc-toggle>summary::after{content:"Expand";overflow:hidden;width:0;height:0;position:absolute;}details.rustdoc-toggle>summary.hideme::after{content:"";}details.rustdoc-toggle>summary:focus::before,details.rustdoc-toggle>summary:hover::before{opacity:1;}details.rustdoc-toggle.top-doc>summary,details.rustdoc-toggle.top-doc>summary::before,details.rustdoc-toggle.non-exhaustive>summary,details.rustdoc-toggle.non-exhaustive>summary::before{font-family:'Fira Sans';font-size:1rem;}details.non-exhaustive{margin-bottom:8px;}details.rustdoc-toggle>summary.hideme::before{position:relative;}details.rustdoc-toggle>summary:not(.hideme)::before{position:absolute;left:-24px;top:3px;}.impl-items>details.rustdoc-toggle>summary:not(.hideme)::before{position:absolute;left:-24px;}details.rustdoc-toggle[open] >summary.hideme{position:absolute;}details.rustdoc-toggle{position:relative;}details.rustdoc-toggle[open] >summary.hideme>span{display:none;}details.undocumented[open] >summary::before,details.rustdoc-toggle[open] >summary::before,details.rustdoc-toggle[open] >summary.hideme::before{background-image:url("toggle-minus.svg");}details.undocumented>summary::before,details.rustdoc-toggle>summary::before{background-image:url("toggle-plus.svg");}details.rustdoc-toggle[open] >summary::before,details.rustdoc-toggle[open] >summary.hideme::before{width:17px;height:max(17px,1.1em);background-repeat:no-repeat;background-position:top left;display:inline-block;content:"";}details.rustdoc-toggle[open] >summary::after,details.rustdoc-toggle[open] >summary.hideme::after{content:"Collapse";}@media (min-width:701px){.docblock>.information:first-child>.tooltip{margin-top:16px;}.sidebar.expanded+main .width-limiter .sub-logo-container.rust-logo{display:none;}.rustdoc.source .sidebar{transition:width .5s;}.source .sidebar.expanded{width:300px;}}@media (max-width:700px){*[id]{scroll-margin-top:45px;}.rustdoc{padding-top:0px;display:block;}main{padding-left:15px;padding-top:0px;}.rustdoc,.main-heading{flex-direction:column;}.content .out-of-band{text-align:left;margin-left:initial;padding:initial;}.content .out-of-band .since::before{content:"Since ";}#copy-path{display:none;}.sidebar .sidebar-logo,.sidebar .location{display:none;}.sidebar-elems{margin-top:1em;}.sidebar{position:fixed;top:45px;left:-1000px;margin-left:0;background-color:rgba(0,0,0,0);margin:0;padding:0;padding-left:15px;z-index:11;}.source main,.source .sidebar{top:0;padding:0;}.sidebar.shown,.sidebar.expanded,.sidebar:focus-within{left:0;}.rustdoc.source>.sidebar{position:fixed;margin:0;z-index:11;width:0;}.mobile-topbar .location{border:none;margin:0;margin-left:auto;padding:0.3em;padding-right:0.6em;text-overflow:ellipsis;overflow-x:hidden;}.mobile-topbar .logo-container{max-height:45px;}.mobile-topbar .logo-container>img{max-width:35px;max-height:35px;margin-left:20px;margin-top:5px;margin-bottom:5px;}.mobile-topbar{display:flex;flex-direction:row;position:sticky;z-index:10;font-size:2rem;height:45px;width:100%;left:0;top:0;}.source .mobile-topbar{display:none;}.sidebar-menu-toggle{width:45px;border:none;}.source nav:not(.sidebar).sub{margin-left:32px;}#theme-picker{display:none;width:0;}.content{margin-left:0px;}.source .content{margin-top:10px;}#search{margin-left:0;padding:0;}.anchor{display:none !important;}.notable-traits{position:absolute;left:-22px;top:24px;}#titles>button>div.count{float:left;width:100%;}#titles{height:50px;}#sidebar-filler{position:fixed;left:45px;width:calc(100% - 45px);top:0;height:45px;z-index:-1;border-bottom:1px solid;}#main-content>details.rustdoc-toggle>summary::before,#main-content>div>details.rustdoc-toggle>summary::before{left:-11px;}.sidebar.expanded #sidebar-toggle{font-size:1.5rem;}.sidebar:not(.expanded) #sidebar-toggle{position:fixed;left:1px;top:100px;width:30px;font-size:1.5rem;text-align:center;padding:0;z-index:10;border-top-right-radius:3px;border-bottom-right-radius:3px;cursor:pointer;font-weight:bold;border:1px solid;border-left:0;}#source-sidebar{z-index:11;}#main-content>.line-numbers{margin-top:0;}.notable-traits .notable-traits-tooltiptext{left:0;top:100%;}#help-button{display:none;}.item-table{display:block;}.item-row{display:flex;flex-flow:column wrap;}.item-left,.item-right{width:100%;}.search-results>a{border-bottom:1px solid #aaa9;padding:5px 0px;}.search-results .result-name,.search-results div.desc,.search-results .result-description{width:100%;}.search-results div.desc,.search-results .result-description,.item-right{padding-left:2em;}.source .sidebar.expanded{max-width:100vw;width:100vw;}details.rustdoc-toggle:not(.top-doc)>summary{margin-left:10px;}.impl-items>details.rustdoc-toggle>summary:not(.hideme)::before,#main-content>details.rustdoc-toggle:not(.top-doc)>summary::before,#main-content>div>details.rustdoc-toggle>summary::before{left:-11px;}}@media print{nav.sub,.content .out-of-band{display:none;}}@media (max-width:464px){#titles,#titles>button{height:73px;}#main-content>table:not(.table-display) td{word-break:break-word;width:50%;}#crate-search{border-radius:4px;border:0;}.docblock{margin-left:12px;}.docblock code{overflow-wrap:break-word;overflow-wrap:anywhere;}.sub-container{flex-direction:column;}.sub-logo-container{align-self:center;}.source .sub-logo-container>img{height:35px;width:35px;}.sidebar:not(.expanded) #sidebar-toggle{top:10px;}}.scraped-example-title{font-family:'Fira Sans';}.scraped-example:not(.expanded) .code-wrapper pre.line-numbers{overflow:hidden;max-height:240px;}.scraped-example:not(.expanded) .code-wrapper .example-wrap pre.rust{overflow-y:hidden;max-height:240px;padding-bottom:0;}.scraped-example .code-wrapper .prev{position:absolute;top:0.25em;right:2.25em;z-index:100;cursor:pointer;}.scraped-example .code-wrapper .next{position:absolute;top:0.25em;right:1.25em;z-index:100;cursor:pointer;}.scraped-example .code-wrapper .expand{position:absolute;top:0.25em;right:0.25em;z-index:100;cursor:pointer;}.scraped-example .code-wrapper{position:relative;display:flex;flex-direction:row;flex-wrap:wrap;width:100%;}.scraped-example:not(.expanded) .code-wrapper:before{content:" ";width:100%;height:5px;position:absolute;z-index:100;top:0;background:linear-gradient(to bottom,rgba(255,255,255,1),rgba(255,255,255,0));}.scraped-example:not(.expanded) .code-wrapper:after{content:" ";width:100%;height:5px;position:absolute;z-index:100;bottom:0;background:linear-gradient(to top,rgba(255,255,255,1),rgba(255,255,255,0));}.scraped-example:not(.expanded) .code-wrapper{overflow:hidden;max-height:240px;}.scraped-example .code-wrapper .line-numbers{margin:0;padding:14px 0;}.scraped-example .code-wrapper .line-numbers span{padding:0 14px;}.scraped-example .code-wrapper .example-wrap{flex:1;overflow-x:auto;overflow-y:hidden;margin-bottom:0;}.scraped-example .code-wrapper .example-wrap pre.rust{overflow-x:inherit;width:inherit;overflow-y:hidden;}.scraped-example .example-wrap .rust span.highlight{background:#fcffd6;}.scraped-example .example-wrap .rust span.highlight.focus{background:#f6fdb0;}.more-examples-toggle{margin-top:10px;}.more-examples-toggle summary{color:#999;font-family:'Fira Sans';}.more-scraped-examples{margin-left:25px;display:flex;flex-direction:row;width:calc(100% - 25px);}.more-scraped-examples-inner{width:calc(100% - 20px);}.toggle-line{align-self:stretch;margin-right:10px;margin-top:5px;padding:0 4px;cursor:pointer;}.toggle-line:hover .toggle-line-inner{background:#aaa;}.toggle-line-inner{min-width:2px;background:#ddd;height:100%;}.more-scraped-examples .scraped-example{margin-bottom:20px;}.more-scraped-examples .scraped-example:last-child{margin-bottom:0;}.example-links a{margin-top:20px;font-family:'Fira Sans';}.example-links ul{margin-bottom:0;} \ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/search-index.js b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/search-index.js index e184ab9204..439361115c 100644 --- a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/search-index.js +++ b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/search-index.js @@ -1,4 +1,5 @@ var searchIndex = JSON.parse('{\ -"bdk":{"doc":"A modern, lightweight, descriptor-based wallet library …","t":[3,13,3,13,13,13,13,6,13,13,13,4,13,13,3,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,4,13,3,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,3,13,13,4,8,13,3,11,11,11,11,11,0,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,12,12,0,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,0,14,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,12,11,11,11,11,11,11,11,11,11,11,11,11,11,14,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,12,12,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,12,12,0,11,11,11,11,11,11,11,11,11,12,11,0,12,12,12,11,11,11,11,11,11,11,12,11,11,11,11,11,11,11,11,11,11,12,12,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,12,11,12,11,11,11,11,11,11,11,11,11,12,12,10,5,11,11,11,11,11,11,11,11,11,0,11,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,13,8,8,4,16,8,3,13,13,8,8,8,16,3,3,8,6,8,8,0,11,11,11,11,11,11,10,10,11,11,11,11,11,11,11,0,11,11,11,11,11,11,11,11,11,11,11,0,11,0,10,11,11,11,11,11,11,10,10,10,11,10,10,11,11,11,11,11,11,11,5,5,5,0,11,11,11,11,11,11,11,11,11,11,11,11,11,10,11,11,11,11,11,10,11,4,4,13,13,13,13,13,13,13,13,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,12,12,12,12,12,12,12,12,13,3,13,3,3,4,13,13,13,13,13,13,13,13,3,13,13,13,3,13,13,13,11,12,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,12,11,11,12,11,11,11,11,12,12,12,12,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,12,12,12,12,12,3,3,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,12,11,12,12,12,11,11,11,11,11,11,11,12,11,11,11,13,3,3,4,13,13,13,13,13,13,13,13,13,13,12,11,11,11,11,11,11,11,11,11,12,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,12,11,12,12,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,12,12,12,12,12,12,12,12,12,12,4,13,13,3,3,3,3,13,12,12,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,12,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,12,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,12,12,11,12,11,11,11,12,12,12,12,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,12,12,11,11,11,11,11,12,12,11,12,12,12,16,8,8,16,8,8,3,3,0,10,11,12,11,11,11,11,10,11,11,11,10,11,12,10,11,10,11,10,11,10,11,10,11,10,11,10,11,11,11,11,11,11,11,11,11,11,11,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,11,11,11,11,10,11,10,11,10,11,10,11,0,11,12,11,10,11,10,11,10,11,10,11,10,11,10,11,11,11,11,11,11,11,11,11,11,4,4,4,13,13,13,13,13,13,3,13,13,13,3,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,12,12,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,12,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,12,12,12,12,12,12,12,12,12,3,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,13,6,4,4,3,6,8,13,6,8,16,6,4,3,13,13,8,4,13,13,6,13,13,4,13,13,13,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,10,11,11,11,11,11,0,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,12,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,0,11,12,11,10,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,10,11,11,11,11,11,11,11,11,10,11,11,11,11,11,10,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,12,12,11,11,11,11,11,11,11,11,11,11,11,10,11,11,0,11,11,11,11,11,11,11,11,11,11,11,10,11,11,0,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,12,11,11,11,11,11,11,11,11,11,11,11,11,11,12,11,12,12,12,12,12,12,12,12,12,5,5,5,5,13,13,4,13,13,13,13,13,13,13,13,13,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,12,12,12,12,12,12,12,12,13,13,13,4,13,3,6,13,13,6,13,13,13,13,13,13,13,13,13,13,13,4,3,4,13,13,13,13,13,4,4,13,13,13,13,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,12,12,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,12,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,12,11,11,11,11,11,11,11,11,12,11,11,11,11,11,12,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,3,3,3,3,3,3,8,6,3,3,3,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,10,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,13,8,4,4,4,16,16,8,4,13,8,8,3,8,13,13,13,16,4,6,13,13,13,16,13,3,13,8,4,13,13,13,3,3,4,3,13,6,13,13,13,5,10,11,0,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,10,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,12,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,10,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,10,11,11,11,11,11,11,10,11,11,11,11,11,11,11,11,11,11,11,11,11,11,12,12,12,11,5,11,10,11,11,5,10,11,11,11,11,11,12,12,11,11,11,11,11,11,10,12,11,11,11,10,11,5,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,12,12,12,12,12,12,12,12,12,12,12,13,13,13,13,4,13,4,3,6,13,4,13,13,13,13,13,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,12,12,12,12,8,10,10,10,4,3,8,13,13,13,13,3,3,11,12,11,11,11,11,11,11,11,11,11,11,0,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,0,11,11,11,11,11,11,11,11,11,11,11,11,11,5,11,11,11,11,11,0,12,11,11,11,11,11,11,11,11,10,11,12,11,11,11,11,11,11,11,12,11,11,11,0,11,0,11,11,11,11,11,11,11,11,11,0,11,11,11,11,0,11,11,11,11,5,12,12,3,13,8,3,6,4,3,13,3,11,11,11,11,11,11,11,11,11,11,11,11,11,11,10,11,11,11,5,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,12,12,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,12,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,12,12,12,12,12,3,6,12,11,11,11,11,11,11,11,11,11,11,11,11,11,11,12,11,11,11,11,11,11,3,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,12,13,13,13,13,13,13,13,8,13,13,13,13,13,13,13,13,13,13,13,13,13,13,3,8,4,4,4,3,3,3,13,4,8,13,11,12,12,11,12,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,10,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,12,10,11,11,10,11,12,11,12,11,11,11,11,11,11,11,11,11,12,12,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,12,12,12,12,12,12,12,12,5,13,3,13,13,4,3,13,13,3,8,4,13,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,13,13,13,13,4,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,5,11,12,12,12,12],"n":["Balance","Bip32","BlockTime","BnBNoExactMatch","BnBTotalTriesExceeded","ChecksumMismatch","CompactFilters","ConfirmationTime","Descriptor","Electrum","Encode","Error","Esplora","External","FeeRate","FeeRateTooLow","FeeRateUnavailable","FeeTooLow","Foreign","Generic","Hex","InsufficientFunds","Internal","InvalidNetwork","InvalidOutpoint","InvalidPolicyPathError","InvalidProgressValue","InvalidU32Bytes","IrreplaceableTransaction","Json","Key","KeychainKind","Local","LocalUtxo","Miniscript","MiniscriptPsbt","MissingCachedScripts","MissingKeyOrigin","NoRecipients","NoUtxosSelected","OutputBelowDustLimit","ProgressUpdateError","Psbt","PsbtParse","Rpc","Rusqlite","ScriptDoesntHaveAddressForm","Secp256k1","Signer","Sled","SpendingPolicyRequired","TransactionConfirmed","TransactionDetails","TransactionNotFound","UnknownUtxo","Utxo","Vbytes","Verification","WeightedUtxo","add","as_byte","as_ref","as_sat_per_vb","base32_len","blockchain","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","check_base32","clone","clone","clone","clone","clone","clone","clone","clone","clone_into","clone_into","clone_into","clone_into","clone_into","clone_into","clone_into","clone_into","confirmation_time","confirmed","database","default","default","default","default_min_relay_fee","deref","deref","deref","deref","deref","deref","deref","deref","deref","deref_mut","deref_mut","deref_mut","deref_mut","deref_mut","deref_mut","deref_mut","deref_mut","deref_mut","descriptor","descriptor","deserialize","deserialize","deserialize","deserialize","deserialize","drop","drop","drop","drop","drop","drop","drop","drop","drop","eq","eq","eq","eq","eq","eq","eq","eq","fee","fee_vb","fee_wu","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fragment","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from_btc_per_kvb","from_sat_per_kvb","from_sat_per_kwu","from_sat_per_vb","from_vb","from_wu","get_hash","get_hash","get_spendable","get_total","hash","hash","height","immature","init","init","init","init","init","init","init","init","init","into","into","into","into","into","into","into","into","into","into_descriptor_key","into_extended_key","into_wallet_descriptor","into_wallet_descriptor","is_spent","keychain","keys","ne","ne","ne","ne","ne","ne","ne","new","outpoint","outpoint","partial_cmp","psbt","received","satisfaction_weight","sent","serialize","serialize","serialize","serialize","serialize","sub","sum","timestamp","to_owned","to_owned","to_owned","to_owned","to_owned","to_owned","to_owned","to_owned","to_string","to_string","transaction","trusted_pending","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","txid","txout","txout","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","untrusted_pending","utxo","vbytes","version","vzip","vzip","vzip","vzip","vzip","vzip","vzip","vzip","vzip","wallet","write_base32","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","available","found","needed","requested","required","required","0","outpoint","psbt_input","AccurateFees","Blockchain","BlockchainFactory","Capability","Config","ConfigurableBlockchain","EsploraBlockchain","FullHistory","GetAnyTx","GetBlockHash","GetHeight","GetTx","Inner","LogProgress","NoopProgress","Progress","ProgressData","StatelessBlockchain","WalletSync","any","borrow","borrow","borrow","borrow_mut","borrow_mut","borrow_mut","broadcast","build","build_for_wallet","clone","clone","clone","clone_into","clone_into","clone_into","compact_filters","default","default","deref","deref","deref","deref_mut","deref_mut","deref_mut","drop","drop","drop","electrum","eq","esplora","estimate_fee","fmt","fmt","fmt","from","from","from","from_config","get_block_hash","get_capabilities","get_hash","get_height","get_tx","hash","init","init","init","into","into","into","log_progress","noop_progress","progress","rpc","sync_wallet","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","update","update","vzip","vzip","vzip","wallet_setup","wallet_sync","AnyBlockchain","AnyBlockchainConfig","CompactFilters","CompactFilters","Electrum","Electrum","Esplora","Esplora","Rpc","Rpc","borrow","borrow","borrow_mut","borrow_mut","broadcast","clone","clone_into","deref","deref","deref_mut","deref_mut","deserialize","drop","drop","eq","estimate_fee","fmt","from","from","from","from","from","from","from","from","from","from","from_config","get_block_hash","get_capabilities","get_height","get_tx","init","init","into","into","ne","serialize","to_owned","try_from","try_from","try_into","try_into","type_id","type_id","vzip","vzip","wallet_setup","wallet_sync","0","0","0","0","0","0","0","0","Bip158","BitcoinPeerConfig","BlockHashNotFound","CompactFiltersBlockchain","CompactFiltersBlockchainConfig","CompactFiltersError","DataCorruption","Db","Global","InvalidFilter","InvalidFilterHeader","InvalidHeaders","InvalidResponse","Io","Mempool","MissingBlock","NoPeers","NotConnected","Peer","PeerBloomDisabled","Time","Timeout","add_tx","address","borrow","borrow","borrow","borrow","borrow","borrow","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","broadcast","clone","clone","clone_into","clone_into","connect","connect_proxy","default","deref","deref","deref","deref","deref","deref","deref_mut","deref_mut","deref_mut","deref_mut","deref_mut","deref_mut","deserialize","deserialize","drop","drop","drop","drop","drop","drop","eq","eq","estimate_fee","fmt","fmt","fmt","fmt","fmt","fmt","fmt","from","from","from","from","from","from","from","from","from","from","from","from_config","get_block_hash","get_capabilities","get_height","get_mempool","get_network","get_tx","get_tx","get_version","has_tx","init","init","init","init","init","init","into","into","into","into","into","into","is_connected","iter_txs","ne","ne","network","new","new","peers","recv","send","serialize","serialize","skip_blocks","socks5","socks5_credentials","storage_dir","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","wallet_setup","0","0","0","0","0","ElectrumBlockchain","ElectrumBlockchainConfig","borrow","borrow","borrow_mut","borrow_mut","broadcast","clone","clone_into","deref","deref","deref","deref_mut","deref_mut","deserialize","drop","drop","eq","estimate_fee","fmt","from","from","from","from_config","get_block_hash","get_capabilities","get_height","get_tx","init","init","into","into","ne","retry","serialize","socks5","stop_gap","timeout","to_owned","try_from","try_from","try_into","try_into","type_id","type_id","url","vzip","vzip","wallet_setup","BitcoinEncoding","EsploraBlockchain","EsploraBlockchainConfig","EsploraError","HeaderHashNotFound","HeaderHeightNotFound","Hex","HttpResponse","Io","NoHeader","Parsing","TransactionNotFound","Ureq","UreqTransport","base_url","borrow","borrow","borrow","borrow_mut","borrow_mut","borrow_mut","broadcast","clone","clone_into","concurrency","deref","deref","deref","deref","deref_mut","deref_mut","deref_mut","deserialize","drop","drop","drop","eq","estimate_fee","fmt","fmt","fmt","fmt","from","from","from","from","from","from","from","from","from","from_client","from_config","get_block_hash","get_capabilities","get_height","get_tx","init","init","init","into","into","into","ne","new","new","proxy","serialize","stop_gap","timeout","to_owned","to_string","try_from","try_from","try_from","try_into","try_into","try_into","type_id","type_id","type_id","vzip","vzip","vzip","wallet_setup","with_concurrency","0","0","0","0","0","0","0","0","0","0","Auth","Cookie","None","RpcBlockchain","RpcBlockchainFactory","RpcConfig","RpcSyncParams","UserPass","auth","auth","borrow","borrow","borrow","borrow","borrow","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","broadcast","build","clone","clone","clone","clone","clone_into","clone_into","clone_into","clone_into","cmp","default","default_skip_blocks","deref","deref","deref","deref","deref","deref","deref_mut","deref_mut","deref_mut","deref_mut","deref_mut","deserialize","deserialize","deserialize","drop","drop","drop","drop","drop","eq","eq","eq","estimate_fee","fmt","fmt","fmt","fmt","fmt","force_start_time","from","from","from","from","from","from_config","get_block_hash","get_capabilities","get_hash","get_height","get_tx","hash","init","init","init","init","init","into","into","into","into","into","ne","ne","ne","network","network","partial_cmp","poll_rate_sec","serialize","serialize","serialize","start_script_count","start_time","sync_params","sync_params","to_owned","to_owned","to_owned","to_owned","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","url","url","vzip","vzip","vzip","vzip","vzip","wallet_name","wallet_name_prefix","wallet_setup","file","password","username","Batch","BatchDatabase","BatchOperations","Config","ConfigurableDatabase","Database","SqliteDatabase","SyncTime","any","begin_batch","begin_batch","block_time","borrow","borrow","borrow_mut","borrow_mut","check_descriptor_checksum","check_descriptor_checksum","clone","clone_into","commit_batch","commit_batch","connection","del_last_index","del_last_index","del_path_from_script_pubkey","del_path_from_script_pubkey","del_raw_tx","del_raw_tx","del_script_pubkey_from_path","del_script_pubkey_from_path","del_sync_time","del_sync_time","del_tx","del_tx","del_utxo","del_utxo","deref","deref","deref_mut","deref_mut","deserialize","drop","drop","fmt","fmt","from","from","from_config","from_config","get_last_index","get_last_index","get_path_from_script_pubkey","get_path_from_script_pubkey","get_raw_tx","get_raw_tx","get_script_pubkey_from_path","get_script_pubkey_from_path","get_sync_time","get_sync_time","get_tx","get_tx","get_utxo","get_utxo","increment_last_index","increment_last_index","init","init","into","into","iter_raw_txs","iter_raw_txs","iter_script_pubkeys","iter_script_pubkeys","iter_txs","iter_txs","iter_utxos","iter_utxos","memory","new","path","serialize","set_last_index","set_last_index","set_raw_tx","set_raw_tx","set_script_pubkey","set_script_pubkey","set_sync_time","set_sync_time","set_tx","set_tx","set_utxo","set_utxo","to_owned","try_from","try_from","try_into","try_into","type_id","type_id","vzip","vzip","AnyBatch","AnyDatabase","AnyDatabaseConfig","Memory","Memory","Memory","Sled","Sled","Sled","SledDbConfiguration","Sqlite","Sqlite","Sqlite","SqliteDbConfiguration","begin_batch","borrow","borrow","borrow","borrow","borrow","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","check_descriptor_checksum","commit_batch","del_last_index","del_last_index","del_path_from_script_pubkey","del_path_from_script_pubkey","del_raw_tx","del_raw_tx","del_script_pubkey_from_path","del_script_pubkey_from_path","del_sync_time","del_sync_time","del_tx","del_tx","del_utxo","del_utxo","deref","deref","deref","deref","deref","deref_mut","deref_mut","deref_mut","deref_mut","deref_mut","deserialize","deserialize","deserialize","drop","drop","drop","drop","drop","fmt","fmt","fmt","fmt","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from_config","get_last_index","get_path_from_script_pubkey","get_raw_tx","get_script_pubkey_from_path","get_sync_time","get_tx","get_utxo","increment_last_index","init","init","init","init","init","into","into","into","into","into","iter_raw_txs","iter_script_pubkeys","iter_txs","iter_utxos","path","path","serialize","serialize","serialize","set_last_index","set_last_index","set_raw_tx","set_raw_tx","set_script_pubkey","set_script_pubkey","set_sync_time","set_sync_time","set_tx","set_tx","set_utxo","set_utxo","tree_name","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","0","0","0","0","0","0","0","0","0","MemoryDatabase","begin_batch","borrow","borrow_mut","check_descriptor_checksum","commit_batch","default","del_last_index","del_path_from_script_pubkey","del_raw_tx","del_script_pubkey_from_path","del_sync_time","del_tx","del_utxo","deref","deref_mut","drop","fmt","from","from_config","get_last_index","get_path_from_script_pubkey","get_raw_tx","get_script_pubkey_from_path","get_sync_time","get_tx","get_utxo","increment_last_index","init","into","iter_raw_txs","iter_script_pubkeys","iter_txs","iter_utxos","new","set_last_index","set_raw_tx","set_script_pubkey","set_sync_time","set_tx","set_utxo","try_from","try_into","type_id","vzip","Bare","DerivedDescriptor","Descriptor","DescriptorPublicKey","DescriptorXKey","ExtendedDescriptor","ExtractPolicy","Hardened","HdKeyPaths","IntoWalletDescriptor","Key","KeyMap","Legacy","Miniscript","None","Pkh","ScriptContext","Segwitv0","Sh","Single","TapKeyOrigins","Tr","Unhardened","Wildcard","Wpkh","Wsh","XPub","address","as_enum","as_enum","as_inner","at_derivation_index","borrow","borrow","borrow","borrow","borrow","borrow","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","branches","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_terminal_non_malleable","check_terminal_non_malleable","check_terminal_non_malleable","check_witness","check_witness","check_witness","checksum","clone","clone","clone","clone","clone","clone","clone_into","clone_into","clone_into","clone_into","clone_into","clone_into","cmp","cmp","cmp","cmp","cmp","cmp","contains_raw_pkh","deref","deref","deref","deref","deref","deref","deref_mut","deref_mut","deref_mut","deref_mut","deref_mut","deref_mut","derivation_path","derive","derived_descriptor","derived_descriptor","desc_type","deserialize","deserialize","drop","drop","drop","drop","drop","drop","encode","eq","eq","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","fmt","fmt","for_each_key","for_each_key","from","from","from","from","from","from","from","from","from","from","from","from","from_ast","from_str","from_str","from_str_ext","from_str_insane","from_tree","from_tree","get_hash","get_hash","get_hash","get_hash","get_hash","get_hash","get_nth_child","get_nth_pk","get_satisfaction","get_satisfaction_mall","has_mixed_timelocks","has_repeated_keys","has_wildcard","hash","hash","hash","hash","hash","hash","init","init","init","init","init","init","into","into","into","into","into","into","into_inner","into_wallet_descriptor","is_deriveable","is_non_malleable","iter","iter_pk","lift","lift","lift_check","matches","max_satisfaction_size","max_satisfaction_size","max_satisfaction_size","max_satisfaction_size","max_satisfaction_weight","max_satisfaction_witness_elements","name_str","name_str","name_str","ne","ne","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","origin","other_top_level_checks","parse","parse_descriptor","parse_insane","parse_with_ext","partial_cmp","partial_cmp","partial_cmp","partial_cmp","partial_cmp","partial_cmp","pk_len","pk_len","pk_len","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","template","to_owned","to_owned","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_from","try_from","try_into","try_into","try_into","try_into","try_into","try_into","ty","type_id","type_id","type_id","type_id","type_id","type_id","unsigned_script_sig","vzip","vzip","vzip","vzip","vzip","vzip","wildcard","within_resource_limits","xkey","0","0","0","0","0","0","0","0","calc_checksum","calc_checksum_bytes","get_checksum","get_checksum_bytes","Base58","Bip32","Error","HardenedDerivationXpub","Hex","InvalidDescriptorCharacter","InvalidDescriptorChecksum","InvalidHdKeyPath","Key","Miniscript","Pk","Policy","borrow","borrow_mut","deref","deref_mut","drop","fmt","fmt","from","from","from","from","from","from","from","from","init","into","to_string","try_from","try_into","type_id","vzip","0","0","0","0","0","0","0","0","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","deref","deref","deref","deref","deref","deref","deref","deref_mut","deref_mut","deref_mut","deref_mut","deref_mut","deref_mut","deref_mut","drop","drop","drop","drop","drop","drop","drop","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","get_hash","get_hash","hash","hash","id","id","init","init","init","init","init","init","init","into","into","into","into","into","into","into","is_leaf","is_leaf","is_null","item","ne","ne","ne","ne","ne","ne","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","0","current_height","input_max_height","psbt","0","0","0","0","0","condition","conditions","conditions","items","items","m","m","n","n","sorted","sorted","0","0","hash","hash","hash","hash","items","keys","threshold","threshold","value","value","0","0","0","0","0","0","0","0","0","1","1","1","1","1","1","2","2","2","Bip44","Bip44Public","Bip49","Bip49Public","Bip84","Bip84Public","DescriptorTemplate","DescriptorTemplateOut","P2Pkh","P2Wpkh","P2Wpkh_P2Sh","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","build","build","build","build","build","build","build","build","build","deref","deref","deref","deref","deref","deref","deref","deref","deref","deref_mut","deref_mut","deref_mut","deref_mut","deref_mut","deref_mut","deref_mut","deref_mut","deref_mut","drop","drop","drop","drop","drop","drop","drop","drop","drop","from","from","from","from","from","from","from","from","from","init","init","init","init","init","init","init","init","init","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","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","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","Bip32","DerivableKey","DescriptorKey","DescriptorPublicKey","DescriptorSecretKey","Entropy","Error","ExtScriptContext","ExtendedKey","FullKey","GeneratableDefaultOptions","GeneratableKey","GeneratedKey","IntoDescriptorKey","InvalidChecksum","InvalidNetwork","InvalidScriptContext","Key","KeyError","KeyMap","Legacy","Message","Miniscript","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","bip39","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","check_global_consensus_validity","check_global_policy_validity","check_global_validity","check_local_consensus_validity","check_local_policy_validity","check_local_validity","check_terminal_non_malleable","check_witness","clone","clone","clone","clone","clone","clone","clone","clone_into","clone_into","clone_into","clone_into","clone_into","clone_into","clone_into","cmp","cmp","cmp","cmp","compressed","default","deref","deref","deref","deref","deref","deref","deref","deref","deref","deref","deref","deref","deref","deref_mut","deref_mut","deref_mut","deref_mut","deref_mut","deref_mut","deref_mut","deref_mut","deref_mut","deref_mut","deref_mut","deref_mut","derive","drop","drop","drop","drop","drop","drop","drop","drop","drop","drop","drop","drop","encode","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","generate","generate_default","generate_with_entropy","generate_with_entropy_default","get_hash","get_hash","get_hash","get_hash","has_secret","has_wildcard","hash","hash","hash","hash","init","init","init","init","init","init","init","init","init","init","init","init","into","into","into","into","into","into","into","into","into","into","into","into","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_xprv","into_xpub","is_deriveable","is_legacy","is_legacy","is_segwit_v0","is_segwit_v0","is_taproot","is_taproot","is_uncompressed","is_x_only_key","k","key","key","lift","mainnet_network","master_fingerprint","max_satisfaction_size","max_satisfaction_size","max_satisfaction_witness_elements","merge_networks","name_str","ne","ne","ne","ne","new","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","sig_type","sorted_node","test_networks","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","0","0","0","0","0","0","0","0","0","0","0","AmbiguousLanguages","BadEntropyBitCount","BadWordCount","English","Error","InvalidChecksum","Language","Mnemonic","MnemonicWithPassphrase","UnknownWord","WordCount","Words12","Words15","Words18","Words21","Words24","all","borrow","borrow","borrow","borrow","borrow_mut","borrow_mut","borrow_mut","borrow_mut","clone","clone","clone","clone_into","clone_into","clone_into","cmp","cmp","deref","deref","deref","deref","deref_mut","deref_mut","deref_mut","deref_mut","deserialize","drop","drop","drop","drop","eq","eq","eq","fmt","fmt","fmt","fmt","fmt","fmt","from","from","from","from","from_entropy","from_entropy_in","from_str","generate_in_with","generate_with_entropy","get_hash","get_hash","hash","hash","init","init","init","init","into","into","into","into","into_descriptor_key","into_extended_key","language","language_of","ne","ne","parse","parse_in","parse_in_normalized","parse_normalized","partial_cmp","partial_cmp","serialize","to_entropy","to_entropy_array","to_owned","to_owned","to_owned","to_seed","to_seed_normalized","to_string","to_string","to_string","try_from","try_from","try_from","try_from","try_into","try_into","try_into","try_into","type_id","type_id","type_id","type_id","vzip","vzip","vzip","vzip","word_count","word_iter","words_by_prefix","0","0","0","0","PsbtUtils","fee_amount","fee_rate","get_utxo_for","AddressIndex","AddressInfo","IsDust","LastUnused","New","Peek","Reset","SyncOptions","Wallet","add_signer","address","borrow","borrow","borrow","borrow","borrow_mut","borrow_mut","borrow_mut","borrow_mut","build_fee_bump","build_tx","coin_selection","database","default","deref","deref","deref","deref","deref","deref_mut","deref_mut","deref_mut","deref_mut","descriptor_checksum","drop","drop","drop","drop","ensure_addresses_cached","eq","export","finalize_psbt","fmt","fmt","fmt","fmt","fmt","from","from","from","from","get_address","get_balance","get_descriptor_for_keychain","get_funded_wallet","get_internal_address","get_psbt_input","get_signers","get_tx","get_utxo","hardwaresigner","index","init","init","init","init","into","into","into","into","is_dust","is_mine","keychain","list_transactions","list_unspent","ne","network","new","new_offline","policies","progress","public_descriptor","secp_ctx","sign","signer","sync","time","to_string","try_from","try_from","try_from","try_from","try_into","try_into","try_into","try_into","tx_builder","type_id","type_id","type_id","type_id","verify","vzip","vzip","vzip","vzip","wallet_name_from_descriptor","0","0","BranchAndBoundCoinSelection","Change","CoinSelectionAlgorithm","CoinSelectionResult","DefaultCoinSelectionAlgorithm","Excess","LargestFirstCoinSelection","NoChange","OldestFirstCoinSelection","borrow","borrow","borrow","borrow","borrow","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","clone","clone","clone_into","clone_into","coin_select","coin_select","coin_select","coin_select","decide_change","default","default","default","deref","deref","deref","deref","deref","deref_mut","deref_mut","deref_mut","deref_mut","deref_mut","drop","drop","drop","drop","drop","excess","fee_amount","fmt","fmt","fmt","fmt","fmt","from","from","from","from","from","init","init","init","init","init","into","into","into","into","into","local_selected_amount","new","selected","selected_amount","to_owned","to_owned","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","amount","change_fee","dust_threshold","fee","remaining_amount","FullyNodedExport","WalletExport","blockheight","borrow","borrow_mut","change_descriptor","deref","deref_mut","descriptor","deserialize","drop","export_wallet","fmt","from","from_str","init","into","label","serialize","to_string","try_from","try_into","type_id","vzip","HWISigner","borrow","borrow_mut","deref","deref_mut","drop","fmt","from","from_device","id","init","into","sign_transaction","try_from","try_into","type_id","vzip","0","All","Dummy","Exclude","Fingerprint","HWIError","Include","InputIndexOutOfRange","InputSigner","InvalidKey","InvalidNonWitnessUtxo","InvalidSighash","Legacy","MissingHdKeypath","MissingKey","MissingNonWitnessUtxo","MissingWitnessScript","MissingWitnessUtxo","NonStandardSighash","None","PkHash","Segwitv0","SighashError","SignOptions","SignerCommon","SignerContext","SignerError","SignerId","SignerOrdering","SignerWrapper","SignersContainer","Tap","TapLeavesOptions","TransactionSigner","UserCanceled","add_external","allow_all_sighashes","allow_grinding","as_key_map","assume_height","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","build","clone","clone","clone","clone","clone","clone","clone","clone","clone_into","clone_into","clone_into","clone_into","clone_into","clone_into","clone_into","clone_into","cmp","cmp","default","default","default","default","deref","deref","deref","deref","deref","deref","deref","deref","deref","deref_mut","deref_mut","deref_mut","deref_mut","deref_mut","deref_mut","deref_mut","deref_mut","descriptor_secret_key","descriptor_secret_key","descriptor_secret_key","drop","drop","drop","drop","drop","drop","drop","drop","eq","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","get_hash","hash","id","id","id","ids","init","init","init","init","init","init","init","init","into","into","into","into","into","into","into","into","ne","ne","ne","ne","ne","new","new","partial_cmp","partial_cmp","remove","remove_partial_sigs","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_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","0","0","0","0","0","0","0","get_timestamp","Bip69Lexicographic","BumpFee","ChangeAllowed","ChangeForbidden","ChangeSpendPolicy","CreateTx","OnlyChange","Shuffle","TxBuilder","TxBuilderContext","TxOrdering","Untouched","add_data","add_foreign_utxo","add_global_xpubs","add_recipient","add_unspendable","add_utxo","add_utxos","allow_dust","allow_shrinking","borrow","borrow","borrow","borrow","borrow","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","change_policy","clone","clone","clone","clone","clone","clone_into","clone_into","clone_into","clone_into","clone_into","cmp","cmp","coin_selection","current_height","default","default","default","default","deref","deref","deref","deref","deref","deref_mut","deref_mut","deref_mut","deref_mut","deref_mut","do_not_spend_change","drain_to","drain_wallet","drop","drop","drop","drop","drop","enable_rbf","enable_rbf_with_sequence","eq","eq","fee_absolute","fee_rate","finish","fmt","fmt","fmt","fmt","fmt","from","from","from","from","from","get_hash","get_hash","hash","hash","include_output_redeem_witness_script","init","init","init","init","init","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_owned","to_owned","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","Consensus","Global","InvalidInput","MissingInputTx","VerifyError","borrow","borrow_mut","deref","deref_mut","drop","fmt","fmt","from","from","from","init","into","to_string","try_from","try_into","type_id","verify_tx","vzip","0","0","0","0"],"q":["bdk","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","bdk::Error","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","bdk::Utxo","","","bdk::blockchain","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","bdk::blockchain::any","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","bdk::blockchain::any::AnyBlockchain","","","","bdk::blockchain::any::AnyBlockchainConfig","","","","bdk::blockchain::compact_filters","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","bdk::blockchain::compact_filters::CompactFiltersError","","","","","bdk::blockchain::electrum","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","bdk::blockchain::esplora","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","bdk::blockchain::esplora::EsploraError","","","","","","","","","","bdk::blockchain::rpc","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","bdk::blockchain::rpc::Auth","","","bdk::database","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","bdk::database::any","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","bdk::database::any::AnyBatch","","","bdk::database::any::AnyDatabase","","","bdk::database::any::AnyDatabaseConfig","","","bdk::database::memory","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","bdk::descriptor","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","bdk::descriptor::Descriptor","","","","","","bdk::descriptor::DescriptorPublicKey","","bdk::descriptor::checksum","","","","bdk::descriptor::error","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","bdk::descriptor::error::Error","","","","","","","","bdk::descriptor::policy","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","bdk::descriptor::policy::BuildSatisfaction","","","","bdk::descriptor::policy::PkOrF","","","bdk::descriptor::policy::PolicyError","","bdk::descriptor::policy::Satisfaction","","","","","","","","","","","bdk::descriptor::policy::SatisfiableItem","","","","","","","","","","","","bdk::descriptor::template","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","bdk::keys","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","bdk::keys::DescriptorPublicKey","","bdk::keys::DescriptorSecretKey","","bdk::keys::ExtendedKey","","bdk::keys::KeyError","","","bdk::keys::SinglePubKey","","bdk::keys::bip39","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","bdk::keys::bip39::Error","","","","bdk::psbt","","","","bdk::wallet","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","bdk::wallet::AddressIndex","","bdk::wallet::coin_selection","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","bdk::wallet::coin_selection::Excess","","","","","bdk::wallet::export","","","","","","","","","","","","","","","","","","","","","","","","bdk::wallet::hardwaresigner","","","","","","","","","","","","","","","","","bdk::wallet::signer","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","bdk::wallet::signer::SignerContext","bdk::wallet::signer::SignerError","","bdk::wallet::signer::SignerId","","","bdk::wallet::signer::TapLeavesOptions","","bdk::wallet::time","bdk::wallet::tx_builder","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","bdk::wallet::verify","","","","","","","","","","","","","","","","","","","","","","","bdk::wallet::verify::VerifyError","","",""],"d":["Balance differentiated in various categories","BIP32 error","Block height and timestamp of a block","Branch and bound coin selection tries to avoid needing a …","Branch and bound coin selection possible attempts with …","Descriptor checksum mismatch","Compact filters client error)","DEPRECATED: Confirmation time of a transaction","Error related to the parsing and usage of descriptors","Electrum client error","Encoding error","Errors that can be thrown by the Wallet","Esplora client error","External","Fee rate","When bumping a tx the fee rate requested is lower than …","Node doesn’t have data to estimate a fee rate","When bumping a tx the absolute fee requested is lower than …","A UTXO owned by another wallet.","Generic error","Hex decoding error","Wallet’s UTXO set is not enough to cover recipient’s …","Internal, usually used for change outputs","Invalid network","Requested outpoint doesn’t exist in the tx (vout greater …","Error while extracting and manipulating policies","Progress value must be between 0.0 (included) and 100.0 …","Wrong number of bytes found when trying to convert to u32","Trying to replace a tx that has a sequence >= 0xFFFFFFFE","Error serializing or deserializing JSON data","Error while working with keys","Types of keychains","A UTXO owned by the local wallet.","An unspent output owned by a Wallet.","Miniscript error","Miniscript PSBT error","crate::blockchain::WalletSync sync attempt failed due to …","In order to use the TxBuilder::add_global_xpubs option …","Cannot build a tx without recipients","manually_selected_only option is selected but no utxo has …","Output created is under the dust limit, 546 satoshis","Progress update error (maybe the channel has been closed)","Partially signed bitcoin transaction error","Partially signed bitcoin transaction parse error","Rpc client error","Rusqlite client error","This error is thrown when trying to convert Bare and …","An ECDSA error","Signing error","Sled database error","Spending policy is not compatible with this KeychainKind","Happens when trying to bump a transaction that is already …","A wallet transaction","Thrown when a tx is not found in the internal database","Happens when trying to spend an UTXO that is not in the …","An unspent transaction output (UTXO).","Trait implemented by types that can be used to measure …","Transaction verification error","A Utxo with its satisfaction_weight.","","Return KeychainKind as a byte","","Return the value as satoshi/vbyte","","Blockchain backends","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","If the transaction is confirmed, contains height and …","Confirmed and immediately spendable balance","Database types","","","","Create a new FeeRate with the default min relay fee value","","","","","","","","","","","","","","","","","","","Descriptors","Macro to write full descriptors with code","","","","","","","","","","","","","","","","","","","","","","","Fee value (sats) if confirmed. The availability of the fee …","Calculate absolute fee in Satoshis using size in virtual …","Calculate absolute fee in Satoshis using size in weight …","","","","","","","","","","","","Macro to write descriptor fragments with code","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","Create a new instance of FeeRate given a float fee rate in …","Create a new instance of FeeRate given a float fee rate in …","Create a new instance of FeeRate given a float fee rate in …","Create a new instance of FeeRate given a float fee rate in …","Calculate fee rate from fee and vbytes.","Calculate fee rate from fee and weight units (wu).","","","Get sum of trusted_pending and confirmed coins","Get the whole balance visible to the wallet","","","confirmation block height","All coinbase outputs not yet matured","","","","","","","","","","","","","","","","","","","","","","","Whether this UTXO is spent or not","Type of keychain","Key formats","","","","","","","","Returns Some BlockTime if both height and timestamp are …","Get the location of the UTXO","Reference to a transaction output","","Additional functions on the rust-bitcoin …","Received value (sats) Sum of owned outputs of this …","The weight of the witness data and scriptSig expressed in …","Sent value (sats) Sum of owned inputs of this transaction.","","","","","","","","confirmation block timestamp","","","","","","","","","","","Optional transaction","Unconfirmed UTXOs generated by a wallet tx","","","","","","","","","","","","","","","","","","","Transaction id","Get the TxOut of the UTXO","Transaction output","","","","","","","","","","Unconfirmed UTXOs received from an external wallet","The UTXO","Convert weight units to virtual bytes.","Get the version of BDK at runtime","","","","","","","","","","Wallet","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","Sats available for spending","found network, for example the network of the bitcoin node","Sats needed for some transaction","requested network, for example what is given as bdk-cli …","Required fee rate (satoshi/vbyte)","Required fee absolute value (satoshi)","","The location of the output.","The information about the input we require to add it to a …","Can compute accurate fees for the transactions found …","Trait that defines the actions that must be supported by a …","Trait for a factory of blockchains that share the …","Capabilities that can be supported by a Blockchain backend","Type that contains the configuration","Trait for Blockchain types that can be created given a …","Structure that implements the logic to sync with Esplora","Can recover the full history of a wallet and not only the …","Can fetch any historical transaction given its txid","Trait for getting block hash by block height","Trait for getting the current height of the blockchain.","Trait for getting a transaction by txid","The type returned when building a blockchain from this …","Type that implements Progress and logs at level INFO every …","Type that implements Progress and drops every update …","Trait for types that can receive and process progress …","Data sent with a progress update over a channel","Trait for blockchains that don’t contain any state","Trait for blockchains that can sync by updating the …","Runtime-checked blockchain types","","","","","","","Broadcast a transaction","Build a new blockchain for the given descriptor wallet_name","Build a new blockchain for a given wallet","","","","","","","Compact Filters","","","","","","","","","","","","Electrum","","Esplora","Estimate the fee rate required to confirm a transaction in …","","","","","","","Create a new instance given a configuration","fetch block hash given its height","Return the set of Capability supported by this backend","","Return the current height","Fetch a transaction given its txid","","","","","","","","Create a new instance of LogProgress","Create a new instance of NoopProgress","Shortcut to create a channel (pair of Sender and Receiver) …","Rpc Blockchain","Use BlockchainFactory::build_for_wallet to get a …","","","","","","","","","","","","","Send a new progress update","","","","","","Setup the backend and populate the internal database for …","If not overridden, it defaults to calling …","Type that can contain any of the Blockchain types defined …","Type that can contain any of the blockchain configurations …","Compact filters client","Compact filters client","Electrum client","Electrum client","Esplora client","Esplora client","RPC client","RPC client configuration","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","Invalid BIP158 filter","Data to connect to a Bitcoin P2P peer","Block hash at specified height not found","Structure implementing the required blockchain traits","Configuration for a CompactFiltersBlockchain","An error that can occur during sync with a …","The data stored in the block filters storage are corrupted","Internal database error","Wrapper for crate::error::Error","The compact filter returned is invalid","The compact filter headers returned are invalid","The headers returned are invalid","A peer sent an invalid or unexpected response","Internal I/O error","Container for unconfirmed, but valid Bitcoin transactions","The peer is missing a block in the valid chain","No peers have been specified","A peer is not connected","A Bitcoin peer","The peer doesn’t advertise the BLOOM service flag","Internal system time error","A peer took too long to reply to one of our messages","Add a transaction to the mempool","Peer address such as 127.0.0.1:18333","","","","","","","","","","","","","","","","","","Connect to a peer over a plaintext TCP connection","Connect to a peer through a SOCKS5 proxy, optionally by …","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","Return the mempool used by this peer","Return the Bitcoin Network in use","Look-up a transaction in the mempool given an Inventory …","","Return the VersionMessage sent by the peer","Return whether or not the mempool contains a transaction …","","","","","","","","","","","","","Return whether or not the peer is still connected","Return the list of transactions contained in the mempool","","","Network used","Create a new empty mempool","Construct a new instance given a list of peers, a path to …","List of peers to try to connect to for asking headers and …","Waits for a specific incoming Bitcoin message, optionally …","Send a raw Bitcoin message to the peer","","","Optionally skip initial skip_blocks blocks (default: 0)","Optional socks5 proxy","Optional socks5 proxy credentials","Storage dir to save partially downloaded headers and full …","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","Wrapper over an Electrum Client that implements the …","Configuration for an ElectrumBlockchain","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","Request retry count","","URL of the socks5 proxy server or a Tor service","Stop searching addresses for transactions after finding an …","Request timeout (seconds)","","","","","","","","URL of the Electrum server (such as ElectrumX, Esplora, …","","","","Invalid Bitcoin data returned","Structure that implements the logic to sync with Esplora","Configuration for an EsploraBlockchain","Errors that can happen during a sync with Esplora","Header hash not found","Header height not found","Invalid Hex data returned","HTTP response error","IO error during ureq response read","No header found in ureq response","Invalid number returned","Transaction not found","Error during ureq HTTP request","Transport error during the ureq HTTP call","Base URL of the esplora service","","","","","","","","","","Number of parallel requests sent to the esplora service …","","","","","","","","","","","","","","","","","","","","","","","","","","","Build a new instance given a client","","","","","","","","","","","","","Create a new instance of the client from a base URL and …","create a config with default values given the base url and …","Optional URL of the proxy to use to make requests to the …","","Stop searching addresses for transactions after finding an …","Socket timeout.","","","","","","","","","","","","","","","","Set the number of parallel requests the client can make.","","","","","","","","","","","This struct is equivalent to bitcoincore_rpc::Auth but it …","Authentication with a cookie file","None authentication","The main struct for RPC backend implementing the …","Factory of RpcBlockchain instances, implements …","RpcBlockchain configuration options","Sync parameters for Bitcoin Core RPC.","Authentication with username and password, usually …","The bitcoin node authentication mechanism","The bitcoin node authentication mechanism","","","","","","","","","","","","","","","","","","","","","","","Default number of blocks to skip which will be inherited …","","","","","","","","","","","","","","","","","","","","","","","","","","","","","Forces every sync to use start_time as import timestamp.","","","","","","Returns RpcBlockchain backend creating an RPC client to a …","","","","","","","","","","","","","","","","","","","","The network we are using (it will be checked the bitcoin …","The network we are using (it will be checked the bitcoin …","","RPC poll rate (in seconds) to get state updates.","","","","The minimum number of scripts to scan for on initial sync.","Time in unix seconds in which initial sync will start …","Sync parameters","Sync parameters","","","","","","","","","","","","","","","","","","","","The bitcoin node url","The bitcoin node url","","","","","","The wallet name in the bitcoin node, consider using …","The optional prefix used to build the full wallet name for …","","Cookie file","Password","Username","Container for the operations","Trait for a database that supports batch operations","Trait for operations that can be batched","Type that contains the configuration","Trait for Database types that can be created given a …","Trait for reading data from a database","Sqlite database stored on filesystem","Blockchain state at the time of syncing","Runtime-checked database types","Create a new batch container","","Block timestamp and height at the time of sync","","","","","Read and checks the descriptor checksum for a given …","","","","Consume and apply a batch of operations","","A rusqlite connection object to the sqlite database","Delete the last derivation index for a keychain.","","Delete the data related to a specific script_pubkey, …","","Delete a raw transaction given its Txid","","Delete a script_pubkey given the keychain and its child …","","Reset the sync time to None","","Delete the metadata of a transaction and optionally the …","","Delete a LocalUtxo given its OutPoint","","","","","","","","","","","","","Create a new instance given a configuration","","Return the last derivation index for a keychain.","","Fetch the keychain and child number of a given …","","Fetch a raw transaction given its Txid","","Fetch a script_pubkey given the child number of a keychain.","","Return the sync time, if present","","Fetch the transaction metadata and optionally also the raw …","","Fetch a LocalUtxo given its OutPoint","","Increment the last derivation index for a keychain and …","","","","","","Return the list of raw transactions","","Return the list of script_pubkeys","","Return the list of transactions metadata","","Return the list of LocalUtxos","","In-memory ephemeral database","Instantiate a new SqliteDatabase instance by creating a …","Path on the local filesystem to store the sqlite file","","Store the last derivation index for a given keychain.","","Store a raw transaction","","Store a script_pubkey along with its keychain and child …","","Store the sync time","","Store the metadata of a transaction","","Store a LocalUtxo","","","","","","","","","","","Type that contains any of the BatchDatabase::Batch types …","Type that can contain any of the Database types defined by …","Type that can contain any of the database configurations …","In-memory ephemeral database","In-memory ephemeral database","Memory database has no config","Simple key-value embedded database based on sled","Simple key-value embedded database based on sled","Simple key-value embedded database based on sled","Configuration type for a sled::Tree database","Sqlite embedded database using rusqlite","Sqlite embedded database using rusqlite","Sqlite embedded database using rusqlite","Configuration type for a sqlite::SqliteDatabase database","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","Main directory of the db","Main directory of the db","","","","","","","","","","","","","","","","Name of the database tree, a separated namespace for the …","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","In-memory ephemeral database","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","Create a new empty database","","","","","","","","","","","A raw scriptpubkey (including pay-to-pubkey) under Legacy …","Alias for a Descriptor that contains extended derived keys","Script descriptor","The descriptor pubkey, either a single pubkey or an xpub.","An extended key with origin, derivation path, and wildcard.","Alias for a Descriptor that can contain extended keys …","Trait implemented on Descriptors to add a method to …","Unhardened wildcard, e.g. *h","Alias for the type of maps that represent derivation paths …","Trait for types which can be converted into an …","The consensus key associated with the type. Must be a …","Alias type for a map of public key to secret key","Legacy ScriptContext To be used as P2SH scripts For …","Top-level script AST type","No wildcard","Pay-to-PubKey-Hash","The ScriptContext for Miniscript. Additional type …","Segwitv0 ScriptContext","Pay-to-ScriptHash(includes nested wsh/wpkh/sorted multi)","Single public key.","Alias for the type of maps that represent taproot key …","Pay-to-Taproot","Unhardened wildcard, e.g. *","Whether a descriptor has a wildcard in it","Pay-to-Witness-PubKey-Hash","Pay-to-Witness-ScriptHash with Segwitv0 context","Extended public key (xpub).","Computes the Bitcoin address of the descriptor, if one …","","","Get a reference to the inner AstElem representing the root …","Replaces all wildcards (i.e. /*) in the descriptor with a …","","","","","","","","","","","","","Enumerates all child nodes of the current AST node (self) …","Depending on script Context, some of the Terminals might …","","","Depending on script Context, some of the script resource …","","Check the consensus + policy(if not disabled) rules that …","Consensus rules at the Miniscript satisfaction time. It is …","","","Policy rules at the Miniscript satisfaction time. It is …","","","Check the consensus + policy(if not disabled) rules …","Depending on ScriptContext, fragments can be malleable. …","","","Check whether the given satisfaction is valid under the …","","","Descriptor checksum","","","","","","","","","","","","","","","","","","","Whether the given miniscript contains a raw pkh fragment","","","","","","","","","","","","","The derivation path","Deprecated name for [at_derivation_index].","Convert all the public keys in the descriptor to …","Convert all the public keys in the descriptor to …","Get the DescriptorType of Descriptor","","","","","","","","","Encode as a Bitcoin script","","","","","","","Descriptor errors","Computes the the underlying script before any hashing is …","Additional information helpful for extra analysis.","Check whether the miniscript follows the given Extra …","Extract the spending policy","","","Utility method for deriving the descriptor at each index …","","","","","","","","","","","","","","","","","","","","","","","Add type information(Type and Extdata) to Miniscript based …","","Parse a Miniscript from string and perform sanity checks …","Attempt to parse an Miniscripts that don’t follow the …","Attempt to parse an insane(scripts don’t clear sanity …","Parse an expression tree into a descriptor.","Parse an expression tree into a Miniscript. As a general …","","","","","","","Returns child node with given index, if any","Returns Option::Some with cloned n’th public key from …","Returns satisfying non-malleable witness and scriptSig to …","Returns a possilbly mallable satisfying non-malleable …","Whether the miniscript contains a combination of timelocks","Whether the miniscript has repeated Pk or Pkh","Whether or not the descriptor has any wildcards i.e. /*.","","","","","","","","","","","","","","","","","","","Extracts the AstElem representing the root of the …","Convert to wallet descriptor","Whether or not the descriptor has any wildcards","Whether the miniscript is malleable","Creates a new Iter iterator that will iterate over all …","Creates a new PkIter iterator that will iterate over all …","","","Lifting corresponds conversion of miniscript into Policy […","Compares this key with a keysource and returns the …","Depending on script context, the size of a satifaction …","","","Maximum size, in bytes, of a satisfying witness. For …","Computes an upper bound on the weight of a satisfying …","Maximum number of witness elements used to satisfy the …","Local helper function to display error messages with …","","","","","Create a new bare descriptor from witness script Errors …","Create a new pk descriptor","Create a new PkH descriptor","Create a new sh for a given redeem script Errors when …","Create a new sh sortedmulti descriptor with threshold k …","Create a new sh wrapper for the given wpkh descriptor","Create a new sh wrapper for the given wsh descriptor","Create a new sh wrapped wpkh from Pk. Errors when …","Create a new sh wrapped wsh descriptor with witness script …","Create a new sh wrapped wsh sortedmulti descriptor from …","Create new tr descriptor Errors when miniscript exceeds …","Create a new Wpkh descriptor Will return Err if …","Create a new wsh descriptor from witness script Errors …","Create a new wsh sorted multi descriptor Errors when …","A node in the Abstract Syntax Tree(","Origin information","Other top level checks that are context specific","Attempt to parse a Script into Miniscript representation.","Parse a descriptor that may contain secret keys","Attempt to parse an insane(scripts don’t clear sanity …","Attempt to parse an miniscript with extra features that …","","","","","","","Get the len of public key when serialized based on context …","","","Descriptor policy","Whether all spend paths of miniscript require a signature","Checks whether the descriptor is safe.","Check whether the underlying Miniscript is safe under the …","Attempts to produce a non-malleable satisfying witness and …","Attempt to produce non-malleable satisfying witness for the","Attempt to produce a malleable satisfying witness for the …","Computes the scriptCode of a transaction output.","Computes the scriptpubkey of the descriptor.","Size, in bytes of the script-pubkey. If this Miniscript is …","","","The type of signature required for satisfaction","","","Descriptor templates","","","","","","","","","Serialize a descriptor to string with its secret keys","Check top level consensus rules.","Check whether the top-level is type B","Converts a descriptor using abstract keys to one using …","Translates a struct from one generic to another where the …","","","","","","","","","","","","","The correctness and malleability type information for the …","","","","","","","Computes the scriptSig that will be in place for an …","","","","","","","Whether the descriptor is wildcard","Whether the miniscript can exceed the resource …","The extended key","","","","","","","","","Compute the checksum of a descriptor, excludes any …","Compute the checksum bytes of a descriptor, excludes any …","Compute the checksum of a descriptor","Compute the checksum bytes of a descriptor","Error during base58 decoding","BIP32 error","Errors related to the parsing and usage of descriptors","The descriptor contains hardened derivation steps on …","Hex decoding error","Invalid byte found in the descriptor checksum","The provided descriptor doesn’t match its checksum","Invalid HD Key path, such as having a wildcard but a …","Error thrown while working with keys","Miniscript error","Key-related error","Error while extracting and manipulating policies","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","Absolute timeclock timestamp","Can not add to an item that is Satisfaction::None or …","Can not add to an item that is …","Options to build the satisfaction field in the policy","Can satisfy the policy item","An extra condition that must be satisfied but that is out …","Type for a map of sets of Condition items keyed by each set…","ECDSA Signature for a raw public key","An extended key fingerprint","Type for a map of folded sets of Condition items keyed by …","SHA256 then RIPEMD160 preimage hash","Double SHA256 preimage hash","Incompatible conditions (not currently used)","Index out of range for an item to satisfy a …","Can not merge CSV or timelock values unless both are less …","Multi-signature public keys with threshold count","Cannot satisfy or contribute to the policy item","Don’t generate satisfaction field","Not enough items are selected to satisfy a …","Only a partial satisfaction of some kind of threshold …","Can reach the threshold of some kind of threshold policy","A unique identifier for a key","Descriptor spending policy","Errors that can happen while extracting and manipulating …","Analyze the given PSBT to check for existing signatures","Like Psbt variant and also check for expired timelocks","A legacy public key","Relative timelock locktime","RIPEMD160 preimage hash","Represent if and how much a policy item is satisfied by …","An item that needs to be satisfied","Schnorr Signature for a raw public key","SHA256 preimage hash","Threshold items with threshold count","A x-only public key","","","","","","","","","","","","","","","","","","","","","","","","","","","How the wallet’s descriptor can satisfy this policy node","Optional CheckSequenceVerify condition","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","Return the conditions that are set by the spending policy …","","","","","Returns a unique id for the SatisfiableItem","Identifier for this policy node","","","","","","","","","","","","","","","Returns whether the SatisfiableItem is a leaf item","Returns whether the Satisfaction is a leaf item","Returns true if there are no extra conditions to verify","Type of this policy node","","","","","","","","Return whether or not a specific path in the policy tree …","How much a given PSBT already satisfies this policy node …","","","","","","Optional timelock condition","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","Current blockchain height","The highest confirmation height between the inputs CSV …","Given PSBT","","","","","","Extra conditions that also need to be satisfied","Extra conditions that also need to be satisfied","Extra conditions that also need to be satisfied","The items that can be satisfied by the descriptor or are …","The items that can be satisfied by the descriptor","Threshold","Threshold","Total number of items","Total number of items","Whether the items are sorted in lexicographic order (used …","Whether the items are sorted in lexicographic order (used …","","","The digest value","The digest value","The digest value","The digest value","The policy items","The raw public key or extended key fingerprint","The required threshold count","The required threshold count","The timelock value","The timelock value","","","","","","","","","","","","","","","","","","","BIP44 template. Expands to pkh(key/44'/{0,1}'/0'/{0,1}/*)","BIP44 public template. Expands to pkh(key/{0,1}/*)","BIP49 template. Expands to …","BIP49 public template. Expands to sh(wpkh(key/{0,1}/*))","BIP84 template. Expands to wpkh(key/84'/{0,1}'/0'/{0,1}/*)","BIP84 public template. Expands to wpkh(key/{0,1}/*)","Trait for descriptor templates that can be built into a …","Type alias for the return type of DescriptorTemplate, …","P2PKH template. Expands to a descriptor pkh(key)","P2WPKH template. Expands to a descriptor wpkh(key)","P2WPKH-P2SH template. Expands to a descriptor sh(wpkh(key))","","","","","","","","","","","","","","","","","","","Build the complete descriptor","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","BIP32 error","Trait for keys that can be derived.","Container for public or secret keys","The descriptor pubkey, either a single pubkey or an xpub.","The descriptor secret key, either a single private key or …","Type specifying the amount of entropy required e.g. [u8;32]","Returned error in case of failure","Trait that adds extra useful methods to ScriptContexts","Enum for extended keys that can be either xprv or xpub","A bitcoin public key (compressed or uncompressed).","Trait that allows generating a key with the default options","Trait for keys that can be generated","Output of a GeneratableKey key generation","Trait for objects that can be turned into a public or …","The key has an invalid checksum","The key is not valid for the given network","The key cannot exist in the given script context","The consensus key associated with the type. Must be a …","Errors thrown while working with keys","Alias type for a map of public key to secret key","Legacy scripts","Custom error message","Miniscript error","Extra options required by the generate_with_entropy","A private extended key, aka an xprv","Options for generating a PrivateKey","A public extended key, aka an xpub","The ScriptContext for Miniscript. Additional type …","Enum representation of the known valid ScriptContexts","Segwitv0 scripts","Single public key.","Single private key.","A descriptor bitcoin::PrivateKey with optional origin …","A descriptor SinglePubKey with optional origin information.","Single public key without any origin or range information.","Contents of a “sortedmulti” descriptor","Taproot scripts","Set of valid networks for a key","An xonly public key.","Extended private key (xpriv).","Extended public key (xpub).","Create a set containing mainnet, testnet and regtest","Returns the ScriptContext as a ScriptContextEnum","Replaces any wildcard (i.e. /*) in the key with a …","BIP-0039","","","","","","","","","","","","","","","","","","","","","","","","","Depending on script Context, some of the Terminals might …","Depending on script Context, some of the script resource …","Check the consensus + policy(if not disabled) rules that …","Consensus rules at the Miniscript satisfaction time. It is …","Policy rules at the Miniscript satisfaction time. It is …","Check the consensus + policy(if not disabled) rules …","Depending on ScriptContext, fragments can be malleable. …","Check whether the given satisfaction is valid under the …","","","","","","","","","","","","","","","","","","","Whether the generated key should be “compressed” or not","","","","","","","","","","","","","","","","","","","","","","","","","","","Deprecated name of [at_derivation_index].","","","","","","","","","","","","","Encode as a Bitcoin script","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","Create an instance given a public key and a set of valid …","Create an instance given a secret key and a set of valid …","","","Parse an expression tree into a SortedMultiVec","Full path, from the master key","Generate a key given the options with a random entropy","Generate a key with the default options and a random …","Generate a key given the extra options and the entropy","Generate a key with the default options and a given entropy","","","","","Return whether or not the key contains the private data","Whether or not the key has a wildcard","","","","","","","","","","","","","","","","","","","","","","","","","","","","","Turn the key into a DescriptorKey within the requested …","Consume self and turn it into a DescriptorKey by adding …","","","","","","Consume self and turn it into an ExtendedKey","","","Consumes self and returns the key","Transform the ExtendedKey into an ExtendedPrivKey for the …","Transform the ExtendedKey into an ExtendedPubKey for the …","Whether or not the key has a wildcard","Returns whether the script context is Legacy","Returns whether the script context is …","Returns whether the script context is Segwitv0","Returns whether the script context is …","Returns whether the script context is Tap, aka Taproot or …","Returns whether the script context is …","","","signatures required","The public key.","The private key.","","Create a set only containing mainnet","The fingerprint of the master key associated with this …","Depending on script context, the size of a satifaction …","Maximum size, in bytes, of a satisfying witness. In …","Maximum number of witness elements used to satisfy the …","Compute the intersection of two sets","Local helper function to display error messages with …","","","","","Create a new instance of SortedMultiVec given a list of …","Origin information (fingerprint and derivation path).","Origin information (fingerprint and derivation path).","Other top level checks that are context specific","Override the computed set of valid networks","","","","","Get the len of public key when serialized based on context …","public keys inside sorted Multi","utility function to sanity a sorted multi vec","Attempt to produce a satisfying witness for the witness …","Size, in bytes of the script-pubkey. If this Miniscript is …","The type of signature required for satisfaction","Create Terminal::Multi containing sorted pubkeys","Create a set containing testnet and regtest","","","","","","","","Returns the public version of this key.","","","","","Check top level consensus rules.","Check whether the top-level is type B","This will panic if fpk returns an uncompressed key when …","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","The mnemonic can be interpreted as multiple languages. Use …","Entropy was not a multiple of 32 bits or between 128-256n …","Mnemonic has a word count that is not a multiple of 6.","The English language.","A BIP39 error.","The mnemonic has an invalid checksum.","Language to be used for the mnemonic phrase.","A mnemonic code.","Type for a BIP39 mnemonic with an optional passphrase","Mnemonic contains an unknown word. Error contains the …","Type describing entropy length (aka word count) in the …","12 words mnemonic (128 bits entropy)","15 words mnemonic (160 bits entropy)","18 words mnemonic (192 bits entropy)","21 words mnemonic (224 bits entropy)","24 words mnemonic (256 bits entropy)","The list of supported languages. Language support is …","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","Create a new English Mnemonic from the given entropy. …","Create a new Mnemonic in the specified language from the …","","Generate a new Mnemonic in the given language with the …","","","","","","","","","","","","","","","","Get the language of the Mnemonic.","Determine the language of the mnemonic.","","","Parse a mnemonic and detect the language from the enabled …","Parse a mnemonic in the given language.","Parse a mnemonic in normalized UTF8 in the given language.","Parse a mnemonic in normalized UTF8.","","","","Convert the mnemonic back to the entropy used to generate …","Convert the mnemonic back to the entropy used to generate …","","","","Convert to seed bytes.","Convert to seed bytes with a passphrase in normalized UTF8.","","","","","","","","","","","","","","","","","","","","Get the number of words in the mnemonic.","Get an iterator over the words.","Get words from the word list that start with the given …","","","","","Trait to add functions to extract utxos and calculate fees.","The total transaction fee amount, sum of input amounts …","The transaction’s fee rate. This value will only be …","Get the TxOut for the specified input index, if it doesn’…","The address index selection strategy to use to derived an …","A derived address and the index it was found at For …","Trait to check if a value is below the dust limit. We are …","Return the address for the current descriptor index if it …","Return a new address after incrementing the current …","Return the address for a specific descriptor index. Does …","Return the address for a specific descriptor index and …","Options to a sync.","A Bitcoin wallet","Add an external signer","Address","","","","","","","","","Bump the fee of a transaction previously created with this …","Start building a transaction.","Coin selection","Return an immutable reference to the internal database","","","","","","","","","","","Return the checksum of the public descriptor associated to …","","","","","Ensures that there are at least max_addresses addresses …","","Wallet export","Finalize a PSBT, i.e., for each input determine if …","","","","","","","","","","Return a derived address using the external descriptor, …","Return the balance, separated into available, …","Returns the descriptor used to create addresses for a …","Return a fake wallet that appears to be funded for testing.","Return a derived address using the internal (change) …","get the corresponding PSBT Input for a LocalUtxo","Get the signers","Return a single transactions made and received by the …","Returns the UTXO owned by this wallet corresponding to …","HWI Signer","Child index of this address","","","","","","","","","Check whether or not a value is below dust limit","Return whether or not a script is part of this wallet …","Type of keychain","Return an unsorted list of transactions made and received …","Return the list of unspent outputs of this wallet","","Get the Bitcoin network the wallet is using.","Create a wallet.","Create a new “offline” wallet","Return the spending policies for the wallet’s descriptor","The progress tracker which may be informed when progress …","Return the “public” version of the wallet’s …","Return the secp256k1 context used for all signing …","Sign a transaction with all the wallet’s signers, in the …","Generalized signers","Sync the internal database with the blockchain","Cross-platform time","","","","","","","","","","Transaction builder","","","","","Verify transactions against the consensus rules","","","","","Deterministically generate a unique name given the …","","","Branch and bound coin selection","It’s possible to create spendable output from excess …","Trait for generalized coin selection algorithms","Result of a successful coin selection","Default coin selection algorithm used by TxBuilder if not …","Remaining amount after performing coin selection","Simple and dumb coin selection","It’s not possible to create spendable output from excess …","OldestFirstCoinSelection always picks the utxo with the …","","","","","","","","","","","","","","","Perform the coin selection","","","","Decide if change can be created","","","","","","","","","","","","","","","","","","","Remaining amount after deducing fees and outgoing outputs","Total fee amount for the selected utxos in satoshis","","","","","","","","","","","","","","","","","","","","","The total value of the inputs selected from the local …","Create new instance with target size for change output","List of outputs selected for use as inputs","The total value of the inputs selected.","","","","","","","","","","","","","","","","","","","","","","","Effective amount available to create change after …","The calculated fee for the drain TxOut with the selected …","Threshold to consider amount as dust for this particular …","The deducted change output fee","Exceeding amount of current selection over outgoing value …","Structure that contains the export of a wallet","Alias for FullyNodedExport","Earliest block to rescan when looking for the wallet’s …","","","Return the internal descriptor, if present","","","Return the external descriptor","","","Export a wallet","","","","","","Arbitrary label for the wallet","","","","","","","Custom signer for Hardware Wallets","","","","","","","","Create a instance from the specified device and chain","","","","","","","","","","The signer will sign all the leaves it has a key for.","Dummy identifier","The signer won’t sign the specified leaves.","The fingerprint of a BIP32 extended key","Error while signing using hardware wallets","The signer won’t sign leaves other than the ones …","Input index is out of range","PSBT Input signer","The private key in use has the right fingerprint but …","The non_witness_utxo specified is invalid","Invalid SIGHASH for the signing context in use","Legacy context","The fingerprint and derivation path are missing from the …","The private key is missing for the required public key","The non_witness_utxo field of the transaction is required …","The witness_script field of the transaction is required to …","The witness_utxo field of the transaction is required to …","The psbt contains a non-SIGHASH_ALL sighash in one of its …","The signer won’t sign any leaf.","Bitcoin HASH160 (RIPEMD160 after SHA256) hash of an ECDSA …","Segwit v0 context (BIP 143)","Error while computing the hash to sign","Options for a software signer","Common signer methods","Signing context","Signing error","Identifier of a signer in the SignersContainers. Used as a …","Defines the order in which signers are called","Wrapper structure to pair a signer with its context","Container for multiple signers","Taproot context (BIP 340)","Customize which taproot script-path leaves the signer …","PSBT signer","The user canceled the operation","Adds an external signer to the container for the specified …","Whether the signer should use the sighash_type set in the …","Whether we should grind ECDSA signature to ensure signing …","Create a map of public keys to secret keys","Whether the wallet should assume a specific height has …","","","","","","","","","","","","","","","","","Build a new signer container from a KeyMap","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","Return the secret key for the signer","","","","","","","","","","","","","","","","Finds the signer with lowest ordering for a given id in …","","","","","","","","","","","","","","","","","","","","","","","","Return the SignerId for this signer","","","Returns the list of identifiers of all the signers in the …","","","","","","","","","","","","","","","","","","","","","","Create a wrapped signer from a signer and a context","Default constructor","","","Removes a signer from the container and returns it","Whether to remove partial signatures from the PSBT inputs …","Sign a single psbt input","","","Sign all the inputs of the psbt","","Whether we should try to sign a taproot transaction with …","Returns the list of signers in the container, sorted by …","Specifies which Taproot script-spend leaves we should sign …","","","","","","","","","","Whether the signer should trust the witness_utxo, if the …","Whether to try finalizing the PSBT after the inputs are …","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","Whether the signer can sign for the internal key or not","","","","","","","","Return the current timestamp in seconds","BIP69 / Lexicographic","Marker type to indicate the TxBuilder is being used to …","Use both change and non-change outputs (default)","Only use non-change outputs (see …","Policy regarding the use of change outputs when creating a …","Marker type to indicate the TxBuilder is being used to …","Only use change outputs (see TxBuilder::only_spend_change)","Randomized (default)","A transaction builder","Context in which the TxBuilder is valid","Ordering of the transaction’s inputs and outputs","Unchanged","Add data as an output, using OP_RETURN","Add a foreign UTXO i.e. a UTXO not owned by this wallet.","Fill-in the PSBT_GLOBAL_XPUB field with the extended keys …","Add a recipient to the internal list","Add a utxo to the internal list of unspendable utxos","Add a utxo to the internal list of utxos that must be spent","Add the list of outpoints to the internal list of UTXOs …","Set whether or not the dust limit is checked.","Explicitly tells the wallet that it is allowed to reduce …","","","","","","","","","","","Set a specific ChangeSpendPolicy. See …","","","","","","","","","","","","","Choose the coin selection algorithm","Set the current blockchain height.","","","","","","","","","","","","","","","Do not spend change outputs","Sets the address to drain excess coins to.","Spend all the available inputs. This respects filters like …","","","","","","Enable signaling RBF","Enable signaling RBF with a specific nSequence value","","","Set an absolute fee","Set a custom fee rate","Finish building the transaction.","","","","","","","","","","","","","","","Fill-in the psbt::Output::redeem_script and …","","","","","","","","","","","Only spend utxos added by add_utxo.","Use a specific nLockTime while creating the transaction","Only spend change outputs","Only Fill-in the psbt::Input::witness_utxo field when …","Choose the ordering for inputs and outputs of the …","","","Set the policy path to use while creating the transaction …","Replace the recipients already added with a new list","Sign with a specific sig hash","Sort transaction inputs and outputs by TxOrdering variant","","","","","","","","","","","","","","","","","","","","","Replace the internal list of unspendable utxos with a new …","Build a transaction with a specific version","","","","","","Consensus error","Generic error","The transaction being spent doesn’t have the requested …","The transaction being spent is not available in the …","Error during validation of a tx agains the consensus rules","","","","","","","","","","","","","","","","","Verify a transaction against the consensus rules","","","","",""],"i":[0,1,0,1,1,1,1,0,1,1,1,0,1,2,0,1,1,1,3,1,1,1,2,1,1,1,1,1,1,1,1,0,3,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,0,0,1,0,4,2,2,5,2,0,1,2,5,6,7,3,8,9,4,1,2,5,6,7,3,8,9,4,2,2,5,6,7,3,8,9,4,2,5,6,7,3,8,9,4,8,4,0,5,9,4,5,1,2,5,6,7,3,8,9,4,1,2,5,6,7,3,8,9,4,0,0,2,6,8,9,4,1,2,5,6,7,3,8,9,4,2,5,6,7,3,8,9,4,8,5,5,1,1,2,5,6,7,3,8,9,4,4,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,5,6,7,3,8,9,9,4,5,5,5,5,5,5,2,6,4,4,2,6,9,4,1,2,5,6,7,3,8,9,4,1,2,5,6,7,3,8,9,4,10,10,11,12,6,6,0,5,6,7,3,8,9,4,9,3,6,5,0,8,7,8,2,6,8,9,4,5,4,9,2,5,6,7,3,8,9,4,1,4,8,4,1,2,5,6,7,3,8,9,4,1,2,5,6,7,3,8,9,4,8,3,6,1,2,5,6,7,3,8,9,4,4,7,13,0,1,2,5,6,7,3,8,9,4,0,2,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,42,43,44,45,46,47,47,48,0,0,0,49,0,0,48,48,0,0,0,50,0,0,0,0,0,0,0,48,51,52,48,51,52,53,50,50,48,51,52,48,51,52,0,51,52,48,51,52,48,51,52,48,51,52,0,48,0,53,48,51,52,48,51,52,49,54,53,48,55,56,48,48,51,52,48,51,52,0,0,0,0,50,48,51,52,48,51,52,48,51,52,48,51,52,57,51,52,48,51,52,58,58,0,0,59,60,59,60,59,60,59,60,59,60,59,60,59,60,60,59,60,59,60,60,59,60,60,59,60,59,59,59,59,59,60,60,60,60,60,59,59,59,59,59,59,60,59,60,60,60,60,59,60,59,60,59,60,59,60,59,59,61,62,63,64,65,66,67,68,69,0,69,0,0,0,69,69,69,69,69,69,69,69,0,69,69,69,0,69,69,69,70,71,70,72,73,71,74,69,70,72,73,71,74,69,73,71,74,71,74,72,72,70,70,72,73,71,74,69,70,72,73,71,74,69,71,74,70,72,73,71,74,69,71,74,73,70,72,73,71,74,69,69,70,72,73,71,74,69,69,69,69,69,69,73,73,73,73,72,72,70,73,72,70,70,72,73,71,74,69,70,72,73,71,74,69,72,70,71,74,74,70,73,74,72,72,71,74,74,71,71,74,71,74,69,70,72,73,71,74,69,70,72,73,71,74,69,70,72,73,71,74,69,70,72,73,71,74,69,73,75,76,77,78,79,0,0,80,81,80,81,80,81,81,80,80,81,80,81,81,80,81,81,80,81,80,80,81,80,80,80,80,80,80,81,80,81,81,81,81,81,81,81,81,80,81,80,81,80,81,81,80,81,80,82,0,0,0,82,82,82,82,82,82,82,82,82,82,83,82,84,83,82,84,83,84,83,83,83,82,84,84,83,82,84,83,83,82,84,83,83,84,82,82,84,83,82,82,82,82,82,82,82,84,83,84,84,84,84,84,84,82,84,83,82,84,83,83,84,83,83,83,83,83,83,82,82,84,83,82,84,83,82,84,83,82,84,83,84,84,85,86,87,88,89,90,91,92,93,94,0,95,95,0,0,0,0,95,96,97,98,96,99,95,97,98,96,99,95,97,98,97,96,99,95,97,96,99,95,97,95,99,97,98,98,96,99,95,97,98,96,99,95,97,96,99,95,98,96,99,95,97,96,99,95,98,98,96,99,95,97,99,98,96,99,95,97,98,98,98,95,98,98,95,98,96,99,95,97,98,96,99,95,97,96,99,95,96,97,95,99,96,99,95,99,99,96,97,96,99,95,97,98,96,99,95,97,98,96,99,95,97,98,96,99,95,97,96,97,98,96,99,95,97,96,97,98,100,101,101,102,0,0,103,0,0,0,0,0,102,104,105,104,105,104,105,106,104,105,105,102,104,104,107,104,107,104,107,104,107,104,107,104,107,104,107,104,104,105,104,105,105,104,105,104,105,104,105,103,104,106,104,106,104,106,104,106,104,106,104,106,104,106,104,106,104,104,105,104,105,106,104,106,104,106,104,106,104,0,104,104,105,107,104,107,104,107,104,107,104,107,104,107,104,105,104,105,104,105,104,105,104,105,0,0,0,108,109,110,108,109,110,0,108,109,110,0,109,108,109,111,112,110,108,109,111,112,110,109,109,108,109,108,109,108,109,108,109,108,109,108,109,108,109,108,109,111,112,110,108,109,111,112,110,111,112,110,108,109,111,112,110,109,111,112,110,108,108,108,108,109,109,109,109,111,112,110,110,110,110,109,109,109,109,109,109,109,109,109,108,109,111,112,110,108,109,111,112,110,109,109,109,109,111,112,111,112,110,108,109,108,109,108,109,108,109,108,109,108,109,111,108,109,111,112,110,108,109,111,112,110,108,109,111,112,110,108,109,111,112,110,113,114,115,116,117,118,119,120,121,0,122,122,122,122,122,122,122,122,122,122,122,122,122,122,122,122,122,122,122,122,122,122,122,122,122,122,122,122,122,122,122,122,122,122,122,122,122,122,122,122,122,122,122,122,123,0,0,0,0,0,0,124,0,0,125,0,0,0,124,123,0,0,123,126,0,123,124,0,123,123,126,123,127,128,129,123,130,124,123,127,128,129,130,124,123,127,128,129,129,125,127,128,125,128,125,125,127,128,125,127,128,125,125,127,128,125,127,128,0,130,124,123,127,128,129,130,124,123,127,128,129,130,124,123,127,128,129,129,130,124,123,127,128,129,130,124,123,127,128,129,130,123,123,123,123,123,129,130,124,123,127,128,129,129,130,124,123,127,128,129,0,123,129,129,131,123,129,123,130,124,123,123,127,128,129,129,123,129,130,124,123,123,123,123,123,123,123,127,128,129,129,123,129,129,129,123,129,130,124,123,127,128,129,129,129,123,123,129,129,123,130,124,123,127,128,129,130,124,123,127,128,129,130,124,123,127,128,129,129,132,123,129,129,129,123,129,129,130,125,127,128,129,123,129,125,127,128,130,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,129,130,125,129,123,129,129,130,124,123,127,128,129,125,127,128,0,129,123,129,123,129,129,123,123,129,123,129,125,127,128,0,130,124,123,127,128,129,123,129,123,125,125,123,129,130,124,123,127,128,129,130,124,123,127,128,129,129,130,124,123,127,128,129,123,130,124,123,127,128,129,130,129,130,133,134,135,136,137,138,139,140,0,0,0,0,141,141,0,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,142,143,144,145,146,147,148,149,150,151,151,0,152,0,0,150,153,0,150,150,151,151,151,150,152,154,151,152,152,0,0,0,154,154,153,150,150,0,0,150,150,150,153,153,150,152,155,156,151,154,153,150,152,155,156,151,154,153,150,152,155,156,154,153,150,152,155,156,154,155,156,156,153,150,152,155,156,151,154,153,150,152,155,156,151,154,153,150,152,155,156,151,154,153,150,152,155,156,151,153,150,152,155,156,151,151,154,153,150,152,152,155,155,156,151,154,155,153,156,153,156,150,155,153,150,152,155,156,151,154,153,150,152,155,156,151,154,150,152,156,155,153,150,152,155,156,151,156,155,155,153,150,152,155,156,156,153,150,152,155,156,154,151,153,150,152,155,156,151,154,153,150,152,155,156,151,154,153,150,152,155,156,151,154,153,150,152,155,156,151,154,157,158,158,158,159,160,161,162,163,164,165,166,165,166,165,166,165,166,165,166,167,168,169,170,171,172,173,174,174,173,175,176,177,178,179,180,181,182,183,184,185,180,181,182,183,184,185,181,183,185,0,0,0,0,0,0,0,0,0,0,0,177,178,179,180,181,182,183,184,185,177,178,179,180,181,182,183,184,185,186,177,178,179,180,181,182,183,184,185,177,178,179,180,181,182,183,184,185,177,178,179,180,181,182,183,184,185,177,178,179,180,181,182,183,184,185,177,178,179,180,181,182,183,184,185,177,178,179,180,181,182,183,184,185,177,178,179,180,181,182,183,184,185,177,178,179,180,181,182,183,184,185,177,178,179,180,181,182,183,184,185,177,178,179,180,181,182,183,184,185,177,178,179,180,181,182,183,184,185,177,178,179,180,181,182,183,184,185,187,0,0,0,0,188,188,0,0,189,0,0,0,0,187,187,187,125,0,0,190,187,187,188,191,0,191,0,0,190,126,192,0,0,0,0,190,0,189,192,126,0,193,126,0,191,194,195,126,192,196,197,189,198,190,199,187,191,194,195,126,192,196,197,189,198,190,199,187,125,125,125,125,125,125,125,125,194,195,126,196,189,190,199,194,195,126,196,189,190,199,195,126,196,189,199,199,191,194,194,195,126,192,196,197,189,198,190,199,187,191,194,195,126,192,196,197,189,198,190,199,187,126,191,194,195,126,192,196,197,189,198,190,199,187,195,195,126,196,189,190,195,195,126,126,192,192,196,197,189,198,190,199,187,187,195,191,191,191,194,195,126,126,192,196,197,189,198,190,199,187,187,187,198,198,126,192,195,126,188,200,188,200,195,126,196,189,191,126,195,126,196,189,191,194,195,126,192,196,197,189,198,190,199,187,191,194,195,126,192,196,197,189,198,190,199,187,201,202,194,194,126,192,198,202,191,194,194,191,191,126,193,190,193,190,193,190,126,126,195,196,197,195,0,126,125,195,195,0,125,195,126,196,189,195,196,197,125,198,195,126,196,189,125,195,195,195,195,125,195,0,194,195,126,196,189,190,199,192,195,126,192,187,125,125,195,191,194,195,126,192,196,197,189,198,190,199,187,191,194,195,126,192,196,197,189,198,190,199,187,191,194,195,126,192,196,197,189,198,190,199,187,191,194,195,126,192,196,197,189,198,190,199,187,139,140,203,204,205,206,207,208,209,210,211,212,212,212,213,0,212,0,0,0,212,0,214,214,214,214,214,213,213,212,215,214,213,212,215,214,213,212,215,213,212,215,213,215,213,212,215,214,213,212,215,214,215,213,212,215,214,213,212,215,213,213,212,212,215,215,213,212,215,214,215,215,215,215,215,213,215,213,215,213,212,215,214,213,212,215,214,215,215,215,215,212,215,215,215,215,215,213,215,215,215,215,213,212,215,215,215,213,212,215,213,212,215,214,213,212,215,214,213,212,215,214,213,212,215,214,215,215,213,216,217,218,219,0,220,220,220,0,0,0,221,221,221,221,0,0,222,223,222,221,223,224,222,221,223,224,222,222,0,222,224,222,221,223,223,224,222,221,223,224,222,222,221,223,224,222,223,0,222,222,221,223,223,224,222,221,223,224,222,222,222,0,222,222,222,222,222,0,223,222,221,223,224,222,221,223,224,225,222,223,222,222,223,222,222,222,222,224,222,222,222,0,222,0,223,222,221,223,224,222,221,223,224,0,222,221,223,224,0,222,221,223,224,0,226,227,0,228,0,0,0,0,0,228,0,228,229,230,231,232,228,229,230,231,232,230,231,230,231,233,230,231,232,0,230,231,232,228,229,230,231,232,228,229,230,231,232,228,229,230,231,232,229,229,228,229,230,231,232,228,229,230,231,232,228,229,230,231,232,228,229,230,231,232,229,232,229,229,230,231,228,229,230,231,232,228,229,230,231,232,228,229,230,231,232,228,229,230,231,232,234,235,235,234,235,0,0,236,236,236,236,236,236,236,236,236,236,236,236,236,236,236,236,236,236,236,236,236,236,0,237,237,237,237,237,237,237,237,237,237,237,237,237,237,237,237,238,239,240,239,240,241,239,241,0,241,241,241,242,241,241,241,241,241,241,239,240,242,241,0,0,0,0,0,0,0,0,242,0,0,241,243,244,244,243,244,240,241,242,245,238,243,244,239,240,241,242,245,238,243,244,239,243,240,241,242,245,238,243,244,239,240,241,242,245,238,243,244,239,240,238,238,243,244,239,240,241,242,245,245,238,243,244,239,240,241,242,245,238,243,244,239,246,245,245,240,241,242,245,238,243,244,239,240,241,242,238,239,243,240,241,241,242,245,238,243,244,239,240,240,240,241,241,241,242,245,238,243,244,239,240,240,246,245,245,243,240,241,242,245,238,243,244,239,240,241,242,245,238,243,244,239,240,241,242,238,239,245,243,240,238,243,244,247,245,245,248,245,244,243,244,240,241,242,245,238,243,244,239,241,244,244,240,241,242,245,238,243,244,239,240,241,242,245,238,243,244,239,240,241,242,245,238,243,244,239,240,241,242,245,238,243,244,239,249,250,251,252,253,254,255,256,0,257,0,258,258,0,0,258,257,0,0,0,257,259,259,259,259,259,259,259,259,259,260,261,259,257,258,260,261,259,257,258,259,260,261,259,257,258,260,261,259,257,258,257,258,259,259,260,261,257,258,260,261,259,257,258,260,261,259,257,258,259,259,259,260,261,259,257,258,259,259,257,258,259,259,259,260,261,259,257,258,260,261,259,257,258,257,258,257,258,259,260,261,259,257,258,260,261,259,257,258,259,259,259,259,259,257,258,259,259,259,257,260,261,259,257,258,260,261,259,257,258,260,261,259,257,258,260,261,259,257,258,259,259,260,261,259,257,258,262,262,262,262,0,262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,0,262,263,264,265,266],"f":[null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,[[]],[[],["u8",15]],[[]],[[],["f32",15]],[[],["usize",15]],null,[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[],["result",4,[["vec",3,[["u5",3],["global",3]]]]]],[[],["keychainkind",4]],[[],["feerate",3]],[[],["localutxo",3]],[[],["weightedutxo",3]],[[],["utxo",4]],[[],["transactiondetails",3]],[[],["blocktime",3]],[[],["balance",3]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],null,null,null,[[]],[[],["blocktime",3]],[[],["balance",3]],[[]],[[["usize",15]]],[[["usize",15]]],[[["usize",15]]],[[["usize",15]]],[[["usize",15]]],[[["usize",15]]],[[["usize",15]]],[[["usize",15]]],[[["usize",15]]],[[["usize",15]]],[[["usize",15]]],[[["usize",15]]],[[["usize",15]]],[[["usize",15]]],[[["usize",15]]],[[["usize",15]]],[[["usize",15]]],[[["usize",15]]],null,null,[[],["result",4]],[[],["result",4]],[[],["result",4]],[[],["result",4]],[[],["result",4]],[[["usize",15]]],[[["usize",15]]],[[["usize",15]]],[[["usize",15]]],[[["usize",15]]],[[["usize",15]]],[[["usize",15]]],[[["usize",15]]],[[["usize",15]]],[[["keychainkind",4]],["bool",15]],[[["feerate",3]],["bool",15]],[[["localutxo",3]],["bool",15]],[[["weightedutxo",3]],["bool",15]],[[["utxo",4]],["bool",15]],[[["transactiondetails",3]],["bool",15]],[[["blocktime",3]],["bool",15]],[[["balance",3]],["bool",15]],null,[[["usize",15]],["u64",15]],[[["usize",15]],["u64",15]],[[["formatter",3]],["result",6]],[[["formatter",3]],["result",6]],[[["formatter",3]],["result",6]],[[["formatter",3]],["result",6]],[[["formatter",3]],["result",6]],[[["formatter",3]],["result",6]],[[["formatter",3]],["result",6]],[[["formatter",3]],["result",6]],[[["formatter",3]],["result",6]],[[["formatter",3]],["result",6]],[[["formatter",3]],["result",6]],null,[[["error",4]]],[[["error",4]]],[[["error",4]]],[[["esploraerror",4]]],[[["verifyerror",4]]],[[["error",4]]],[[["error",4]]],[[["psbtparseerror",4]]],[[["error",4]]],[[["error",4]]],[[["error",4]]],[[["error",3]]],[[["compactfilterserror",4]]],[[["error",4]]],[[["error",4]]],[[]],[[["policyerror",4]]],[[["error",4]]],[[["keyerror",4]],["error",4]],[[["signererror",4]]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[["blocktime",3]]],[[]],[[["f32",15]]],[[["f32",15]]],[[["f32",15]]],[[["f32",15]]],[[["u64",15],["usize",15]],["feerate",3]],[[["u64",15],["usize",15]],["feerate",3]],[[],["u64",15]],[[],["u64",15]],[[],["u64",15]],[[],["u64",15]],[[]],[[]],null,null,[[],["usize",15]],[[],["usize",15]],[[],["usize",15]],[[],["usize",15]],[[],["usize",15]],[[],["usize",15]],[[],["usize",15]],[[],["usize",15]],[[],["usize",15]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[["option",4,[["keysource",6]]],["derivationpath",3]],["result",4,[["descriptorkey",4],["keyerror",4]]]],[[],["result",4,[["extendedkey",4],["keyerror",4]]]],[[["secp256k1",3],["network",4]],["result",4,[["descriptorerror",4]]]],[[["secp256k1",3],["network",4]],["result",4,[["descriptorerror",4]]]],null,null,null,[[["feerate",3]],["bool",15]],[[["localutxo",3]],["bool",15]],[[["weightedutxo",3]],["bool",15]],[[["utxo",4]],["bool",15]],[[["transactiondetails",3]],["bool",15]],[[["blocktime",3]],["bool",15]],[[["balance",3]],["bool",15]],[[["option",4,[["u32",15]]],["option",4,[["u64",15]]]],["option",4]],[[],["outpoint",3]],null,[[["feerate",3]],["option",4,[["ordering",4]]]],null,null,null,null,[[],["result",4]],[[],["result",4]],[[],["result",4]],[[],["result",4]],[[],["result",4]],[[["feerate",3]]],[[["iterator",8]]],null,[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[],["string",3]],[[],["string",3]],null,null,[[],["result",4]],[[],["result",4]],[[],["result",4]],[[],["result",4]],[[],["result",4]],[[],["result",4]],[[],["result",4]],[[],["result",4]],[[],["result",4]],[[],["result",4]],[[],["result",4]],[[],["result",4]],[[],["result",4]],[[],["result",4]],[[],["result",4]],[[],["result",4]],[[],["result",4]],[[],["result",4]],null,[[],["txout",3]],null,[[],["typeid",3]],[[],["typeid",3]],[[],["typeid",3]],[[],["typeid",3]],[[],["typeid",3]],[[],["typeid",3]],[[],["typeid",3]],[[],["typeid",3]],[[],["typeid",3]],null,null,[[],["usize",15]],[[],["str",15]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],null,[[],["result",4]],null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,[[]],[[]],[[]],[[]],[[]],[[]],[[["transaction",3]],["result",4,[["error",4]]]],[[["str",15],["option",4,[["u32",15]]]],["result",4,[["error",4]]]],[[["wallet",3],["option",4,[["u32",15]]]],["result",4,[["error",4]]]],[[],["capability",4]],[[],["noopprogress",3]],[[],["logprogress",3]],[[]],[[]],[[]],null,[[],["noopprogress",3]],[[],["logprogress",3]],[[["usize",15]]],[[["usize",15]]],[[["usize",15]]],[[["usize",15]]],[[["usize",15]]],[[["usize",15]]],[[["usize",15]]],[[["usize",15]]],[[["usize",15]]],null,[[["capability",4]],["bool",15]],null,[[["usize",15]],["result",4,[["feerate",3],["error",4]]]],[[["formatter",3]],["result",6]],[[["formatter",3]],["result",6]],[[["formatter",3]],["result",6]],[[]],[[]],[[]],[[],["result",4,[["error",4]]]],[[["u64",15]],["result",4,[["blockhash",3],["error",4]]]],[[],["hashset",3,[["capability",4]]]],[[],["u64",15]],[[],["result",4,[["u32",15],["error",4]]]],[[["txid",3]],["result",4,[["option",4,[["transaction",3]]],["error",4]]]],[[]],[[],["usize",15]],[[],["usize",15]],[[],["usize",15]],[[]],[[]],[[]],[[],["logprogress",3]],[[],["noopprogress",3]],[[]],null,[[["wallet",3],["option",4,[["u32",15]]],["syncoptions",3]],["result",4,[["error",4]]]],[[]],[[]],[[]],[[],["result",4]],[[],["result",4]],[[],["result",4]],[[],["result",4]],[[],["result",4]],[[],["result",4]],[[],["typeid",3]],[[],["typeid",3]],[[],["typeid",3]],[[["f32",15],["option",4,[["string",3]]]],["result",4,[["error",4]]]],[[["f32",15],["option",4,[["string",3]]]],["result",4,[["error",4]]]],[[["f32",15],["option",4,[["string",3]]]],["result",4,[["error",4]]]],[[]],[[]],[[]],[[["box",3,[["progress",8]]]],["result",4,[["error",4]]]],[[["box",3,[["progress",8]]]],["result",4,[["error",4]]]],null,null,null,null,null,null,null,null,null,null,[[]],[[]],[[]],[[]],[[["transaction",3]],["result",4,[["error",4]]]],[[],["anyblockchainconfig",4]],[[]],[[["usize",15]]],[[["usize",15]]],[[["usize",15]]],[[["usize",15]]],[[],["result",4]],[[["usize",15]]],[[["usize",15]]],[[["anyblockchainconfig",4]],["bool",15]],[[["usize",15]],["result",4,[["feerate",3],["error",4]]]],[[["formatter",3]],["result",6]],[[["electrumblockchain",3]]],[[["esplorablockchain",3]]],[[]],[[["rpcblockchain",3]]],[[["compactfiltersblockchain",3]]],[[["compactfiltersblockchainconfig",3]]],[[["esplorablockchainconfig",3]]],[[]],[[["electrumblockchainconfig",3]]],[[["rpcconfig",3]]],[[],["result",4,[["error",4]]]],[[["u64",15]],["result",4,[["blockhash",3],["error",4]]]],[[],["hashset",3,[["capability",4]]]],[[],["result",4,[["u32",15],["error",4]]]],[[["txid",3]],["result",4,[["option",4,[["transaction",3]]],["error",4]]]],[[],["usize",15]],[[],["usize",15]],[[]],[[]],[[["anyblockchainconfig",4]],["bool",15]],[[],["result",4]],[[]],[[],["result",4]],[[],["result",4]],[[],["result",4]],[[],["result",4]],[[],["typeid",3]],[[],["typeid",3]],[[]],[[]],[[["box",3,[["progress",8]]]],["result",4,[["error",4]]]],[[["box",3,[["progress",8]]]],["result",4,[["error",4]]]],null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,[[["transaction",3]]],null,[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[["transaction",3]],["result",4,[["error",4]]]],[[],["bitcoinpeerconfig",3]],[[],["compactfiltersblockchainconfig",3]],[[]],[[]],[[["tosocketaddrs",8],["arc",3,[["mempool",3]]],["network",4]],["result",4,[["compactfilterserror",4]]]],[[["totargetaddr",8],["tosocketaddrs",8],["option",4],["arc",3,[["mempool",3]]],["network",4]],["result",4,[["compactfilterserror",4]]]],[[],["mempool",3]],[[["usize",15]]],[[["usize",15]]],[[["usize",15]]],[[["usize",15]]],[[["usize",15]]],[[["usize",15]]],[[["usize",15]]],[[["usize",15]]],[[["usize",15]]],[[["usize",15]]],[[["usize",15]]],[[["usize",15]]],[[],["result",4]],[[],["result",4]],[[["usize",15]]],[[["usize",15]]],[[["usize",15]]],[[["usize",15]]],[[["usize",15]]],[[["usize",15]]],[[["bitcoinpeerconfig",3]],["bool",15]],[[["compactfiltersblockchainconfig",3]],["bool",15]],[[["usize",15]],["result",4,[["feerate",3],["error",4]]]],[[["formatter",3]],["result",6]],[[["formatter",3]],["result",6]],[[["formatter",3]],["result",6]],[[["formatter",3]],["result",6]],[[["formatter",3]],["result",6]],[[["formatter",3]],["result",6]],[[["formatter",3]],["result",6]],[[]],[[]],[[]],[[]],[[]],[[["error",3]]],[[["systemtimeerror",3]]],[[]],[[["error",4]]],[[["error",3]]],[[["error",4]]],[[],["result",4,[["error",4]]]],[[["u64",15]],["result",4,[["blockhash",3],["error",4]]]],[[],["hashset",3,[["capability",4]]]],[[],["result",4,[["u32",15],["error",4]]]],[[],["arc",3,[["mempool",3]]]],[[],["network",4]],[[["inventory",4]],["option",4,[["transaction",3]]]],[[["txid",3]],["result",4,[["option",4,[["transaction",3]]],["error",4]]]],[[],["versionmessage",3]],[[["txid",3]],["bool",15]],[[],["usize",15]],[[],["usize",15]],[[],["usize",15]],[[],["usize",15]],[[],["usize",15]],[[],["usize",15]],[[]],[[]],[[]],[[]],[[]],[[]],[[],["bool",15]],[[],["vec",3,[["transaction",3]]]],[[["bitcoinpeerconfig",3]],["bool",15]],[[["compactfiltersblockchainconfig",3]],["bool",15]],null,[[]],[[["vec",3,[["peer",3]]],["asref",8,[["path",3]]],["option",4,[["usize",15]]]],["result",4,[["compactfilterserror",4]]]],null,[[["str",15],["option",4,[["duration",3]]]],["result",4,[["option",4,[["networkmessage",4]]],["compactfilterserror",4]]]],[[["networkmessage",4]],["result",4,[["compactfilterserror",4]]]],[[],["result",4]],[[],["result",4]],null,null,null,null,[[]],[[]],[[],["string",3]],[[],["result",4]],[[],["result",4]],[[],["result",4]],[[],["result",4]],[[],["result",4]],[[],["result",4]],[[],["result",4]],[[],["result",4]],[[],["result",4]],[[],["result",4]],[[],["result",4]],[[],["result",4]],[[],["typeid",3]],[[],["typeid",3]],[[],["typeid",3]],[[],["typeid",3]],[[],["typeid",3]],[[],["typeid",3]],[[]],[[]],[[]],[[]],[[]],[[]],[[["box",3,[["progress",8]]]],["result",4,[["error",4]]]],null,null,null,null,null,null,null,[[]],[[]],[[]],[[]],[[["transaction",3]],["result",4,[["error",4]]]],[[],["electrumblockchainconfig",3]],[[]],[[]],[[["usize",15]]],[[["usize",15]]],[[["usize",15]]],[[["usize",15]]],[[],["result",4]],[[["usize",15]]],[[["usize",15]]],[[["electrumblockchainconfig",3]],["bool",15]],[[["usize",15]],["result",4,[["feerate",3],["error",4]]]],[[["formatter",3]],["result",6]],[[["client",3]]],[[]],[[]],[[],["result",4,[["error",4]]]],[[["u64",15]],["result",4,[["blockhash",3],["error",4]]]],[[],["hashset",3,[["capability",4]]]],[[],["result",4,[["u32",15],["error",4]]]],[[["txid",3]],["result",4,[["option",4,[["transaction",3]]],["error",4]]]],[[],["usize",15]],[[],["usize",15]],[[]],[[]],[[["electrumblockchainconfig",3]],["bool",15]],null,[[],["result",4]],null,null,null,[[]],[[],["result",4]],[[],["result",4]],[[],["result",4]],[[],["result",4]],[[],["typeid",3]],[[],["typeid",3]],null,[[]],[[]],[[["box",3,[["progress",8]]]],["result",4,[["error",4]]]],null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,[[]],[[]],[[]],[[]],[[]],[[]],[[["transaction",3]],["result",4,[["error",4]]]],[[],["esplorablockchainconfig",3]],[[]],null,[[["usize",15]]],[[["usize",15]]],[[]],[[["usize",15]]],[[["usize",15]]],[[["usize",15]]],[[["usize",15]]],[[],["result",4]],[[["usize",15]]],[[["usize",15]]],[[["usize",15]]],[[["esplorablockchainconfig",3]],["bool",15]],[[["usize",15]],["result",4,[["feerate",3],["error",4]]]],[[["formatter",3]],["result",4,[["error",3]]]],[[["formatter",3]],["result",4,[["error",3]]]],[[["formatter",3]],["result",6]],[[["formatter",3]],["result",6]],[[["transport",3]],["error",4]],[[["error",3]],["error",4]],[[]],[[["parseinterror",3]],["error",4]],[[["error",4]],["error",4]],[[["error",4]],["error",4]],[[["error",4]],["error",4]],[[]],[[]],[[["blockingclient",3],["usize",15]]],[[],["result",4,[["error",4]]]],[[["u64",15]],["result",4,[["blockhash",3],["error",4]]]],[[],["hashset",3,[["capability",4]]]],[[],["result",4,[["u32",15],["error",4]]]],[[["txid",3]],["result",4,[["option",4,[["transaction",3]]],["error",4]]]],[[],["usize",15]],[[],["usize",15]],[[],["usize",15]],[[]],[[]],[[]],[[["esplorablockchainconfig",3]],["bool",15]],[[["str",15],["usize",15]]],[[["string",3],["usize",15]]],null,[[],["result",4]],null,null,[[]],[[],["string",3]],[[],["result",4]],[[],["result",4]],[[],["result",4]],[[],["result",4]],[[],["result",4]],[[],["result",4]],[[],["typeid",3]],[[],["typeid",3]],[[],["typeid",3]],[[]],[[]],[[]],[[["box",3,[["progress",8]]]],["result",4,[["error",4]]]],[[["u8",15]]],null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[["transaction",3]],["result",4,[["error",4]]]],[[["str",15],["option",4,[["u32",15]]]],["result",4,[["error",4]]]],[[],["rpcconfig",3]],[[],["rpcsyncparams",3]],[[],["auth",4]],[[],["rpcblockchainfactory",3]],[[]],[[]],[[]],[[]],[[["auth",4]],["ordering",4]],[[]],null,[[["usize",15]]],[[]],[[["usize",15]]],[[["usize",15]]],[[["usize",15]]],[[["usize",15]]],[[["usize",15]]],[[["usize",15]]],[[["usize",15]]],[[["usize",15]]],[[["usize",15]]],[[],["result",4]],[[],["result",4]],[[],["result",4]],[[["usize",15]]],[[["usize",15]]],[[["usize",15]]],[[["usize",15]]],[[["usize",15]]],[[["rpcconfig",3]],["bool",15]],[[["rpcsyncparams",3]],["bool",15]],[[["auth",4]],["bool",15]],[[["usize",15]],["result",4,[["feerate",3],["error",4]]]],[[["formatter",3]],["result",6]],[[["formatter",3]],["result",6]],[[["formatter",3]],["result",6]],[[["formatter",3]],["result",6]],[[["formatter",3]],["result",6]],null,[[]],[[]],[[]],[[]],[[]],[[],["result",4,[["error",4]]]],[[["u64",15]],["result",4,[["blockhash",3],["error",4]]]],[[],["hashset",3,[["capability",4]]]],[[],["u64",15]],[[],["result",4,[["u32",15],["error",4]]]],[[["txid",3]],["result",4,[["option",4,[["transaction",3]]],["error",4]]]],[[]],[[],["usize",15]],[[],["usize",15]],[[],["usize",15]],[[],["usize",15]],[[],["usize",15]],[[]],[[]],[[]],[[]],[[]],[[["rpcconfig",3]],["bool",15]],[[["rpcsyncparams",3]],["bool",15]],[[["auth",4]],["bool",15]],null,null,[[["auth",4]],["option",4,[["ordering",4]]]],null,[[],["result",4]],[[],["result",4]],[[],["result",4]],null,null,null,null,[[]],[[]],[[]],[[]],[[],["result",4]],[[],["result",4]],[[],["result",4]],[[],["result",4]],[[],["result",4]],[[],["result",4]],[[],["result",4]],[[],["result",4]],[[],["result",4]],[[],["result",4]],[[],["typeid",3]],[[],["typeid",3]],[[],["typeid",3]],[[],["typeid",3]],[[],["typeid",3]],null,null,[[]],[[]],[[]],[[]],[[]],null,null,[[["box",3,[["progress",8]]]],["result",4,[["error",4]]]],null,null,null,null,null,null,null,null,null,null,null,null,[[]],[[]],null,[[]],[[]],[[]],[[]],[[["keychainkind",4],["asref",8]],["result",4,[["error",4]]]],[[["keychainkind",4],["asref",8]],["result",4,[["error",4]]]],[[],["synctime",3]],[[]],[[],["result",4,[["error",4]]]],[[],["result",4,[["error",4]]]],null,[[["keychainkind",4]],["result",4,[["option",4,[["u32",15]]],["error",4]]]],[[["keychainkind",4]],["result",4,[["option",4,[["u32",15]]],["error",4]]]],[[["script",3]],["result",4,[["option",4],["error",4]]]],[[["script",3]],["result",4,[["option",4],["error",4]]]],[[["txid",3]],["result",4,[["option",4,[["transaction",3]]],["error",4]]]],[[["txid",3]],["result",4,[["option",4,[["transaction",3]]],["error",4]]]],[[["keychainkind",4],["u32",15]],["result",4,[["option",4,[["script",3]]],["error",4]]]],[[["keychainkind",4],["u32",15]],["result",4,[["option",4,[["script",3]]],["error",4]]]],[[],["result",4,[["option",4,[["synctime",3]]],["error",4]]]],[[],["result",4,[["option",4,[["synctime",3]]],["error",4]]]],[[["txid",3],["bool",15]],["result",4,[["option",4,[["transactiondetails",3]]],["error",4]]]],[[["txid",3],["bool",15]],["result",4,[["option",4,[["transactiondetails",3]]],["error",4]]]],[[["outpoint",3]],["result",4,[["option",4,[["localutxo",3]]],["error",4]]]],[[["outpoint",3]],["result",4,[["option",4,[["localutxo",3]]],["error",4]]]],[[["usize",15]]],[[["usize",15]]],[[["usize",15]]],[[["usize",15]]],[[],["result",4]],[[["usize",15]]],[[["usize",15]]],[[["formatter",3]],["result",6]],[[["formatter",3]],["result",6]],[[]],[[]],[[],["result",4,[["error",4]]]],[[],["result",4,[["error",4]]]],[[["keychainkind",4]],["result",4,[["option",4,[["u32",15]]],["error",4]]]],[[["keychainkind",4]],["result",4,[["option",4,[["u32",15]]],["error",4]]]],[[["script",3]],["result",4,[["option",4],["error",4]]]],[[["script",3]],["result",4,[["option",4],["error",4]]]],[[["txid",3]],["result",4,[["option",4,[["transaction",3]]],["error",4]]]],[[["txid",3]],["result",4,[["option",4,[["transaction",3]]],["error",4]]]],[[["keychainkind",4],["u32",15]],["result",4,[["option",4,[["script",3]]],["error",4]]]],[[["keychainkind",4],["u32",15]],["result",4,[["option",4,[["script",3]]],["error",4]]]],[[],["result",4,[["option",4,[["synctime",3]]],["error",4]]]],[[],["result",4,[["option",4,[["synctime",3]]],["error",4]]]],[[["txid",3],["bool",15]],["result",4,[["option",4,[["transactiondetails",3]]],["error",4]]]],[[["txid",3],["bool",15]],["result",4,[["option",4,[["transactiondetails",3]]],["error",4]]]],[[["outpoint",3]],["result",4,[["option",4,[["localutxo",3]]],["error",4]]]],[[["outpoint",3]],["result",4,[["option",4,[["localutxo",3]]],["error",4]]]],[[["keychainkind",4]],["result",4,[["u32",15],["error",4]]]],[[["keychainkind",4]],["result",4,[["u32",15],["error",4]]]],[[],["usize",15]],[[],["usize",15]],[[]],[[]],[[],["result",4,[["vec",3,[["transaction",3]]],["error",4]]]],[[],["result",4,[["vec",3,[["transaction",3]]],["error",4]]]],[[["option",4,[["keychainkind",4]]]],["result",4,[["vec",3,[["script",3]]],["error",4]]]],[[["option",4,[["keychainkind",4]]]],["result",4,[["vec",3,[["script",3]]],["error",4]]]],[[["bool",15]],["result",4,[["vec",3,[["transactiondetails",3]]],["error",4]]]],[[["bool",15]],["result",4,[["vec",3,[["transactiondetails",3]]],["error",4]]]],[[],["result",4,[["vec",3,[["localutxo",3]]],["error",4]]]],[[],["result",4,[["vec",3,[["localutxo",3]]],["error",4]]]],null,[[["asref",8,[["path",3]]]]],null,[[],["result",4]],[[["keychainkind",4],["u32",15]],["result",4,[["error",4]]]],[[["keychainkind",4],["u32",15]],["result",4,[["error",4]]]],[[["transaction",3]],["result",4,[["error",4]]]],[[["transaction",3]],["result",4,[["error",4]]]],[[["script",3],["keychainkind",4],["u32",15]],["result",4,[["error",4]]]],[[["script",3],["keychainkind",4],["u32",15]],["result",4,[["error",4]]]],[[["synctime",3]],["result",4,[["error",4]]]],[[["synctime",3]],["result",4,[["error",4]]]],[[["transactiondetails",3]],["result",4,[["error",4]]]],[[["transactiondetails",3]],["result",4,[["error",4]]]],[[["localutxo",3]],["result",4,[["error",4]]]],[[["localutxo",3]],["result",4,[["error",4]]]],[[]],[[],["result",4]],[[],["result",4]],[[],["result",4]],[[],["result",4]],[[],["typeid",3]],[[],["typeid",3]],[[]],[[]],null,null,null,null,null,null,null,null,null,null,null,null,null,null,[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[["keychainkind",4],["asref",8]],["result",4,[["error",4]]]],[[],["result",4,[["error",4]]]],[[["keychainkind",4]],["result",4,[["option",4,[["u32",15]]],["error",4]]]],[[["keychainkind",4]],["result",4,[["option",4,[["u32",15]]],["error",4]]]],[[["script",3]],["result",4,[["option",4],["error",4]]]],[[["script",3]],["result",4,[["option",4],["error",4]]]],[[["txid",3]],["result",4,[["option",4,[["transaction",3]]],["error",4]]]],[[["txid",3]],["result",4,[["option",4,[["transaction",3]]],["error",4]]]],[[["keychainkind",4],["u32",15]],["result",4,[["option",4,[["script",3]]],["error",4]]]],[[["keychainkind",4],["u32",15]],["result",4,[["option",4,[["script",3]]],["error",4]]]],[[],["result",4,[["option",4,[["synctime",3]]],["error",4]]]],[[],["result",4,[["option",4,[["synctime",3]]],["error",4]]]],[[["txid",3],["bool",15]],["result",4,[["option",4,[["transactiondetails",3]]],["error",4]]]],[[["txid",3],["bool",15]],["result",4,[["option",4,[["transactiondetails",3]]],["error",4]]]],[[["outpoint",3]],["result",4,[["option",4,[["localutxo",3]]],["error",4]]]],[[["outpoint",3]],["result",4,[["option",4,[["localutxo",3]]],["error",4]]]],[[["usize",15]]],[[["usize",15]]],[[["usize",15]]],[[["usize",15]]],[[["usize",15]]],[[["usize",15]]],[[["usize",15]]],[[["usize",15]]],[[["usize",15]]],[[["usize",15]]],[[],["result",4]],[[],["result",4]],[[],["result",4]],[[["usize",15]]],[[["usize",15]]],[[["usize",15]]],[[["usize",15]]],[[["usize",15]]],[[["formatter",3]],["result",6]],[[["formatter",3]],["result",6]],[[["formatter",3]],["result",6]],[[["formatter",3]],["result",6]],[[]],[[]],[[]],[[]],[[["sqlitedatabase",3]]],[[]],[[["memorydatabase",3]]],[[["tree",3]]],[[]],[[]],[[["sleddbconfiguration",3]]],[[]],[[["sqlitedbconfiguration",3]]],[[]],[[],["result",4,[["error",4]]]],[[["keychainkind",4]],["result",4,[["option",4,[["u32",15]]],["error",4]]]],[[["script",3]],["result",4,[["option",4],["error",4]]]],[[["txid",3]],["result",4,[["option",4,[["transaction",3]]],["error",4]]]],[[["keychainkind",4],["u32",15]],["result",4,[["option",4,[["script",3]]],["error",4]]]],[[],["result",4,[["option",4,[["synctime",3]]],["error",4]]]],[[["txid",3],["bool",15]],["result",4,[["option",4,[["transactiondetails",3]]],["error",4]]]],[[["outpoint",3]],["result",4,[["option",4,[["localutxo",3]]],["error",4]]]],[[["keychainkind",4]],["result",4,[["u32",15],["error",4]]]],[[],["usize",15]],[[],["usize",15]],[[],["usize",15]],[[],["usize",15]],[[],["usize",15]],[[]],[[]],[[]],[[]],[[]],[[],["result",4,[["vec",3,[["transaction",3]]],["error",4]]]],[[["option",4,[["keychainkind",4]]]],["result",4,[["vec",3,[["script",3]]],["error",4]]]],[[["bool",15]],["result",4,[["vec",3,[["transactiondetails",3]]],["error",4]]]],[[],["result",4,[["vec",3,[["localutxo",3]]],["error",4]]]],null,null,[[],["result",4]],[[],["result",4]],[[],["result",4]],[[["keychainkind",4],["u32",15]],["result",4,[["error",4]]]],[[["keychainkind",4],["u32",15]],["result",4,[["error",4]]]],[[["transaction",3]],["result",4,[["error",4]]]],[[["transaction",3]],["result",4,[["error",4]]]],[[["script",3],["keychainkind",4],["u32",15]],["result",4,[["error",4]]]],[[["script",3],["keychainkind",4],["u32",15]],["result",4,[["error",4]]]],[[["synctime",3]],["result",4,[["error",4]]]],[[["synctime",3]],["result",4,[["error",4]]]],[[["transactiondetails",3]],["result",4,[["error",4]]]],[[["transactiondetails",3]],["result",4,[["error",4]]]],[[["localutxo",3]],["result",4,[["error",4]]]],[[["localutxo",3]],["result",4,[["error",4]]]],null,[[],["result",4]],[[],["result",4]],[[],["result",4]],[[],["result",4]],[[],["result",4]],[[],["result",4]],[[],["result",4]],[[],["result",4]],[[],["result",4]],[[],["result",4]],[[],["typeid",3]],[[],["typeid",3]],[[],["typeid",3]],[[],["typeid",3]],[[],["typeid",3]],[[]],[[]],[[]],[[]],[[]],null,null,null,null,null,null,null,null,null,null,[[]],[[]],[[]],[[["keychainkind",4],["asref",8]],["result",4,[["error",4]]]],[[],["result",4,[["error",4]]]],[[],["memorydatabase",3]],[[["keychainkind",4]],["result",4,[["option",4,[["u32",15]]],["error",4]]]],[[["script",3]],["result",4,[["option",4],["error",4]]]],[[["txid",3]],["result",4,[["option",4,[["transaction",3]]],["error",4]]]],[[["keychainkind",4],["u32",15]],["result",4,[["option",4,[["script",3]]],["error",4]]]],[[],["result",4,[["option",4,[["synctime",3]]],["error",4]]]],[[["txid",3],["bool",15]],["result",4,[["option",4,[["transactiondetails",3]]],["error",4]]]],[[["outpoint",3]],["result",4,[["option",4,[["localutxo",3]]],["error",4]]]],[[["usize",15]]],[[["usize",15]]],[[["usize",15]]],[[["formatter",3]],["result",6]],[[]],[[],["result",4,[["error",4]]]],[[["keychainkind",4]],["result",4,[["option",4,[["u32",15]]],["error",4]]]],[[["script",3]],["result",4,[["option",4],["error",4]]]],[[["txid",3]],["result",4,[["option",4,[["transaction",3]]],["error",4]]]],[[["keychainkind",4],["u32",15]],["result",4,[["option",4,[["script",3]]],["error",4]]]],[[],["result",4,[["option",4,[["synctime",3]]],["error",4]]]],[[["txid",3],["bool",15]],["result",4,[["option",4,[["transactiondetails",3]]],["error",4]]]],[[["outpoint",3]],["result",4,[["option",4,[["localutxo",3]]],["error",4]]]],[[["keychainkind",4]],["result",4,[["u32",15],["error",4]]]],[[],["usize",15]],[[]],[[],["result",4,[["vec",3,[["transaction",3]]],["error",4]]]],[[["option",4,[["keychainkind",4]]]],["result",4,[["vec",3,[["script",3]]],["error",4]]]],[[["bool",15]],["result",4,[["vec",3,[["transactiondetails",3]]],["error",4]]]],[[],["result",4,[["vec",3,[["localutxo",3]]],["error",4]]]],[[]],[[["keychainkind",4],["u32",15]],["result",4,[["error",4]]]],[[["transaction",3]],["result",4,[["error",4]]]],[[["script",3],["keychainkind",4],["u32",15]],["result",4,[["error",4]]]],[[["synctime",3]],["result",4,[["error",4]]]],[[["transactiondetails",3]],["result",4,[["error",4]]]],[[["localutxo",3]],["result",4,[["error",4]]]],[[],["result",4]],[[],["result",4]],[[],["typeid",3]],[[]],null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,[[["network",4]],["result",4,[["address",3],["error",4]]]],[[],["scriptcontextenum",4]],[[],["scriptcontextenum",4]],[[],["terminal",4]],[[["u32",15]],["descriptor",4,[["definitedescriptorkey",3]]]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[],["vec",3,[["miniscript",3],["global",3]]]],[[["miniscript",3]],["result",4,[["scriptcontexterror",4]]]],[[["miniscript",3]],["result",4,[["scriptcontexterror",4]]]],[[["miniscript",3]],["result",4,[["scriptcontexterror",4]]]],[[["miniscript",3]],["result",4,[["scriptcontexterror",4]]]],[[["miniscript",3]],["result",4,[["scriptcontexterror",4]]]],[[["miniscript",3]],["result",4,[["scriptcontexterror",4]]]],[[["miniscript",3]],["result",4,[["scriptcontexterror",4]]]],[[["miniscript",3]],["result",4,[["scriptcontexterror",4]]]],[[["miniscript",3]],["result",4,[["scriptcontexterror",4]]]],[[["miniscript",3]],["result",4,[["scriptcontexterror",4]]]],[[["miniscript",3]],["result",4,[["scriptcontexterror",4]]]],[[["miniscript",3]],["result",4,[["scriptcontexterror",4]]]],[[["miniscript",3]],["result",4,[["scriptcontexterror",4]]]],[[["terminal",4]],["result",4,[["scriptcontexterror",4]]]],[[["terminal",4]],["result",4,[["scriptcontexterror",4]]]],[[["terminal",4]],["result",4,[["scriptcontexterror",4]]]],[[],["result",4,[["scriptcontexterror",4]]]],[[],["result",4,[["scriptcontexterror",4]]]],[[],["result",4,[["scriptcontexterror",4]]]],null,[[],["descriptorxkey",3]],[[],["wildcard",4]],[[],["descriptor",4]],[[],["legacy",4]],[[],["segwitv0",4]],[[],["miniscript",3]],[[]],[[]],[[]],[[]],[[]],[[]],[[["descriptorxkey",3]],["ordering",4]],[[["wildcard",4]],["ordering",4]],[[["descriptor",4]],["ordering",4]],[[["legacy",4]],["ordering",4]],[[["segwitv0",4]],["ordering",4]],[[["miniscript",3]],["ordering",4]],[[],["bool",15]],[[["usize",15]]],[[["usize",15]]],[[["usize",15]]],[[["usize",15]]],[[["usize",15]]],[[["usize",15]]],[[["usize",15]]],[[["usize",15]]],[[["usize",15]]],[[["usize",15]]],[[["usize",15]]],[[["usize",15]]],null,[[["u32",15]],["descriptor",4,[["definitedescriptorkey",3]]]],[[["secp256k1",3]],["result",4,[["descriptor",4,[["publickey",3]]],["conversionerror",4]]]],[[["secp256k1",3],["u32",15]],["result",4,[["descriptor",4,[["publickey",3]]],["conversionerror",4]]]],[[],["descriptortype",4]],[[],["result",4,[["descriptor",4]]]],[[],["result",4,[["miniscript",3]]]],[[["usize",15]]],[[["usize",15]]],[[["usize",15]]],[[["usize",15]]],[[["usize",15]]],[[["usize",15]]],[[],["script",3]],[[["descriptorxkey",3]],["bool",15]],[[["wildcard",4]],["bool",15]],[[["descriptor",4]],["bool",15]],[[["legacy",4]],["bool",15]],[[["segwitv0",4]],["bool",15]],[[["miniscript",3]],["bool",15]],null,[[],["result",4,[["script",3],["error",4]]]],null,[[["extparams",3]],["result",4,[["analysiserror",4]]]],[[["signerscontainer",3],["buildsatisfaction",4],["secp256k1",3]],["result",4,[["option",4,[["policy",3]]],["descriptorerror",4]]]],[[["signerscontainer",3],["buildsatisfaction",4],["secp256k1",3]],["result",4,[["option",4,[["policy",3]]],["error",4]]]],[[["signerscontainer",3],["buildsatisfaction",4],["secp256k1",3]],["result",4,[["option",4,[["policy",3]]],["error",4]]]],[[["secp256k1",3],["script",3],["range",3,[["u32",15]]]],["result",4,[["option",4],["conversionerror",4]]]],[[["formatter",3]],["result",4,[["error",3]]]],[[["formatter",3]],["result",4,[["error",3]]]],[[["formatter",3]],["result",4,[["error",3]]]],[[["formatter",3]],["result",4,[["error",3]]]],[[["formatter",3]],["result",4,[["error",3]]]],[[["formatter",3]],["result",4,[["error",3]]]],[[["formatter",3]],["result",4,[["error",3]]]],[[["formatter",3]],["result",4,[["error",3]]]],[[],["bool",15]],[[],["bool",15]],[[]],[[]],[[["wsh",3]],["descriptor",4]],[[]],[[["bare",3]],["descriptor",4]],[[["wpkh",3]],["descriptor",4]],[[["sh",3]],["descriptor",4]],[[["pkh",3]],["descriptor",4]],[[["tr",3]],["descriptor",4]],[[]],[[]],[[]],[[["terminal",4]],["result",4,[["miniscript",3],["error",4]]]],[[["str",15]],["result",4,[["descriptor",4],["error",4]]]],[[["str",15]],["result",4,[["miniscript",3],["error",4]]]],[[["str",15],["extparams",3]],["result",4,[["miniscript",3],["error",4]]]],[[["str",15]],["result",4,[["miniscript",3],["error",4]]]],[[["tree",3]],["result",4,[["descriptor",4],["error",4]]]],[[["tree",3]],["result",4,[["miniscript",3],["error",4]]]],[[],["u64",15]],[[],["u64",15]],[[],["u64",15]],[[],["u64",15]],[[],["u64",15]],[[],["u64",15]],[[["usize",15]],["option",4,[["miniscript",3]]]],[[["usize",15]],["option",4]],[[],["result",4,[["error",4]]]],[[],["result",4,[["error",4]]]],[[],["bool",15]],[[],["bool",15]],[[],["bool",15]],[[]],[[]],[[]],[[]],[[]],[[]],[[],["usize",15]],[[],["usize",15]],[[],["usize",15]],[[],["usize",15]],[[],["usize",15]],[[],["usize",15]],[[]],[[]],[[]],[[]],[[]],[[]],[[],["terminal",4]],[[["secp256k1",3],["network",4]],["result",4,[["descriptorerror",4]]]],[[],["bool",15]],[[],["bool",15]],[[],["iter",3]],[[],["pkiter",3]],[[],["result",4,[["policy",4],["error",4]]]],[[],["result",4,[["policy",4],["error",4]]]],[[],["result",4,[["lifterror",4]]]],[[["secp256k1",3]],["option",4,[["derivationpath",3]]]],[[["miniscript",3]],["option",4,[["usize",15]]]],[[["miniscript",3]],["option",4,[["usize",15]]]],[[["miniscript",3]],["option",4,[["usize",15]]]],[[],["result",4,[["usize",15],["error",4]]]],[[],["result",4,[["usize",15],["error",4]]]],[[],["result",4,[["usize",15],["error",4]]]],[[],["str",15]],[[],["str",15]],[[],["str",15]],[[["descriptorxkey",3]],["bool",15]],[[["descriptor",4]],["bool",15]],[[["miniscript",3,[["barectx",4]]]],["result",4,[["descriptor",4],["error",4]]]],[[],["descriptor",4]],[[],["descriptor",4]],[[["miniscript",3,[["legacy",4]]]],["result",4,[["descriptor",4],["error",4]]]],[[["usize",15],["vec",3,[["global",3]]]],["result",4,[["descriptor",4],["error",4]]]],[[["wpkh",3]],["descriptor",4]],[[["wsh",3]],["descriptor",4]],[[],["result",4,[["descriptor",4],["error",4]]]],[[["miniscript",3,[["segwitv0",4]]]],["result",4,[["descriptor",4],["error",4]]]],[[["usize",15],["vec",3,[["global",3]]]],["result",4,[["descriptor",4],["error",4]]]],[[["option",4,[["taptree",4]]]],["result",4,[["descriptor",4],["error",4]]]],[[],["result",4,[["descriptor",4],["error",4]]]],[[["miniscript",3,[["segwitv0",4]]]],["result",4,[["descriptor",4],["error",4]]]],[[["usize",15],["vec",3,[["global",3]]]],["result",4,[["descriptor",4],["error",4]]]],null,null,[[["miniscript",3]],["result",4,[["error",4]]]],[[["script",3]],["result",4,[["miniscript",3],["error",4]]]],[[["secp256k1",3],["str",15]],["result",4,[["error",4]]]],[[["script",3]],["result",4,[["miniscript",3],["error",4]]]],[[["script",3],["extparams",3]],["result",4,[["miniscript",3],["error",4]]]],[[["descriptorxkey",3]],["option",4,[["ordering",4]]]],[[["wildcard",4]],["option",4,[["ordering",4]]]],[[["descriptor",4]],["option",4,[["ordering",4]]]],[[["legacy",4]],["option",4,[["ordering",4]]]],[[["segwitv0",4]],["option",4,[["ordering",4]]]],[[["miniscript",3]],["option",4,[["ordering",4]]]],[[],["usize",15]],[[],["usize",15]],[[],["usize",15]],null,[[],["bool",15]],[[],["result",4,[["error",4]]]],[[],["result",4,[["analysiserror",4]]]],[[["txin",3]],["result",4,[["error",4]]]],[[],["result",4,[["vec",3,[["vec",3,[["u8",15],["global",3]]],["global",3]]],["error",4]]]],[[],["result",4,[["vec",3,[["vec",3,[["u8",15],["global",3]]],["global",3]]],["error",4]]]],[[],["result",4,[["script",3],["error",4]]]],[[],["script",3]],[[],["usize",15]],[[],["result",4]],[[],["result",4]],[[],["sigtype",4]],[[],["sigtype",4]],[[],["sigtype",4]],null,[[]],[[]],[[]],[[]],[[]],[[]],[[],["string",3]],[[],["string",3]],[[["hashmap",3]],["string",3]],[[["miniscript",3]],["result",4,[["error",4]]]],[[["miniscript",3]],["result",4,[["error",4]]]],[[],["result",4]],[[],["result",4]],[[],["result",4]],[[],["result",4]],[[],["result",4]],[[],["result",4]],[[],["result",4]],[[],["result",4]],[[],["result",4]],[[],["result",4]],[[],["result",4]],[[],["result",4]],[[],["result",4]],[[],["result",4]],null,[[],["typeid",3]],[[],["typeid",3]],[[],["typeid",3]],[[],["typeid",3]],[[],["typeid",3]],[[],["typeid",3]],[[],["script",3]],[[]],[[]],[[]],[[]],[[]],[[]],null,[[],["bool",15]],null,null,null,null,null,null,null,null,null,[[["str",15]],["result",4,[["string",3],["descriptorerror",4]]]],[[["str",15]],["result",4,[["descriptorerror",4]]]],[[["str",15]],["result",4,[["string",3],["descriptorerror",4]]]],[[["str",15]],["result",4,[["descriptorerror",4]]]],null,null,null,null,null,null,null,null,null,null,null,null,[[]],[[]],[[["usize",15]]],[[["usize",15]]],[[["usize",15]]],[[["formatter",3]],["result",6]],[[["formatter",3]],["result",6]],[[["error",4]]],[[["error",4]]],[[["error",4]]],[[]],[[["error",4]]],[[["policyerror",4]]],[[["error",4]]],[[["keyerror",4]],["error",4]],[[],["usize",15]],[[]],[[],["string",3]],[[],["result",4]],[[],["result",4]],[[],["typeid",3]],[[]],null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[],["pkorf",4]],[[],["satisfiableitem",4]],[[],["satisfaction",4]],[[],["policy",3]],[[],["condition",3]],[[],["buildsatisfaction",4]],[[]],[[]],[[]],[[]],[[]],[[]],null,null,[[],["condition",3]],[[["usize",15]]],[[["usize",15]]],[[["usize",15]]],[[["usize",15]]],[[["usize",15]]],[[["usize",15]]],[[["usize",15]]],[[["usize",15]]],[[["usize",15]]],[[["usize",15]]],[[["usize",15]]],[[["usize",15]]],[[["usize",15]]],[[["usize",15]]],[[["usize",15]]],[[["usize",15]]],[[["usize",15]]],[[["usize",15]]],[[["usize",15]]],[[["usize",15]]],[[["usize",15]]],[[["pkorf",4]],["bool",15]],[[["satisfiableitem",4]],["bool",15]],[[["satisfaction",4]],["bool",15]],[[["policy",3]],["bool",15]],[[["condition",3]],["bool",15]],[[["policyerror",4]],["bool",15]],[[["formatter",3]],["result",6]],[[["formatter",3]],["result",6]],[[["formatter",3]],["result",6]],[[["formatter",3]],["result",6]],[[["formatter",3]],["result",6]],[[["formatter",3]],["result",6]],[[["formatter",3]],["result",6]],[[["formatter",3]],["result",6]],[[]],[[]],[[]],[[["bool",15]]],[[]],[[["satisfiableitem",4]]],[[]],[[]],[[]],[[["btreemap",3]],["result",4,[["condition",3],["policyerror",4]]]],[[],["u64",15]],[[],["u64",15]],[[]],[[]],[[],["string",3]],null,[[],["usize",15]],[[],["usize",15]],[[],["usize",15]],[[],["usize",15]],[[],["usize",15]],[[],["usize",15]],[[],["usize",15]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[],["bool",15]],[[],["bool",15]],[[],["bool",15]],null,[[["pkorf",4]],["bool",15]],[[["satisfiableitem",4]],["bool",15]],[[["satisfaction",4]],["bool",15]],[[["policy",3]],["bool",15]],[[["condition",3]],["bool",15]],[[["policyerror",4]],["bool",15]],[[["condition",3]],["option",4,[["ordering",4]]]],[[],["bool",15]],null,[[],["result",4]],[[],["result",4]],[[],["result",4]],[[],["result",4]],[[],["result",4]],null,[[]],[[]],[[]],[[]],[[]],[[]],[[],["string",3]],[[],["result",4]],[[],["result",4]],[[],["result",4]],[[],["result",4]],[[],["result",4]],[[],["result",4]],[[],["result",4]],[[],["result",4]],[[],["result",4]],[[],["result",4]],[[],["result",4]],[[],["result",4]],[[],["result",4]],[[],["result",4]],[[],["typeid",3]],[[],["typeid",3]],[[],["typeid",3]],[[],["typeid",3]],[[],["typeid",3]],[[],["typeid",3]],[[],["typeid",3]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[["network",4]],["result",4,[["descriptortemplateout",6],["descriptorerror",4]]]],[[["network",4]],["result",4,[["descriptortemplateout",6],["descriptorerror",4]]]],[[["network",4]],["result",4,[["descriptortemplateout",6],["descriptorerror",4]]]],[[["network",4]],["result",4,[["descriptortemplateout",6],["descriptorerror",4]]]],[[["network",4]],["result",4,[["descriptortemplateout",6],["descriptorerror",4]]]],[[["network",4]],["result",4,[["descriptortemplateout",6],["descriptorerror",4]]]],[[["network",4]],["result",4,[["descriptortemplateout",6],["descriptorerror",4]]]],[[["network",4]],["result",4,[["descriptortemplateout",6],["descriptorerror",4]]]],[[["network",4]],["result",4,[["descriptortemplateout",6],["descriptorerror",4]]]],[[["network",4]],["result",4,[["descriptortemplateout",6],["descriptorerror",4]]]],[[["usize",15]]],[[["usize",15]]],[[["usize",15]]],[[["usize",15]]],[[["usize",15]]],[[["usize",15]]],[[["usize",15]]],[[["usize",15]]],[[["usize",15]]],[[["usize",15]]],[[["usize",15]]],[[["usize",15]]],[[["usize",15]]],[[["usize",15]]],[[["usize",15]]],[[["usize",15]]],[[["usize",15]]],[[["usize",15]]],[[["usize",15]]],[[["usize",15]]],[[["usize",15]]],[[["usize",15]]],[[["usize",15]]],[[["usize",15]]],[[["usize",15]]],[[["usize",15]]],[[["usize",15]]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[],["usize",15]],[[],["usize",15]],[[],["usize",15]],[[],["usize",15]],[[],["usize",15]],[[],["usize",15]],[[],["usize",15]],[[],["usize",15]],[[],["usize",15]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[["secp256k1",3],["network",4]],["result",4,[["error",4]]]],[[["secp256k1",3],["network",4]],["result",4,[["error",4]]]],[[["secp256k1",3],["network",4]],["result",4,[["error",4]]]],[[["secp256k1",3],["network",4]],["result",4,[["error",4]]]],[[["secp256k1",3],["network",4]],["result",4,[["error",4]]]],[[["secp256k1",3],["network",4]],["result",4,[["error",4]]]],[[["secp256k1",3],["network",4]],["result",4,[["error",4]]]],[[["secp256k1",3],["network",4]],["result",4,[["error",4]]]],[[["secp256k1",3],["network",4]],["result",4,[["error",4]]]],[[],["result",4]],[[],["result",4]],[[],["result",4]],[[],["result",4]],[[],["result",4]],[[],["result",4]],[[],["result",4]],[[],["result",4]],[[],["result",4]],[[],["result",4]],[[],["result",4]],[[],["result",4]],[[],["result",4]],[[],["result",4]],[[],["result",4]],[[],["result",4]],[[],["result",4]],[[],["result",4]],[[],["typeid",3]],[[],["typeid",3]],[[],["typeid",3]],[[],["typeid",3]],[[],["typeid",3]],[[],["typeid",3]],[[],["typeid",3]],[[],["typeid",3]],[[],["typeid",3]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,[[],["validnetworks",6]],[[],["scriptcontextenum",4]],[[["u32",15]],["definitedescriptorkey",3]],null,[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[["miniscript",3]],["result",4,[["scriptcontexterror",4]]]],[[["miniscript",3]],["result",4,[["scriptcontexterror",4]]]],[[["miniscript",3]],["result",4,[["scriptcontexterror",4]]]],[[["miniscript",3]],["result",4,[["scriptcontexterror",4]]]],[[["miniscript",3]],["result",4,[["scriptcontexterror",4]]]],[[["miniscript",3]],["result",4,[["scriptcontexterror",4]]]],[[["terminal",4]],["result",4,[["scriptcontexterror",4]]]],[[],["result",4,[["scriptcontexterror",4]]]],[[],["generatedkey",3]],[[],["sortedmultivec",3]],[[],["descriptorpublickey",4]],[[],["singlepub",3]],[[],["singlepubkey",4]],[[],["scriptcontextenum",4]],[[],["privatekeygenerateoptions",3]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[["sortedmultivec",3]],["ordering",4]],[[["descriptorpublickey",4]],["ordering",4]],[[["singlepub",3]],["ordering",4]],[[["singlepubkey",4]],["ordering",4]],null,[[]],[[["usize",15]]],[[]],[[["usize",15]]],[[["usize",15]]],[[["usize",15]]],[[["usize",15]]],[[["usize",15]]],[[["usize",15]]],[[["usize",15]]],[[["usize",15]]],[[["usize",15]]],[[["usize",15]]],[[["usize",15]]],[[["usize",15]]],[[["usize",15]]],[[["usize",15]]],[[["usize",15]]],[[["usize",15]]],[[["usize",15]]],[[["usize",15]]],[[["usize",15]]],[[["usize",15]]],[[["usize",15]]],[[["usize",15]]],[[["usize",15]]],[[["u32",15]],["definitedescriptorkey",3]],[[["usize",15]]],[[["usize",15]]],[[["usize",15]]],[[["usize",15]]],[[["usize",15]]],[[["usize",15]]],[[["usize",15]]],[[["usize",15]]],[[["usize",15]]],[[["usize",15]]],[[["usize",15]]],[[["usize",15]]],[[],["script",3]],[[["sortedmultivec",3]],["bool",15]],[[["descriptorpublickey",4]],["bool",15]],[[["singlepub",3]],["bool",15]],[[["singlepubkey",4]],["bool",15]],[[["scriptcontextenum",4]],["bool",15]],[[["formatter",3]],["result",4,[["error",3]]]],[[["formatter",3]],["result",4,[["error",3]]]],[[["formatter",3]],["result",4,[["error",3]]]],[[["formatter",3]],["result",4,[["error",3]]]],[[["formatter",3]],["result",4,[["error",3]]]],[[["formatter",3]],["result",4,[["error",3]]]],[[["formatter",3]],["result",4,[["error",3]]]],[[["formatter",3]],["result",4,[["error",3]]]],[[["formatter",3]],["result",4,[["error",3]]]],[[["formatter",3]],["result",6]],[[["formatter",3]],["result",6]],[[["formatter",3]],["result",6]],[[["formatter",3]],["result",6]],[[["formatter",3]],["result",6]],[[],["bool",15]],[[["extendedpubkey",3]]],[[]],[[["extendedprivkey",3]]],[[]],[[]],[[]],[[["definitedescriptorkey",3]],["descriptorpublickey",4]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[["error",4]]],[[["error",4]]],[[]],[[["descriptorpublickey",4],["validnetworks",6]]],[[["descriptorsecretkey",4],["validnetworks",6]]],[[["str",15]],["result",4,[["descriptorpublickey",4]]]],[[["str",15]],["result",4,[["descriptorsecretkey",4]]]],[[["tree",3]],["result",4,[["sortedmultivec",3],["error",4]]]],[[],["derivationpath",3]],[[],["result",4,[["generatedkey",3]]]],[[],["result",4,[["generatedkey",3]]]],[[],["result",4,[["generatedkey",3]]]],[[],["result",4,[["generatedkey",3]]]],[[],["u64",15]],[[],["u64",15]],[[],["u64",15]],[[],["u64",15]],[[],["bool",15]],[[],["bool",15]],[[]],[[]],[[]],[[]],[[],["usize",15]],[[],["usize",15]],[[],["usize",15]],[[],["usize",15]],[[],["usize",15]],[[],["usize",15]],[[],["usize",15]],[[],["usize",15]],[[],["usize",15]],[[],["usize",15]],[[],["usize",15]],[[],["usize",15]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[],["result",4,[["descriptorkey",4],["keyerror",4]]]],[[["option",4,[["keysource",6]]],["derivationpath",3]],["result",4,[["descriptorkey",4],["keyerror",4]]]],[[],["result",4,[["descriptorkey",4],["keyerror",4]]]],[[["option",4,[["keysource",6]]],["derivationpath",3]],["result",4,[["descriptorkey",4],["keyerror",4]]]],[[],["result",4,[["descriptorkey",4],["keyerror",4]]]],[[],["result",4,[["descriptorkey",4],["keyerror",4]]]],[[],["result",4,[["descriptorkey",4],["keyerror",4]]]],[[],["result",4,[["extendedkey",4],["keyerror",4]]]],[[],["result",4,[["extendedkey",4],["keyerror",4]]]],[[],["result",4,[["extendedkey",4],["keyerror",4]]]],[[]],[[["network",4]],["option",4,[["extendedprivkey",3]]]],[[["network",4],["secp256k1",3]],["extendedpubkey",3]],[[],["bool",15]],[[],["bool",15]],[[],["bool",15]],[[],["bool",15]],[[],["bool",15]],[[],["bool",15]],[[],["bool",15]],[[],["bool",15]],[[],["bool",15]],null,null,null,[[],["result",4,[["policy",4],["error",4]]]],[[],["validnetworks",6]],[[],["fingerprint",3]],[[["miniscript",3]],["option",4,[["usize",15]]]],[[],["usize",15]],[[],["usize",15]],[[["validnetworks",6],["validnetworks",6]],["validnetworks",6]],[[],["str",15]],[[["sortedmultivec",3]],["bool",15]],[[["descriptorpublickey",4]],["bool",15]],[[["singlepub",3]],["bool",15]],[[["singlepubkey",4]],["bool",15]],[[["usize",15],["vec",3,[["global",3]]]],["result",4,[["sortedmultivec",3],["error",4]]]],null,null,[[["miniscript",3]],["result",4,[["error",4]]]],[[["validnetworks",6]]],[[["sortedmultivec",3]],["option",4,[["ordering",4]]]],[[["descriptorpublickey",4]],["option",4,[["ordering",4]]]],[[["singlepub",3]],["option",4,[["ordering",4]]]],[[["singlepubkey",4]],["option",4,[["ordering",4]]]],[[],["usize",15]],null,[[],["result",4,[["error",4]]]],[[],["result",4,[["vec",3,[["vec",3,[["u8",15],["global",3]]],["global",3]]],["error",4]]]],[[],["usize",15]],[[],["sigtype",4]],[[],["terminal",4]],[[],["validnetworks",6]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[["secp256k1",3]],["result",4,[["descriptorpublickey",4],["descriptorkeyparseerror",3]]]],[[],["string",3]],[[],["string",3]],[[],["string",3]],[[],["string",3]],[[["miniscript",3]],["result",4,[["error",4]]]],[[["miniscript",3]],["result",4,[["error",4]]]],[[],["result",4,[["sortedmultivec",3]]]],[[],["result",4]],[[],["result",4]],[[],["result",4]],[[],["result",4]],[[],["result",4]],[[],["result",4]],[[],["result",4]],[[],["result",4]],[[],["result",4]],[[],["result",4]],[[],["result",4]],[[],["result",4]],[[],["result",4]],[[],["result",4]],[[],["result",4]],[[],["result",4]],[[],["result",4]],[[],["result",4]],[[],["result",4]],[[],["result",4]],[[],["result",4]],[[],["result",4]],[[],["result",4]],[[],["result",4]],[[],["typeid",3]],[[],["typeid",3]],[[],["typeid",3]],[[],["typeid",3]],[[],["typeid",3]],[[],["typeid",3]],[[],["typeid",3]],[[],["typeid",3]],[[],["typeid",3]],[[],["typeid",3]],[[],["typeid",3]],[[],["typeid",3]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[],["language",4]],[[],["error",4]],[[],["mnemonic",3]],[[]],[[]],[[]],[[["language",4]],["ordering",4]],[[["mnemonic",3]],["ordering",4]],[[["usize",15]]],[[["usize",15]]],[[["usize",15]]],[[["usize",15]]],[[["usize",15]]],[[["usize",15]]],[[["usize",15]]],[[["usize",15]]],[[],["result",4,[["mnemonic",3]]]],[[["usize",15]]],[[["usize",15]]],[[["usize",15]]],[[["usize",15]]],[[["language",4]],["bool",15]],[[["error",4]],["bool",15]],[[["mnemonic",3]],["bool",15]],[[["formatter",3]],["result",4,[["error",3]]]],[[["formatter",3]],["result",4,[["error",3]]]],[[["formatter",3]],["result",4,[["error",3]]]],[[["formatter",3]],["result",4,[["error",3]]]],[[["formatter",3]],["result",4,[["error",3]]]],[[["formatter",3]],["result",4,[["error",3]]]],[[]],[[]],[[]],[[]],[[],["result",4,[["mnemonic",3],["error",4]]]],[[["language",4]],["result",4,[["mnemonic",3],["error",4]]]],[[["str",15]],["result",4,[["mnemonic",3],["error",4]]]],[[["language",4],["usize",15]],["result",4,[["mnemonic",3],["error",4]]]],[[],["result",4,[["generatedkey",3]]]],[[],["u64",15]],[[],["u64",15]],[[]],[[]],[[],["usize",15]],[[],["usize",15]],[[],["usize",15]],[[],["usize",15]],[[]],[[]],[[]],[[]],[[["option",4,[["keysource",6]]],["derivationpath",3]],["result",4,[["descriptorkey",4],["keyerror",4]]]],[[],["result",4,[["extendedkey",4],["keyerror",4]]]],[[],["language",4]],[[],["result",4,[["language",4],["error",4]]]],[[["error",4]],["bool",15]],[[["mnemonic",3]],["bool",15]],[[],["result",4,[["mnemonic",3],["error",4]]]],[[["language",4]],["result",4,[["mnemonic",3],["error",4]]]],[[["language",4],["str",15]],["result",4,[["mnemonic",3],["error",4]]]],[[["str",15]],["result",4,[["mnemonic",3],["error",4]]]],[[["language",4]],["option",4,[["ordering",4]]]],[[["mnemonic",3]],["option",4,[["ordering",4]]]],[[],["result",4]],[[],["vec",3,[["u8",15],["global",3]]]],[[]],[[]],[[]],[[]],[[]],[[["str",15]]],[[],["string",3]],[[],["string",3]],[[],["string",3]],[[],["result",4]],[[],["result",4]],[[],["result",4]],[[],["result",4]],[[],["result",4]],[[],["result",4]],[[],["result",4]],[[],["result",4]],[[],["typeid",3]],[[],["typeid",3]],[[],["typeid",3]],[[],["typeid",3]],[[]],[[]],[[]],[[]],[[],["usize",15]],[[]],[[["str",15]]],null,null,null,null,null,[[],["option",4,[["u64",15]]]],[[],["option",4,[["feerate",3]]]],[[["usize",15]],["option",4,[["txout",3]]]],null,null,null,null,null,null,null,null,null,[[["keychainkind",4],["signerordering",3],["arc",3,[["transactionsigner",8]]]]],null,[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[["txid",3]],["result",4,[["txbuilder",3,[["defaultcoinselectionalgorithm",6],["bumpfee",3]]],["error",4]]]],[[],["txbuilder",3,[["defaultcoinselectionalgorithm",6],["createtx",3]]]],null,[[]],[[],["syncoptions",3]],[[["usize",15]]],[[["usize",15]]],[[["usize",15]]],[[]],[[["usize",15]]],[[["usize",15]]],[[["usize",15]]],[[["usize",15]]],[[["usize",15]]],[[["keychainkind",4]],["string",3]],[[["usize",15]]],[[["usize",15]]],[[["usize",15]]],[[["usize",15]]],[[["u32",15]],["result",4,[["bool",15],["error",4]]]],[[["addressinfo",3]],["bool",15]],null,[[["partiallysignedtransaction",3],["signoptions",3]],["result",4,[["bool",15],["error",4]]]],[[["formatter",3]],["result",6]],[[["formatter",3]],["result",6]],[[["formatter",3]],["result",6]],[[["formatter",3]],["result",6]],[[["formatter",3]],["result",6]],[[]],[[]],[[]],[[]],[[["addressindex",4]],["result",4,[["addressinfo",3],["error",4]]]],[[],["result",4,[["balance",3],["error",4]]]],[[["keychainkind",4]],["extendeddescriptor",6]],[[["str",15]]],[[["addressindex",4]],["result",4,[["addressinfo",3],["error",4]]]],[[["localutxo",3],["option",4,[["psbtsighashtype",3]]],["bool",15]],["result",4,[["input",3],["error",4]]]],[[["keychainkind",4]],["arc",3,[["signerscontainer",3]]]],[[["txid",3],["bool",15]],["result",4,[["option",4,[["transactiondetails",3]]],["error",4]]]],[[["outpoint",3]],["result",4,[["option",4,[["localutxo",3]]],["error",4]]]],null,null,[[],["usize",15]],[[],["usize",15]],[[],["usize",15]],[[],["usize",15]],[[]],[[]],[[]],[[]],[[["script",3]],["bool",15]],[[["script",3]],["result",4,[["bool",15],["error",4]]]],null,[[["bool",15]],["result",4,[["vec",3,[["transactiondetails",3]]],["error",4]]]],[[],["result",4,[["vec",3,[["localutxo",3]]],["error",4]]]],[[["addressinfo",3]],["bool",15]],[[],["network",4]],[[["intowalletdescriptor",8],["option",4,[["intowalletdescriptor",8]]],["network",4]],["result",4,[["error",4]]]],[[["intowalletdescriptor",8],["option",4,[["intowalletdescriptor",8]]],["network",4]],["result",4,[["error",4]]]],[[["keychainkind",4]],["result",4,[["option",4,[["policy",3]]],["error",4]]]],null,[[["keychainkind",4]],["result",4,[["option",4,[["extendeddescriptor",6]]],["error",4]]]],[[],["secp256k1",3]],[[["partiallysignedtransaction",3],["signoptions",3]],["result",4,[["bool",15],["error",4]]]],null,[[["syncoptions",3]],["result",4,[["error",4]]]],null,[[],["string",3]],[[],["result",4]],[[],["result",4]],[[],["result",4]],[[],["result",4]],[[],["result",4]],[[],["result",4]],[[],["result",4]],[[],["result",4]],null,[[],["typeid",3]],[[],["typeid",3]],[[],["typeid",3]],[[],["typeid",3]],null,[[]],[[]],[[]],[[]],[[["option",4],["network",4],["secp256k1",3]],["result",4,[["string",3],["error",4]]]],null,null,null,null,null,null,null,null,null,null,null,[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[],["largestfirstcoinselection",3]],[[],["oldestfirstcoinselection",3]],[[]],[[]],[[["vec",3,[["weightedutxo",3]]],["vec",3,[["weightedutxo",3]]],["feerate",3],["u64",15],["script",3]],["result",4,[["coinselectionresult",3],["error",4]]]],[[["vec",3,[["weightedutxo",3]]],["vec",3,[["weightedutxo",3]]],["feerate",3],["u64",15],["script",3]],["result",4,[["coinselectionresult",3],["error",4]]]],[[["vec",3,[["weightedutxo",3]]],["vec",3,[["weightedutxo",3]]],["feerate",3],["u64",15],["script",3]],["result",4,[["coinselectionresult",3],["error",4]]]],[[["vec",3,[["weightedutxo",3]]],["vec",3,[["weightedutxo",3]]],["feerate",3],["u64",15],["script",3]],["result",4,[["coinselectionresult",3],["error",4]]]],[[["u64",15],["feerate",3],["script",3]],["excess",4]],[[],["largestfirstcoinselection",3]],[[],["oldestfirstcoinselection",3]],[[]],[[["usize",15]]],[[["usize",15]]],[[["usize",15]]],[[["usize",15]]],[[["usize",15]]],[[["usize",15]]],[[["usize",15]]],[[["usize",15]]],[[["usize",15]]],[[["usize",15]]],[[["usize",15]]],[[["usize",15]]],[[["usize",15]]],[[["usize",15]]],[[["usize",15]]],null,null,[[["formatter",3]],["result",6]],[[["formatter",3]],["result",6]],[[["formatter",3]],["result",6]],[[["formatter",3]],["result",6]],[[["formatter",3]],["result",6]],[[]],[[]],[[]],[[]],[[]],[[],["usize",15]],[[],["usize",15]],[[],["usize",15]],[[],["usize",15]],[[],["usize",15]],[[]],[[]],[[]],[[]],[[]],[[],["u64",15]],[[["u64",15]]],null,[[],["u64",15]],[[]],[[]],[[],["result",4]],[[],["result",4]],[[],["result",4]],[[],["result",4]],[[],["result",4]],[[],["result",4]],[[],["result",4]],[[],["result",4]],[[],["result",4]],[[],["result",4]],[[],["typeid",3]],[[],["typeid",3]],[[],["typeid",3]],[[],["typeid",3]],[[],["typeid",3]],[[]],[[]],[[]],[[]],[[]],null,null,null,null,null,null,null,null,[[]],[[]],[[],["option",4,[["string",3]]]],[[["usize",15]]],[[["usize",15]]],[[],["string",3]],[[],["result",4]],[[["usize",15]]],[[["wallet",3],["str",15],["bool",15]],["result",4,[["str",15]]]],[[["formatter",3]],["result",6]],[[]],[[["str",15]],["result",4]],[[],["usize",15]],[[]],null,[[],["result",4]],[[],["string",3]],[[],["result",4]],[[],["result",4]],[[],["typeid",3]],[[]],null,[[]],[[]],[[["usize",15]]],[[["usize",15]]],[[["usize",15]]],[[["formatter",3]],["result",6]],[[]],[[["hwidevice",3],["hwichain",4]],["result",4,[["hwisigner",3],["error",4]]]],[[["secp256k1",3]],["signerid",4]],[[],["usize",15]],[[]],[[["partiallysignedtransaction",3],["signoptions",3],["secp256k1",3]],["result",4,[["signererror",4]]]],[[],["result",4]],[[],["result",4]],[[],["typeid",3]],[[]],null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,[[["signerid",4],["signerordering",3],["arc",3,[["transactionsigner",8]]]],["option",4,[["arc",3,[["transactionsigner",8]]]]]],null,null,[[["secp256k1",3]],["keymap",6]],null,[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[["keymap",6],["descriptor",4],["secp256k1",3]],["signerscontainer",3]],[[],["signerid",4]],[[],["signererror",4]],[[],["signercontext",4]],[[],["signerwrapper",3]],[[],["signerordering",3]],[[],["signerscontainer",3]],[[],["signoptions",3]],[[],["tapleavesoptions",4]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[["signerid",4]],["ordering",4]],[[["signerordering",3]],["ordering",4]],[[]],[[],["signerscontainer",3]],[[]],[[]],[[["usize",15]]],[[["usize",15]]],[[["usize",15]]],[[]],[[["usize",15]]],[[["usize",15]]],[[["usize",15]]],[[["usize",15]]],[[["usize",15]]],[[["usize",15]]],[[["usize",15]]],[[["usize",15]]],[[["usize",15]]],[[["usize",15]]],[[["usize",15]]],[[["usize",15]]],[[["usize",15]]],[[],["option",4,[["descriptorsecretkey",4]]]],[[],["option",4,[["descriptorsecretkey",4]]]],[[],["option",4,[["descriptorsecretkey",4]]]],[[["usize",15]]],[[["usize",15]]],[[["usize",15]]],[[["usize",15]]],[[["usize",15]]],[[["usize",15]]],[[["usize",15]]],[[["usize",15]]],[[["signerid",4]],["bool",15]],[[["signererror",4]],["bool",15]],[[["signercontext",4]],["bool",15]],[[["signerordering",3]],["bool",15]],[[["tapleavesoptions",4]],["bool",15]],[[["signerid",4]],["option",4,[["arc",3]]]],[[["formatter",3]],["result",6]],[[["formatter",3]],["result",6]],[[["formatter",3]],["result",6]],[[["formatter",3]],["result",6]],[[["formatter",3]],["result",6]],[[["formatter",3]],["result",6]],[[["formatter",3]],["result",6]],[[["formatter",3]],["result",6]],[[["formatter",3]],["result",6]],[[["hash",3]],["signerid",4]],[[["fingerprint",3]],["signerid",4]],[[]],[[["error",4]]],[[["error",4]]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[],["u64",15]],[[]],[[["secp256k1",3]],["signerid",4]],[[["secp256k1",3]],["signerid",4]],[[["secp256k1",3]],["signerid",4]],[[],["vec",3,[["signerid",4]]]],[[],["usize",15]],[[],["usize",15]],[[],["usize",15]],[[],["usize",15]],[[],["usize",15]],[[],["usize",15]],[[],["usize",15]],[[],["usize",15]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[["signerid",4]],["bool",15]],[[["signererror",4]],["bool",15]],[[["signercontext",4]],["bool",15]],[[["signerordering",3]],["bool",15]],[[["tapleavesoptions",4]],["bool",15]],[[["signercontext",4]]],[[]],[[["signerid",4]],["option",4,[["ordering",4]]]],[[["signerordering",3]],["option",4,[["ordering",4]]]],[[["signerid",4],["signerordering",3]],["option",4,[["arc",3,[["transactionsigner",8]]]]]],null,[[["partiallysignedtransaction",3],["usize",15],["signoptions",3],["secp256k1",3]],["result",4,[["signererror",4]]]],[[["partiallysignedtransaction",3],["usize",15],["signoptions",3],["secp256k1",3]],["result",4,[["signererror",4]]]],[[["partiallysignedtransaction",3],["usize",15],["signoptions",3],["secp256k1",3]],["result",4,[["signererror",4]]]],[[["partiallysignedtransaction",3],["signoptions",3],["secp256k1",3]],["result",4,[["signererror",4]]]],[[["partiallysignedtransaction",3],["signoptions",3],["secp256k1",3]],["result",4,[["signererror",4]]]],null,[[],["vec",3,[["arc",3]]]],null,[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[],["string",3]],null,null,[[],["result",4]],[[],["result",4]],[[],["result",4]],[[],["result",4]],[[],["result",4]],[[],["result",4]],[[],["result",4]],[[],["result",4]],[[],["result",4]],[[],["result",4]],[[],["result",4]],[[],["result",4]],[[],["result",4]],[[],["result",4]],[[],["result",4]],[[],["result",4]],[[],["typeid",3]],[[],["typeid",3]],[[],["typeid",3]],[[],["typeid",3]],[[],["typeid",3]],[[],["typeid",3]],[[],["typeid",3]],[[],["typeid",3]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],null,null,null,null,null,null,null,null,[[],["u64",15]],null,null,null,null,null,null,null,null,null,null,null,null,[[]],[[["outpoint",3],["input",3],["usize",15]],["result",4,[["error",4]]]],[[]],[[["script",3],["u64",15]]],[[["outpoint",3]]],[[["outpoint",3]],["result",4,[["error",4]]]],[[],["result",4,[["error",4]]]],[[["bool",15]]],[[["script",3]],["result",4,[["error",4]]]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[["changespendpolicy",4]]],[[],["createtx",3]],[[],["bumpfee",3]],[[]],[[],["txordering",4]],[[],["changespendpolicy",4]],[[]],[[]],[[]],[[]],[[]],[[["txordering",4]],["ordering",4]],[[["changespendpolicy",4]],["ordering",4]],[[["coinselectionalgorithm",8]],["txbuilder",3,[["coinselectionalgorithm",8]]]],[[["u32",15]]],[[],["createtx",3]],[[],["bumpfee",3]],[[]],[[]],[[["usize",15]]],[[["usize",15]]],[[["usize",15]]],[[["usize",15]]],[[["usize",15]]],[[["usize",15]]],[[["usize",15]]],[[["usize",15]]],[[["usize",15]]],[[["usize",15]]],[[]],[[["script",3]]],[[]],[[["usize",15]]],[[["usize",15]]],[[["usize",15]]],[[["usize",15]]],[[["usize",15]]],[[]],[[["sequence",3]]],[[["txordering",4]],["bool",15]],[[["changespendpolicy",4]],["bool",15]],[[["u64",15]]],[[["feerate",3]]],[[],["result",4,[["error",4]]]],[[["formatter",3]],["result",6]],[[["formatter",3]],["result",6]],[[["formatter",3]],["result",6]],[[["formatter",3]],["result",6]],[[["formatter",3]],["result",6]],[[]],[[]],[[]],[[]],[[]],[[],["u64",15]],[[],["u64",15]],[[]],[[]],[[]],[[],["usize",15]],[[],["usize",15]],[[],["usize",15]],[[],["usize",15]],[[],["usize",15]],[[]],[[]],[[]],[[]],[[]],[[]],[[["locktime",4]]],[[]],[[]],[[["txordering",4]]],[[["txordering",4]],["option",4,[["ordering",4]]]],[[["changespendpolicy",4]],["option",4,[["ordering",4]]]],[[["btreemap",3,[["string",3],["vec",3,[["usize",15]]]]],["keychainkind",4]]],[[["vec",3]]],[[["psbtsighashtype",3]]],[[["transaction",3]]],[[]],[[]],[[]],[[]],[[]],[[],["result",4]],[[],["result",4]],[[],["result",4]],[[],["result",4]],[[],["result",4]],[[],["result",4]],[[],["result",4]],[[],["result",4]],[[],["result",4]],[[],["result",4]],[[],["typeid",3]],[[],["typeid",3]],[[],["typeid",3]],[[],["typeid",3]],[[],["typeid",3]],[[["vec",3,[["outpoint",3]]]]],[[["i32",15]]],[[]],[[]],[[]],[[]],[[]],null,null,null,null,null,[[]],[[]],[[["usize",15]]],[[["usize",15]]],[[["usize",15]]],[[["formatter",3]],["result",6]],[[["formatter",3]],["result",6]],[[["error",4]]],[[["error",4]]],[[]],[[],["usize",15]],[[]],[[],["string",3]],[[],["result",4]],[[],["result",4]],[[],["typeid",3]],[[["transaction",3]],["result",4,[["verifyerror",4]]]],[[]],null,null,null,null],"p":[[4,"Error"],[4,"KeychainKind"],[4,"Utxo"],[3,"Balance"],[3,"FeeRate"],[3,"LocalUtxo"],[3,"WeightedUtxo"],[3,"TransactionDetails"],[3,"BlockTime"],[6,"MnemonicWithPassphrase"],[6,"DescriptorTemplateOut"],[6,"ExtendedDescriptor"],[8,"Vbytes"],[13,"InvalidU32Bytes"],[13,"Generic"],[13,"OutputBelowDustLimit"],[13,"MissingKeyOrigin"],[13,"Key"],[13,"SpendingPolicyRequired"],[13,"InvalidPolicyPathError"],[13,"Signer"],[13,"Verification"],[13,"InvalidProgressValue"],[13,"InvalidOutpoint"],[13,"Descriptor"],[13,"Encode"],[13,"Miniscript"],[13,"MiniscriptPsbt"],[13,"Bip32"],[13,"Secp256k1"],[13,"Json"],[13,"Hex"],[13,"Psbt"],[13,"PsbtParse"],[13,"MissingCachedScripts"],[13,"Electrum"],[13,"Esplora"],[13,"CompactFilters"],[13,"Sled"],[13,"Rpc"],[13,"Rusqlite"],[13,"InsufficientFunds"],[13,"InvalidNetwork"],[13,"FeeRateTooLow"],[13,"FeeTooLow"],[13,"Local"],[13,"Foreign"],[4,"Capability"],[8,"ConfigurableBlockchain"],[8,"BlockchainFactory"],[3,"NoopProgress"],[3,"LogProgress"],[8,"Blockchain"],[8,"GetBlockHash"],[8,"GetHeight"],[8,"GetTx"],[8,"Progress"],[8,"WalletSync"],[4,"AnyBlockchain"],[4,"AnyBlockchainConfig"],[13,"Electrum"],[13,"Esplora"],[13,"CompactFilters"],[13,"Rpc"],[13,"Electrum"],[13,"Esplora"],[13,"CompactFilters"],[13,"Rpc"],[4,"CompactFiltersError"],[3,"Mempool"],[3,"BitcoinPeerConfig"],[3,"Peer"],[3,"CompactFiltersBlockchain"],[3,"CompactFiltersBlockchainConfig"],[13,"Db"],[13,"Io"],[13,"Bip158"],[13,"Time"],[13,"Global"],[3,"ElectrumBlockchain"],[3,"ElectrumBlockchainConfig"],[4,"EsploraError"],[3,"EsploraBlockchainConfig"],[3,"EsploraBlockchain"],[13,"Ureq"],[13,"UreqTransport"],[13,"HttpResponse"],[13,"Io"],[13,"Parsing"],[13,"BitcoinEncoding"],[13,"Hex"],[13,"TransactionNotFound"],[13,"HeaderHeightNotFound"],[13,"HeaderHashNotFound"],[4,"Auth"],[3,"RpcConfig"],[3,"RpcBlockchainFactory"],[3,"RpcBlockchain"],[3,"RpcSyncParams"],[13,"Cookie"],[13,"UserPass"],[8,"BatchDatabase"],[8,"ConfigurableDatabase"],[3,"SqliteDatabase"],[3,"SyncTime"],[8,"Database"],[8,"BatchOperations"],[4,"AnyBatch"],[4,"AnyDatabase"],[4,"AnyDatabaseConfig"],[3,"SledDbConfiguration"],[3,"SqliteDbConfiguration"],[13,"Memory"],[13,"Sled"],[13,"Sqlite"],[13,"Memory"],[13,"Sled"],[13,"Sqlite"],[13,"Memory"],[13,"Sled"],[13,"Sqlite"],[3,"MemoryDatabase"],[4,"Descriptor"],[4,"Wildcard"],[8,"ScriptContext"],[4,"DescriptorPublicKey"],[4,"Legacy"],[4,"Segwitv0"],[3,"Miniscript"],[3,"DescriptorXKey"],[8,"ExtractPolicy"],[8,"IntoWalletDescriptor"],[13,"Bare"],[13,"Pkh"],[13,"Wpkh"],[13,"Sh"],[13,"Wsh"],[13,"Tr"],[13,"Single"],[13,"XPub"],[4,"Error"],[13,"Key"],[13,"Policy"],[13,"InvalidDescriptorCharacter"],[13,"Bip32"],[13,"Base58"],[13,"Pk"],[13,"Miniscript"],[13,"Hex"],[4,"SatisfiableItem"],[4,"PolicyError"],[4,"Satisfaction"],[4,"PkOrF"],[4,"BuildSatisfaction"],[3,"Policy"],[3,"Condition"],[13,"Psbt"],[13,"PsbtTimelocks"],[13,"Pubkey"],[13,"XOnlyPubkey"],[13,"Fingerprint"],[13,"NotEnoughItemsSelected"],[13,"IndexOutOfRange"],[13,"Complete"],[13,"Partial"],[13,"PartialComplete"],[13,"EcdsaSignature"],[13,"SchnorrSignature"],[13,"Sha256Preimage"],[13,"Hash256Preimage"],[13,"Ripemd160Preimage"],[13,"Hash160Preimage"],[13,"Thresh"],[13,"Multisig"],[13,"AbsoluteTimelock"],[13,"RelativeTimelock"],[3,"P2Pkh"],[3,"P2Wpkh_P2Sh"],[3,"P2Wpkh"],[3,"Bip44"],[3,"Bip44Public"],[3,"Bip49"],[3,"Bip49Public"],[3,"Bip84"],[3,"Bip84Public"],[8,"DescriptorTemplate"],[4,"KeyError"],[8,"GeneratableKey"],[4,"SinglePubKey"],[4,"ScriptContextEnum"],[4,"ExtendedKey"],[4,"DescriptorSecretKey"],[8,"ExtScriptContext"],[3,"GeneratedKey"],[3,"SortedMultiVec"],[3,"SinglePub"],[3,"SinglePriv"],[4,"DescriptorKey"],[3,"PrivateKeyGenerateOptions"],[8,"GeneratableDefaultOptions"],[8,"IntoDescriptorKey"],[8,"DerivableKey"],[13,"Single"],[13,"XPrv"],[13,"Private"],[13,"Public"],[13,"Message"],[13,"Bip32"],[13,"Miniscript"],[13,"FullKey"],[13,"XOnly"],[4,"Error"],[4,"Language"],[4,"WordCount"],[3,"Mnemonic"],[13,"BadWordCount"],[13,"UnknownWord"],[13,"BadEntropyBitCount"],[13,"AmbiguousLanguages"],[8,"PsbtUtils"],[4,"AddressIndex"],[3,"Wallet"],[3,"AddressInfo"],[3,"SyncOptions"],[8,"IsDust"],[13,"Peek"],[13,"Reset"],[4,"Excess"],[3,"CoinSelectionResult"],[3,"LargestFirstCoinSelection"],[3,"OldestFirstCoinSelection"],[3,"BranchAndBoundCoinSelection"],[8,"CoinSelectionAlgorithm"],[13,"Change"],[13,"NoChange"],[3,"FullyNodedExport"],[3,"HWISigner"],[3,"SignerOrdering"],[4,"TapLeavesOptions"],[4,"SignerId"],[4,"SignerError"],[4,"SignerContext"],[3,"SignersContainer"],[3,"SignOptions"],[3,"SignerWrapper"],[8,"SignerCommon"],[8,"InputSigner"],[8,"TransactionSigner"],[13,"Tap"],[13,"SighashError"],[13,"HWIError"],[13,"PkHash"],[13,"Fingerprint"],[13,"Dummy"],[13,"Include"],[13,"Exclude"],[4,"TxOrdering"],[4,"ChangeSpendPolicy"],[3,"TxBuilder"],[3,"CreateTx"],[3,"BumpFee"],[4,"VerifyError"],[13,"MissingInputTx"],[13,"InvalidInput"],[13,"Consensus"],[13,"Global"]]}\ +"bdk":{"doc":"A modern, lightweight, descriptor-based wallet library …","t":[3,13,3,13,13,13,13,6,13,13,13,4,13,13,3,13,13,13,13,13,2,13,13,13,13,13,13,13,13,13,13,13,4,13,3,13,13,13,13,13,13,13,13,13,13,13,13,13,13,2,13,13,13,2,13,3,13,2,13,4,8,13,2,3,11,11,11,11,11,0,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,12,12,0,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,0,14,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,12,11,11,11,11,11,11,11,11,11,11,11,11,11,14,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,12,12,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,12,12,0,11,11,12,11,11,0,12,12,12,11,11,11,11,11,2,11,11,2,12,11,11,11,11,11,11,11,11,11,11,12,12,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,12,11,12,11,11,11,11,11,11,11,11,11,12,12,10,5,11,11,11,11,11,11,11,11,11,0,11,12,12,12,12,12,12,12,12,13,2,2,8,8,4,2,16,8,2,2,3,13,13,8,8,8,16,3,3,8,6,2,2,8,8,0,11,11,11,11,11,11,10,10,11,11,11,11,11,11,11,0,11,11,11,11,11,11,11,11,11,11,11,0,11,0,10,11,11,11,11,11,11,10,10,10,11,10,10,11,11,11,11,11,11,11,5,5,5,0,11,11,11,11,11,11,11,11,11,11,11,11,11,10,11,11,11,11,11,10,11,4,4,13,13,13,13,13,13,13,13,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,13,3,13,3,3,4,13,13,13,13,13,13,13,13,3,13,13,13,3,13,13,13,11,12,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,12,11,11,12,11,11,11,11,11,12,12,12,12,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,3,3,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,12,11,12,12,12,11,11,11,11,11,11,11,12,11,11,11,13,3,3,4,13,13,13,13,13,13,13,13,13,13,12,11,11,11,11,11,11,11,11,11,12,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,12,11,12,12,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,4,13,13,3,3,3,3,13,12,12,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,12,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,12,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,12,12,11,12,11,11,11,12,12,12,12,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,12,12,11,11,11,11,11,12,12,11,12,12,12,2,2,16,8,8,16,8,8,2,3,3,0,10,11,12,11,11,11,11,10,11,11,11,10,11,12,10,11,10,11,10,11,10,11,10,11,10,11,10,11,11,11,11,11,11,11,11,11,11,11,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,11,11,11,11,10,11,10,11,10,11,10,11,0,11,12,11,10,11,10,11,10,11,10,11,10,11,10,11,11,11,11,11,11,11,11,11,11,4,4,4,13,13,13,13,13,13,3,13,13,13,3,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,12,12,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,12,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,3,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,13,6,4,2,4,3,6,8,13,6,8,16,6,4,3,13,13,2,8,4,13,13,6,13,13,4,13,13,13,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,2,11,11,11,11,11,11,11,11,11,11,11,11,11,10,11,11,11,11,11,0,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,12,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,0,11,12,11,10,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,10,11,11,11,11,11,11,11,11,11,10,11,11,11,11,11,10,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,12,12,11,11,11,11,11,11,11,11,11,11,11,10,11,11,0,11,11,11,11,11,11,11,11,11,11,11,10,11,11,0,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,12,11,11,11,11,11,11,11,11,11,11,11,11,11,12,11,12,5,5,5,5,13,13,4,13,13,13,13,13,13,13,13,13,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,13,13,13,4,13,3,6,13,13,6,13,13,13,13,13,13,13,13,13,13,13,4,3,4,13,13,13,13,13,4,4,13,13,13,13,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,12,12,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,12,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,12,11,11,11,12,11,11,11,11,11,12,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,3,3,3,3,3,3,8,6,3,3,3,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,10,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,13,8,4,4,4,16,16,8,4,13,8,8,3,8,13,13,13,16,4,6,13,13,13,16,13,3,13,8,4,13,13,13,3,3,4,3,13,6,13,13,13,5,10,11,0,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,10,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,12,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,10,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,10,11,11,11,11,11,11,10,11,11,11,11,11,11,11,11,11,11,11,11,11,11,12,12,12,11,5,11,10,11,11,5,10,11,12,12,11,11,11,11,11,11,10,12,11,11,11,11,10,11,5,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,13,13,13,13,4,13,4,3,6,13,4,13,13,13,13,13,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,8,10,10,10,4,3,8,13,13,13,13,3,3,11,12,11,11,11,11,11,11,11,11,11,11,0,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,0,11,11,11,11,11,11,11,11,11,11,11,11,11,5,11,11,11,11,11,0,12,11,11,11,11,11,11,11,11,10,11,12,11,11,11,11,11,11,12,11,11,11,0,11,0,11,11,11,11,11,11,11,11,11,0,11,11,11,11,0,11,11,11,11,5,3,13,8,3,6,4,3,13,3,11,11,11,11,11,11,11,11,11,11,11,11,11,11,10,11,11,11,5,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,12,12,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,12,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,12,12,12,12,12,3,6,12,11,11,11,11,11,11,11,11,11,11,11,11,11,11,12,11,11,11,11,11,11,3,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,13,13,13,13,13,13,13,8,13,13,13,13,13,13,13,13,13,13,13,13,13,13,3,8,4,4,4,3,3,3,13,4,8,13,11,12,12,11,12,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,10,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,12,10,11,11,10,11,12,11,12,11,11,11,11,11,11,11,11,11,12,12,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,12,5,13,3,13,13,4,3,13,13,3,8,4,13,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,13,13,13,13,4,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,5,11],"n":["Balance","Bip32","BlockTime","BnBNoExactMatch","BnBTotalTriesExceeded","ChecksumMismatch","CompactFilters","ConfirmationTime","Descriptor","Electrum","Encode","Error","Esplora","External","FeeRate","FeeRateTooLow","FeeRateUnavailable","FeeTooLow","Foreign","Generic","HdKeyPaths","Hex","InsufficientFunds","Internal","InvalidNetwork","InvalidOutpoint","InvalidPolicyPathError","InvalidProgressValue","InvalidU32Bytes","IrreplaceableTransaction","Json","Key","KeychainKind","Local","LocalUtxo","Miniscript","MiniscriptPsbt","MissingCachedScripts","MissingKeyOrigin","NoRecipients","NoUtxosSelected","OutputBelowDustLimit","ProgressUpdateError","Psbt","PsbtParse","Rpc","Rusqlite","ScriptDoesntHaveAddressForm","Secp256k1","SignOptions","Signer","Sled","SpendingPolicyRequired","SyncOptions","TransactionConfirmed","TransactionDetails","TransactionNotFound","TxBuilder","UnknownUtxo","Utxo","Vbytes","Verification","Wallet","WeightedUtxo","add","as_byte","as_ref","as_sat_per_vb","base32_len","blockchain","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","check_base32","clone","clone","clone","clone","clone","clone","clone","clone","clone_into","clone_into","clone_into","clone_into","clone_into","clone_into","clone_into","clone_into","confirmation_time","confirmed","database","default","default","default","default_min_relay_fee","deref","deref","deref","deref","deref","deref","deref","deref","deref","deref_mut","deref_mut","deref_mut","deref_mut","deref_mut","deref_mut","deref_mut","deref_mut","deref_mut","descriptor","descriptor","deserialize","deserialize","deserialize","deserialize","deserialize","drop","drop","drop","drop","drop","drop","drop","drop","drop","eq","eq","eq","eq","eq","eq","eq","eq","fee","fee_vb","fee_wu","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fragment","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from_btc_per_kvb","from_sat_per_kvb","from_sat_per_kwu","from_sat_per_vb","from_vb","from_wu","get_hash","get_hash","get_spendable","get_total","hash","hash","height","immature","init","init","init","init","init","init","init","init","init","into","into","into","into","into","into","into","into","into","is_spent","keychain","keys","new","outpoint","outpoint","partial_cmp","provide","psbt","received","satisfaction_weight","sent","serialize","serialize","serialize","serialize","serialize","signer","sub","sum","template","timestamp","to_owned","to_owned","to_owned","to_owned","to_owned","to_owned","to_owned","to_owned","to_string","to_string","transaction","trusted_pending","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","txid","txout","txout","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","untrusted_pending","utxo","vbytes","version","vzip","vzip","vzip","vzip","vzip","vzip","vzip","vzip","vzip","wallet","write_base32","available","found","needed","requested","required","required","outpoint","psbt_input","AccurateFees","AnyBlockchain","AnyBlockchainConfig","Blockchain","BlockchainFactory","Capability","CompactFiltersBlockchain","Config","ConfigurableBlockchain","ElectrumBlockchain","ElectrumBlockchainConfig","EsploraBlockchain","FullHistory","GetAnyTx","GetBlockHash","GetHeight","GetTx","Inner","LogProgress","NoopProgress","Progress","ProgressData","RpcBlockchain","RpcConfig","StatelessBlockchain","WalletSync","any","borrow","borrow","borrow","borrow_mut","borrow_mut","borrow_mut","broadcast","build","build_for_wallet","clone","clone","clone","clone_into","clone_into","clone_into","compact_filters","default","default","deref","deref","deref","deref_mut","deref_mut","deref_mut","drop","drop","drop","electrum","eq","esplora","estimate_fee","fmt","fmt","fmt","from","from","from","from_config","get_block_hash","get_capabilities","get_hash","get_height","get_tx","hash","init","init","init","into","into","into","log_progress","noop_progress","progress","rpc","sync_wallet","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","update","update","vzip","vzip","vzip","wallet_setup","wallet_sync","AnyBlockchain","AnyBlockchainConfig","CompactFilters","CompactFilters","Electrum","Electrum","Esplora","Esplora","Rpc","Rpc","borrow","borrow","borrow_mut","borrow_mut","broadcast","clone","clone_into","deref","deref","deref_mut","deref_mut","deserialize","drop","drop","eq","estimate_fee","fmt","from","from","from","from","from","from","from","from","from","from","from_config","get_block_hash","get_capabilities","get_height","get_tx","init","init","into","into","serialize","to_owned","try_from","try_from","try_into","try_into","type_id","type_id","vzip","vzip","wallet_setup","wallet_sync","Bip158","BitcoinPeerConfig","BlockHashNotFound","CompactFiltersBlockchain","CompactFiltersBlockchainConfig","CompactFiltersError","DataCorruption","Db","Global","InvalidFilter","InvalidFilterHeader","InvalidHeaders","InvalidResponse","Io","Mempool","MissingBlock","NoPeers","NotConnected","Peer","PeerBloomDisabled","Time","Timeout","add_tx","address","borrow","borrow","borrow","borrow","borrow","borrow","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","broadcast","clone","clone","clone_into","clone_into","connect","connect_proxy","default","deref","deref","deref","deref","deref","deref","deref_mut","deref_mut","deref_mut","deref_mut","deref_mut","deref_mut","deserialize","deserialize","drop","drop","drop","drop","drop","drop","eq","eq","estimate_fee","fmt","fmt","fmt","fmt","fmt","fmt","fmt","from","from","from","from","from","from","from","from","from","from","from","from_config","get_block_hash","get_capabilities","get_height","get_mempool","get_network","get_tx","get_tx","get_version","has_tx","init","init","init","init","init","init","into","into","into","into","into","into","is_connected","iter_txs","network","new","new","peers","provide","recv","send","serialize","serialize","skip_blocks","socks5","socks5_credentials","storage_dir","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","wallet_setup","ElectrumBlockchain","ElectrumBlockchainConfig","borrow","borrow","borrow_mut","borrow_mut","broadcast","clone","clone_into","deref","deref","deref","deref_mut","deref_mut","deserialize","drop","drop","eq","estimate_fee","fmt","from","from","from","from_config","get_block_hash","get_capabilities","get_height","get_tx","init","init","into","into","retry","serialize","socks5","stop_gap","timeout","to_owned","try_from","try_from","try_into","try_into","type_id","type_id","url","vzip","vzip","wallet_setup","BitcoinEncoding","EsploraBlockchain","EsploraBlockchainConfig","EsploraError","HeaderHashNotFound","HeaderHeightNotFound","Hex","HttpResponse","Io","NoHeader","Parsing","TransactionNotFound","Ureq","UreqTransport","base_url","borrow","borrow","borrow","borrow_mut","borrow_mut","borrow_mut","broadcast","clone","clone_into","concurrency","deref","deref","deref","deref","deref_mut","deref_mut","deref_mut","deserialize","drop","drop","drop","eq","estimate_fee","fmt","fmt","fmt","fmt","from","from","from","from","from","from","from","from","from","from_client","from_config","get_block_hash","get_capabilities","get_height","get_tx","init","init","init","into","into","into","new","new","provide","proxy","serialize","stop_gap","timeout","to_owned","to_string","try_from","try_from","try_from","try_into","try_into","try_into","type_id","type_id","type_id","vzip","vzip","vzip","wallet_setup","with_concurrency","Auth","Cookie","None","RpcBlockchain","RpcBlockchainFactory","RpcConfig","RpcSyncParams","UserPass","auth","auth","borrow","borrow","borrow","borrow","borrow","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","broadcast","build","clone","clone","clone","clone","clone_into","clone_into","clone_into","clone_into","cmp","default","default_skip_blocks","deref","deref","deref","deref","deref","deref","deref_mut","deref_mut","deref_mut","deref_mut","deref_mut","deserialize","deserialize","deserialize","drop","drop","drop","drop","drop","eq","eq","eq","estimate_fee","fmt","fmt","fmt","fmt","fmt","force_start_time","from","from","from","from","from","from_config","get_block_hash","get_capabilities","get_hash","get_height","get_tx","hash","init","init","init","init","init","into","into","into","into","into","network","network","partial_cmp","poll_rate_sec","serialize","serialize","serialize","start_script_count","start_time","sync_params","sync_params","to_owned","to_owned","to_owned","to_owned","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","url","url","vzip","vzip","vzip","vzip","vzip","wallet_name","wallet_name_prefix","wallet_setup","file","password","username","AnyDatabase","AnyDatabaseConfig","Batch","BatchDatabase","BatchOperations","Config","ConfigurableDatabase","Database","MemoryDatabase","SqliteDatabase","SyncTime","any","begin_batch","begin_batch","block_time","borrow","borrow","borrow_mut","borrow_mut","check_descriptor_checksum","check_descriptor_checksum","clone","clone_into","commit_batch","commit_batch","connection","del_last_index","del_last_index","del_path_from_script_pubkey","del_path_from_script_pubkey","del_raw_tx","del_raw_tx","del_script_pubkey_from_path","del_script_pubkey_from_path","del_sync_time","del_sync_time","del_tx","del_tx","del_utxo","del_utxo","deref","deref","deref_mut","deref_mut","deserialize","drop","drop","fmt","fmt","from","from","from_config","from_config","get_last_index","get_last_index","get_path_from_script_pubkey","get_path_from_script_pubkey","get_raw_tx","get_raw_tx","get_script_pubkey_from_path","get_script_pubkey_from_path","get_sync_time","get_sync_time","get_tx","get_tx","get_utxo","get_utxo","increment_last_index","increment_last_index","init","init","into","into","iter_raw_txs","iter_raw_txs","iter_script_pubkeys","iter_script_pubkeys","iter_txs","iter_txs","iter_utxos","iter_utxos","memory","new","path","serialize","set_last_index","set_last_index","set_raw_tx","set_raw_tx","set_script_pubkey","set_script_pubkey","set_sync_time","set_sync_time","set_tx","set_tx","set_utxo","set_utxo","to_owned","try_from","try_from","try_into","try_into","type_id","type_id","vzip","vzip","AnyBatch","AnyDatabase","AnyDatabaseConfig","Memory","Memory","Memory","Sled","Sled","Sled","SledDbConfiguration","Sqlite","Sqlite","Sqlite","SqliteDbConfiguration","begin_batch","borrow","borrow","borrow","borrow","borrow","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","check_descriptor_checksum","commit_batch","del_last_index","del_last_index","del_path_from_script_pubkey","del_path_from_script_pubkey","del_raw_tx","del_raw_tx","del_script_pubkey_from_path","del_script_pubkey_from_path","del_sync_time","del_sync_time","del_tx","del_tx","del_utxo","del_utxo","deref","deref","deref","deref","deref","deref_mut","deref_mut","deref_mut","deref_mut","deref_mut","deserialize","deserialize","deserialize","drop","drop","drop","drop","drop","fmt","fmt","fmt","fmt","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from_config","get_last_index","get_path_from_script_pubkey","get_raw_tx","get_script_pubkey_from_path","get_sync_time","get_tx","get_utxo","increment_last_index","init","init","init","init","init","into","into","into","into","into","iter_raw_txs","iter_script_pubkeys","iter_txs","iter_utxos","path","path","serialize","serialize","serialize","set_last_index","set_last_index","set_raw_tx","set_raw_tx","set_script_pubkey","set_script_pubkey","set_sync_time","set_sync_time","set_tx","set_tx","set_utxo","set_utxo","tree_name","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","MemoryDatabase","begin_batch","borrow","borrow_mut","check_descriptor_checksum","commit_batch","default","del_last_index","del_path_from_script_pubkey","del_raw_tx","del_script_pubkey_from_path","del_sync_time","del_tx","del_utxo","deref","deref_mut","drop","fmt","from","from_config","get_last_index","get_path_from_script_pubkey","get_raw_tx","get_script_pubkey_from_path","get_sync_time","get_tx","get_utxo","increment_last_index","init","into","iter_raw_txs","iter_script_pubkeys","iter_txs","iter_utxos","new","set_last_index","set_raw_tx","set_script_pubkey","set_sync_time","set_tx","set_utxo","try_from","try_into","type_id","vzip","Bare","DerivedDescriptor","Descriptor","DescriptorError","DescriptorPublicKey","DescriptorXKey","ExtendedDescriptor","ExtractPolicy","Hardened","HdKeyPaths","IntoWalletDescriptor","Key","KeyMap","Legacy","Miniscript","None","Pkh","Policy","ScriptContext","Segwitv0","Sh","Single","TapKeyOrigins","Tr","Unhardened","Wildcard","Wpkh","Wsh","XPub","address","as_enum","as_enum","as_inner","at_derivation_index","borrow","borrow","borrow","borrow","borrow","borrow","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","branches","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_terminal_non_malleable","check_terminal_non_malleable","check_terminal_non_malleable","check_witness","check_witness","check_witness","checksum","clone","clone","clone","clone","clone","clone","clone_into","clone_into","clone_into","clone_into","clone_into","clone_into","cmp","cmp","cmp","cmp","cmp","cmp","contains_raw_pkh","deref","deref","deref","deref","deref","deref","deref_mut","deref_mut","deref_mut","deref_mut","deref_mut","deref_mut","derivation_path","derive","derived_descriptor","derived_descriptor","desc_type","deserialize","deserialize","drop","drop","drop","drop","drop","drop","encode","eq","eq","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","fmt","fmt","for_each_key","for_each_key","from","from","from","from","from","from","from","from","from","from","from","from","from_ast","from_str","from_str","from_str_ext","from_str_insane","from_tree","from_tree","get_hash","get_hash","get_hash","get_hash","get_hash","get_hash","get_nth_child","get_nth_pk","get_satisfaction","get_satisfaction_mall","has_mixed_timelocks","has_repeated_keys","has_wildcard","hash","hash","hash","hash","hash","hash","init","init","init","init","init","init","into","into","into","into","into","into","into_inner","into_wallet_descriptor","into_wallet_descriptor","is_deriveable","is_non_malleable","iter","iter_pk","lift","lift","lift_check","matches","max_satisfaction_size","max_satisfaction_size","max_satisfaction_size","max_satisfaction_size","max_satisfaction_weight","max_satisfaction_witness_elements","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","origin","other_top_level_checks","parse","parse_descriptor","parse_insane","parse_with_ext","partial_cmp","partial_cmp","partial_cmp","partial_cmp","partial_cmp","partial_cmp","pk_len","pk_len","pk_len","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","template","to_owned","to_owned","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_from","try_from","try_into","try_into","try_into","try_into","try_into","try_into","ty","type_id","type_id","type_id","type_id","type_id","type_id","unsigned_script_sig","vzip","vzip","vzip","vzip","vzip","vzip","wildcard","within_resource_limits","xkey","calc_checksum","calc_checksum_bytes","get_checksum","get_checksum_bytes","Base58","Bip32","Error","HardenedDerivationXpub","Hex","InvalidDescriptorCharacter","InvalidDescriptorChecksum","InvalidHdKeyPath","Key","Miniscript","Pk","Policy","borrow","borrow_mut","deref","deref_mut","drop","fmt","fmt","from","from","from","from","from","from","from","from","init","into","provide","to_string","try_from","try_into","type_id","vzip","AbsoluteTimelock","AddOnLeaf","AddOnPartialComplete","BuildSatisfaction","Complete","Condition","ConditionMap","EcdsaSignature","Fingerprint","FoldedConditionMap","Hash160Preimage","Hash256Preimage","IncompatibleConditions","IndexOutOfRange","MixedTimelockUnits","Multisig","None","None","NotEnoughItemsSelected","Partial","PartialComplete","PkOrF","Policy","PolicyError","Psbt","PsbtTimelocks","Pubkey","RelativeTimelock","Ripemd160Preimage","Satisfaction","SatisfiableItem","SchnorrSignature","Sha256Preimage","Thresh","XOnlyPubkey","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","clone","clone","clone","clone","clone","clone","clone_into","clone_into","clone_into","clone_into","clone_into","clone_into","contribution","csv","default","deref","deref","deref","deref","deref","deref","deref","deref_mut","deref_mut","deref_mut","deref_mut","deref_mut","deref_mut","deref_mut","drop","drop","drop","drop","drop","drop","drop","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","get_hash","get_hash","hash","hash","id","id","init","init","init","init","init","init","init","into","into","into","into","into","into","into","is_leaf","is_leaf","is_null","item","partial_cmp","provide","requires_path","satisfaction","serialize","serialize","serialize","serialize","serialize","timelock","to_owned","to_owned","to_owned","to_owned","to_owned","to_owned","to_string","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_into","try_into","try_into","try_into","try_into","try_into","try_into","type_id","type_id","type_id","type_id","type_id","type_id","type_id","vzip","vzip","vzip","vzip","vzip","vzip","vzip","current_height","input_max_height","psbt","condition","conditions","conditions","items","items","m","m","n","n","sorted","sorted","hash","hash","hash","hash","items","keys","threshold","threshold","value","value","Bip44","Bip44Public","Bip49","Bip49Public","Bip84","Bip84Public","DescriptorTemplate","DescriptorTemplateOut","P2Pkh","P2Wpkh","P2Wpkh_P2Sh","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","build","build","build","build","build","build","build","build","build","deref","deref","deref","deref","deref","deref","deref","deref","deref","deref_mut","deref_mut","deref_mut","deref_mut","deref_mut","deref_mut","deref_mut","deref_mut","deref_mut","drop","drop","drop","drop","drop","drop","drop","drop","drop","from","from","from","from","from","from","from","from","from","init","init","init","init","init","init","init","init","init","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","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","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","Bip32","DerivableKey","DescriptorKey","DescriptorPublicKey","DescriptorSecretKey","Entropy","Error","ExtScriptContext","ExtendedKey","FullKey","GeneratableDefaultOptions","GeneratableKey","GeneratedKey","IntoDescriptorKey","InvalidChecksum","InvalidNetwork","InvalidScriptContext","Key","KeyError","KeyMap","Legacy","Message","Miniscript","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","bip39","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","check_global_consensus_validity","check_global_policy_validity","check_global_validity","check_local_consensus_validity","check_local_policy_validity","check_local_validity","check_terminal_non_malleable","check_witness","clone","clone","clone","clone","clone","clone","clone","clone_into","clone_into","clone_into","clone_into","clone_into","clone_into","clone_into","cmp","cmp","cmp","cmp","compressed","default","deref","deref","deref","deref","deref","deref","deref","deref","deref","deref","deref","deref","deref","deref_mut","deref_mut","deref_mut","deref_mut","deref_mut","deref_mut","deref_mut","deref_mut","deref_mut","deref_mut","deref_mut","deref_mut","derive","drop","drop","drop","drop","drop","drop","drop","drop","drop","drop","drop","drop","encode","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","generate","generate_default","generate_with_entropy","generate_with_entropy_default","get_hash","get_hash","get_hash","get_hash","has_secret","has_wildcard","hash","hash","hash","hash","init","init","init","init","init","init","init","init","init","init","init","init","into","into","into","into","into","into","into","into","into","into","into","into","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_xprv","into_xpub","is_deriveable","is_legacy","is_legacy","is_segwit_v0","is_segwit_v0","is_taproot","is_taproot","is_uncompressed","is_x_only_key","k","key","key","lift","mainnet_network","master_fingerprint","max_satisfaction_size","max_satisfaction_size","max_satisfaction_witness_elements","merge_networks","name_str","new","origin","origin","other_top_level_checks","override_valid_networks","partial_cmp","partial_cmp","partial_cmp","partial_cmp","pk_len","pks","provide","sanity_check","satisfy","script_size","sig_type","sorted_node","test_networks","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","AmbiguousLanguages","BadEntropyBitCount","BadWordCount","English","Error","InvalidChecksum","Language","Mnemonic","MnemonicWithPassphrase","UnknownWord","WordCount","Words12","Words15","Words18","Words21","Words24","all","borrow","borrow","borrow","borrow","borrow_mut","borrow_mut","borrow_mut","borrow_mut","clone","clone","clone","clone_into","clone_into","clone_into","cmp","cmp","deref","deref","deref","deref","deref_mut","deref_mut","deref_mut","deref_mut","deserialize","drop","drop","drop","drop","eq","eq","eq","fmt","fmt","fmt","fmt","fmt","fmt","from","from","from","from","from_entropy","from_entropy_in","from_str","generate_in_with","generate_with_entropy","get_hash","get_hash","hash","hash","init","init","init","init","into","into","into","into","into_descriptor_key","into_descriptor_key","into_extended_key","into_extended_key","language","language_of","parse","parse_in","parse_in_normalized","parse_normalized","partial_cmp","partial_cmp","provide","serialize","to_entropy","to_entropy_array","to_owned","to_owned","to_owned","to_seed","to_seed_normalized","to_string","to_string","to_string","try_from","try_from","try_from","try_from","try_into","try_into","try_into","try_into","type_id","type_id","type_id","type_id","vzip","vzip","vzip","vzip","word_count","word_iter","words_by_prefix","PsbtUtils","fee_amount","fee_rate","get_utxo_for","AddressIndex","AddressInfo","IsDust","LastUnused","New","Peek","Reset","SyncOptions","Wallet","add_signer","address","borrow","borrow","borrow","borrow","borrow_mut","borrow_mut","borrow_mut","borrow_mut","build_fee_bump","build_tx","coin_selection","database","default","deref","deref","deref","deref","deref","deref_mut","deref_mut","deref_mut","deref_mut","descriptor_checksum","drop","drop","drop","drop","ensure_addresses_cached","eq","export","finalize_psbt","fmt","fmt","fmt","fmt","fmt","from","from","from","from","get_address","get_balance","get_descriptor_for_keychain","get_funded_wallet","get_internal_address","get_psbt_input","get_signers","get_tx","get_utxo","hardwaresigner","index","init","init","init","init","into","into","into","into","is_dust","is_mine","keychain","list_transactions","list_unspent","network","new","new_offline","policies","progress","public_descriptor","secp_ctx","sign","signer","sync","time","to_string","try_from","try_from","try_from","try_from","try_into","try_into","try_into","try_into","tx_builder","type_id","type_id","type_id","type_id","verify","vzip","vzip","vzip","vzip","wallet_name_from_descriptor","BranchAndBoundCoinSelection","Change","CoinSelectionAlgorithm","CoinSelectionResult","DefaultCoinSelectionAlgorithm","Excess","LargestFirstCoinSelection","NoChange","OldestFirstCoinSelection","borrow","borrow","borrow","borrow","borrow","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","clone","clone","clone_into","clone_into","coin_select","coin_select","coin_select","coin_select","decide_change","default","default","default","deref","deref","deref","deref","deref","deref_mut","deref_mut","deref_mut","deref_mut","deref_mut","drop","drop","drop","drop","drop","excess","fee_amount","fmt","fmt","fmt","fmt","fmt","from","from","from","from","from","init","init","init","init","init","into","into","into","into","into","local_selected_amount","new","selected","selected_amount","to_owned","to_owned","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","amount","change_fee","dust_threshold","fee","remaining_amount","FullyNodedExport","WalletExport","blockheight","borrow","borrow_mut","change_descriptor","deref","deref_mut","descriptor","deserialize","drop","export_wallet","fmt","from","from_str","init","into","label","serialize","to_string","try_from","try_into","type_id","vzip","HWISigner","borrow","borrow_mut","deref","deref_mut","drop","fmt","from","from_device","id","init","into","sign_transaction","try_from","try_into","type_id","vzip","All","Dummy","Exclude","Fingerprint","HWIError","Include","InputIndexOutOfRange","InputSigner","InvalidKey","InvalidNonWitnessUtxo","InvalidSighash","Legacy","MissingHdKeypath","MissingKey","MissingNonWitnessUtxo","MissingWitnessScript","MissingWitnessUtxo","NonStandardSighash","None","PkHash","Segwitv0","SighashError","SignOptions","SignerCommon","SignerContext","SignerError","SignerId","SignerOrdering","SignerWrapper","SignersContainer","Tap","TapLeavesOptions","TransactionSigner","UserCanceled","add_external","allow_all_sighashes","allow_grinding","as_key_map","assume_height","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","build","clone","clone","clone","clone","clone","clone","clone","clone","clone_into","clone_into","clone_into","clone_into","clone_into","clone_into","clone_into","clone_into","cmp","cmp","default","default","default","default","deref","deref","deref","deref","deref","deref","deref","deref","deref","deref_mut","deref_mut","deref_mut","deref_mut","deref_mut","deref_mut","deref_mut","deref_mut","descriptor_secret_key","descriptor_secret_key","descriptor_secret_key","drop","drop","drop","drop","drop","drop","drop","drop","eq","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","get_hash","hash","id","id","id","ids","init","init","init","init","init","init","init","init","into","into","into","into","into","into","into","into","new","new","partial_cmp","partial_cmp","provide","remove","remove_partial_sigs","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_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","get_timestamp","Bip69Lexicographic","BumpFee","ChangeAllowed","ChangeForbidden","ChangeSpendPolicy","CreateTx","OnlyChange","Shuffle","TxBuilder","TxBuilderContext","TxOrdering","Untouched","add_data","add_foreign_utxo","add_global_xpubs","add_recipient","add_unspendable","add_utxo","add_utxos","allow_dust","allow_shrinking","borrow","borrow","borrow","borrow","borrow","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","change_policy","clone","clone","clone","clone","clone","clone_into","clone_into","clone_into","clone_into","clone_into","cmp","cmp","coin_selection","current_height","default","default","default","default","deref","deref","deref","deref","deref","deref_mut","deref_mut","deref_mut","deref_mut","deref_mut","do_not_spend_change","drain_to","drain_wallet","drop","drop","drop","drop","drop","enable_rbf","enable_rbf_with_sequence","eq","eq","fee_absolute","fee_rate","finish","fmt","fmt","fmt","fmt","fmt","from","from","from","from","from","get_hash","get_hash","hash","hash","include_output_redeem_witness_script","init","init","init","init","init","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_owned","to_owned","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","Consensus","Global","InvalidInput","MissingInputTx","VerifyError","borrow","borrow_mut","deref","deref_mut","drop","fmt","fmt","from","from","from","init","into","provide","to_string","try_from","try_into","type_id","verify_tx","vzip"],"q":["bdk","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","bdk::Error","","","","","","bdk::Utxo","","bdk::blockchain","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","bdk::blockchain::any","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","bdk::blockchain::compact_filters","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","bdk::blockchain::electrum","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","bdk::blockchain::esplora","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","bdk::blockchain::rpc","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","bdk::blockchain::rpc::Auth","","","bdk::database","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","bdk::database::any","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","bdk::database::memory","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","bdk::descriptor","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","bdk::descriptor::checksum","","","","bdk::descriptor::error","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","bdk::descriptor::policy","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","bdk::descriptor::policy::BuildSatisfaction","","","bdk::descriptor::policy::Satisfaction","","","","","","","","","","","bdk::descriptor::policy::SatisfiableItem","","","","","","","","","","bdk::descriptor::template","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","bdk::keys","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","bdk::keys::bip39","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","bdk::psbt","","","","bdk::wallet","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","bdk::wallet::coin_selection","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","bdk::wallet::coin_selection::Excess","","","","","bdk::wallet::export","","","","","","","","","","","","","","","","","","","","","","","","bdk::wallet::hardwaresigner","","","","","","","","","","","","","","","","","bdk::wallet::signer","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","bdk::wallet::signer::SignerContext","bdk::wallet::time","bdk::wallet::tx_builder","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","bdk::wallet::verify","","","","","","","","","","","","","","","","","","","","","","",""],"d":["Balance differentiated in various categories","BIP32 error","Block height and timestamp of a block","Branch and bound coin selection tries to avoid needing a …","Branch and bound coin selection possible attempts with …","Descriptor checksum mismatch","Compact filters client error)","DEPRECATED: Confirmation time of a transaction","Error related to the parsing and usage of descriptors","Electrum client error","Encoding error","Errors that can be thrown by the Wallet","Esplora client error","External","Fee rate","When bumping a tx the fee rate requested is lower than …","Node doesn’t have data to estimate a fee rate","When bumping a tx the absolute fee requested is lower than …","A UTXO owned by another wallet.","Generic error","","Hex decoding error","Wallet’s UTXO set is not enough to cover recipient’s …","Internal, usually used for change outputs","Invalid network","Requested outpoint doesn’t exist in the tx (vout greater …","Error while extracting and manipulating policies","Progress value must be between 0.0 (included) and 100.0 …","Wrong number of bytes found when trying to convert to u32","Trying to replace a tx that has a sequence >= 0xFFFFFFFE","Error serializing or deserializing JSON data","Error while working with keys","Types of keychains","A UTXO owned by the local wallet.","An unspent output owned by a Wallet.","Miniscript error","Miniscript PSBT error","crate::blockchain::WalletSync sync attempt failed due to …","In order to use the TxBuilder::add_global_xpubs option …","Cannot build a tx without recipients","manually_selected_only option is selected but no utxo has …","Output created is under the dust limit, 546 satoshis","Progress update error (maybe the channel has been closed)","Partially signed bitcoin transaction error","Partially signed bitcoin transaction parse error","Rpc client error","Rusqlite client error","This error is thrown when trying to convert Bare and …","An ECDSA error","","Signing error","Sled database error","Spending policy is not compatible with this KeychainKind","","Happens when trying to bump a transaction that is already …","A wallet transaction","Thrown when a tx is not found in the internal database","","Happens when trying to spend an UTXO that is not in the …","An unspent transaction output (UTXO).","Trait implemented by types that can be used to measure …","Transaction verification error","","A Utxo with its satisfaction_weight.","","Return KeychainKind as a byte","","Return the value as satoshi/vbyte","","Blockchain backends","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","If the transaction is confirmed, contains height and …","Confirmed and immediately spendable balance","Database types","","","","Create a new FeeRate with the default min relay fee value","","","","","","","","","","","","","","","","","","","Descriptors","Macro to write full descriptors with code","","","","","","","","","","","","","","","","","","","","","","","Fee value (sats) if confirmed. The availability of the fee …","Calculate absolute fee in Satoshis using size in virtual …","Calculate absolute fee in Satoshis using size in weight …","","","","","","","","","","","","Macro to write descriptor fragments with code","","","","","","","","","","","","","","","","","Returns the argument unchanged.","","","","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","","Returns the argument unchanged.","Returns the argument unchanged.","Create a new instance of FeeRate given a float fee rate in …","Create a new instance of FeeRate given a float fee rate in …","Create a new instance of FeeRate given a float fee rate in …","Create a new instance of FeeRate given a float fee rate in …","Calculate fee rate from fee and vbytes.","Calculate fee rate from fee and weight units (wu).","","","Get sum of trusted_pending and confirmed coins","Get the whole balance visible to the wallet","","","confirmation block height","All coinbase outputs not yet matured","","","","","","","","","","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Whether this UTXO is spent or not","Type of keychain","Key formats","Returns Some BlockTime if both height and timestamp are …","Get the location of the UTXO","Reference to a transaction output","","","Additional functions on the rust-bitcoin …","Received value (sats) Sum of owned outputs of this …","The weight of the witness data and scriptSig expressed in …","Sent value (sats) Sum of owned inputs of this transaction.","","","","","","","","","","confirmation block timestamp","","","","","","","","","","","Optional transaction","Unconfirmed UTXOs generated by a wallet tx","","","","","","","","","","","","","","","","","","","Transaction id","Get the TxOut of the UTXO","Transaction output","","","","","","","","","","Unconfirmed UTXOs received from an external wallet","The UTXO","Convert weight units to virtual bytes.","Get the version of BDK at runtime","","","","","","","","","","Wallet","","Sats available for spending","found network, for example the network of the bitcoin node","Sats needed for some transaction","requested network, for example what is given as bdk-cli …","Required fee rate (satoshi/vbyte)","Required fee absolute value (satoshi)","The location of the output.","The information about the input we require to add it to a …","Can compute accurate fees for the transactions found …","","","Trait that defines the actions that must be supported by a …","Trait for a factory of blockchains that share the …","Capabilities that can be supported by a Blockchain backend","","Type that contains the configuration","Trait for Blockchain types that can be created given a …","","","Structure that implements the logic to sync with Esplora","Can recover the full history of a wallet and not only the …","Can fetch any historical transaction given its txid","Trait for getting block hash by block height","Trait for getting the current height of the blockchain.","Trait for getting a transaction by txid","The type returned when building a blockchain from this …","Type that implements Progress and logs at level INFO every …","Type that implements Progress and drops every update …","Trait for types that can receive and process progress …","Data sent with a progress update over a channel","","","Trait for blockchains that don’t contain any state","Trait for blockchains that can sync by updating the …","Runtime-checked blockchain types","","","","","","","Broadcast a transaction","Build a new blockchain for the given descriptor wallet_name","Build a new blockchain for a given wallet","","","","","","","Compact Filters","","","","","","","","","","","","Electrum","","Esplora","Estimate the fee rate required to confirm a transaction in …","","","","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Create a new instance given a configuration","fetch block hash given its height","Return the set of Capability supported by this backend","","Return the current height","Fetch a transaction given its txid","","","","","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Create a new instance of LogProgress","Create a new instance of NoopProgress","Shortcut to create a channel (pair of Sender and Receiver) …","Rpc Blockchain","Use BlockchainFactory::build_for_wallet to get a …","","","","","","","","","","","","","Send a new progress update","","","","","","Setup the backend and populate the internal database for …","If not overridden, it defaults to calling …","Type that can contain any of the Blockchain types defined …","Type that can contain any of the blockchain configurations …","Compact filters client","Compact filters client","Electrum client","Electrum client","Esplora client","Esplora client","RPC client","RPC client configuration","","","","","","","","","","","","","","","","","","","","","Returns the argument unchanged.","","Returns the argument unchanged.","","","","","","","","","","","","Calls U::from(self).","Calls U::from(self).","","","","","","","","","","","","","Invalid BIP158 filter","Data to connect to a Bitcoin P2P peer","Block hash at specified height not found","Structure implementing the required blockchain traits","Configuration for a CompactFiltersBlockchain","An error that can occur during sync with a …","The data stored in the block filters storage are corrupted","Internal database error","Wrapper for crate::error::Error","The compact filter returned is invalid","The compact filter headers returned are invalid","The headers returned are invalid","A peer sent an invalid or unexpected response","Internal I/O error","Container for unconfirmed, but valid Bitcoin transactions","The peer is missing a block in the valid chain","No peers have been specified","A peer is not connected","A Bitcoin peer","The peer doesn’t advertise the BLOOM service flag","Internal system time error","A peer took too long to reply to one of our messages","Add a transaction to the mempool","Peer address such as 127.0.0.1:18333","","","","","","","","","","","","","","","","","","Connect to a peer over a plaintext TCP connection","Connect to a peer through a SOCKS5 proxy, optionally by …","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","","","","","","Returns the argument unchanged.","","","","","Return the mempool used by this peer","Return the Bitcoin Network in use","Look-up a transaction in the mempool given an Inventory …","","Return the VersionMessage sent by the peer","Return whether or not the mempool contains a transaction …","","","","","","","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Return whether or not the peer is still connected","Return the list of transactions contained in the mempool","Network used","Create a new empty mempool","Construct a new instance given a list of peers, a path to …","List of peers to try to connect to for asking headers and …","","Waits for a specific incoming Bitcoin message, optionally …","Send a raw Bitcoin message to the peer","","","Optionally skip initial skip_blocks blocks (default: 0)","Optional socks5 proxy","Optional socks5 proxy credentials","Storage dir to save partially downloaded headers and full …","","","","","","","","","","","","","","","","","","","","","","","","","","","","","Wrapper over an Electrum Client that implements the …","Configuration for an ElectrumBlockchain","","","","","","","","","","","","","","","","","","","Returns the argument unchanged.","","Returns the argument unchanged.","","","","","","","","Calls U::from(self).","Calls U::from(self).","Request retry count","","URL of the socks5 proxy server or a Tor service","Stop searching addresses for transactions after finding an …","Request timeout (seconds)","","","","","","","","URL of the Electrum server (such as ElectrumX, Esplora, …","","","","Invalid Bitcoin data returned","Structure that implements the logic to sync with Esplora","Configuration for an EsploraBlockchain","Errors that can happen during a sync with Esplora","Header hash not found","Header height not found","Invalid Hex data returned","HTTP response error","IO error during ureq response read","No header found in ureq response","Invalid number returned","Transaction not found","Error during ureq HTTP request","Transport error during the ureq HTTP call","Base URL of the esplora service","","","","","","","","","","Number of parallel requests sent to the esplora service …","","","","","","","","","","","","","","","","","","Returns the argument unchanged.","","","","","","","Returns the argument unchanged.","Returns the argument unchanged.","Build a new instance given a client","","","","","","","","","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Create a new instance of the client from a base URL and …","create a config with default values given the base url and …","","Optional URL of the proxy to use to make requests to the …","","Stop searching addresses for transactions after finding an …","Socket timeout.","","","","","","","","","","","","","","","","Set the number of parallel requests the client can make.","This struct is equivalent to bitcoincore_rpc::Auth but it …","Authentication with a cookie file","None authentication","The main struct for RPC backend implementing the …","Factory of RpcBlockchain instances, implements …","RpcBlockchain configuration options","Sync parameters for Bitcoin Core RPC.","Authentication with username and password, usually …","The bitcoin node authentication mechanism","The bitcoin node authentication mechanism","","","","","","","","","","","","","","","","","","","","","","","Default number of blocks to skip which will be inherited …","","","","","","","","","","","","","","","","","","","","","","","","","","","","","Forces every sync to use start_time as import timestamp.","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Returns RpcBlockchain backend creating an RPC client to a …","","","","","","","","","","","","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","The network we are using (it will be checked the bitcoin …","The network we are using (it will be checked the bitcoin …","","RPC poll rate (in seconds) to get state updates.","","","","The minimum number of scripts to scan for on initial sync.","Time in unix seconds in which initial sync will start …","Sync parameters","Sync parameters","","","","","","","","","","","","","","","","","","","","The bitcoin node url","The bitcoin node url","","","","","","The wallet name in the bitcoin node, consider using …","The optional prefix used to build the full wallet name for …","","Cookie file","Password","Username","","","Container for the operations","Trait for a database that supports batch operations","Trait for operations that can be batched","Type that contains the configuration","Trait for Database types that can be created given a …","Trait for reading data from a database","","Sqlite database stored on filesystem","Blockchain state at the time of syncing","Runtime-checked database types","Create a new batch container","","Block timestamp and height at the time of sync","","","","","Read and checks the descriptor checksum for a given …","","","","Consume and apply a batch of operations","","A rusqlite connection object to the sqlite database","Delete the last derivation index for a keychain.","","Delete the data related to a specific script_pubkey, …","","Delete a raw transaction given its Txid","","Delete a script_pubkey given the keychain and its child …","","Reset the sync time to None","","Delete the metadata of a transaction and optionally the …","","Delete a LocalUtxo given its OutPoint","","","","","","","","","","","Returns the argument unchanged.","Returns the argument unchanged.","Create a new instance given a configuration","","Return the last derivation index for a keychain.","","Fetch the keychain and child number of a given …","","Fetch a raw transaction given its Txid","","Fetch a script_pubkey given the child number of a keychain.","","Return the sync time, if present","","Fetch the transaction metadata and optionally also the raw …","","Fetch a LocalUtxo given its OutPoint","","Increment the last derivation index for a keychain and …","","","","Calls U::from(self).","Calls U::from(self).","Return the list of raw transactions","","Return the list of script_pubkeys","","Return the list of transactions metadata","","Return the list of LocalUtxos","","In-memory ephemeral database","Instantiate a new SqliteDatabase instance by creating a …","Path on the local filesystem to store the sqlite file","","Store the last derivation index for a given keychain.","","Store a raw transaction","","Store a script_pubkey along with its keychain and child …","","Store the sync time","","Store the metadata of a transaction","","Store a LocalUtxo","","","","","","","","","","","Type that contains any of the BatchDatabase::Batch types …","Type that can contain any of the Database types defined by …","Type that can contain any of the database configurations …","In-memory ephemeral database","In-memory ephemeral database","Memory database has no config","Simple key-value embedded database based on sled","Simple key-value embedded database based on sled","Simple key-value embedded database based on sled","Configuration type for a sled::Tree database","Sqlite embedded database using rusqlite","Sqlite embedded database using rusqlite","Sqlite embedded database using rusqlite","Configuration type for a sqlite::SqliteDatabase database","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","Returns the argument unchanged.","","","","","","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","","Returns the argument unchanged.","","","","","","","","","","","","","","","","","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","","","","","Main directory of the db","Main directory of the db","","","","","","","","","","","","","","","","Name of the database tree, a separated namespace for the …","","","","","","","","","","","","","","","","","","","","","In-memory ephemeral database","","","","","","","","","","","","","","","","","","Returns the argument unchanged.","","","","","","","","","","","Calls U::from(self).","","","","","Create a new empty database","","","","","","","","","","","A raw scriptpubkey (including pay-to-pubkey) under Legacy …","Alias for a Descriptor that contains extended derived keys","Script descriptor","","The descriptor pubkey, either a single pubkey or an xpub.","An extended key with origin, derivation path, and wildcard.","Alias for a Descriptor that can contain extended keys …","Trait implemented on Descriptors to add a method to …","Unhardened wildcard, e.g. *h","Alias for the type of maps that represent derivation paths …","Trait for types which can be converted into an …","The consensus key associated with the type. Must be a …","Alias type for a map of public key to secret key","Legacy ScriptContext To be used as P2SH scripts For …","Top-level script AST type","No wildcard","Pay-to-PubKey-Hash","","The ScriptContext for Miniscript. Additional type …","Segwitv0 ScriptContext","Pay-to-ScriptHash(includes nested wsh/wpkh/sorted multi)","Single public key.","Alias for the type of maps that represent taproot key …","Pay-to-Taproot","Unhardened wildcard, e.g. *","Whether a descriptor has a wildcard in it","Pay-to-Witness-PubKey-Hash","Pay-to-Witness-ScriptHash with Segwitv0 context","Extended public key (xpub).","Computes the Bitcoin address of the descriptor, if one …","","","Get a reference to the inner AstElem representing the root …","Replaces all wildcards (i.e. /*) in the descriptor with a …","","","","","","","","","","","","","Enumerates all child nodes of the current AST node (self) …","","Depending on script Context, some of the Terminals might …","","","Depending on script Context, some of the script resource …","","Check the consensus + policy(if not disabled) rules that …","Consensus rules at the Miniscript satisfaction time. It is …","","","Policy rules at the Miniscript satisfaction time. It is …","","","Check the consensus + policy(if not disabled) rules …","Depending on ScriptContext, fragments can be malleable. …","","","Check whether the given satisfaction is valid under the …","","","Descriptor checksum","","","","","","","","","","","","","","","","","","","Whether the given miniscript contains a raw pkh fragment","","","","","","","","","","","","","The derivation path","Deprecated name for [at_derivation_index].","Convert all the public keys in the descriptor to …","Convert all the public keys in the descriptor to …","Get the DescriptorType of Descriptor","","","","","","","","","Encode as a Bitcoin script","","","","","","","Descriptor errors","Computes the the underlying script before any hashing is …","Additional information helpful for extra analysis.","Check whether the miniscript follows the given Extra …","Extract the spending policy","","","Utility method for deriving the descriptor at each index …","","","","","","","","","","","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","","","","","","","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Add type information(Type and Extdata) to Miniscript based …","","Parse a Miniscript from string and perform sanity checks …","Attempt to parse an Miniscripts that don’t follow the …","Attempt to parse an insane(scripts don’t clear sanity …","Parse an expression tree into a descriptor.","Parse an expression tree into a Miniscript. As a general …","","","","","","","Returns child node with given index, if any","Returns Option::Some with cloned n’th public key from …","Returns satisfying non-malleable witness and scriptSig to …","Returns a possilbly mallable satisfying non-malleable …","Whether the miniscript contains a combination of timelocks","Whether the miniscript has repeated Pk or Pkh","Whether or not the descriptor has any wildcards i.e. /*.","","","","","","","","","","","","","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Extracts the AstElem representing the root of the …","Convert to wallet descriptor","","Whether or not the descriptor has any wildcards","Whether the miniscript is malleable","Creates a new Iter iterator that will iterate over all …","Creates a new PkIter iterator that will iterate over all …","","","Lifting corresponds conversion of miniscript into Policy […","Compares this key with a keysource and returns the …","Depending on script context, the size of a satifaction …","","","Maximum size, in bytes, of a satisfying witness. For …","Computes an upper bound on the weight of a satisfying …","Maximum number of witness elements used to satisfy the …","Local helper function to display error messages with …","","","Create a new bare descriptor from witness script Errors …","Create a new pk descriptor","Create a new PkH descriptor","Create a new sh for a given redeem script Errors when …","Create a new sh sortedmulti descriptor with threshold k …","Create a new sh wrapper for the given wpkh descriptor","Create a new sh wrapper for the given wsh descriptor","Create a new sh wrapped wpkh from Pk. Errors when …","Create a new sh wrapped wsh descriptor with witness script …","Create a new sh wrapped wsh sortedmulti descriptor from …","Create new tr descriptor Errors when miniscript exceeds …","Create a new Wpkh descriptor Will return Err if …","Create a new wsh descriptor from witness script Errors …","Create a new wsh sorted multi descriptor Errors when …","A node in the Abstract Syntax Tree(","Origin information","Other top level checks that are context specific","Attempt to parse a Script into Miniscript representation.","Parse a descriptor that may contain secret keys","Attempt to parse an insane(scripts don’t clear sanity …","Attempt to parse an miniscript with extra features that …","","","","","","","Get the len of public key when serialized based on context …","","","Descriptor policy","Whether all spend paths of miniscript require a signature","Checks whether the descriptor is safe.","Check whether the underlying Miniscript is safe under the …","Attempts to produce a non-malleable satisfying witness and …","Attempt to produce non-malleable satisfying witness for the","Attempt to produce a malleable satisfying witness for the …","Computes the scriptCode of a transaction output.","Computes the scriptpubkey of the descriptor.","Size, in bytes of the script-pubkey. If this Miniscript is …","","","The type of signature required for satisfaction","","","Descriptor templates","","","","","","","","","Serialize a descriptor to string with its secret keys","Check top level consensus rules.","Check whether the top-level is type B","Converts a descriptor using abstract keys to one using …","Translates a struct from one generic to another where the …","","","","","","","","","","","","","The correctness and malleability type information for the …","","","","","","","Computes the scriptSig that will be in place for an …","","","","","","","Whether the descriptor is wildcard","Whether the miniscript can exceed the resource …","The extended key","Compute the checksum of a descriptor, excludes any …","Compute the checksum bytes of a descriptor, excludes any …","Compute the checksum of a descriptor","Compute the checksum bytes of a descriptor","Error during base58 decoding","BIP32 error","Errors related to the parsing and usage of descriptors","The descriptor contains hardened derivation steps on …","Hex decoding error","Invalid byte found in the descriptor checksum","The provided descriptor doesn’t match its checksum","Invalid HD Key path, such as having a wildcard but a …","Error thrown while working with keys","Miniscript error","Key-related error","Error while extracting and manipulating policies","","","","","","","","","","","Returns the argument unchanged.","","","","","","Calls U::from(self).","","","","","","","Absolute timeclock timestamp","Can not add to an item that is Satisfaction::None or …","Can not add to an item that is …","Options to build the satisfaction field in the policy","Can satisfy the policy item","An extra condition that must be satisfied but that is out …","Type for a map of sets of Condition items keyed by each set…","ECDSA Signature for a raw public key","An extended key fingerprint","Type for a map of folded sets of Condition items keyed by …","SHA256 then RIPEMD160 preimage hash","Double SHA256 preimage hash","Incompatible conditions (not currently used)","Index out of range for an item to satisfy a …","Can not merge CSV or timelock values unless both are less …","Multi-signature public keys with threshold count","Cannot satisfy or contribute to the policy item","Don’t generate satisfaction field","Not enough items are selected to satisfy a …","Only a partial satisfaction of some kind of threshold …","Can reach the threshold of some kind of threshold policy","A unique identifier for a key","Descriptor spending policy","Errors that can happen while extracting and manipulating …","Analyze the given PSBT to check for existing signatures","Like Psbt variant and also check for expired timelocks","A legacy public key","Relative timelock locktime","RIPEMD160 preimage hash","Represent if and how much a policy item is satisfied by …","An item that needs to be satisfied","Schnorr Signature for a raw public key","SHA256 preimage hash","Threshold items with threshold count","A x-only public key","","","","","","","","","","","","","","","","","","","","","","","","","","","How the wallet’s descriptor can satisfy this policy node","Optional CheckSequenceVerify condition","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","Returns the argument unchanged.","Returns the argument unchanged.","","Returns the argument unchanged.","","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Return the conditions that are set by the spending policy …","","","","","Returns a unique id for the SatisfiableItem","Identifier for this policy node","","","","","","","","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Returns whether the SatisfiableItem is a leaf item","Returns whether the Satisfaction is a leaf item","Returns true if there are no extra conditions to verify","Type of this policy node","","","Return whether or not a specific path in the policy tree …","How much a given PSBT already satisfies this policy node …","","","","","","Optional timelock condition","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","Current blockchain height","The highest confirmation height between the inputs CSV …","Given PSBT","Extra conditions that also need to be satisfied","Extra conditions that also need to be satisfied","Extra conditions that also need to be satisfied","The items that can be satisfied by the descriptor or are …","The items that can be satisfied by the descriptor","Threshold","Threshold","Total number of items","Total number of items","Whether the items are sorted in lexicographic order (used …","Whether the items are sorted in lexicographic order (used …","The digest value","The digest value","The digest value","The digest value","The policy items","The raw public key or extended key fingerprint","The required threshold count","The required threshold count","The timelock value","The timelock value","BIP44 template. Expands to pkh(key/44'/{0,1}'/0'/{0,1}/*)","BIP44 public template. Expands to pkh(key/{0,1}/*)","BIP49 template. Expands to …","BIP49 public template. Expands to sh(wpkh(key/{0,1}/*))","BIP84 template. Expands to wpkh(key/84'/{0,1}'/0'/{0,1}/*)","BIP84 public template. Expands to wpkh(key/{0,1}/*)","Trait for descriptor templates that can be built into a …","Type alias for the return type of DescriptorTemplate, …","P2PKH template. Expands to a descriptor pkh(key)","P2WPKH template. Expands to a descriptor wpkh(key)","P2WPKH-P2SH template. Expands to a descriptor sh(wpkh(key))","","","","","","","","","","","","","","","","","","","Build the complete descriptor","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","","","","","","","","","","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","BIP32 error","Trait for keys that can be derived.","Container for public or secret keys","The descriptor pubkey, either a single pubkey or an xpub.","The descriptor secret key, either a single private key or …","Type specifying the amount of entropy required e.g. [u8;32]","Returned error in case of failure","Trait that adds extra useful methods to ScriptContexts","Enum for extended keys that can be either xprv or xpub","A bitcoin public key (compressed or uncompressed).","Trait that allows generating a key with the default options","Trait for keys that can be generated","Output of a GeneratableKey key generation","Trait for objects that can be turned into a public or …","The key has an invalid checksum","The key is not valid for the given network","The key cannot exist in the given script context","The consensus key associated with the type. Must be a …","Errors thrown while working with keys","Alias type for a map of public key to secret key","Legacy scripts","Custom error message","Miniscript error","Extra options required by the generate_with_entropy","A private extended key, aka an xprv","Options for generating a PrivateKey","A public extended key, aka an xpub","The ScriptContext for Miniscript. Additional type …","Enum representation of the known valid ScriptContexts","Segwitv0 scripts","Single public key.","Single private key.","A descriptor bitcoin::PrivateKey with optional origin …","A descriptor SinglePubKey with optional origin information.","Single public key without any origin or range information.","Contents of a “sortedmulti” descriptor","Taproot scripts","Set of valid networks for a key","An xonly public key.","Extended private key (xpriv).","Extended public key (xpub).","Create a set containing mainnet, testnet and regtest","Returns the ScriptContext as a ScriptContextEnum","Replaces any wildcard (i.e. /*) in the key with a …","BIP-0039","","","","","","","","","","","","","","","","","","","","","","","","","Depending on script Context, some of the Terminals might …","Depending on script Context, some of the script resource …","Check the consensus + policy(if not disabled) rules that …","Consensus rules at the Miniscript satisfaction time. It is …","Policy rules at the Miniscript satisfaction time. It is …","Check the consensus + policy(if not disabled) rules …","Depending on ScriptContext, fragments can be malleable. …","Check whether the given satisfaction is valid under the …","","","","","","","","","","","","","","","","","","","Whether the generated key should be “compressed” or not","","","","","","","","","","","","","","","","","","","","","","","","","","","Deprecated name of [at_derivation_index].","","","","","","","","","","","","","Encode as a Bitcoin script","","","","","","","","","","","","","","","","","","","","","","","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","","","Returns the argument unchanged.","Create an instance given a public key and a set of valid …","Create an instance given a secret key and a set of valid …","","","Parse an expression tree into a SortedMultiVec","Full path, from the master key","Generate a key given the options with a random entropy","Generate a key with the default options and a random …","Generate a key given the extra options and the entropy","Generate a key with the default options and a given entropy","","","","","Return whether or not the key contains the private data","Whether or not the key has a wildcard","","","","","","","","","","","","","","","","","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Turn the key into a DescriptorKey within the requested …","Consume self and turn it into a DescriptorKey by adding …","","","","","","Consume self and turn it into an ExtendedKey","","","Consumes self and returns the key","Transform the ExtendedKey into an ExtendedPrivKey for the …","Transform the ExtendedKey into an ExtendedPubKey for the …","Whether or not the key has a wildcard","Returns whether the script context is Legacy","Returns whether the script context is …","Returns whether the script context is Segwitv0","Returns whether the script context is …","Returns whether the script context is Tap, aka Taproot or …","Returns whether the script context is …","","","signatures required","The public key.","The private key.","","Create a set only containing mainnet","The fingerprint of the master key associated with this …","Depending on script context, the size of a satifaction …","Maximum size, in bytes, of a satisfying witness. In …","Maximum number of witness elements used to satisfy the …","Compute the intersection of two sets","Local helper function to display error messages with …","Create a new instance of SortedMultiVec given a list of …","Origin information (fingerprint and derivation path).","Origin information (fingerprint and derivation path).","Other top level checks that are context specific","Override the computed set of valid networks","","","","","Get the len of public key when serialized based on context …","public keys inside sorted Multi","","utility function to sanity a sorted multi vec","Attempt to produce a satisfying witness for the witness …","Size, in bytes of the script-pubkey. If this Miniscript is …","The type of signature required for satisfaction","Create Terminal::Multi containing sorted pubkeys","Create a set containing testnet and regtest","","","","","","","","Returns the public version of this key.","","","","","Check top level consensus rules.","Check whether the top-level is type B","This will panic if fpk returns an uncompressed key when …","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","The mnemonic can be interpreted as multiple languages. Use …","Entropy was not a multiple of 32 bits or between 128-256n …","Mnemonic has a word count that is not a multiple of 6.","The English language.","A BIP39 error.","The mnemonic has an invalid checksum.","Language to be used for the mnemonic phrase.","A mnemonic code.","Type for a BIP39 mnemonic with an optional passphrase","Mnemonic contains an unknown word. Error contains the …","Type describing entropy length (aka word count) in the …","12 words mnemonic (128 bits entropy)","15 words mnemonic (160 bits entropy)","18 words mnemonic (192 bits entropy)","21 words mnemonic (224 bits entropy)","24 words mnemonic (256 bits entropy)","The list of supported languages. Language support is …","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Create a new English Mnemonic from the given entropy. …","Create a new Mnemonic in the specified language from the …","","Generate a new Mnemonic in the given language with the …","","","","","","","","","","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","","","","","Get the language of the Mnemonic.","Determine the language of the mnemonic.","Parse a mnemonic and detect the language from the enabled …","Parse a mnemonic in the given language.","Parse a mnemonic in normalized UTF8 in the given language.","Parse a mnemonic in normalized UTF8.","","","","","Convert the mnemonic back to the entropy used to generate …","Convert the mnemonic back to the entropy used to generate …","","","","Convert to seed bytes.","Convert to seed bytes with a passphrase in normalized UTF8.","","","","","","","","","","","","","","","","","","","","Get the number of words in the mnemonic.","Get an iterator over the words.","Get words from the word list that start with the given …","Trait to add functions to extract utxos and calculate fees.","The total transaction fee amount, sum of input amounts …","The transaction’s fee rate. This value will only be …","Get the TxOut for the specified input index, if it doesn’…","The address index selection strategy to use to derived an …","A derived address and the index it was found at For …","Trait to check if a value is below the dust limit. We are …","Return the address for the current descriptor index if it …","Return a new address after incrementing the current …","Return the address for a specific descriptor index. Does …","Return the address for a specific descriptor index and …","Options to a sync.","A Bitcoin wallet","Add an external signer","Address","","","","","","","","","Bump the fee of a transaction previously created with this …","Start building a transaction.","Coin selection","Return an immutable reference to the internal database","","","","","","","","","","","Return the checksum of the public descriptor associated to …","","","","","Ensures that there are at least max_addresses addresses …","","Wallet export","Finalize a PSBT, i.e., for each input determine if …","","","","","","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Return a derived address using the external descriptor, …","Return the balance, separated into available, …","Returns the descriptor used to create addresses for a …","Return a fake wallet that appears to be funded for testing.","Return a derived address using the internal (change) …","get the corresponding PSBT Input for a LocalUtxo","Get the signers","Return a single transactions made and received by the …","Returns the UTXO owned by this wallet corresponding to …","HWI Signer","Child index of this address","","","","","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Check whether or not a value is below dust limit","Return whether or not a script is part of this wallet …","Type of keychain","Return an unsorted list of transactions made and received …","Return the list of unspent outputs of this wallet","Get the Bitcoin network the wallet is using.","Create a wallet.","Create a new “offline” wallet","Return the spending policies for the wallet’s descriptor","The progress tracker which may be informed when progress …","Return the “public” version of the wallet’s …","Return the secp256k1 context used for all signing …","Sign a transaction with all the wallet’s signers, in the …","Generalized signers","Sync the internal database with the blockchain","Cross-platform time","","","","","","","","","","Transaction builder","","","","","Verify transactions against the consensus rules","","","","","Deterministically generate a unique name given the …","Branch and bound coin selection","It’s possible to create spendable output from excess …","Trait for generalized coin selection algorithms","Result of a successful coin selection","Default coin selection algorithm used by TxBuilder if not …","Remaining amount after performing coin selection","Simple and dumb coin selection","It’s not possible to create spendable output from excess …","OldestFirstCoinSelection always picks the utxo with the …","","","","","","","","","","","","","","","Perform the coin selection","","","","Decide if change can be created","","","","","","","","","","","","","","","","","","","Remaining amount after deducing fees and outgoing outputs","Total fee amount for the selected utxos in satoshis","","","","","","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","","","","","","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","The total value of the inputs selected from the local …","Create new instance with target size for change output","List of outputs selected for use as inputs","The total value of the inputs selected.","","","","","","","","","","","","","","","","","","","","","","","Effective amount available to create change after …","The calculated fee for the drain TxOut with the selected …","Threshold to consider amount as dust for this particular …","The deducted change output fee","Exceeding amount of current selection over outgoing value …","Structure that contains the export of a wallet","Alias for FullyNodedExport","Earliest block to rescan when looking for the wallet’s …","","","Return the internal descriptor, if present","","","Return the external descriptor","","","Export a wallet","","Returns the argument unchanged.","","","Calls U::from(self).","Arbitrary label for the wallet","","","","","","","Custom signer for Hardware Wallets","","","","","","","Returns the argument unchanged.","Create a instance from the specified device and chain","","","Calls U::from(self).","","","","","","The signer will sign all the leaves it has a key for.","Dummy identifier","The signer won’t sign the specified leaves.","The fingerprint of a BIP32 extended key","Error while signing using hardware wallets","The signer won’t sign leaves other than the ones …","Input index is out of range","PSBT Input signer","The private key in use has the right fingerprint but …","The non_witness_utxo specified is invalid","Invalid SIGHASH for the signing context in use","Legacy context","The fingerprint and derivation path are missing from the …","The private key is missing for the required public key","The non_witness_utxo field of the transaction is required …","The witness_script field of the transaction is required to …","The witness_utxo field of the transaction is required to …","The psbt contains a non-SIGHASH_ALL sighash in one of its …","The signer won’t sign any leaf.","Bitcoin HASH160 (RIPEMD160 after SHA256) hash of an ECDSA …","Segwit v0 context (BIP 143)","Error while computing the hash to sign","Options for a software signer","Common signer methods","Signing context","Signing error","Identifier of a signer in the SignersContainers. Used as a …","Defines the order in which signers are called","Wrapper structure to pair a signer with its context","Container for multiple signers","Taproot context (BIP 340)","Customize which taproot script-path leaves the signer …","PSBT signer","The user canceled the operation","Adds an external signer to the container for the specified …","Whether the signer should use the sighash_type set in the …","Whether we should grind ECDSA signature to ensure signing …","Create a map of public keys to secret keys","Whether the wallet should assume a specific height has …","","","","","","","","","","","","","","","","","Build a new signer container from a KeyMap","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","Return the secret key for the signer","","","","","","","","","","","","","","","","Finds the signer with lowest ordering for a given id in …","","","","","","","","","","","Returns the argument unchanged.","","","Returns the argument unchanged.","","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","","","Return the SignerId for this signer","","","Returns the list of identifiers of all the signers in the …","","","","","","","","","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Create a wrapped signer from a signer and a context","Default constructor","","","","Removes a signer from the container and returns it","Whether to remove partial signatures from the PSBT inputs …","Sign a single psbt input","","","Sign all the inputs of the psbt","","Whether we should try to sign a taproot transaction with …","Returns the list of signers in the container, sorted by …","Specifies which Taproot script-spend leaves we should sign …","","","","","","","","","","Whether the signer should trust the witness_utxo, if the …","Whether to try finalizing the PSBT after the inputs are …","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","Whether the signer can sign for the internal key or not","Return the current timestamp in seconds","BIP69 / Lexicographic","Marker type to indicate the TxBuilder is being used to …","Use both change and non-change outputs (default)","Only use non-change outputs (see …","Policy regarding the use of change outputs when creating a …","Marker type to indicate the TxBuilder is being used to …","Only use change outputs (see TxBuilder::only_spend_change)","Randomized (default)","A transaction builder","Context in which the TxBuilder is valid","Ordering of the transaction’s inputs and outputs","Unchanged","Add data as an output, using OP_RETURN","Add a foreign UTXO i.e. a UTXO not owned by this wallet.","Fill-in the PSBT_GLOBAL_XPUB field with the extended keys …","Add a recipient to the internal list","Add a utxo to the internal list of unspendable utxos","Add a utxo to the internal list of utxos that must be spent","Add the list of outpoints to the internal list of UTXOs …","Set whether or not the dust limit is checked.","Explicitly tells the wallet that it is allowed to reduce …","","","","","","","","","","","Set a specific ChangeSpendPolicy. See …","","","","","","","","","","","","","Choose the coin selection algorithm","Set the current blockchain height.","","","","","","","","","","","","","","","Do not spend change outputs","Sets the address to drain excess coins to.","Spend all the available inputs. This respects filters like …","","","","","","Enable signaling RBF","Enable signaling RBF with a specific nSequence value","","","Set an absolute fee","Set a custom fee rate","Finish building the transaction.","","","","","","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","","","","","Fill-in the psbt::Output::redeem_script and …","","","","","","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Only spend utxos added by add_utxo.","Use a specific nLockTime while creating the transaction","Only spend change outputs","Only Fill-in the psbt::Input::witness_utxo field when …","Choose the ordering for inputs and outputs of the …","","","Set the policy path to use while creating the transaction …","Replace the recipients already added with a new list","Sign with a specific sig hash","Sort transaction inputs and outputs by TxOrdering variant","","","","","","","","","","","","","","","","","","","","","Replace the internal list of unspendable utxos with a new …","Build a transaction with a specific version","","","","","","Consensus error","Generic error","The transaction being spent doesn’t have the requested …","The transaction being spent is not available in the …","Error during validation of a tx agains the consensus rules","","","","","","","","","Returns the argument unchanged.","","","Calls U::from(self).","","","","","","Verify a transaction against the consensus rules",""],"i":[0,18,0,18,18,18,18,0,18,18,18,0,18,2,0,18,18,18,13,18,0,18,18,2,18,18,18,18,18,18,18,18,0,13,0,18,18,18,18,18,18,18,18,18,18,18,18,18,18,0,18,18,18,0,18,0,18,0,18,0,0,18,0,0,1,2,2,4,2,0,18,2,4,11,12,13,14,15,1,18,2,4,11,12,13,14,15,1,2,2,4,11,12,13,14,15,1,2,4,11,12,13,14,15,1,14,1,0,4,15,1,4,18,2,4,11,12,13,14,15,1,18,2,4,11,12,13,14,15,1,0,0,2,11,14,15,1,18,2,4,11,12,13,14,15,1,2,4,11,12,13,14,15,1,14,4,4,18,18,2,4,11,12,13,14,15,1,1,0,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,2,4,11,12,13,14,15,15,1,4,4,4,4,4,4,2,11,1,1,2,11,15,1,18,2,4,11,12,13,14,15,1,18,2,4,11,12,13,14,15,1,11,11,0,15,13,11,4,18,0,14,12,14,2,11,14,15,1,0,4,1,0,15,2,4,11,12,13,14,15,1,18,1,14,1,18,2,4,11,12,13,14,15,1,18,2,4,11,12,13,14,15,1,14,13,11,18,2,4,11,12,13,14,15,1,1,12,231,0,18,2,4,11,12,13,14,15,1,0,2,232,233,232,233,234,235,236,236,53,0,0,0,0,0,0,237,0,0,0,0,53,53,0,0,0,238,0,0,0,0,0,0,0,0,0,53,54,55,53,54,55,239,238,238,53,54,55,53,54,55,0,54,55,53,54,55,53,54,55,53,54,55,0,53,0,239,53,54,55,53,54,55,237,240,239,53,241,242,53,53,54,55,53,54,55,0,0,0,0,238,53,54,55,53,54,55,53,54,55,53,54,55,60,54,55,53,54,55,243,243,0,0,62,63,62,63,62,63,62,63,62,63,62,63,62,63,63,62,63,62,63,63,62,63,63,62,63,62,62,62,62,62,63,63,63,63,63,62,62,62,62,62,62,63,62,63,63,63,62,63,62,63,62,63,62,63,62,62,36,0,36,0,0,0,36,36,36,36,36,36,36,36,0,36,36,36,0,36,36,36,72,73,72,77,66,73,69,36,72,77,66,73,69,36,66,73,69,73,69,77,77,72,72,77,66,73,69,36,72,77,66,73,69,36,73,69,72,77,66,73,69,36,73,69,66,72,77,66,73,69,36,36,72,77,66,73,69,36,36,36,36,36,36,66,66,66,66,77,77,72,66,77,72,72,77,66,73,69,36,72,77,66,73,69,36,77,72,69,72,66,69,36,77,77,73,69,69,73,73,69,73,69,36,72,77,66,73,69,36,72,77,66,73,69,36,72,77,66,73,69,36,72,77,66,73,69,36,66,0,0,64,71,64,71,64,71,71,64,64,71,64,71,71,64,71,71,64,71,64,64,71,64,64,64,64,64,64,71,64,71,71,71,71,71,71,71,64,71,64,71,64,71,71,64,71,64,26,0,0,0,26,26,26,26,26,26,26,26,26,26,70,26,65,70,26,65,70,65,70,70,70,26,65,65,70,26,65,70,70,26,65,70,70,65,26,26,65,70,26,26,26,26,26,26,26,65,70,65,65,65,65,65,65,26,65,70,26,65,70,65,70,26,70,70,70,70,70,26,26,65,70,26,65,70,26,65,70,26,65,70,65,65,0,97,97,0,0,0,0,97,68,95,67,68,96,97,95,67,68,96,97,95,67,95,68,96,97,95,68,96,97,95,97,96,95,67,67,68,96,97,95,67,68,96,97,95,68,96,97,67,68,96,97,95,68,96,97,67,67,68,96,97,95,96,67,68,96,97,95,67,67,67,97,67,67,97,67,68,96,97,95,67,68,96,97,95,68,95,97,96,68,96,97,96,96,68,95,68,96,97,95,67,68,96,97,95,67,68,96,97,95,67,68,96,97,95,68,95,67,68,96,97,95,68,95,67,244,245,245,0,0,222,0,0,246,0,0,0,0,0,0,222,98,99,98,99,98,99,247,98,99,99,222,98,98,248,98,248,98,248,98,248,98,248,98,248,98,248,98,98,99,98,99,99,98,99,98,99,98,99,246,98,247,98,247,98,247,98,247,98,247,98,247,98,247,98,247,98,98,99,98,99,247,98,247,98,247,98,247,98,0,98,98,99,248,98,248,98,248,98,248,98,248,98,248,98,99,98,99,98,99,98,99,98,99,0,0,0,102,101,105,102,101,105,0,102,101,105,0,101,102,101,103,104,105,102,101,103,104,105,101,101,102,101,102,101,102,101,102,101,102,101,102,101,102,101,102,101,103,104,105,102,101,103,104,105,103,104,105,102,101,103,104,105,101,103,104,105,102,102,102,102,101,101,101,101,103,104,105,105,105,105,101,101,101,101,101,101,101,101,101,102,101,103,104,105,102,101,103,104,105,101,101,101,101,103,104,103,104,105,102,101,102,101,102,101,102,101,102,101,102,101,103,102,101,103,104,105,102,101,103,104,105,102,101,103,104,105,102,101,103,104,105,0,106,106,106,106,106,106,106,106,106,106,106,106,106,106,106,106,106,106,106,106,106,106,106,106,106,106,106,106,106,106,106,106,106,106,106,106,106,106,106,106,106,106,106,106,108,0,0,0,0,0,0,0,117,0,0,129,0,0,0,117,108,0,0,0,108,113,0,108,117,0,108,108,113,108,118,119,111,108,116,117,108,118,119,111,116,117,108,118,119,111,111,0,129,118,119,129,119,129,129,118,119,129,118,119,129,129,118,119,129,118,119,0,116,117,108,118,119,111,116,117,108,118,119,111,116,117,108,118,119,111,111,116,117,108,118,119,111,116,117,108,118,119,111,116,108,108,108,108,108,111,116,117,108,118,119,111,111,116,117,108,118,119,111,0,108,111,111,249,108,111,108,116,117,108,108,118,119,111,111,108,111,116,117,108,108,108,108,108,108,108,118,119,111,111,108,111,111,111,108,111,116,117,108,118,119,111,111,111,108,108,111,111,108,116,117,108,118,119,111,116,117,108,118,119,111,116,117,108,118,119,111,111,202,138,108,111,111,111,108,111,111,116,129,118,119,111,108,111,129,118,119,108,108,108,108,108,108,108,108,108,108,108,108,108,108,111,116,129,111,108,111,111,116,117,108,118,119,111,129,118,119,0,111,108,111,108,111,111,108,108,111,108,111,129,118,119,0,116,117,108,118,119,111,108,111,108,129,129,108,111,116,117,108,118,119,111,116,117,108,118,119,111,111,116,117,108,118,119,111,108,116,117,108,118,119,111,116,111,116,0,0,0,0,29,29,0,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,152,28,28,0,153,0,0,152,151,0,152,152,28,28,28,152,153,127,28,153,153,0,0,0,127,127,151,152,152,0,0,152,152,152,151,151,152,153,128,154,28,127,151,152,153,128,154,28,127,151,152,153,128,154,127,151,152,153,128,154,127,128,154,154,151,152,153,128,154,28,127,151,152,153,128,154,28,127,151,152,153,128,154,28,127,151,152,153,128,154,28,151,152,153,128,154,28,28,127,151,152,153,153,128,128,154,28,127,128,151,154,151,154,152,128,151,152,153,128,154,28,127,151,152,153,128,154,28,127,152,153,154,128,154,28,128,128,151,152,153,128,154,154,151,152,153,128,154,127,28,151,152,153,128,154,28,127,151,152,153,128,154,28,127,151,152,153,128,154,28,127,151,152,153,128,154,28,127,250,250,250,251,252,253,252,253,252,253,252,253,252,253,254,255,256,257,258,259,259,258,260,261,0,0,0,0,0,0,0,0,0,0,0,158,159,160,162,163,164,165,166,167,158,159,160,162,163,164,165,166,167,262,158,159,160,162,163,164,165,166,167,158,159,160,162,163,164,165,166,167,158,159,160,162,163,164,165,166,167,158,159,160,162,163,164,165,166,167,158,159,160,162,163,164,165,166,167,158,159,160,162,163,164,165,166,167,158,159,160,162,163,164,165,166,167,156,158,159,160,162,163,164,165,166,167,158,159,160,162,163,164,165,166,167,158,159,160,162,163,164,165,166,167,158,159,160,162,163,164,165,166,167,158,159,160,162,163,164,165,166,167,21,0,0,0,0,263,263,0,0,173,0,0,0,0,21,21,21,129,0,0,110,21,21,263,180,0,180,0,0,110,113,175,0,0,0,0,110,0,173,175,113,0,264,113,0,180,170,171,113,175,172,176,173,178,110,174,21,180,170,171,113,175,172,176,173,178,110,174,21,129,129,129,129,129,129,129,129,170,171,113,172,173,110,174,170,171,113,172,173,110,174,171,113,172,173,174,174,180,170,170,171,113,175,172,176,173,178,110,174,21,180,170,171,113,175,172,176,173,178,110,174,21,113,180,170,171,113,175,172,176,173,178,110,174,21,171,171,113,172,173,110,171,171,113,113,175,175,172,176,173,178,110,174,21,21,171,180,180,180,170,171,113,113,175,172,176,173,178,110,174,21,21,21,178,178,113,175,171,113,263,265,263,265,171,113,172,173,180,113,171,113,172,173,180,170,171,113,175,172,176,173,178,110,174,21,180,170,171,113,175,172,176,173,178,110,174,21,157,161,170,170,113,175,178,161,180,170,170,180,180,113,264,110,264,110,264,110,113,113,171,172,176,171,0,113,129,171,171,0,129,171,172,176,129,178,171,113,172,173,129,171,21,171,171,171,129,171,0,170,171,113,172,173,110,174,175,171,113,175,21,129,129,171,180,170,171,113,175,172,176,173,178,110,174,21,180,170,171,113,175,172,176,173,178,110,174,21,180,170,171,113,175,172,176,173,178,110,174,21,180,170,171,113,175,172,176,173,178,110,174,21,186,186,186,185,0,186,0,0,0,186,0,266,266,266,266,266,185,185,186,187,266,185,186,187,266,185,186,187,185,186,187,185,187,185,186,187,266,185,186,187,266,187,185,186,187,266,185,186,187,185,185,186,186,187,187,185,186,187,266,187,187,187,187,187,185,187,185,187,185,186,187,266,185,186,187,266,187,188,187,188,187,187,187,187,187,187,185,187,186,187,187,187,185,186,187,187,187,185,186,187,185,186,187,266,185,186,187,266,185,186,187,266,185,186,187,266,187,187,185,0,267,267,267,0,0,0,199,199,199,199,0,0,52,196,52,199,196,59,52,199,196,59,52,52,0,52,59,52,199,196,196,59,52,199,196,59,52,52,199,196,59,52,196,0,52,52,199,196,196,59,52,199,196,59,52,52,52,0,52,52,52,52,52,0,196,52,199,196,59,52,199,196,59,268,52,196,52,52,52,52,52,52,59,52,52,52,0,52,0,196,52,199,196,59,52,199,196,59,0,52,199,196,59,0,52,199,196,59,0,0,207,0,0,0,0,0,207,0,207,205,203,204,206,207,205,203,204,206,203,204,203,204,223,203,204,206,0,203,204,206,207,205,203,204,206,207,205,203,204,206,207,205,203,204,206,205,205,207,205,203,204,206,207,205,203,204,206,207,205,203,204,206,207,205,203,204,206,205,206,205,205,203,204,207,205,203,204,206,207,205,203,204,206,207,205,203,204,206,207,205,203,204,206,269,270,270,269,270,0,0,208,208,208,208,208,208,208,208,208,208,208,208,208,208,208,208,208,208,208,208,208,208,0,209,209,209,209,209,209,209,209,209,209,209,209,209,209,209,209,218,213,218,213,27,218,27,0,27,27,27,215,27,27,27,27,27,27,218,213,215,27,0,0,0,0,0,0,0,0,215,0,0,27,126,198,198,126,198,213,27,215,217,189,126,198,218,213,27,215,217,189,126,198,218,126,213,27,215,217,189,126,198,218,213,27,215,217,189,126,198,218,213,189,189,126,198,218,213,27,215,217,217,189,126,198,218,213,27,215,217,189,126,198,218,271,217,217,213,27,215,217,189,126,198,218,213,27,215,189,218,126,213,27,27,215,217,189,126,198,218,213,213,213,27,27,27,215,217,189,126,198,218,213,213,271,217,217,126,213,27,215,217,189,126,198,218,213,27,215,217,189,126,198,218,217,126,213,189,27,126,198,272,217,217,190,217,198,126,198,213,27,215,217,189,126,198,218,27,198,198,213,27,215,217,189,126,198,218,213,27,215,217,189,126,198,218,213,27,215,217,189,126,198,218,213,27,215,217,189,126,198,218,273,0,226,0,225,225,0,0,225,226,0,0,0,226,193,193,193,193,193,193,193,193,193,194,192,193,226,225,194,192,193,226,225,193,194,192,193,226,225,194,192,193,226,225,226,225,193,193,194,192,226,225,194,192,193,226,225,194,192,193,226,225,193,193,193,194,192,193,226,225,193,193,226,225,193,193,193,194,192,193,226,225,194,192,193,226,225,226,225,226,225,193,194,192,193,226,225,194,192,193,226,225,193,193,193,193,193,226,225,193,193,193,226,194,192,193,226,225,194,192,193,226,225,194,192,193,226,225,194,192,193,226,225,193,193,194,192,193,226,225,33,33,33,33,0,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,0,33],"f":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,[[1,1],1],[2,3],[2],[4,5],[[],6],0,[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[],[[10,[[9,[7,8]]]]]],[2,2],[4,4],[11,11],[12,12],[13,13],[14,14],[15,15],[1,1],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],0,0,0,[[],4],[[],15],[[],1],[[],4],[6],[6],[6],[6],[6],[6],[6],[6],[6],[6],[6],[6],[6],[6],[6],[6],[6],[6],0,0,[[],[[10,[2]]]],[[],[[10,[11]]]],[[],[[10,[14]]]],[[],[[10,[15]]]],[[],[[10,[1]]]],[6],[6],[6],[6],[6],[6],[6],[6],[6],[[2,2],16],[[4,4],16],[[11,11],16],[[12,12],16],[[13,13],16],[[14,14],16],[[15,15],16],[[1,1],16],0,[[4,6],17],[[4,6],17],[[18,19],20],[[18,19],20],[[2,19],20],[[4,19],20],[[11,19],20],[[12,19],20],[[13,19],20],[[14,19],20],[[15,19],20],[[1,19],20],[[1,19],20],0,[21,18],[22,18],[23,18],[24,18],[25,18],[26,18],[27,18],[28,18],[29,18],[30,18],[31,18],[32,18],[33,18],[34,18],[35,18],[36,18],[[]],[37,18],[38,18],[39,18],[[]],[[]],[[]],[[]],[[]],[[]],[40,15],[[]],[[]],[5,4],[5,4],[5,4],[5,4],[[17,6],4],[[17,6],4],[[],17],[[],17],[1,17],[1,17],[2],[11],0,0,[[],6],[[],6],[[],6],[[],6],[[],6],[[],6],[[],6],[[],6],[[],6],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],0,0,0,[[[42,[41]],[42,[17]]],[[42,[15]]]],[13,43],0,[[4,4],[[42,[44]]]],[45],0,0,0,0,[2,10],[11,10],[14,10],[15,10],[1,10],0,[[4,4]],[46,1],0,0,[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[],47],[[],47],0,0,[[],10],[[],10],[[],10],[[],10],[[],10],[[],10],[[],10],[[],10],[[],10],[[],10],[[],10],[[],10],[[],10],[[],10],[[],10],[[],10],[[],10],[[],10],0,[13,48],0,[[],49],[[],49],[[],49],[[],49],[[],49],[[],49],[[],49],[[],49],[[],49],0,0,[[],6],[[],50],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],0,[[],10],0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,[[]],[[]],[[]],[[]],[[]],[[]],[51,[[10,[18]]]],[[50,[42,[41]]],[[10,[18]]]],[[52,[42,[41]]],[[10,[18]]]],[53,53],[54,54],[55,55],[[]],[[]],[[]],0,[[],54],[[],55],[6],[6],[6],[6],[6],[6],[6],[6],[6],0,[[53,53],16],0,[6,[[10,[4,18]]]],[[53,19],20],[[54,19],20],[[55,19],20],[[]],[[]],[[]],[[],[[10,[18]]]],[17,[[10,[56,18]]]],[[],[[57,[53]]]],[[],17],[[],[[10,[41,18]]]],[58,[[10,[[42,[51]],18]]]],[53],[[],6],[[],6],[[],6],[[]],[[]],[[]],[[],55],[[],54],[[]],0,[[52,[42,[41]],59],[[10,[18]]]],[[]],[[]],[[]],[[],10],[[],10],[[],10],[[],10],[[],10],[[],10],[[],49],[[],49],[[],49],[[5,[42,[47]]],[[10,[18]]]],[[54,5,[42,[47]]],[[10,[18]]]],[[55,5,[42,[47]]],[[10,[18]]]],[[]],[[]],[[]],[[[61,[60]]],[[10,[18]]]],[[[61,[60]]],[[10,[18]]]],0,0,0,0,0,0,0,0,0,0,[[]],[[]],[[]],[[]],[[62,51],[[10,[18]]]],[63,63],[[]],[6],[6],[6],[6],[[],[[10,[63]]]],[6],[6],[[63,63],16],[[62,6],[[10,[4,18]]]],[[63,19],20],[64,62],[65,62],[66,62],[[]],[67,62],[[]],[68,63],[69,63],[70,63],[71,63],[[],[[10,[62,18]]]],[[62,17],[[10,[56,18]]]],[62,[[57,[53]]]],[62,[[10,[41,18]]]],[[62,58],[[10,[[42,[51]],18]]]],[[],6],[[],6],[[]],[[]],[63,10],[[]],[[],10],[[],10],[[],10],[[],10],[[],49],[[],49],[[]],[[]],[[62,[61,[60]]],[[10,[18]]]],[[62,[61,[60]]],[[10,[18]]]],0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,[[72,51]],0,[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[66,51],[[10,[18]]]],[73,73],[69,69],[[]],[[]],[[74,[75,[72]],76],[[10,[77,36]]]],[[78,74,42,[75,[72]],76],[[10,[77,36]]]],[[],72],[6],[6],[6],[6],[6],[6],[6],[6],[6],[6],[6],[6],[[],[[10,[73]]]],[[],[[10,[69]]]],[6],[6],[6],[6],[6],[6],[[73,73],16],[[69,69],16],[[66,6],[[10,[4,18]]]],[[72,19],20],[[77,19],20],[[66,19],20],[[73,19],20],[[69,19],20],[[36,19],20],[[36,19],20],[[]],[[]],[[]],[[]],[[]],[79,36],[80,36],[81,36],[82,36],[18,36],[[]],[[],[[10,[66,18]]]],[[66,17],[[10,[56,18]]]],[66,[[57,[53]]]],[66,[[10,[41,18]]]],[77,[[75,[72]]]],[77,76],[[72,83],[[42,[51]]]],[[66,58],[[10,[[42,[51]],18]]]],[77,84],[[72,58],16],[[],6],[[],6],[[],6],[[],6],[[],6],[[],6],[[]],[[]],[[]],[[]],[[]],[[]],[77,16],[72,[[9,[51]]]],0,[[],72],[[[9,[77]],[86,[85]],[42,[6]]],[[10,[66,36]]]],0,[45],[[77,50,[42,[87]]],[[10,[[42,[88]],36]]]],[[77,88],[[10,[36]]]],[73,10],[69,10],0,0,0,0,[[]],[[]],[[],47],[[],10],[[],10],[[],10],[[],10],[[],10],[[],10],[[],10],[[],10],[[],10],[[],10],[[],10],[[],10],[[],49],[[],49],[[],49],[[],49],[[],49],[[],49],[[]],[[]],[[]],[[]],[[]],[[]],[[66,[61,[60]]],[[10,[18]]]],0,0,[[]],[[]],[[]],[[]],[[64,51],[[10,[18]]]],[71,71],[[]],[6],[64],[6],[6],[6],[[],[[10,[71]]]],[6],[6],[[71,71],16],[[64,6],[[10,[4,18]]]],[[71,19],20],[[]],[89,64],[[]],[[],[[10,[64,18]]]],[[64,17],[[10,[56,18]]]],[64,[[57,[53]]]],[64,[[10,[41,18]]]],[[64,58],[[10,[[42,[51]],18]]]],[[],6],[[],6],[[]],[[]],0,[71,10],0,0,0,[[]],[[],10],[[],10],[[],10],[[],10],[[],49],[[],49],0,[[]],[[]],[[64,[61,[60]]],[[10,[18]]]],0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,[[]],[[]],[[]],[[]],[[]],[[]],[[65,51],[[10,[18]]]],[70,70],[[]],0,[6],[65],[6],[6],[6],[6],[6],[[],[[10,[70]]]],[6],[6],[6],[[70,70],16],[[65,6],[[10,[4,18]]]],[[26,19],[[10,[90]]]],[[26,19],[[10,[90]]]],[[65,19],20],[[70,19],20],[[]],[91,26],[38,26],[81,26],[92,26],[93,26],[25,26],[[]],[[]],[[94,6],65],[[],[[10,[65,18]]]],[[65,17],[[10,[56,18]]]],[65,[[57,[53]]]],[65,[[10,[41,18]]]],[[65,58],[[10,[[42,[51]],18]]]],[[],6],[[],6],[[],6],[[]],[[]],[[]],[[50,6],65],[[47,6],70],[45],0,[70,10],0,0,[[]],[[],47],[[],10],[[],10],[[],10],[[],10],[[],10],[[],10],[[],49],[[],49],[[],49],[[]],[[]],[[]],[[65,[61,[60]]],[[10,[18]]]],[[65,3],65],0,0,0,0,0,0,0,0,0,0,[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[67,51],[[10,[18]]]],[[95,50,[42,[41]]],[[10,[18]]]],[68,68],[96,96],[97,97],[95,95],[[]],[[]],[[]],[[]],[[97,97],44],[[],96],0,[67],[6],[6],[6],[6],[6],[6],[6],[6],[6],[6],[[],[[10,[68]]]],[[],[[10,[96]]]],[[],[[10,[97]]]],[6],[6],[6],[6],[6],[[68,68],16],[[96,96],16],[[97,97],16],[[67,6],[[10,[4,18]]]],[[67,19],20],[[68,19],20],[[96,19],20],[[97,19],20],[[95,19],20],0,[[]],[[]],[[]],[[]],[[]],[[],[[10,[67,18]]]],[[67,17],[[10,[56,18]]]],[67,[[57,[53]]]],[[],17],[67,[[10,[41,18]]]],[[67,58],[[10,[[42,[51]],18]]]],[97],[[],6],[[],6],[[],6],[[],6],[[],6],[[]],[[]],[[]],[[]],[[]],0,0,[[97,97],[[42,[44]]]],0,[68,10],[96,10],[97,10],0,0,0,0,[[]],[[]],[[]],[[]],[[],10],[[],10],[[],10],[[],10],[[],10],[[],10],[[],10],[[],10],[[],10],[[],10],[[],49],[[],49],[[],49],[[],49],[[],49],0,0,[[]],[[]],[[]],[[]],[[]],0,0,[[67,[61,[60]]],[[10,[18]]]],0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,[[]],[98],0,[[]],[[]],[[]],[[]],[[2,86],[[10,[18]]]],[[98,2,86],[[10,[18]]]],[99,99],[[]],[[],[[10,[18]]]],[98,[[10,[18]]]],0,[2,[[10,[[42,[41]],18]]]],[[98,2],[[10,[[42,[41]],18]]]],[100,[[10,[42,18]]]],[[98,100],[[10,[42,18]]]],[58,[[10,[[42,[51]],18]]]],[[98,58],[[10,[[42,[51]],18]]]],[[2,41],[[10,[[42,[100]],18]]]],[[98,2,41],[[10,[[42,[100]],18]]]],[[],[[10,[[42,[99]],18]]]],[98,[[10,[[42,[99]],18]]]],[[58,16],[[10,[[42,[14]],18]]]],[[98,58,16],[[10,[[42,[14]],18]]]],[43,[[10,[[42,[11]],18]]]],[[98,43],[[10,[[42,[11]],18]]]],[6],[6],[6],[6],[[],[[10,[99]]]],[6],[6],[[98,19],20],[[99,19],20],[[]],[[]],[[],[[10,[18]]]],[[],[[10,[98,18]]]],[2,[[10,[[42,[41]],18]]]],[[98,2],[[10,[[42,[41]],18]]]],[100,[[10,[42,18]]]],[[98,100],[[10,[42,18]]]],[58,[[10,[[42,[51]],18]]]],[[98,58],[[10,[[42,[51]],18]]]],[[2,41],[[10,[[42,[100]],18]]]],[[98,2,41],[[10,[[42,[100]],18]]]],[[],[[10,[[42,[99]],18]]]],[98,[[10,[[42,[99]],18]]]],[[58,16],[[10,[[42,[14]],18]]]],[[98,58,16],[[10,[[42,[14]],18]]]],[43,[[10,[[42,[11]],18]]]],[[98,43],[[10,[[42,[11]],18]]]],[2,[[10,[41,18]]]],[[98,2],[[10,[41,18]]]],[[],6],[[],6],[[]],[[]],[[],[[10,[[9,[51]],18]]]],[98,[[10,[[9,[51]],18]]]],[[[42,[2]]],[[10,[[9,[100]],18]]]],[[98,[42,[2]]],[[10,[[9,[100]],18]]]],[16,[[10,[[9,[14]],18]]]],[[98,16],[[10,[[9,[14]],18]]]],[[],[[10,[[9,[11]],18]]]],[98,[[10,[[9,[11]],18]]]],0,[[[86,[85]]],98],0,[99,10],[[2,41],[[10,[18]]]],[[98,2,41],[[10,[18]]]],[51,[[10,[18]]]],[[98,51],[[10,[18]]]],[[100,2,41],[[10,[18]]]],[[98,100,2,41],[[10,[18]]]],[99,[[10,[18]]]],[[98,99],[[10,[18]]]],[14,[[10,[18]]]],[[98,14],[[10,[18]]]],[11,[[10,[18]]]],[[98,11],[[10,[18]]]],[[]],[[],10],[[],10],[[],10],[[],10],[[],49],[[],49],[[]],[[]],0,0,0,0,0,0,0,0,0,0,0,0,0,0,[101],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[101,2,86],[[10,[18]]]],[101,[[10,[18]]]],[[102,2],[[10,[[42,[41]],18]]]],[[101,2],[[10,[[42,[41]],18]]]],[[102,100],[[10,[42,18]]]],[[101,100],[[10,[42,18]]]],[[102,58],[[10,[[42,[51]],18]]]],[[101,58],[[10,[[42,[51]],18]]]],[[102,2,41],[[10,[[42,[100]],18]]]],[[101,2,41],[[10,[[42,[100]],18]]]],[102,[[10,[[42,[99]],18]]]],[101,[[10,[[42,[99]],18]]]],[[102,58,16],[[10,[[42,[14]],18]]]],[[101,58,16],[[10,[[42,[14]],18]]]],[[102,43],[[10,[[42,[11]],18]]]],[[101,43],[[10,[[42,[11]],18]]]],[6],[6],[6],[6],[6],[6],[6],[6],[6],[6],[[],[[10,[103]]]],[[],[[10,[104]]]],[[],[[10,[105]]]],[6],[6],[6],[6],[6],[[101,19],20],[[103,19],20],[[104,19],20],[[105,19],20],[[],102],[[]],[[],102],[[],102],[98,101],[106,101],[107,101],[[]],[[]],[[]],[104,105],[[]],[[],105],[103,105],[[],[[10,[101,18]]]],[[101,2],[[10,[[42,[41]],18]]]],[[101,100],[[10,[42,18]]]],[[101,58],[[10,[[42,[51]],18]]]],[[101,2,41],[[10,[[42,[100]],18]]]],[101,[[10,[[42,[99]],18]]]],[[101,58,16],[[10,[[42,[14]],18]]]],[[101,43],[[10,[[42,[11]],18]]]],[[101,2],[[10,[41,18]]]],[[],6],[[],6],[[],6],[[],6],[[],6],[[]],[[]],[[]],[[]],[[]],[101,[[10,[[9,[51]],18]]]],[[101,[42,[2]]],[[10,[[9,[100]],18]]]],[[101,16],[[10,[[9,[14]],18]]]],[101,[[10,[[9,[11]],18]]]],0,0,[103,10],[104,10],[105,10],[[102,2,41],[[10,[18]]]],[[101,2,41],[[10,[18]]]],[[102,51],[[10,[18]]]],[[101,51],[[10,[18]]]],[[102,100,2,41],[[10,[18]]]],[[101,100,2,41],[[10,[18]]]],[[102,99],[[10,[18]]]],[[101,99],[[10,[18]]]],[[102,14],[[10,[18]]]],[[101,14],[[10,[18]]]],[[102,11],[[10,[18]]]],[[101,11],[[10,[18]]]],0,[[],10],[[],10],[[],10],[[],10],[[],10],[[],10],[[],10],[[],10],[[],10],[[],10],[[],49],[[],49],[[],49],[[],49],[[],49],[[]],[[]],[[]],[[]],[[]],0,[106],[[]],[[]],[[106,2,86],[[10,[18]]]],[106,[[10,[18]]]],[[],106],[[106,2],[[10,[[42,[41]],18]]]],[[106,100],[[10,[42,18]]]],[[106,58],[[10,[[42,[51]],18]]]],[[106,2,41],[[10,[[42,[100]],18]]]],[106,[[10,[[42,[99]],18]]]],[[106,58,16],[[10,[[42,[14]],18]]]],[[106,43],[[10,[[42,[11]],18]]]],[6],[6],[6],[[106,19],20],[[]],[[],[[10,[106,18]]]],[[106,2],[[10,[[42,[41]],18]]]],[[106,100],[[10,[42,18]]]],[[106,58],[[10,[[42,[51]],18]]]],[[106,2,41],[[10,[[42,[100]],18]]]],[106,[[10,[[42,[99]],18]]]],[[106,58,16],[[10,[[42,[14]],18]]]],[[106,43],[[10,[[42,[11]],18]]]],[[106,2],[[10,[41,18]]]],[[],6],[[]],[106,[[10,[[9,[51]],18]]]],[[106,[42,[2]]],[[10,[[9,[100]],18]]]],[[106,16],[[10,[[9,[14]],18]]]],[106,[[10,[[9,[11]],18]]]],[[],106],[[106,2,41],[[10,[18]]]],[[106,51],[[10,[18]]]],[[106,100,2,41],[[10,[18]]]],[[106,99],[[10,[18]]]],[[106,14],[[10,[18]]]],[[106,11],[[10,[18]]]],[[],10],[[],10],[[],49],[[]],0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,[[108,76],[[10,[109,24]]]],[[],110],[[],110],[111,112],[[[108,[113]],41],[[108,[114]]]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[111,[[9,[111,8]]]],0,[111,[[10,[115]]]],[111,[[10,[115]]]],[111,[[10,[115]]]],[111,[[10,[115]]]],[111,[[10,[115]]]],[111,[[10,[115]]]],[111,[[10,[115]]]],[111,[[10,[115]]]],[111,[[10,[115]]]],[111,[[10,[115]]]],[111,[[10,[115]]]],[111,[[10,[115]]]],[111,[[10,[115]]]],[112,[[10,[115]]]],[112,[[10,[115]]]],[112,[[10,[115]]]],[[],[[10,[115]]]],[[],[[10,[115]]]],[[],[[10,[115]]]],0,[116,116],[117,117],[108,108],[118,118],[119,119],[111,111],[[]],[[]],[[]],[[]],[[]],[[]],[[116,116],44],[[117,117],44],[[108,108],44],[[118,118],44],[[119,119],44],[[111,111],44],[111,16],[6],[6],[6],[6],[6],[6],[6],[6],[6],[6],[6],[6],0,[[[108,[113]],41],[[108,[114]]]],[[[108,[114]],120],[[10,[[108,[121]],122]]]],[[[108,[113]],120,41],[[10,[[108,[121]],122]]]],[108,123],[[],[[10,[108]]]],[[],[[10,[111]]]],[6],[6],[6],[6],[6],[6],[111,100],[[116,116],16],[[117,117],16],[[108,108],16],[[118,118],16],[[119,119],16],[[111,111],16],0,[108,[[10,[100,24]]]],0,[[111,124],[[10,[125]]]],[[126,127,120],[[10,[[42,[128]],29]]]],[[[108,[113]],126,127,120],[[10,[[42,[128]],29]]]],[[[111,[113,129]],126,127,120],[[10,[[42,[128]],29]]]],[[[108,[113]],120,100,[130,[41]]],[[10,[42,122]]]],[[116,19],[[10,[90]]]],[[117,19],[[10,[90]]]],[[108,19],[[10,[90]]]],[[108,19],[[10,[90]]]],[[118,19],[[10,[90]]]],[[119,19],[[10,[90]]]],[[111,19],[[10,[90]]]],[[111,19],[[10,[90]]]],[108,16],[111,16],[[]],[[]],[[]],[131,108],[132,108],[133,108],[134,108],[135,108],[136,108],[[]],[[]],[[]],[112,[[10,[111,24]]]],[50,[[10,[108,24]]]],[50,[[10,[111,24]]]],[[50,124],[[10,[111,24]]]],[50,[[10,[111,24]]]],[137,[[10,[108,24]]]],[137,[[10,[111,24]]]],[[],17],[[],17],[[],17],[[],17],[[],17],[[],17],[[111,6],[[42,[111]]]],[[111,6],42],[108,[[10,[24]]]],[108,[[10,[24]]]],[111,16],[111,16],[[[108,[113]]],16],[116],[117],[108],[118],[119],[111],[[],6],[[],6],[[],6],[[],6],[[],6],[[],6],[[]],[[]],[[]],[[]],[[]],[[]],[111,112],[[120,76],[[10,[29]]]],[[138,120,76],[[10,[29]]]],[[[108,[113]]],16],[111,16],[111,139],[111,140],[108,[[10,[141,24]]]],[111,[[10,[141,24]]]],[111,[[10,[142]]]],[[116,120],[[42,[143]]]],[111,[[42,[6]]]],[111,[[42,[6]]]],[111,[[42,[6]]]],[111,[[10,[6,24]]]],[108,[[10,[6,24]]]],[111,[[10,[6,24]]]],[[],50],[[],50],[[],50],[[[111,[144]]],[[10,[108,24]]]],[[],108],[[],108],[[[111,[118]]],[[10,[108,24]]]],[[6,[9,[8]]],[[10,[108,24]]]],[134,108],[136,108],[[],[[10,[108,24]]]],[[[111,[119]]],[[10,[108,24]]]],[[6,[9,[8]]],[[10,[108,24]]]],[[[42,[145]]],[[10,[108,24]]]],[[],[[10,[108,24]]]],[[[111,[119]]],[[10,[108,24]]]],[[6,[9,[8]]],[[10,[108,24]]]],0,0,[111,[[10,[24]]]],[100,[[10,[111,24]]]],[[120,50],[[10,[24]]]],[100,[[10,[111,24]]]],[[100,124],[[10,[111,24]]]],[[116,116],[[42,[44]]]],[[117,117],[[42,[44]]]],[[108,108],[[42,[44]]]],[[118,118],[[42,[44]]]],[[119,119],[[42,[44]]]],[[111,111],[[42,[44]]]],[[],6],[[],6],[[],6],0,[111,16],[108,[[10,[24]]]],[111,[[10,[125]]]],[[108,146],[[10,[24]]]],[111,[[10,[[9,[[9,[3,8]],8]],24]]]],[111,[[10,[[9,[[9,[3,8]],8]],24]]]],[108,[[10,[100,24]]]],[108,100],[111,6],[108,10],[111,10],[[],147],[[],147],[[],147],0,[[]],[[]],[[]],[[]],[[]],[[]],[[],47],[[],47],[[[108,[113]],148],47],[111,[[10,[24]]]],[111,[[10,[24]]]],[108,10],[111,10],[[],10],[[],10],[[],10],[[],10],[[],10],[[],10],[[],10],[[],10],[[],10],[[],10],[[],10],[[],10],0,[[],49],[[],49],[[],49],[[],49],[[],49],[[],49],[108,100],[[]],[[]],[[]],[[]],[[]],[[]],0,[111,16],0,[50,[[10,[47,29]]]],[50,[[10,[29]]]],[50,[[10,[47,29]]]],[50,[[10,[29]]]],0,0,0,0,0,0,0,0,0,0,0,0,[[]],[[]],[6],[6],[6],[[29,19],20],[[29,19],20],[38,29],[24,29],[149,29],[[]],[21,29],[28,29],[23,29],[150,29],[[],6],[[]],[45],[[],47],[[],10],[[],10],[[],49],[[]],0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[151,151],[152,152],[153,153],[128,128],[154,154],[127,127],[[]],[[]],[[]],[[]],[[]],[[]],0,0,[[],154],[6],[6],[6],[6],[6],[6],[6],[6],[6],[6],[6],[6],[6],[6],[6],[6],[6],[6],[6],[6],[6],[[151,151],16],[[152,152],16],[[153,153],16],[[128,128],16],[[154,154],16],[[28,28],16],[[151,19],20],[[152,19],20],[[153,19],20],[[128,19],20],[[154,19],20],[[28,19],20],[[28,19],20],[[127,19],20],[[]],[[]],[16,153],[[]],[152,128],[[]],[[]],[[]],[[]],[[128,155],[[10,[154,28]]]],[[],17],[[],17],[151],[154],[152,47],0,[[],6],[[],6],[[],6],[[],6],[[],6],[[],6],[[],6],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[152,16],[153,16],[154,16],0,[[154,154],[[42,[44]]]],[45],[128,16],0,[151,10],[152,10],[153,10],[128,10],[154,10],0,[[]],[[]],[[]],[[]],[[]],[[]],[[],47],[[],10],[[],10],[[],10],[[],10],[[],10],[[],10],[[],10],[[],10],[[],10],[[],10],[[],10],[[],10],[[],10],[[],10],[[],49],[[],49],[[],49],[[],49],[[],49],[[],49],[[],49],[[]],[[]],[[]],[[]],[[]],[[]],[[]],0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[76,[[10,[156,29]]]],[[[158,[[157,[118]]]],76],[[10,[156,29]]]],[[[159,[[157,[119]]]],76],[[10,[156,29]]]],[[[160,[[157,[119]]]],76],[[10,[156,29]]]],[[[162,[[161,[118]]]],76],[[10,[156,29]]]],[[[163,[[161,[118]]]],76],[[10,[156,29]]]],[[[164,[[161,[119]]]],76],[[10,[156,29]]]],[[[165,[[161,[119]]]],76],[[10,[156,29]]]],[[[166,[[161,[119]]]],76],[[10,[156,29]]]],[[[167,[[161,[119]]]],76],[[10,[156,29]]]],[6],[6],[6],[6],[6],[6],[6],[6],[6],[6],[6],[6],[6],[6],[6],[6],[6],[6],[6],[6],[6],[6],[6],[6],[6],[6],[6],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[],6],[[],6],[[],6],[[],6],[[],6],[[],6],[[],6],[[],6],[[],6],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[156,120,76],[[10,[29]]]],[[120,76],[[10,[29]]]],[[120,76],[[10,[29]]]],[[120,76],[[10,[29]]]],[[120,76],[[10,[29]]]],[[120,76],[[10,[29]]]],[[120,76],[[10,[29]]]],[[120,76],[[10,[29]]]],[[120,76],[[10,[29]]]],[[120,76],[[10,[29]]]],[[],10],[[],10],[[],10],[[],10],[[],10],[[],10],[[],10],[[],10],[[],10],[[],10],[[],10],[[],10],[[],10],[[],10],[[],10],[[],10],[[],10],[[],10],[[],49],[[],49],[[],49],[[],49],[[],49],[[],49],[[],49],[[],49],[[],49],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,[[],168],[[],110],[[113,41],114],0,[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[111,[[10,[115]]]],[111,[[10,[115]]]],[111,[[10,[115]]]],[111,[[10,[115]]]],[111,[[10,[115]]]],[111,[[10,[115]]]],[112,[[10,[115]]]],[[],[[10,[115]]]],[[[170,[169,129]]],[[170,[169,129]]]],[171,171],[113,113],[172,172],[173,173],[110,110],[174,174],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[171,171],44],[[113,113],44],[[172,172],44],[[173,173],44],0,[[],174],[6],[[[170,[129]]]],[6],[6],[6],[6],[6],[6],[6],[6],[6],[6],[6],[6],[6],[6],[6],[6],[6],[6],[6],[6],[6],[6],[6],[[113,41],114],[6],[6],[6],[6],[6],[6],[6],[6],[6],[6],[6],[6],[171,100],[[171,171],16],[[113,113],16],[[172,172],16],[[173,173],16],[[110,110],16],[[171,19],[[10,[90]]]],[[171,19],[[10,[90]]]],[[113,19],[[10,[90]]]],[[113,19],[[10,[90]]]],[[175,19],[[10,[90]]]],[[175,19],[[10,[90]]]],[[172,19],[[10,[90]]]],[[176,19],[[10,[90]]]],[[173,19],[[10,[90]]]],[[[178,[[0,[177,129]]]],19],20],[[110,19],20],[[174,19],20],[[21,19],20],[[21,19],20],[171,16],[179,[[180,[129]]]],[181,[[180,[129]]]],[[]],[[]],[[]],[[]],[114,113],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[23,21],[24,21],[[]],[[113,168],[[178,[129]]]],[[175,168],[[178,[129]]]],[50,[[10,[113]]]],[50,[[10,[175]]]],[137,[[10,[171,24]]]],[113,143],[[],[[10,[170]]]],[[],[[10,[170]]]],[[],[[10,[170]]]],[[],[[10,[170]]]],[[],17],[[],17],[[],17],[[],17],[[[180,[129]]],16],[113,16],[171],[113],[172],[173],[[],6],[[],6],[[],6],[[],6],[[],6],[[],6],[[],6],[[],6],[[],6],[[],6],[[],6],[[],6],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[],[[10,[178,21]]]],[[[42,[182]],143],[[10,[178,21]]]],[[170,[42,[182]],143],[[10,[178,21]]]],[170,[[10,[178,21]]]],[113,[[10,[[178,[129]],21]]]],[175,[[10,[[178,[129]],21]]]],[[[178,[129]]],[[10,[[178,[129]],21]]]],[[],[[10,[180,21]]]],[[[180,[129]]],[[10,[[180,[129]],21]]]],[170,[[10,[180,21]]]],[[[170,[129]]]],[[[180,[129]],76],[[42,[179]]]],[[[180,[129]],76,120],181],[113,16],[[],16],[110,16],[[],16],[110,16],[[],16],[110,16],[113,16],[113,16],0,0,0,[171,[[10,[141,24]]]],[[],168],[113,183],[111,[[42,[6]]]],[171,6],[171,6],[[168,168],168],[[],50],[[6,[9,[8]]],[[10,[171,24]]]],0,0,[111,[[10,[24]]]],[[[178,[129]],168],[[178,[129]]]],[[171,171],[[42,[44]]]],[[113,113],[[42,[44]]]],[[172,172],[[42,[44]]]],[[173,173],[[42,[44]]]],[[],6],0,[45],[171,[[10,[24]]]],[171,[[10,[[9,[[9,[3,8]],8]],24]]]],[171,6],[[],147],[171,112],[[],168],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[175,120],[[10,[113,184]]]],[[],47],[[],47],[[],47],[[],47],[111,[[10,[24]]]],[111,[[10,[24]]]],[171,[[10,[171]]]],[[],10],[[],10],[[],10],[[],10],[[],10],[[],10],[[],10],[[],10],[[],10],[[],10],[[],10],[[],10],[[],10],[[],10],[[],10],[[],10],[[],10],[[],10],[[],10],[[],10],[[],10],[[],10],[[],10],[[],10],[[],49],[[],49],[[],49],[[],49],[[],49],[[],49],[[],49],[[],49],[[],49],[[],49],[[],49],[[],49],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[185,185],[186,186],[187,187],[[]],[[]],[[]],[[185,185],44],[[187,187],44],[6],[6],[6],[6],[6],[6],[6],[6],[[],[[10,[187]]]],[6],[6],[6],[6],[[185,185],16],[[186,186],16],[[187,187],16],[[185,19],[[10,[90]]]],[[185,19],[[10,[90]]]],[[186,19],[[10,[90]]]],[[186,19],[[10,[90]]]],[[187,19],[[10,[90]]]],[[187,19],[[10,[90]]]],[[]],[[]],[[]],[[]],[[],[[10,[187,186]]]],[185,[[10,[187,186]]]],[50,[[10,[187,186]]]],[[185,6],[[10,[187,186]]]],[[],[[10,[[170,[187,129]]]]]],[[],17],[[],17],[185],[187],[[],6],[[],6],[[],6],[[],6],[[]],[[]],[[]],[[]],[[187,[42,[182]],143],[[10,[[178,[129]],21]]]],[[188,[42,[182]],143],[[10,[[178,[129]],21]]]],[187,[[10,[[180,[129]],21]]]],[188,[[10,[[180,[129]],21]]]],[187,185],[[],[[10,[185,186]]]],[[],[[10,[187,186]]]],[185,[[10,[187,186]]]],[[185,50],[[10,[187,186]]]],[50,[[10,[187,186]]]],[[185,185],[[42,[44]]]],[[187,187],[[42,[44]]]],[45],[187,10],[187,[[9,[3,8]]]],[187],[[]],[[]],[[]],[187],[[187,50]],[[],47],[[],47],[[],47],[[],10],[[],10],[[],10],[[],10],[[],10],[[],10],[[],10],[[],10],[[],49],[[],49],[[],49],[[],49],[[]],[[]],[[]],[[]],[187,6],[187,[[0,[46,169]]]],[[185,50]],0,[[],[[42,[17]]]],[[],[[42,[4]]]],[6,[[42,[48]]]],0,0,0,0,0,0,0,0,0,[[52,2,189,[75,[190]]]],0,[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[52,58],[[10,[[193,[191,192]],18]]]],[52,[[193,[191,194]]]],0,[52,195],[[],59],[6],[6],[196],[6],[6],[6],[6],[6],[6],[[52,2],47],[6],[6],[6],[6],[[52,41],[[10,[16,18]]]],[[196,196],16],0,[[52,197,198],[[10,[16,18]]]],[[[52,[177]],19],20],[[199,19],20],[[196,19],20],[[196,19],20],[[59,19],20],[[]],[[]],[[]],[[]],[[52,199],[[10,[196,18]]]],[52,[[10,[1,18]]]],[[52,2],138],[50],[[52,199],[[10,[196,18]]]],[[52,11,[42,[200]],16],[[10,[201,18]]]],[[52,2],[[75,[126]]]],[[52,58,16],[[10,[[42,[14]],18]]]],[[52,43],[[10,[[42,[11]],18]]]],0,0,[[],6],[[],6],[[],6],[[],6],[[]],[[]],[[]],[[]],[100,16],[[52,100],[[10,[16,18]]]],0,[[52,16],[[10,[[9,[14]],18]]]],[52,[[10,[[9,[11]],18]]]],[52,76],[[202,[42,[202]],76],[[10,[52,18]]]],[[202,[42,[202]],76],[[10,[52,18]]]],[[52,2],[[10,[[42,[128]],18]]]],0,[[52,2],[[10,[[42,[138]],18]]]],[52,120],[[52,197,198],[[10,[16,18]]]],0,[[52,59],[[10,[18]]]],0,[[],47],[[],10],[[],10],[[],10],[[],10],[[],10],[[],10],[[],10],[[],10],0,[[],49],[[],49],[[],49],[[],49],0,[[]],[[]],[[]],[[]],[[42,76,120],[[10,[47,18]]]],0,0,0,0,0,0,0,0,0,[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[203,203],[204,204],[[]],[[]],[[[9,[12]],[9,[12]],4,17,100],[[10,[205,18]]]],[[203,[9,[12]],[9,[12]],4,17,100],[[10,[205,18]]]],[[204,[9,[12]],[9,[12]],4,17,100],[[10,[205,18]]]],[[206,[9,[12]],[9,[12]],4,17,100],[[10,[205,18]]]],[[17,4,100],207],[[],203],[[],204],[[],206],[6],[6],[6],[6],[6],[6],[6],[6],[6],[6],[6],[6],[6],[6],[6],0,0,[[207,19],20],[[205,19],20],[[203,19],20],[[204,19],20],[[206,19],20],[[]],[[]],[[]],[[]],[[]],[[],6],[[],6],[[],6],[[],6],[[],6],[[]],[[]],[[]],[[]],[[]],[205,17],[17,206],0,[205,17],[[]],[[]],[[],10],[[],10],[[],10],[[],10],[[],10],[[],10],[[],10],[[],10],[[],10],[[],10],[[],49],[[],49],[[],49],[[],49],[[],49],[[]],[[]],[[]],[[]],[[]],0,0,0,0,0,0,0,0,[[]],[[]],[208,[[42,[47]]]],[6],[6],[208,47],[[],[[10,[208]]]],[6],[[52,50,16],[[10,[208,50]]]],[[208,19],20],[[]],[50,[[10,[208]]]],[[],6],[[]],0,[208,10],[208,47],[[],10],[[],10],[[],49],[[]],0,[[]],[[]],[6],[6],[6],[[209,19],20],[[]],[[210,211],[[10,[209,212]]]],[[209,120],213],[[],6],[[]],[[209,197,198,120],[[10,[27]]]],[[],10],[[],10],[[],49],[[]],0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,[[126,213,189,[75,[190]]],[[42,[[75,[190]]]]]],0,0,[[126,120],214],0,[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[214,108,120],126],[213,213],[27,27],[215,215],[[[217,[[0,[169,216,177,169]]]]],[[217,[[0,[169,216,177,169]]]]]],[189,189],[126,126],[198,198],[218,218],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[213,213],44],[[189,189],44],[[],189],[[],126],[[],198],[[],218],[6],[6],[6],[[[217,[[0,[216,177,169]]]]]],[6],[6],[6],[6],[6],[6],[6],[6],[6],[6],[6],[6],[6],[[],[[42,[175]]]],[[[217,[219]]],[[42,[175]]]],[[[217,[[116,[179]]]]],[[42,[175]]]],[6],[6],[6],[6],[6],[6],[6],[6],[[213,213],16],[[27,27],16],[[215,215],16],[[189,189],16],[[218,218],16],[[126,213],[[42,[75]]]],[[213,19],20],[[27,19],20],[[27,19],20],[[215,19],20],[[[217,[[0,[177,216,177,169]]]],19],20],[[189,19],20],[[126,19],20],[[198,19],20],[[218,19],20],[220,213],[[]],[183,213],[221,27],[[]],[212,27],[[]],[[]],[[]],[[]],[[]],[[]],[[],17],[213],[120,213],[[[217,[219]],120],213],[[[217,[[116,[179]]]],120],213],[126,[[9,[213]]]],[[],6],[[],6],[[],6],[[],6],[[],6],[[],6],[[],6],[[],6],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[[0,[216,177,169]],215],[[217,[[0,[216,177,169]]]]]],[[],126],[[213,213],[[42,[44]]]],[[189,189],[[42,[44]]]],[45],[[126,213,189],[[42,[[75,[190]]]]]],0,[[197,6,198,120],[[10,[27]]]],[[[217,[[116,[179]]]],197,6,198,120],[[10,[27]]]],[[[217,[219]],197,6,198,120],[[10,[27]]]],[[197,198,120],[[10,[27]]]],[[197,198,120],[[10,[27]]]],0,[126,[[9,[75]]]],0,[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[],47],0,0,[[],10],[[],10],[[],10],[[],10],[[],10],[[],10],[[],10],[[],10],[[],10],[[],10],[[],10],[[],10],[[],10],[[],10],[[],10],[[],10],[[],49],[[],49],[[],49],[[],49],[[],49],[[],49],[[],49],[[],49],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],0,[[],17],0,0,0,0,0,0,0,0,0,0,0,0,[[[193,[222,[223,[222]],194]]],[[193,[222,[223,[222]],194]]]],[[[193,[222,[223,[222]],224]],43,201,6],[[10,[[193,[222,[223,[222]],224]],18]]]],[[[193,[222,[223,[222]],224]]],[[193,[222,[223,[222]],224]]]],[[[193,[222,[223,[222]],194]],100,17],[[193,[222,[223,[222]],194]]]],[[[193,[222,[223,[222]],224]],43],[[193,[222,[223,[222]],224]]]],[[[193,[222,[223,[222]],224]],43],[[10,[[193,[222,[223,[222]],224]],18]]]],[[[193,[222,[223,[222]],224]]],[[10,[[193,[222,[223,[222]],224]],18]]]],[[[193,[222,[223,[222]],224]],16],[[193,[222,[223,[222]],224]]]],[[[193,[222,191,192]],100],[[10,[[193,[222,191,192]],18]]]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[[193,[222,[223,[222]],224]],225],[[193,[222,[223,[222]],224]]]],[194,194],[192,192],[[[193,[169]]],[[193,[169]]]],[226,226],[225,225],[[]],[[]],[[]],[[]],[[]],[[226,226],44],[[225,225],44],[[[193,[222,[223,[222]],224]],[223,[222]]],[[193,[222,[223,[222]],224]]]],[[[193,[222,[223,[222]],224]],41],[[193,[222,[223,[222]],224]]]],[[],194],[[],192],[[],226],[[],225],[6],[6],[6],[6],[6],[6],[6],[6],[6],[6],[[[193,[222,[223,[222]],224]]],[[193,[222,[223,[222]],224]]]],[[[193,[222,[223,[222]],194]],100],[[193,[222,[223,[222]],194]]]],[[[193,[222,[223,[222]],224]]],[[193,[222,[223,[222]],224]]]],[6],[6],[6],[6],[6],[[[193,[222,[223,[222]],224]]],[[193,[222,[223,[222]],224]]]],[[[193,[222,[223,[222]],224]],227],[[193,[222,[223,[222]],224]]]],[[226,226],16],[[225,225],16],[[[193,[222,[223,[222]],224]],17],[[193,[222,[223,[222]],224]]]],[[[193,[222,[223,[222]],224]],4],[[193,[222,[223,[222]],224]]]],[[[193,[222,[223,[222]],224]]],[[10,[18]]]],[[194,19],20],[[192,19],20],[[[193,[177,177,177]],19],20],[[226,19],20],[[225,19],20],[[]],[[]],[[]],[[]],[[]],[[],17],[[],17],[226],[225],[[[193,[222,[223,[222]],224]]],[[193,[222,[223,[222]],224]]]],[[],6],[[],6],[[],6],[[],6],[[],6],[[]],[[]],[[]],[[]],[[]],[[[193,[222,[223,[222]],224]]],[[193,[222,[223,[222]],224]]]],[[[193,[222,[223,[222]],224]],228],[[193,[222,[223,[222]],224]]]],[[[193,[222,[223,[222]],224]]],[[193,[222,[223,[222]],224]]]],[[[193,[222,[223,[222]],224]]],[[193,[222,[223,[222]],224]]]],[[[193,[222,[223,[222]],224]],226],[[193,[222,[223,[222]],224]]]],[[226,226],[[42,[44]]]],[[225,225],[[42,[44]]]],[[[193,[222,[223,[222]],224]],[155,[47,[9,[6]]]],2],[[193,[222,[223,[222]],224]]]],[[[193,[222,[223,[222]],194]],9],[[193,[222,[223,[222]],194]]]],[[[193,[222,[223,[222]],224]],200],[[193,[222,[223,[222]],224]]]],[[226,51]],[[]],[[]],[[]],[[]],[[]],[[],10],[[],10],[[],10],[[],10],[[],10],[[],10],[[],10],[[],10],[[],10],[[],10],[[],49],[[],49],[[],49],[[],49],[[],49],[[[193,[222,[223,[222]],224]],[9,[43]]],[[193,[222,[223,[222]],224]]]],[[[193,[222,[223,[222]],224]],229],[[193,[222,[223,[222]],224]]]],[[]],[[]],[[]],[[]],[[]],0,0,0,0,0,[[]],[[]],[6],[6],[6],[[33,19],20],[[33,19],20],[18,33],[[]],[230,33],[[],6],[[]],[45],[[],47],[[],10],[[],10],[[],49],[51,[[10,[33]]]],[[]]],"p":[[3,"Balance"],[4,"KeychainKind"],[15,"u8"],[3,"FeeRate"],[15,"f32"],[15,"usize"],[3,"u5"],[3,"Global"],[3,"Vec"],[4,"Result"],[3,"LocalUtxo"],[3,"WeightedUtxo"],[4,"Utxo"],[3,"TransactionDetails"],[3,"BlockTime"],[15,"bool"],[15,"u64"],[4,"Error"],[3,"Formatter"],[6,"Result"],[4,"KeyError"],[4,"PsbtParseError"],[4,"Error"],[4,"Error"],[4,"Error"],[4,"EsploraError"],[4,"SignerError"],[4,"PolicyError"],[4,"Error"],[4,"Error"],[4,"Error"],[4,"Error"],[4,"VerifyError"],[4,"Error"],[4,"Error"],[4,"CompactFiltersError"],[4,"Error"],[4,"Error"],[3,"Error"],[3,"BlockTime"],[15,"u32"],[4,"Option"],[3,"OutPoint"],[4,"Ordering"],[3,"Demand"],[8,"Iterator"],[3,"String"],[3,"TxOut"],[3,"TypeId"],[15,"str"],[3,"Transaction"],[3,"Wallet"],[4,"Capability"],[3,"NoopProgress"],[3,"LogProgress"],[3,"BlockHash"],[3,"HashSet"],[3,"Txid"],[3,"SyncOptions"],[8,"Progress"],[3,"Box"],[4,"AnyBlockchain"],[4,"AnyBlockchainConfig"],[3,"ElectrumBlockchain"],[3,"EsploraBlockchain"],[3,"CompactFiltersBlockchain"],[3,"RpcBlockchain"],[3,"RpcConfig"],[3,"CompactFiltersBlockchainConfig"],[3,"EsploraBlockchainConfig"],[3,"ElectrumBlockchainConfig"],[3,"Mempool"],[3,"BitcoinPeerConfig"],[8,"ToSocketAddrs"],[3,"Arc"],[4,"Network"],[3,"Peer"],[8,"ToTargetAddr"],[4,"Error"],[3,"Error"],[3,"Error"],[3,"SystemTimeError"],[4,"Inventory"],[3,"VersionMessage"],[3,"Path"],[8,"AsRef"],[3,"Duration"],[4,"NetworkMessage"],[3,"Client"],[3,"Error"],[3,"Transport"],[4,"Error"],[3,"ParseIntError"],[3,"BlockingClient"],[3,"RpcBlockchainFactory"],[3,"RpcSyncParams"],[4,"Auth"],[3,"SqliteDatabase"],[3,"SyncTime"],[3,"Script"],[4,"AnyDatabase"],[4,"AnyBatch"],[3,"SledDbConfiguration"],[3,"SqliteDbConfiguration"],[4,"AnyDatabaseConfig"],[3,"MemoryDatabase"],[3,"Tree"],[4,"Descriptor"],[3,"Address"],[4,"ScriptContextEnum"],[3,"Miniscript"],[4,"Terminal"],[4,"DescriptorPublicKey"],[3,"DefiniteDescriptorKey"],[4,"ScriptContextError"],[3,"DescriptorXKey"],[4,"Wildcard"],[4,"Legacy"],[4,"Segwitv0"],[3,"Secp256k1"],[3,"PublicKey"],[4,"ConversionError"],[4,"DescriptorType"],[3,"ExtParams"],[4,"AnalysisError"],[3,"SignersContainer"],[4,"BuildSatisfaction"],[3,"Policy"],[8,"ScriptContext"],[3,"Range"],[3,"Pkh"],[3,"Tr"],[3,"Sh"],[3,"Wpkh"],[3,"Bare"],[3,"Wsh"],[3,"Tree"],[6,"ExtendedDescriptor"],[3,"Iter"],[3,"PkIter"],[4,"Policy"],[4,"LiftError"],[3,"DerivationPath"],[4,"BareCtx"],[4,"TapTree"],[3,"TxIn"],[4,"SigType"],[3,"HashMap"],[4,"Error"],[4,"Error"],[4,"PkOrF"],[4,"SatisfiableItem"],[4,"Satisfaction"],[3,"Condition"],[3,"BTreeMap"],[6,"DescriptorTemplateOut"],[8,"IntoDescriptorKey"],[3,"P2Pkh"],[3,"P2Wpkh_P2Sh"],[3,"P2Wpkh"],[8,"DerivableKey"],[3,"Bip44"],[3,"Bip44Public"],[3,"Bip49"],[3,"Bip49Public"],[3,"Bip84"],[3,"Bip84Public"],[6,"ValidNetworks"],[8,"Clone"],[3,"GeneratedKey"],[3,"SortedMultiVec"],[3,"SinglePub"],[4,"SinglePubKey"],[3,"PrivateKeyGenerateOptions"],[4,"DescriptorSecretKey"],[3,"SinglePriv"],[8,"Debug"],[4,"DescriptorKey"],[3,"ExtendedPrivKey"],[4,"ExtendedKey"],[3,"ExtendedPubKey"],[6,"KeySource"],[3,"Fingerprint"],[3,"DescriptorKeyParseError"],[4,"Language"],[4,"Error"],[3,"Mnemonic"],[6,"MnemonicWithPassphrase"],[3,"SignerOrdering"],[8,"TransactionSigner"],[6,"DefaultCoinSelectionAlgorithm"],[3,"BumpFee"],[3,"TxBuilder"],[3,"CreateTx"],[8,"Deref"],[3,"AddressInfo"],[3,"PartiallySignedTransaction"],[3,"SignOptions"],[4,"AddressIndex"],[3,"PsbtSighashType"],[3,"Input"],[8,"IntoWalletDescriptor"],[3,"LargestFirstCoinSelection"],[3,"OldestFirstCoinSelection"],[3,"CoinSelectionResult"],[3,"BranchAndBoundCoinSelection"],[4,"Excess"],[3,"FullyNodedExport"],[3,"HWISigner"],[3,"HWIDevice"],[4,"HWIChain"],[4,"Error"],[4,"SignerId"],[6,"KeyMap"],[4,"SignerContext"],[8,"Sized"],[3,"SignerWrapper"],[4,"TapLeavesOptions"],[3,"PrivateKey"],[3,"Hash"],[4,"Error"],[8,"BatchDatabase"],[8,"CoinSelectionAlgorithm"],[8,"TxBuilderContext"],[4,"ChangeSpendPolicy"],[4,"TxOrdering"],[3,"Sequence"],[4,"LockTime"],[15,"i32"],[4,"Error"],[8,"Vbytes"],[13,"InsufficientFunds"],[13,"InvalidNetwork"],[13,"FeeRateTooLow"],[13,"FeeTooLow"],[13,"Foreign"],[8,"ConfigurableBlockchain"],[8,"BlockchainFactory"],[8,"Blockchain"],[8,"GetBlockHash"],[8,"GetHeight"],[8,"GetTx"],[8,"WalletSync"],[13,"Cookie"],[13,"UserPass"],[8,"ConfigurableDatabase"],[8,"Database"],[8,"BatchOperations"],[8,"ExtractPolicy"],[13,"PsbtTimelocks"],[13,"Complete"],[13,"Partial"],[13,"PartialComplete"],[13,"Sha256Preimage"],[13,"Hash256Preimage"],[13,"Ripemd160Preimage"],[13,"Hash160Preimage"],[13,"Thresh"],[13,"Multisig"],[13,"AbsoluteTimelock"],[13,"RelativeTimelock"],[8,"DescriptorTemplate"],[8,"GeneratableKey"],[8,"ExtScriptContext"],[8,"GeneratableDefaultOptions"],[4,"WordCount"],[8,"PsbtUtils"],[8,"IsDust"],[13,"Change"],[13,"NoChange"],[8,"SignerCommon"],[8,"InputSigner"],[13,"Tap"]]}\ }'); -if (window.initSearch) {window.initSearch(searchIndex)}; \ No newline at end of file +if (typeof window !== 'undefined' && window.initSearch) {window.initSearch(searchIndex)}; +if (typeof exports !== 'undefined') {exports.searchIndex = searchIndex}; diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/search.js b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/search.js deleted file mode 100644 index 3aa506077c..0000000000 --- a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/search.js +++ /dev/null @@ -1,2 +0,0 @@ -(function(){var itemTypes=["mod","externcrate","import","struct","enum","fn","type","static","trait","impl","tymethod","method","structfield","variant","macro","primitive","associatedtype","constant","associatedconstant","union","foreigntype","keyword","existential","attr","derive","traitalias",];var TY_PRIMITIVE=itemTypes.indexOf("primitive");var TY_KEYWORD=itemTypes.indexOf("keyword");function printTab(nb){if(nb===0||nb===1||nb===2){searchState.currentTab=nb}var nb_copy=nb;onEachLazy(document.getElementById("titles").childNodes,function(elem){if(nb_copy===0){addClass(elem,"selected")}else{removeClass(elem,"selected")}nb_copy-=1});onEachLazy(document.getElementById("results").childNodes,function(elem){if(nb===0){addClass(elem,"active")}else{removeClass(elem,"active")}nb-=1})}function removeEmptyStringsFromArray(x){for(var i=0,len=x.length;i-1){var obj=searchIndex[result.id];obj.lev=result.lev;var res=buildHrefAndPath(obj);obj.displayPath=pathSplitter(res[0]);obj.fullPath=obj.displayPath+obj.name;obj.fullPath+="|"+obj.ty;if(duplicates[obj.fullPath]){continue}duplicates[obj.fullPath]=true;obj.href=res[1];out.push(obj);if(out.length>=MAX_RESULTS){break}}}return out}function sortResults(results,isType){var ar=[];for(var entry in results){if(hasOwnPropertyRustdoc(results,entry)){var result=results[entry];result.word=searchWords[result.id];result.item=searchIndex[result.id]||{};ar.push(result)}}results=ar;if(results.length===0){return[]}results.sort(function(aaa,bbb){var a,b;a=(aaa.word!==val);b=(bbb.word!==val);if(a!==b){return a-b}a=(aaa.lev);b=(bbb.lev);if(a!==b){return a-b}a=(aaa.item.crate!==window.currentCrate);b=(bbb.item.crate!==window.currentCrate);if(a!==b){return a-b}a=aaa.word.length;b=bbb.word.length;if(a!==b){return a-b}a=aaa.word;b=bbb.word;if(a!==b){return(a>b?+1:-1)}a=(aaa.index<0);b=(bbb.index<0);if(a!==b){return a-b}a=aaa.index;b=bbb.index;if(a!==b){return a-b}if((aaa.item.ty===TY_PRIMITIVE&&bbb.item.ty!==TY_KEYWORD)||(aaa.item.ty===TY_KEYWORD&&bbb.item.ty!==TY_PRIMITIVE)){return-1}if((bbb.item.ty===TY_PRIMITIVE&&aaa.item.ty!==TY_PRIMITIVE)||(bbb.item.ty===TY_KEYWORD&&aaa.item.ty!==TY_KEYWORD)){return 1}a=(aaa.item.desc==="");b=(bbb.item.desc==="");if(a!==b){return a-b}a=aaa.item.ty;b=bbb.item.ty;if(a!==b){return a-b}a=aaa.item.path;b=bbb.item.path;if(a!==b){return(a>b?+1:-1)}return 0});for(var i=0,len=results.length;i"));return{name:val.substring(0,val.indexOf("<")),generics:values.split(/\s*,\s*/),}}return{name:val,generics:[],}}function checkGenerics(obj,val){var tmp_lev,elem_name;if(val.generics.length>0){if(obj.length>GENERICS_DATA&&obj[GENERICS_DATA].length>=val.generics.length){var elems=Object.create(null);var elength=obj[GENERICS_DATA].length;for(var x=0;xGENERICS_DATA&&obj[GENERICS_DATA].length>0){var elems=Object.create(null);len=obj[GENERICS_DATA].length;for(x=0;xGENERICS_DATA&&obj[GENERICS_DATA].length!==0){tmp_lev=checkGenerics(obj,val);if(tmp_lev<=MAX_LEV_DISTANCE){return tmp_lev}}}}else if(literalSearch){var found=false;if((!val.generics||val.generics.length===0)&&obj.length>GENERICS_DATA&&obj[GENERICS_DATA].length>0){found=obj[GENERICS_DATA].some(function(gen){return gen[NAME]===val.name})}return found?0:MAX_LEV_DISTANCE+1}lev_distance=Math.min(levenshtein(obj[NAME],val.name),lev_distance);if(lev_distance<=MAX_LEV_DISTANCE){lev_distance=Math.ceil((checkGenerics(obj,val)+lev_distance)/2)}if(obj.length>GENERICS_DATA&&obj[GENERICS_DATA].length>0){var olength=obj[GENERICS_DATA].length;for(x=0;x0){var length=obj.type[INPUTS_DATA].length;for(var i=0;iOUTPUT_DATA){var ret=obj.type[OUTPUT_DATA];if(typeof ret[0]==="string"){ret=[ret]}for(var x=0,len=ret.length;xlength){return MAX_LEV_DISTANCE+1}for(var i=0;ilength){break}var lev_total=0;var aborted=false;for(var x=0;xMAX_LEV_DISTANCE){aborted=true;break}lev_total+=lev}if(!aborted){ret_lev=Math.min(ret_lev,Math.round(lev_total/clength))}}return ret_lev}function typePassesFilter(filter,type){if(filter<=NO_TYPE_FILTER)return true;if(filter===type)return true;var name=itemTypes[type];switch(itemTypes[filter]){case"constant":return name==="associatedconstant";case"fn":return name==="method"||name==="tymethod";case"type":return name==="primitive"||name==="associatedtype";case"trait":return name==="traitalias"}return false}function createAliasFromItem(item){return{crate:item.crate,name:item.name,path:item.path,desc:item.desc,ty:item.ty,parent:item.parent,type:item.type,is_alias:true,}}function handleAliases(ret,query,filterCrates){var aliases=[];var crateAliases=[];if(filterCrates!==undefined){if(ALIASES[filterCrates]&&ALIASES[filterCrates][query.search]){var query_aliases=ALIASES[filterCrates][query.search];var len=query_aliases.length;for(var i=0;iMAX_RESULTS){ret.others.pop()}};onEach(aliases,pushFunc);onEach(crateAliases,pushFunc)}function addIntoResults(isExact,res,fullId,id,index,lev){if(lev===0||(!isExact&&lev<=MAX_LEV_DISTANCE)){if(res[fullId]!==undefined){var result=res[fullId];if(result.dontValidate||result.lev<=lev){return}}res[fullId]={id:id,index:index,dontValidate:isExact,lev:lev,}}}var nSearchWords=searchWords.length;var i,it;var ty;var fullId;var returned;var in_args;var len;if((val.charAt(0)==="\""||val.charAt(0)==="'")&&val.charAt(val.length-1)===val.charAt(0)){val=extractGenerics(val.substr(1,val.length-2));for(i=0;i")>-1){var trimmer=function(s){return s.trim()};var parts=val.split("->").map(trimmer);var input=parts[0];var inputs=input.split(",").map(trimmer).sort();for(i=0,len=inputs.length;i0){firstNonZeroDistance=distance;break}}in_args=firstNonZeroDistance}addIntoResults(true,results_in_args,fullId,i,-1,in_args);addIntoResults(true,results_returned,fullId,i,-1,returned);if(is_module){addIntoResults(true,results,fullId,i,-1,0)}}}query.inputs=inputs.map(function(input){return input.name});query.output=output.name}else{query.inputs=[val];query.output=val;query.search=val;val=val.replace(/_/g,"");var valGenerics=extractGenerics(val);var paths=valLower.split("::");removeEmptyStringsFromArray(paths);val=paths[paths.length-1];var contains=paths.slice(0,paths.length>1?paths.length-1:1);var lev,j;for(j=0;j1){lev=checkPath(contains,paths[paths.length-1],ty);if(lev>MAX_LEV_DISTANCE){continue}else if(lev>0){lev_add=lev/10}}returned=MAX_LEV_DISTANCE+1;in_args=MAX_LEV_DISTANCE+1;var index=-1;lev=MAX_LEV_DISTANCE+1;fullId=ty.id;if(searchWords[j].indexOf(split[i])>-1||searchWords[j].indexOf(val)>-1||ty.normalizedName.indexOf(val)>-1){if(typePassesFilter(typeFilter,ty.ty)&&results[fullId]===undefined){index=ty.normalizedName.indexOf(val)}}if((lev=levenshtein(searchWords[j],val))<=MAX_LEV_DISTANCE){if(typePassesFilter(typeFilter,ty.ty)){lev+=1}else{lev=MAX_LEV_DISTANCE+1}}in_args=findArg(ty,valGenerics,false,typeFilter);returned=checkReturned(ty,valGenerics,false,typeFilter);lev+=lev_add;if(lev>0&&val.length>3&&searchWords[j].indexOf(val)>-1){if(val.length<6){lev-=1}else{lev=0}}addIntoResults(false,results_in_args,fullId,j,index,in_args);addIntoResults(false,results_returned,fullId,j,index,returned);if(typePassesFilter(typeFilter,ty.ty)&&(index!==-1||lev<=MAX_LEV_DISTANCE)){if(index!==-1&&paths.length<2){lev=0}addIntoResults(false,results,fullId,j,index,lev)}}}var ret={"in_args":sortResults(results_in_args,true),"returned":sortResults(results_returned,true),"others":sortResults(results,false),};handleAliases(ret,query,filterCrates);return ret}function validateResult(name,path,keys,parent){for(var i=0,len=keys.length;i-1||path.indexOf(keys[i])>-1||(parent!==undefined&&parent.name!==undefined&&parent.name.toLowerCase().indexOf(keys[i])>-1)||levenshtein(name,keys[i])<=MAX_LEV_DISTANCE)){return false}}return true}function getQuery(raw){var matches,type="",query;query=raw;matches=query.match(/^(fn|mod|struct|enum|trait|type|const|macro)\s*:\s*/i);if(matches){type=matches[1].replace(/^const$/,"constant");query=query.substring(matches[0].length)}return{raw:raw,query:query,type:type,id:query+type}}function nextTab(direction){var next=(searchState.currentTab+direction+3)%searchState.focusedByTab.length;searchState.focusedByTab[searchState.currentTab]=document.activeElement;printTab(next);focusSearchResult()}function focusSearchResult(){var target=searchState.focusedByTab[searchState.currentTab]||document.querySelectorAll(".search-results.active a").item(0)||document.querySelectorAll("#titles > button").item(searchState.currentTab);if(target){target.focus()}}function buildHrefAndPath(item){var displayPath;var href;var type=itemTypes[item.ty];var name=item.name;var path=item.path;if(type==="mod"){displayPath=path+"::";href=window.rootPath+path.replace(/::/g,"/")+"/"+name+"/index.html"}else if(type==="primitive"||type==="keyword"){displayPath="";href=window.rootPath+path.replace(/::/g,"/")+"/"+type+"."+name+".html"}else if(type==="externcrate"){displayPath="";href=window.rootPath+name+"/index.html"}else if(item.parent!==undefined){var myparent=item.parent;var anchor="#"+type+"."+name;var parentType=itemTypes[myparent.ty];var pageType=parentType;var pageName=myparent.name;if(parentType==="primitive"){displayPath=myparent.name+"::"}else if(type==="structfield"&&parentType==="variant"){var enumNameIdx=item.path.lastIndexOf("::");var enumName=item.path.substr(enumNameIdx+2);path=item.path.substr(0,enumNameIdx);displayPath=path+"::"+enumName+"::"+myparent.name+"::";anchor="#variant."+myparent.name+".field."+name;pageType="enum";pageName=enumName}else{displayPath=path+"::"+myparent.name+"::"}href=window.rootPath+path.replace(/::/g,"/")+"/"+pageType+"."+pageName+".html"+anchor}else{displayPath=item.path+"::";href=window.rootPath+item.path.replace(/::/g,"/")+"/"+type+"."+name+".html"}return[displayPath,href]}function escape(content){var h1=document.createElement("h1");h1.textContent=content;return h1.innerHTML}function pathSplitter(path){var tmp=""+path.replace(/::/g,"::");if(tmp.endsWith("")){return tmp.slice(0,tmp.length-6)}return tmp}function addTab(array,query,display){var extraClass="";if(display===true){extraClass=" active"}var output=document.createElement("div");var length=0;if(array.length>0){output.className="search-results "+extraClass;array.forEach(function(item){var name=item.name;var type=itemTypes[item.ty];length+=1;var extra="";if(type==="primitive"){extra=" (primitive type)"}else if(type==="keyword"){extra=" (keyword)"}var link=document.createElement("a");link.className="result-"+type;link.href=item.href;var wrapper=document.createElement("div");var resultName=document.createElement("div");resultName.className="result-name";if(item.is_alias){var alias=document.createElement("span");alias.className="alias";var bold=document.createElement("b");bold.innerText=item.alias;alias.appendChild(bold);alias.insertAdjacentHTML("beforeend"," - see ");resultName.appendChild(alias)}resultName.insertAdjacentHTML("beforeend",item.displayPath+""+name+extra+"");wrapper.appendChild(resultName);var description=document.createElement("div");description.className="desc";var spanDesc=document.createElement("span");spanDesc.insertAdjacentHTML("beforeend",item.desc);description.appendChild(spanDesc);wrapper.appendChild(description);link.appendChild(wrapper);output.appendChild(link)})}else{output.className="search-failed"+extraClass;output.innerHTML="No results :(
    "+"Try on DuckDuckGo?

    "+"Or try looking in one of these:"}return[output,length]}function makeTabHeader(tabNb,text,nbElems){if(searchState.currentTab===tabNb){return""}return""}function showResults(results,go_to_first,filterCrates){var search=searchState.outputElement();if(go_to_first||(results.others.length===1&&getSettingValue("go-to-only-result")==="true"&&(!search.firstChild||search.firstChild.innerText!==searchState.loadingText))){var elem=document.createElement("a");elem.href=results.others[0].href;removeClass(elem,"active");document.body.appendChild(elem);elem.click();return}var query=getQuery(searchState.input.value);currentResults=query.id;var ret_others=addTab(results.others,query,true);var ret_in_args=addTab(results.in_args,query,false);var ret_returned=addTab(results.returned,query,false);var currentTab=searchState.currentTab;if((currentTab===0&&ret_others[1]===0)||(currentTab===1&&ret_in_args[1]===0)||(currentTab===2&&ret_returned[1]===0)){if(ret_others[1]!==0){currentTab=0}else if(ret_in_args[1]!==0){currentTab=1}else if(ret_returned[1]!==0){currentTab=2}}let crates="";if(window.ALL_CRATES.length>1){crates=` in `}var output=`
    -

    Results for ${escape(query.query)} `+(query.type?" (type: "+escape(query.type)+")":"")+"

    "+crates+`
    `+makeTabHeader(0,"In Names",ret_others[1])+makeTabHeader(1,"In Parameters",ret_in_args[1])+makeTabHeader(2,"In Return Types",ret_returned[1])+"
    ";var resultsElem=document.createElement("div");resultsElem.id="results";resultsElem.appendChild(ret_others[0]);resultsElem.appendChild(ret_in_args[0]);resultsElem.appendChild(ret_returned[0]);search.innerHTML=output;let crateSearch=document.getElementById("crate-search");if(crateSearch){crateSearch.addEventListener("input",updateCrate)}search.appendChild(resultsElem);searchState.focusedByTab=[null,null,null];searchState.showResults(search);var elems=document.getElementById("titles").childNodes;elems[0].onclick=function(){printTab(0)};elems[1].onclick=function(){printTab(1)};elems[2].onclick=function(){printTab(2)};printTab(currentTab)}function execSearch(query,searchWords,filterCrates){function getSmallest(arrays,positions,notDuplicates){var start=null;for(var it=0,len=positions.length;itpositions[it]&&(start===null||start>arrays[it][positions[it]].lev)&&!notDuplicates[arrays[it][positions[it]].fullPath]){start=arrays[it][positions[it]].lev}}return start}function mergeArrays(arrays){var ret=[];var positions=[];var notDuplicates={};for(var x=0,arrays_len=arrays.length;xpositions[x]&&arrays[x][positions[x]].lev===smallest&&!notDuplicates[arrays[x][positions[x]].fullPath]){ret.push(arrays[x][positions[x]]);notDuplicates[arrays[x][positions[x]].fullPath]=true;positions[x]+=1}}}return ret}function tokenizeQuery(raw){var i,matched;var l=raw.length;var depth=0;var nextAngle=/(<|>)/g;var ret=[];var start=0;for(i=0;i'){depth+=1}break;case">":if(depth>0){depth-=1}break;case",":if(depth===0){ret.push(raw.substring(start,i));start=i+1}break}}if(start!==i){ret.push(raw.substring(start,i))}return ret}var queries=tokenizeQuery(query.raw);var results={"in_args":[],"returned":[],"others":[],};for(var i=0,len=queries.length;i1){return{"in_args":mergeArrays(results.in_args),"returned":mergeArrays(results.returned),"others":mergeArrays(results.others),}}return{"in_args":results.in_args[0],"returned":results.returned[0],"others":results.others[0],}}function getFilterCrates(){var elem=document.getElementById("crate-search");if(elem&&elem.value!=="All crates"&&hasOwnPropertyRustdoc(rawSearchIndex,elem.value)){return elem.value}return undefined}function search(e,forced){var params=searchState.getQueryStringParams();var query=getQuery(searchState.input.value.trim());if(e){e.preventDefault()}if(query.query.length===0){return}if(!forced&&query.id===currentResults){if(query.query.length>0){searchState.putBackSearch(searchState.input)}return}searchState.title="Results for "+query.query+" - Rust";if(searchState.browserSupportsHistoryApi()){var newURL=getNakedUrl()+"?search="+encodeURIComponent(query.raw)+window.location.hash;if(!history.state&&!params.search){history.pushState(query,"",newURL)}else{history.replaceState(query,"",newURL)}}var filterCrates=getFilterCrates();showResults(execSearch(query,searchWords,filterCrates),params["go_to_first"],filterCrates)}function buildIndex(rawSearchIndex){searchIndex=[];var searchWords=[];var i,word;var currentIndex=0;var id=0;for(var crate in rawSearchIndex){if(!hasOwnPropertyRustdoc(rawSearchIndex,crate)){continue}var crateSize=0;var crateCorpus=rawSearchIndex[crate];searchWords.push(crate);var crateRow={crate:crate,ty:1,name:crate,path:"",desc:crateCorpus.doc,parent:undefined,type:null,id:id,normalizedName:crate.indexOf("_")===-1?crate:crate.replace(/_/g,""),};id+=1;searchIndex.push(crateRow);currentIndex+=1;var itemTypes=crateCorpus.t;var itemNames=crateCorpus.n;var itemPaths=crateCorpus.q;var itemDescs=crateCorpus.d;var itemParentIdxs=crateCorpus.i;var itemFunctionSearchTypes=crateCorpus.f;var paths=crateCorpus.p;var aliases=crateCorpus.a;var len=paths.length;for(i=0;i0?paths[itemParentIdxs[i]-1]:undefined,type:itemFunctionSearchTypes[i],id:id,normalizedName:word.indexOf("_")===-1?word:word.replace(/_/g,""),};id+=1;searchIndex.push(row);lastPath=row.path;crateSize+=1}if(aliases){ALIASES[crate]={};var j,local_aliases;for(var alias_name in aliases){if(!hasOwnPropertyRustdoc(aliases,alias_name)){continue}if(!hasOwnPropertyRustdoc(ALIASES[crate],alias_name)){ALIASES[crate][alias_name]=[]}local_aliases=aliases[alias_name];for(j=0,len=local_aliases.length;j0){searchState.input.value=params.search;search(e)}else{searchState.input.value="";searchState.hideResults()}})}window.onpageshow=function(){var qSearch=searchState.getQueryStringParams().search;if(searchState.input.value===""&&qSearch){searchState.input.value=qSearch}search()}}function updateCrate(ev){updateLocalStorage("rustdoc-saved-filter-crate",ev.target.value);currentResults=null;search(undefined,true)}searchWords=buildIndex(rawSearchIndex);registerSearchEvents();if(searchState.getQueryStringParams().search){search()}};if(window.searchIndex!==undefined){initSearch(window.searchIndex)}})() \ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/settings.css b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/settings.css deleted file mode 100644 index 670986588e..0000000000 --- a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/settings.css +++ /dev/null @@ -1 +0,0 @@ -.setting-line{padding:5px;position:relative;}.setting-line>div{display:inline-block;vertical-align:top;font-size:17px;padding-top:2px;}.setting-line>.title{font-size:19px;width:100%;max-width:none;border-bottom:1px solid;}.toggle{position:relative;display:inline-block;width:45px;height:27px;margin-right:20px;}.toggle input{opacity:0;position:absolute;}.select-wrapper{float:right;position:relative;height:27px;min-width:25%;}.select-wrapper select{appearance:none;-moz-appearance:none;-webkit-appearance:none;background:none;border:2px solid #ccc;padding-right:28px;width:100%;}.select-wrapper img{pointer-events:none;position:absolute;right:0;bottom:0;background:#ccc;height:100%;width:28px;padding:0px 4px;}.select-wrapper select option{color:initial;}.slider{position:absolute;cursor:pointer;top:0;left:0;right:0;bottom:0;background-color:#ccc;-webkit-transition:.3s;transition:.3s;}.slider:before{position:absolute;content:"";height:19px;width:19px;left:4px;bottom:4px;background-color:white;-webkit-transition:.3s;transition:.3s;}input:checked+.slider{background-color:#2196F3;}input:focus+.slider{box-shadow:0 0 0 2px #0a84ff,0 0 0 6px rgba(10,132,255,0.3);}input:checked+.slider:before{-webkit-transform:translateX(19px);-ms-transform:translateX(19px);transform:translateX(19px);}.setting-line>.sub-settings{padding-left:42px;width:100%;display:block;} \ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/settings.html b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/settings.html index 1ebee7be3a..9cff0c494d 100644 --- a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/settings.html +++ b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/settings.html @@ -1,10 +1,2 @@ -Rustdoc settings - -

    Rustdoc settings

    Theme preferences
    Use system theme
    Theme
    Preferred dark theme
    Preferred light theme
    -
    Auto-hide item contents for large items.
    Auto-hide item methods' documentation
    Auto-hide trait implementation documentation
    Directly go to item in search if there is only one result
    Show line numbers on code examples
    Disable keyboard shortcuts
    - \ No newline at end of file +Rustdoc settings

    Rustdoc settings

    Back
    \ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/settings.js b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/settings.js deleted file mode 100644 index b26bdadc6c..0000000000 --- a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/settings.js +++ /dev/null @@ -1 +0,0 @@ -(function(){function changeSetting(settingName,value){updateLocalStorage("rustdoc-"+settingName,value);switch(settingName){case"theme":case"preferred-dark-theme":case"preferred-light-theme":case"use-system-theme":updateSystemTheme();updateLightAndDark();break}}function handleKey(ev){if(ev.ctrlKey||ev.altKey||ev.metaKey){return}switch(getVirtualKey(ev)){case"Enter":case"Return":case"Space":ev.target.checked=!ev.target.checked;ev.preventDefault();break}}function showLightAndDark(){addClass(document.getElementById("theme").parentElement.parentElement,"hidden");removeClass(document.getElementById("preferred-light-theme").parentElement.parentElement,"hidden");removeClass(document.getElementById("preferred-dark-theme").parentElement.parentElement,"hidden")}function hideLightAndDark(){addClass(document.getElementById("preferred-light-theme").parentElement.parentElement,"hidden");addClass(document.getElementById("preferred-dark-theme").parentElement.parentElement,"hidden");removeClass(document.getElementById("theme").parentElement.parentElement,"hidden")}function updateLightAndDark(){if(getSettingValue("use-system-theme")!=="false"){showLightAndDark()}else{hideLightAndDark()}}function setEvents(){updateLightAndDark();onEachLazy(document.getElementsByClassName("slider"),function(elem){var toggle=elem.previousElementSibling;var settingId=toggle.id;var settingValue=getSettingValue(settingId);if(settingValue!==null){toggle.checked=settingValue==="true"}toggle.onchange=function(){changeSetting(this.id,this.checked)};toggle.onkeyup=handleKey;toggle.onkeyrelease=handleKey});onEachLazy(document.getElementsByClassName("select-wrapper"),function(elem){var select=elem.getElementsByTagName("select")[0];var settingId=select.id;var settingValue=getSettingValue(settingId);if(settingValue!==null){select.value=settingValue}select.onchange=function(){changeSetting(this.id,this.value)}})}window.addEventListener("DOMContentLoaded",setEvents)})() \ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/source-files.js b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/source-files.js index 8dcec546df..8777308688 100644 --- a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/source-files.js +++ b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/source-files.js @@ -1,3 +1,4 @@ -var N = null;var sourcesIndex = {}; -sourcesIndex["bdk"] = {"name":"","dirs":[{"name":"blockchain","dirs":[{"name":"compact_filters","files":["mod.rs","peer.rs","store.rs","sync.rs"]},{"name":"esplora","files":["blocking.rs","mod.rs"]}],"files":["any.rs","electrum.rs","mod.rs","rpc.rs","script_sync.rs"]},{"name":"database","files":["any.rs","keyvalue.rs","memory.rs","mod.rs","sqlite.rs"]},{"name":"descriptor","files":["checksum.rs","dsl.rs","error.rs","mod.rs","policy.rs","template.rs"]},{"name":"keys","files":["bip39.rs","mod.rs"]},{"name":"psbt","files":["mod.rs"]},{"name":"testutils","files":["mod.rs"]},{"name":"wallet","files":["coin_selection.rs","export.rs","hardwaresigner.rs","mod.rs","signer.rs","time.rs","tx_builder.rs","utils.rs","verify.rs"]}],"files":["error.rs","lib.rs","types.rs"]}; +var sourcesIndex = JSON.parse('{\ +"bdk":["",[["blockchain",[["compact_filters",[],["mod.rs","peer.rs","store.rs","sync.rs"]],["esplora",[],["blocking.rs","mod.rs"]]],["any.rs","electrum.rs","mod.rs","rpc.rs","script_sync.rs"]],["database",[],["any.rs","keyvalue.rs","memory.rs","mod.rs","sqlite.rs"]],["descriptor",[],["checksum.rs","dsl.rs","error.rs","mod.rs","policy.rs","template.rs"]],["keys",[],["bip39.rs","mod.rs"]],["psbt",[],["mod.rs"]],["testutils",[],["mod.rs"]],["wallet",[],["coin_selection.rs","export.rs","hardwaresigner.rs","mod.rs","signer.rs","time.rs","tx_builder.rs","utils.rs","verify.rs"]]],["error.rs","lib.rs","types.rs"]]\ +}'); createSourceSidebar(); diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/source-script.js b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/source-script.js deleted file mode 100644 index 3ce85994f3..0000000000 --- a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/source-script.js +++ /dev/null @@ -1 +0,0 @@ -(function(){function getCurrentFilePath(){var parts=window.location.pathname.split("/");var rootPathParts=window.rootPath.split("/");for(var i=0,len=rootPathParts.length;i"){sidebar.classList.add("expanded");child.innerText="<";updateLocalStorage("rustdoc-source-sidebar-show","true")}else{sidebar.classList.remove("expanded");child.innerText=">";updateLocalStorage("rustdoc-source-sidebar-show","false")}}function createSidebarToggle(){var sidebarToggle=document.createElement("div");sidebarToggle.id="sidebar-toggle";sidebarToggle.onclick=toggleSidebar;var inner=document.createElement("div");if(getCurrentValue("rustdoc-source-sidebar-show")==="true"){inner.innerText="<"}else{inner.innerText=">"}sidebarToggle.appendChild(inner);return sidebarToggle}function createSourceSidebar(){if(!window.rootPath.endsWith("/")){window.rootPath+="/"}var container=document.querySelector("nav.sidebar");var sidebarToggle=createSidebarToggle();container.insertBefore(sidebarToggle,container.firstChild);var sidebar=document.createElement("div");sidebar.id="source-sidebar";if(getCurrentValue("rustdoc-source-sidebar-show")!=="true"){container.classList.remove("expanded")}else{container.classList.add("expanded")}var currentFile=getCurrentFilePath();var hasFoundFile=false;var title=document.createElement("div");title.className="title";title.innerText="Files";sidebar.appendChild(title);Object.keys(sourcesIndex).forEach(function(key){sourcesIndex[key].name=key;hasFoundFile=createDirEntry(sourcesIndex[key],sidebar,"",currentFile,hasFoundFile)});container.appendChild(sidebar);var selected_elem=sidebar.getElementsByClassName("selected")[0];if(typeof selected_elem!=="undefined"){selected_elem.focus()}}var lineNumbersRegex=/^#?(\d+)(?:-(\d+))?$/;function highlightSourceLines(scrollTo,match){if(typeof match==="undefined"){match=window.location.hash.match(lineNumbersRegex)}if(!match){return}var from=parseInt(match[1],10);var to=from;if(typeof match[2]!=="undefined"){to=parseInt(match[2],10)}if(tocur_line_id){var tmp=prev_line_id;prev_line_id=cur_line_id;cur_line_id=tmp}set_fragment(prev_line_id+"-"+cur_line_id)}else{prev_line_id=cur_line_id;set_fragment(cur_line_id)}}}());window.addEventListener("hashchange",function(){var match=window.location.hash.match(lineNumbersRegex);if(match){return highlightSourceLines(false,match)}});onEachLazy(document.getElementsByClassName("line-numbers"),function(el){el.addEventListener("click",handleSourceHighlight)});highlightSourceLines(true);window.createSourceSidebar=createSourceSidebar})() \ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/src/bdk/blockchain/any.rs.html b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/src/bdk/blockchain/any.rs.html index 1946a2b5cb..15589792fe 100644 --- a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/src/bdk/blockchain/any.rs.html +++ b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/src/bdk/blockchain/any.rs.html @@ -1,502 +1,495 @@ -any.rs - source - -
      1
    -  2
    -  3
    -  4
    -  5
    -  6
    -  7
    -  8
    -  9
    - 10
    - 11
    - 12
    - 13
    - 14
    - 15
    - 16
    - 17
    - 18
    - 19
    - 20
    - 21
    - 22
    - 23
    - 24
    - 25
    - 26
    - 27
    - 28
    - 29
    - 30
    - 31
    - 32
    - 33
    - 34
    - 35
    - 36
    - 37
    - 38
    - 39
    - 40
    - 41
    - 42
    - 43
    - 44
    - 45
    - 46
    - 47
    - 48
    - 49
    - 50
    - 51
    - 52
    - 53
    - 54
    - 55
    - 56
    - 57
    - 58
    - 59
    - 60
    - 61
    - 62
    - 63
    - 64
    - 65
    - 66
    - 67
    - 68
    - 69
    - 70
    - 71
    - 72
    - 73
    - 74
    - 75
    - 76
    - 77
    - 78
    - 79
    - 80
    - 81
    - 82
    - 83
    - 84
    - 85
    - 86
    - 87
    - 88
    - 89
    - 90
    - 91
    - 92
    - 93
    - 94
    - 95
    - 96
    - 97
    - 98
    - 99
    -100
    -101
    -102
    -103
    -104
    -105
    -106
    -107
    -108
    -109
    -110
    -111
    -112
    -113
    -114
    -115
    -116
    -117
    -118
    -119
    -120
    -121
    -122
    -123
    -124
    -125
    -126
    -127
    -128
    -129
    -130
    -131
    -132
    -133
    -134
    -135
    -136
    -137
    -138
    -139
    -140
    -141
    -142
    -143
    -144
    -145
    -146
    -147
    -148
    -149
    -150
    -151
    -152
    -153
    -154
    -155
    -156
    -157
    -158
    -159
    -160
    -161
    -162
    -163
    -164
    -165
    -166
    -167
    -168
    -169
    -170
    -171
    -172
    -173
    -174
    -175
    -176
    -177
    -178
    -179
    -180
    -181
    -182
    -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
    -245
    -246
    -
    // Bitcoin Dev Kit
    -// Written in 2020 by Alekos Filini <alekos.filini@gmail.com>
    -//
    -// Copyright (c) 2020-2021 Bitcoin Dev Kit Developers
    -//
    -// This file is licensed under the Apache License, Version 2.0 <LICENSE-APACHE
    -// or http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
    -// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your option.
    -// You may not use this file except in accordance with one or both of these
    -// licenses.
    +any.rs - source
    1
    +2
    +3
    +4
    +5
    +6
    +7
    +8
    +9
    +10
    +11
    +12
    +13
    +14
    +15
    +16
    +17
    +18
    +19
    +20
    +21
    +22
    +23
    +24
    +25
    +26
    +27
    +28
    +29
    +30
    +31
    +32
    +33
    +34
    +35
    +36
    +37
    +38
    +39
    +40
    +41
    +42
    +43
    +44
    +45
    +46
    +47
    +48
    +49
    +50
    +51
    +52
    +53
    +54
    +55
    +56
    +57
    +58
    +59
    +60
    +61
    +62
    +63
    +64
    +65
    +66
    +67
    +68
    +69
    +70
    +71
    +72
    +73
    +74
    +75
    +76
    +77
    +78
    +79
    +80
    +81
    +82
    +83
    +84
    +85
    +86
    +87
    +88
    +89
    +90
    +91
    +92
    +93
    +94
    +95
    +96
    +97
    +98
    +99
    +100
    +101
    +102
    +103
    +104
    +105
    +106
    +107
    +108
    +109
    +110
    +111
    +112
    +113
    +114
    +115
    +116
    +117
    +118
    +119
    +120
    +121
    +122
    +123
    +124
    +125
    +126
    +127
    +128
    +129
    +130
    +131
    +132
    +133
    +134
    +135
    +136
    +137
    +138
    +139
    +140
    +141
    +142
    +143
    +144
    +145
    +146
    +147
    +148
    +149
    +150
    +151
    +152
    +153
    +154
    +155
    +156
    +157
    +158
    +159
    +160
    +161
    +162
    +163
    +164
    +165
    +166
    +167
    +168
    +169
    +170
    +171
    +172
    +173
    +174
    +175
    +176
    +177
    +178
    +179
    +180
    +181
    +182
    +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
    +245
    +246
    +
    // Bitcoin Dev Kit
    +// Written in 2020 by Alekos Filini <alekos.filini@gmail.com>
    +//
    +// Copyright (c) 2020-2021 Bitcoin Dev Kit Developers
    +//
    +// This file is licensed under the Apache License, Version 2.0 <LICENSE-APACHE
    +// or http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
    +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your option.
    +// You may not use this file except in accordance with one or both of these
    +// licenses.
     
    -//! Runtime-checked blockchain types
    -//!
    -//! This module provides the implementation of [`AnyBlockchain`] which allows switching the
    -//! inner [`Blockchain`] type at runtime.
    -//!
    -//! ## Example
    -//!
    -//! When paired with the use of [`ConfigurableBlockchain`], it allows creating any
    -//! blockchain type supported using a single line of code:
    -//!
    -//! ```no_run
    -//! # use bitcoin::Network;
    -//! # use bdk::blockchain::*;
    -//! # #[cfg(all(feature = "esplora", feature = "ureq"))]
    -//! # {
    -//! let config = serde_json::from_str("...")?;
    -//! let blockchain = AnyBlockchain::from_config(&config)?;
    -//! let height = blockchain.get_height();
    -//! # }
    -//! # Ok::<(), bdk::Error>(())
    -//! ```
    +//! Runtime-checked blockchain types
    +//!
    +//! This module provides the implementation of [`AnyBlockchain`] which allows switching the
    +//! inner [`Blockchain`] type at runtime.
    +//!
    +//! ## Example
    +//!
    +//! When paired with the use of [`ConfigurableBlockchain`], it allows creating any
    +//! blockchain type supported using a single line of code:
    +//!
    +//! ```no_run
    +//! # use bitcoin::Network;
    +//! # use bdk::blockchain::*;
    +//! # #[cfg(all(feature = "esplora", feature = "ureq"))]
    +//! # {
    +//! let config = serde_json::from_str("...")?;
    +//! let blockchain = AnyBlockchain::from_config(&config)?;
    +//! let height = blockchain.get_height();
    +//! # }
    +//! # Ok::<(), bdk::Error>(())
    +//! ```
     
    -use super::*;
    +use super::*;
     
    -macro_rules! impl_from {
    -    ( boxed $from:ty, $to:ty, $variant:ident, $( $cfg:tt )* ) => {
    -        $( $cfg )*
    -        impl From<$from> for $to {
    -            fn from(inner: $from) -> Self {
    -                <$to>::$variant(Box::new(inner))
    +macro_rules! impl_from {
    +    ( boxed $from:ty, $to:ty, $variant:ident, $( $cfg:tt )* ) => {
    +        $( $cfg )*
    +        impl From<$from> for $to {
    +            fn from(inner: $from) -> Self {
    +                <$to>::$variant(Box::new(inner))
                 }
             }
         };
    -    ( $from:ty, $to:ty, $variant:ident, $( $cfg:tt )* ) => {
    -        $( $cfg )*
    -        impl From<$from> for $to {
    -            fn from(inner: $from) -> Self {
    -                <$to>::$variant(inner)
    +    ( $from:ty, $to:ty, $variant:ident, $( $cfg:tt )* ) => {
    +        $( $cfg )*
    +        impl From<$from> for $to {
    +            fn from(inner: $from) -> Self {
    +                <$to>::$variant(inner)
                 }
             }
         };
     }
     
    -macro_rules! impl_inner_method {
    -    ( $self:expr, $name:ident $(, $args:expr)* ) => {
    -        match $self {
    -            #[cfg(feature = "electrum")]
    -            AnyBlockchain::Electrum(inner) => inner.$name( $($args, )* ),
    -            #[cfg(feature = "esplora")]
    -            AnyBlockchain::Esplora(inner) => inner.$name( $($args, )* ),
    -            #[cfg(feature = "compact_filters")]
    -            AnyBlockchain::CompactFilters(inner) => inner.$name( $($args, )* ),
    -            #[cfg(feature = "rpc")]
    -            AnyBlockchain::Rpc(inner) => inner.$name( $($args, )* ),
    +macro_rules! impl_inner_method {
    +    ( $self:expr, $name:ident $(, $args:expr)* ) => {
    +        match $self {
    +            #[cfg(feature = "electrum")]
    +            AnyBlockchain::Electrum(inner) => inner.$name( $($args, )* ),
    +            #[cfg(feature = "esplora")]
    +            AnyBlockchain::Esplora(inner) => inner.$name( $($args, )* ),
    +            #[cfg(feature = "compact_filters")]
    +            AnyBlockchain::CompactFilters(inner) => inner.$name( $($args, )* ),
    +            #[cfg(feature = "rpc")]
    +            AnyBlockchain::Rpc(inner) => inner.$name( $($args, )* ),
             }
         }
     }
     
    -/// Type that can contain any of the [`Blockchain`] types defined by the library
    -///
    -/// It allows switching backend at runtime
    -///
    -/// See [this module](crate::blockchain::any)'s documentation for a usage example.
    -pub enum AnyBlockchain {
    -    #[cfg(feature = "electrum")]
    -    #[cfg_attr(docsrs, doc(cfg(feature = "electrum")))]
    -    /// Electrum client
    -    Electrum(Box<electrum::ElectrumBlockchain>),
    -    #[cfg(feature = "esplora")]
    -    #[cfg_attr(docsrs, doc(cfg(feature = "esplora")))]
    -    /// Esplora client
    -    Esplora(Box<esplora::EsploraBlockchain>),
    -    #[cfg(feature = "compact_filters")]
    -    #[cfg_attr(docsrs, doc(cfg(feature = "compact_filters")))]
    -    /// Compact filters client
    -    CompactFilters(Box<compact_filters::CompactFiltersBlockchain>),
    -    #[cfg(feature = "rpc")]
    -    #[cfg_attr(docsrs, doc(cfg(feature = "rpc")))]
    -    /// RPC client
    -    Rpc(Box<rpc::RpcBlockchain>),
    +/// Type that can contain any of the [`Blockchain`] types defined by the library
    +///
    +/// It allows switching backend at runtime
    +///
    +/// See [this module](crate::blockchain::any)'s documentation for a usage example.
    +pub enum AnyBlockchain {
    +    #[cfg(feature = "electrum")]
    +    #[cfg_attr(docsrs, doc(cfg(feature = "electrum")))]
    +    /// Electrum client
    +    Electrum(Box<electrum::ElectrumBlockchain>),
    +    #[cfg(feature = "esplora")]
    +    #[cfg_attr(docsrs, doc(cfg(feature = "esplora")))]
    +    /// Esplora client
    +    Esplora(Box<esplora::EsploraBlockchain>),
    +    #[cfg(feature = "compact_filters")]
    +    #[cfg_attr(docsrs, doc(cfg(feature = "compact_filters")))]
    +    /// Compact filters client
    +    CompactFilters(Box<compact_filters::CompactFiltersBlockchain>),
    +    #[cfg(feature = "rpc")]
    +    #[cfg_attr(docsrs, doc(cfg(feature = "rpc")))]
    +    /// RPC client
    +    Rpc(Box<rpc::RpcBlockchain>),
     }
     
    -#[maybe_async]
    -impl Blockchain for AnyBlockchain {
    -    fn get_capabilities(&self) -> HashSet<Capability> {
    -        maybe_await!(impl_inner_method!(self, get_capabilities))
    +#[maybe_async]
    +impl Blockchain for AnyBlockchain {
    +    fn get_capabilities(&self) -> HashSet<Capability> {
    +        maybe_await!(impl_inner_method!(self, get_capabilities))
         }
     
    -    fn broadcast(&self, tx: &Transaction) -> Result<(), Error> {
    -        maybe_await!(impl_inner_method!(self, broadcast, tx))
    +    fn broadcast(&self, tx: &Transaction) -> Result<(), Error> {
    +        maybe_await!(impl_inner_method!(self, broadcast, tx))
         }
     
    -    fn estimate_fee(&self, target: usize) -> Result<FeeRate, Error> {
    -        maybe_await!(impl_inner_method!(self, estimate_fee, target))
    +    fn estimate_fee(&self, target: usize) -> Result<FeeRate, Error> {
    +        maybe_await!(impl_inner_method!(self, estimate_fee, target))
         }
     }
     
    -#[maybe_async]
    -impl GetHeight for AnyBlockchain {
    -    fn get_height(&self) -> Result<u32, Error> {
    -        maybe_await!(impl_inner_method!(self, get_height))
    +#[maybe_async]
    +impl GetHeight for AnyBlockchain {
    +    fn get_height(&self) -> Result<u32, Error> {
    +        maybe_await!(impl_inner_method!(self, get_height))
         }
     }
     
    -#[maybe_async]
    -impl GetTx for AnyBlockchain {
    -    fn get_tx(&self, txid: &Txid) -> Result<Option<Transaction>, Error> {
    -        maybe_await!(impl_inner_method!(self, get_tx, txid))
    +#[maybe_async]
    +impl GetTx for AnyBlockchain {
    +    fn get_tx(&self, txid: &Txid) -> Result<Option<Transaction>, Error> {
    +        maybe_await!(impl_inner_method!(self, get_tx, txid))
         }
     }
     
    -#[maybe_async]
    -impl GetBlockHash for AnyBlockchain {
    -    fn get_block_hash(&self, height: u64) -> Result<BlockHash, Error> {
    -        maybe_await!(impl_inner_method!(self, get_block_hash, height))
    +#[maybe_async]
    +impl GetBlockHash for AnyBlockchain {
    +    fn get_block_hash(&self, height: u64) -> Result<BlockHash, Error> {
    +        maybe_await!(impl_inner_method!(self, get_block_hash, height))
         }
     }
     
    -#[maybe_async]
    -impl WalletSync for AnyBlockchain {
    -    fn wallet_sync<D: BatchDatabase>(
    +#[maybe_async]
    +impl WalletSync for AnyBlockchain {
    +    fn wallet_sync<D: BatchDatabase>(
             &self,
    -        database: &mut D,
    -        progress_update: Box<dyn Progress>,
    -    ) -> Result<(), Error> {
    +        database: &mut D,
    +        progress_update: Box<dyn Progress>,
    +    ) -> Result<(), Error> {
             maybe_await!(impl_inner_method!(
                 self,
    -            wallet_sync,
    -            database,
    -            progress_update
    +            wallet_sync,
    +            database,
    +            progress_update
             ))
         }
     
    -    fn wallet_setup<D: BatchDatabase>(
    +    fn wallet_setup<D: BatchDatabase>(
             &self,
    -        database: &mut D,
    -        progress_update: Box<dyn Progress>,
    -    ) -> Result<(), Error> {
    +        database: &mut D,
    +        progress_update: Box<dyn Progress>,
    +    ) -> Result<(), Error> {
             maybe_await!(impl_inner_method!(
                 self,
    -            wallet_setup,
    -            database,
    -            progress_update
    +            wallet_setup,
    +            database,
    +            progress_update
             ))
         }
     }
     
    -impl_from!(boxed electrum::ElectrumBlockchain, AnyBlockchain, Electrum, #[cfg(feature = "electrum")]);
    -impl_from!(boxed esplora::EsploraBlockchain, AnyBlockchain, Esplora, #[cfg(feature = "esplora")]);
    -impl_from!(boxed compact_filters::CompactFiltersBlockchain, AnyBlockchain, CompactFilters, #[cfg(feature = "compact_filters")]);
    -impl_from!(boxed rpc::RpcBlockchain, AnyBlockchain, Rpc, #[cfg(feature = "rpc")]);
    +impl_from!(boxed electrum::ElectrumBlockchain, AnyBlockchain, Electrum, #[cfg(feature = "electrum")]);
    +impl_from!(boxed esplora::EsploraBlockchain, AnyBlockchain, Esplora, #[cfg(feature = "esplora")]);
    +impl_from!(boxed compact_filters::CompactFiltersBlockchain, AnyBlockchain, CompactFilters, #[cfg(feature = "compact_filters")]);
    +impl_from!(boxed rpc::RpcBlockchain, AnyBlockchain, Rpc, #[cfg(feature = "rpc")]);
     
    -/// Type that can contain any of the blockchain configurations defined by the library
    -///
    -/// This allows storing a single configuration that can be loaded into an [`AnyBlockchain`]
    -/// instance. Wallets that plan to offer users the ability to switch blockchain backend at runtime
    -/// will find this particularly useful.
    -///
    -/// This type can be serialized from a JSON object like:
    -///
    -/// ```
    -/// # #[cfg(feature = "electrum")]
    -/// # {
    -/// use bdk::blockchain::{electrum::ElectrumBlockchainConfig, AnyBlockchainConfig};
    -/// let config: AnyBlockchainConfig = serde_json::from_str(
    -///     r#"{
    -///    "type" : "electrum",
    -///    "url" : "ssl://electrum.blockstream.info:50002",
    -///    "retry": 2,
    -///    "stop_gap": 20
    -/// }"#,
    -/// )
    -/// .unwrap();
    -/// assert_eq!(
    -///     config,
    -///     AnyBlockchainConfig::Electrum(ElectrumBlockchainConfig {
    -///         url: "ssl://electrum.blockstream.info:50002".into(),
    -///         retry: 2,
    -///         socks5: None,
    -///         timeout: None,
    -///         stop_gap: 20,
    -///     })
    -/// );
    -/// # }
    -/// ```
    -#[derive(Debug, serde::Serialize, serde::Deserialize, Clone, PartialEq, Eq)]
    -#[serde(tag = "type", rename_all = "snake_case")]
    -pub enum AnyBlockchainConfig {
    -    #[cfg(feature = "electrum")]
    -    #[cfg_attr(docsrs, doc(cfg(feature = "electrum")))]
    -    /// Electrum client
    -    Electrum(electrum::ElectrumBlockchainConfig),
    -    #[cfg(feature = "esplora")]
    -    #[cfg_attr(docsrs, doc(cfg(feature = "esplora")))]
    -    /// Esplora client
    -    Esplora(esplora::EsploraBlockchainConfig),
    -    #[cfg(feature = "compact_filters")]
    -    #[cfg_attr(docsrs, doc(cfg(feature = "compact_filters")))]
    -    /// Compact filters client
    -    CompactFilters(compact_filters::CompactFiltersBlockchainConfig),
    -    #[cfg(feature = "rpc")]
    -    #[cfg_attr(docsrs, doc(cfg(feature = "rpc")))]
    -    /// RPC client configuration
    -    Rpc(rpc::RpcConfig),
    +/// Type that can contain any of the blockchain configurations defined by the library
    +///
    +/// This allows storing a single configuration that can be loaded into an [`AnyBlockchain`]
    +/// instance. Wallets that plan to offer users the ability to switch blockchain backend at runtime
    +/// will find this particularly useful.
    +///
    +/// This type can be serialized from a JSON object like:
    +///
    +/// ```
    +/// # #[cfg(feature = "electrum")]
    +/// # {
    +/// use bdk::blockchain::{electrum::ElectrumBlockchainConfig, AnyBlockchainConfig};
    +/// let config: AnyBlockchainConfig = serde_json::from_str(
    +///     r#"{
    +///    "type" : "electrum",
    +///    "url" : "ssl://electrum.blockstream.info:50002",
    +///    "retry": 2,
    +///    "stop_gap": 20
    +/// }"#,
    +/// )
    +/// .unwrap();
    +/// assert_eq!(
    +///     config,
    +///     AnyBlockchainConfig::Electrum(ElectrumBlockchainConfig {
    +///         url: "ssl://electrum.blockstream.info:50002".into(),
    +///         retry: 2,
    +///         socks5: None,
    +///         timeout: None,
    +///         stop_gap: 20,
    +///     })
    +/// );
    +/// # }
    +/// ```
    +#[derive(Debug, serde::Serialize, serde::Deserialize, Clone, PartialEq, Eq)]
    +#[serde(tag = "type", rename_all = "snake_case")]
    +pub enum AnyBlockchainConfig {
    +    #[cfg(feature = "electrum")]
    +    #[cfg_attr(docsrs, doc(cfg(feature = "electrum")))]
    +    /// Electrum client
    +    Electrum(electrum::ElectrumBlockchainConfig),
    +    #[cfg(feature = "esplora")]
    +    #[cfg_attr(docsrs, doc(cfg(feature = "esplora")))]
    +    /// Esplora client
    +    Esplora(esplora::EsploraBlockchainConfig),
    +    #[cfg(feature = "compact_filters")]
    +    #[cfg_attr(docsrs, doc(cfg(feature = "compact_filters")))]
    +    /// Compact filters client
    +    CompactFilters(compact_filters::CompactFiltersBlockchainConfig),
    +    #[cfg(feature = "rpc")]
    +    #[cfg_attr(docsrs, doc(cfg(feature = "rpc")))]
    +    /// RPC client configuration
    +    Rpc(rpc::RpcConfig),
     }
     
    -impl ConfigurableBlockchain for AnyBlockchain {
    -    type Config = AnyBlockchainConfig;
    +impl ConfigurableBlockchain for AnyBlockchain {
    +    type Config = AnyBlockchainConfig;
     
    -    fn from_config(config: &Self::Config) -> Result<Self, Error> {
    -        Ok(match config {
    -            #[cfg(feature = "electrum")]
    -            AnyBlockchainConfig::Electrum(inner) => {
    -                AnyBlockchain::Electrum(Box::new(electrum::ElectrumBlockchain::from_config(inner)?))
    +    fn from_config(config: &Self::Config) -> Result<Self, Error> {
    +        Ok(match config {
    +            #[cfg(feature = "electrum")]
    +            AnyBlockchainConfig::Electrum(inner) => {
    +                AnyBlockchain::Electrum(Box::new(electrum::ElectrumBlockchain::from_config(inner)?))
                 }
    -            #[cfg(feature = "esplora")]
    -            AnyBlockchainConfig::Esplora(inner) => {
    -                AnyBlockchain::Esplora(Box::new(esplora::EsploraBlockchain::from_config(inner)?))
    +            #[cfg(feature = "esplora")]
    +            AnyBlockchainConfig::Esplora(inner) => {
    +                AnyBlockchain::Esplora(Box::new(esplora::EsploraBlockchain::from_config(inner)?))
                 }
    -            #[cfg(feature = "compact_filters")]
    -            AnyBlockchainConfig::CompactFilters(inner) => AnyBlockchain::CompactFilters(Box::new(
    -                compact_filters::CompactFiltersBlockchain::from_config(inner)?,
    +            #[cfg(feature = "compact_filters")]
    +            AnyBlockchainConfig::CompactFilters(inner) => AnyBlockchain::CompactFilters(Box::new(
    +                compact_filters::CompactFiltersBlockchain::from_config(inner)?,
                 )),
    -            #[cfg(feature = "rpc")]
    -            AnyBlockchainConfig::Rpc(inner) => {
    -                AnyBlockchain::Rpc(Box::new(rpc::RpcBlockchain::from_config(inner)?))
    +            #[cfg(feature = "rpc")]
    +            AnyBlockchainConfig::Rpc(inner) => {
    +                AnyBlockchain::Rpc(Box::new(rpc::RpcBlockchain::from_config(inner)?))
                 }
             })
         }
     }
     
    -impl_from!(electrum::ElectrumBlockchainConfig, AnyBlockchainConfig, Electrum, #[cfg(feature = "electrum")]);
    -impl_from!(esplora::EsploraBlockchainConfig, AnyBlockchainConfig, Esplora, #[cfg(feature = "esplora")]);
    -impl_from!(compact_filters::CompactFiltersBlockchainConfig, AnyBlockchainConfig, CompactFilters, #[cfg(feature = "compact_filters")]);
    -impl_from!(rpc::RpcConfig, AnyBlockchainConfig, Rpc, #[cfg(feature = "rpc")]);
    +impl_from!(electrum::ElectrumBlockchainConfig, AnyBlockchainConfig, Electrum, #[cfg(feature = "electrum")]);
    +impl_from!(esplora::EsploraBlockchainConfig, AnyBlockchainConfig, Esplora, #[cfg(feature = "esplora")]);
    +impl_from!(compact_filters::CompactFiltersBlockchainConfig, AnyBlockchainConfig, CompactFilters, #[cfg(feature = "compact_filters")]);
    +impl_from!(rpc::RpcConfig, AnyBlockchainConfig, Rpc, #[cfg(feature = "rpc")]);
     
    -
    - \ No newline at end of file +
    \ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/src/bdk/blockchain/compact_filters/mod.rs.html b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/src/bdk/blockchain/compact_filters/mod.rs.html index dcd02fc166..a39d4576e6 100644 --- a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/src/bdk/blockchain/compact_filters/mod.rs.html +++ b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/src/bdk/blockchain/compact_filters/mod.rs.html @@ -1,1198 +1,1191 @@ -mod.rs - source - -
      1
    -  2
    -  3
    -  4
    -  5
    -  6
    -  7
    -  8
    -  9
    - 10
    - 11
    - 12
    - 13
    - 14
    - 15
    - 16
    - 17
    - 18
    - 19
    - 20
    - 21
    - 22
    - 23
    - 24
    - 25
    - 26
    - 27
    - 28
    - 29
    - 30
    - 31
    - 32
    - 33
    - 34
    - 35
    - 36
    - 37
    - 38
    - 39
    - 40
    - 41
    - 42
    - 43
    - 44
    - 45
    - 46
    - 47
    - 48
    - 49
    - 50
    - 51
    - 52
    - 53
    - 54
    - 55
    - 56
    - 57
    - 58
    - 59
    - 60
    - 61
    - 62
    - 63
    - 64
    - 65
    - 66
    - 67
    - 68
    - 69
    - 70
    - 71
    - 72
    - 73
    - 74
    - 75
    - 76
    - 77
    - 78
    - 79
    - 80
    - 81
    - 82
    - 83
    - 84
    - 85
    - 86
    - 87
    - 88
    - 89
    - 90
    - 91
    - 92
    - 93
    - 94
    - 95
    - 96
    - 97
    - 98
    - 99
    -100
    -101
    -102
    -103
    -104
    -105
    -106
    -107
    -108
    -109
    -110
    -111
    -112
    -113
    -114
    -115
    -116
    -117
    -118
    -119
    -120
    -121
    -122
    -123
    -124
    -125
    -126
    -127
    -128
    -129
    -130
    -131
    -132
    -133
    -134
    -135
    -136
    -137
    -138
    -139
    -140
    -141
    -142
    -143
    -144
    -145
    -146
    -147
    -148
    -149
    -150
    -151
    -152
    -153
    -154
    -155
    -156
    -157
    -158
    -159
    -160
    -161
    -162
    -163
    -164
    -165
    -166
    -167
    -168
    -169
    -170
    -171
    -172
    -173
    -174
    -175
    -176
    -177
    -178
    -179
    -180
    -181
    -182
    -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
    -245
    -246
    -247
    -248
    -249
    -250
    -251
    -252
    -253
    -254
    -255
    -256
    -257
    -258
    -259
    -260
    -261
    -262
    -263
    -264
    -265
    -266
    -267
    -268
    -269
    -270
    -271
    -272
    -273
    -274
    -275
    -276
    -277
    -278
    -279
    -280
    -281
    -282
    -283
    -284
    -285
    -286
    -287
    -288
    -289
    -290
    -291
    -292
    -293
    -294
    -295
    -296
    -297
    -298
    -299
    -300
    -301
    -302
    -303
    -304
    -305
    -306
    -307
    -308
    -309
    -310
    -311
    -312
    -313
    -314
    -315
    -316
    -317
    -318
    -319
    -320
    -321
    -322
    -323
    -324
    -325
    -326
    -327
    -328
    -329
    -330
    -331
    -332
    -333
    -334
    -335
    -336
    -337
    -338
    -339
    -340
    -341
    -342
    -343
    -344
    -345
    -346
    -347
    -348
    -349
    -350
    -351
    -352
    -353
    -354
    -355
    -356
    -357
    -358
    -359
    -360
    -361
    -362
    -363
    -364
    -365
    -366
    -367
    -368
    -369
    -370
    -371
    -372
    -373
    -374
    -375
    -376
    -377
    -378
    -379
    -380
    -381
    -382
    -383
    -384
    -385
    -386
    -387
    -388
    -389
    -390
    -391
    -392
    -393
    -394
    -395
    -396
    -397
    -398
    -399
    -400
    -401
    -402
    -403
    -404
    -405
    -406
    -407
    -408
    -409
    -410
    -411
    -412
    -413
    -414
    -415
    -416
    -417
    -418
    -419
    -420
    -421
    -422
    -423
    -424
    -425
    -426
    -427
    -428
    -429
    -430
    -431
    -432
    -433
    -434
    -435
    -436
    -437
    -438
    -439
    -440
    -441
    -442
    -443
    -444
    -445
    -446
    -447
    -448
    -449
    -450
    -451
    -452
    -453
    -454
    -455
    -456
    -457
    -458
    -459
    -460
    -461
    -462
    -463
    -464
    -465
    -466
    -467
    -468
    -469
    -470
    -471
    -472
    -473
    -474
    -475
    -476
    -477
    -478
    -479
    -480
    -481
    -482
    -483
    -484
    -485
    -486
    -487
    -488
    -489
    -490
    -491
    -492
    -493
    -494
    -495
    -496
    -497
    -498
    -499
    -500
    -501
    -502
    -503
    -504
    -505
    -506
    -507
    -508
    -509
    -510
    -511
    -512
    -513
    -514
    -515
    -516
    -517
    -518
    -519
    -520
    -521
    -522
    -523
    -524
    -525
    -526
    -527
    -528
    -529
    -530
    -531
    -532
    -533
    -534
    -535
    -536
    -537
    -538
    -539
    -540
    -541
    -542
    -543
    -544
    -545
    -546
    -547
    -548
    -549
    -550
    -551
    -552
    -553
    -554
    -555
    -556
    -557
    -558
    -559
    -560
    -561
    -562
    -563
    -564
    -565
    -566
    -567
    -568
    -569
    -570
    -571
    -572
    -573
    -574
    -575
    -576
    -577
    -578
    -579
    -580
    -581
    -582
    -583
    -584
    -585
    -586
    -587
    -588
    -589
    -590
    -591
    -592
    -593
    -594
    -
    // Bitcoin Dev Kit
    -// Written in 2020 by Alekos Filini <alekos.filini@gmail.com>
    -//
    -// Copyright (c) 2020-2021 Bitcoin Dev Kit Developers
    -//
    -// This file is licensed under the Apache License, Version 2.0 <LICENSE-APACHE
    -// or http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
    -// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your option.
    -// You may not use this file except in accordance with one or both of these
    -// licenses.
    -
    -//! Compact Filters
    -//!
    -//! This module contains a multithreaded implementation of an [`Blockchain`] backend that
    -//! uses BIP157 (aka "Neutrino") to populate the wallet's [database](crate::database::Database)
    -//! by downloading compact filters from the P2P network.
    -//!
    -//! Since there are currently very few peers "in the wild" that advertise the required service
    -//! flag, this implementation requires that one or more known peers are provided by the user.
    -//! No dns or other kinds of peer discovery are done internally.
    -//!
    -//! Moreover, this module doesn't currently support detecting and resolving conflicts between
    -//! messages received by different peers. Thus, it's recommended to use this module by only
    -//! connecting to a single peer at a time, optionally by opening multiple connections if it's
    -//! desirable to use multiple threads at once to sync in parallel.
    -//!
    -//! This is an **EXPERIMENTAL** feature, API and other major changes are expected.
    -//!
    -//! ## Example
    -//!
    -//! ```no_run
    -//! # use std::sync::Arc;
    -//! # use bitcoin::*;
    -//! # use bdk::*;
    -//! # use bdk::blockchain::compact_filters::*;
    -//! let num_threads = 4;
    -//!
    -//! let mempool = Arc::new(Mempool::default());
    -//! let peers = (0..num_threads)
    -//!     .map(|_| {
    -//!         Peer::connect(
    -//!             "btcd-mainnet.lightning.computer:8333",
    -//!             Arc::clone(&mempool),
    -//!             Network::Bitcoin,
    -//!         )
    -//!     })
    -//!     .collect::<Result<_, _>>()?;
    -//! let blockchain = CompactFiltersBlockchain::new(peers, "./wallet-filters", Some(500_000))?;
    -//! # Ok::<(), CompactFiltersError>(())
    -//! ```
    -
    -use std::collections::HashSet;
    -use std::fmt;
    -use std::path::Path;
    -use std::sync::atomic::{AtomicUsize, Ordering};
    -use std::sync::{Arc, Mutex};
    -
    -#[allow(unused_imports)]
    -use log::{debug, error, info, trace};
    -
    -use bitcoin::network::message_blockdata::Inventory;
    -use bitcoin::{Network, OutPoint, Transaction, Txid};
    -
    -use rocksdb::{Options, SliceTransform, DB};
    -
    -mod peer;
    -mod store;
    -mod sync;
    -
    -use crate::blockchain::*;
    -use crate::database::{BatchDatabase, BatchOperations, DatabaseUtils};
    -use crate::error::Error;
    -use crate::types::{KeychainKind, LocalUtxo, TransactionDetails};
    -use crate::{BlockTime, FeeRate};
    -
    -use peer::*;
    -use store::*;
    -use sync::*;
    -
    -pub use peer::{Mempool, Peer};
    -
    -const SYNC_HEADERS_COST: f32 = 1.0;
    -const SYNC_FILTERS_COST: f32 = 11.6 * 1_000.0;
    -const PROCESS_BLOCKS_COST: f32 = 20_000.0;
    -
    -/// Structure implementing the required blockchain traits
    -///
    -/// ## Example
    -/// See the [`blockchain::compact_filters`](crate::blockchain::compact_filters) module for a usage example.
    -#[derive(Debug)]
    -pub struct CompactFiltersBlockchain {
    -    peers: Vec<Arc<Peer>>,
    -    headers: Arc<ChainStore<Full>>,
    -    skip_blocks: Option<usize>,
    +mod.rs - source
    1
    +2
    +3
    +4
    +5
    +6
    +7
    +8
    +9
    +10
    +11
    +12
    +13
    +14
    +15
    +16
    +17
    +18
    +19
    +20
    +21
    +22
    +23
    +24
    +25
    +26
    +27
    +28
    +29
    +30
    +31
    +32
    +33
    +34
    +35
    +36
    +37
    +38
    +39
    +40
    +41
    +42
    +43
    +44
    +45
    +46
    +47
    +48
    +49
    +50
    +51
    +52
    +53
    +54
    +55
    +56
    +57
    +58
    +59
    +60
    +61
    +62
    +63
    +64
    +65
    +66
    +67
    +68
    +69
    +70
    +71
    +72
    +73
    +74
    +75
    +76
    +77
    +78
    +79
    +80
    +81
    +82
    +83
    +84
    +85
    +86
    +87
    +88
    +89
    +90
    +91
    +92
    +93
    +94
    +95
    +96
    +97
    +98
    +99
    +100
    +101
    +102
    +103
    +104
    +105
    +106
    +107
    +108
    +109
    +110
    +111
    +112
    +113
    +114
    +115
    +116
    +117
    +118
    +119
    +120
    +121
    +122
    +123
    +124
    +125
    +126
    +127
    +128
    +129
    +130
    +131
    +132
    +133
    +134
    +135
    +136
    +137
    +138
    +139
    +140
    +141
    +142
    +143
    +144
    +145
    +146
    +147
    +148
    +149
    +150
    +151
    +152
    +153
    +154
    +155
    +156
    +157
    +158
    +159
    +160
    +161
    +162
    +163
    +164
    +165
    +166
    +167
    +168
    +169
    +170
    +171
    +172
    +173
    +174
    +175
    +176
    +177
    +178
    +179
    +180
    +181
    +182
    +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
    +245
    +246
    +247
    +248
    +249
    +250
    +251
    +252
    +253
    +254
    +255
    +256
    +257
    +258
    +259
    +260
    +261
    +262
    +263
    +264
    +265
    +266
    +267
    +268
    +269
    +270
    +271
    +272
    +273
    +274
    +275
    +276
    +277
    +278
    +279
    +280
    +281
    +282
    +283
    +284
    +285
    +286
    +287
    +288
    +289
    +290
    +291
    +292
    +293
    +294
    +295
    +296
    +297
    +298
    +299
    +300
    +301
    +302
    +303
    +304
    +305
    +306
    +307
    +308
    +309
    +310
    +311
    +312
    +313
    +314
    +315
    +316
    +317
    +318
    +319
    +320
    +321
    +322
    +323
    +324
    +325
    +326
    +327
    +328
    +329
    +330
    +331
    +332
    +333
    +334
    +335
    +336
    +337
    +338
    +339
    +340
    +341
    +342
    +343
    +344
    +345
    +346
    +347
    +348
    +349
    +350
    +351
    +352
    +353
    +354
    +355
    +356
    +357
    +358
    +359
    +360
    +361
    +362
    +363
    +364
    +365
    +366
    +367
    +368
    +369
    +370
    +371
    +372
    +373
    +374
    +375
    +376
    +377
    +378
    +379
    +380
    +381
    +382
    +383
    +384
    +385
    +386
    +387
    +388
    +389
    +390
    +391
    +392
    +393
    +394
    +395
    +396
    +397
    +398
    +399
    +400
    +401
    +402
    +403
    +404
    +405
    +406
    +407
    +408
    +409
    +410
    +411
    +412
    +413
    +414
    +415
    +416
    +417
    +418
    +419
    +420
    +421
    +422
    +423
    +424
    +425
    +426
    +427
    +428
    +429
    +430
    +431
    +432
    +433
    +434
    +435
    +436
    +437
    +438
    +439
    +440
    +441
    +442
    +443
    +444
    +445
    +446
    +447
    +448
    +449
    +450
    +451
    +452
    +453
    +454
    +455
    +456
    +457
    +458
    +459
    +460
    +461
    +462
    +463
    +464
    +465
    +466
    +467
    +468
    +469
    +470
    +471
    +472
    +473
    +474
    +475
    +476
    +477
    +478
    +479
    +480
    +481
    +482
    +483
    +484
    +485
    +486
    +487
    +488
    +489
    +490
    +491
    +492
    +493
    +494
    +495
    +496
    +497
    +498
    +499
    +500
    +501
    +502
    +503
    +504
    +505
    +506
    +507
    +508
    +509
    +510
    +511
    +512
    +513
    +514
    +515
    +516
    +517
    +518
    +519
    +520
    +521
    +522
    +523
    +524
    +525
    +526
    +527
    +528
    +529
    +530
    +531
    +532
    +533
    +534
    +535
    +536
    +537
    +538
    +539
    +540
    +541
    +542
    +543
    +544
    +545
    +546
    +547
    +548
    +549
    +550
    +551
    +552
    +553
    +554
    +555
    +556
    +557
    +558
    +559
    +560
    +561
    +562
    +563
    +564
    +565
    +566
    +567
    +568
    +569
    +570
    +571
    +572
    +573
    +574
    +575
    +576
    +577
    +578
    +579
    +580
    +581
    +582
    +583
    +584
    +585
    +586
    +587
    +588
    +589
    +590
    +591
    +592
    +593
    +594
    +
    // Bitcoin Dev Kit
    +// Written in 2020 by Alekos Filini <alekos.filini@gmail.com>
    +//
    +// Copyright (c) 2020-2021 Bitcoin Dev Kit Developers
    +//
    +// This file is licensed under the Apache License, Version 2.0 <LICENSE-APACHE
    +// or http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
    +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your option.
    +// You may not use this file except in accordance with one or both of these
    +// licenses.
    +
    +//! Compact Filters
    +//!
    +//! This module contains a multithreaded implementation of an [`Blockchain`] backend that
    +//! uses BIP157 (aka "Neutrino") to populate the wallet's [database](crate::database::Database)
    +//! by downloading compact filters from the P2P network.
    +//!
    +//! Since there are currently very few peers "in the wild" that advertise the required service
    +//! flag, this implementation requires that one or more known peers are provided by the user.
    +//! No dns or other kinds of peer discovery are done internally.
    +//!
    +//! Moreover, this module doesn't currently support detecting and resolving conflicts between
    +//! messages received by different peers. Thus, it's recommended to use this module by only
    +//! connecting to a single peer at a time, optionally by opening multiple connections if it's
    +//! desirable to use multiple threads at once to sync in parallel.
    +//!
    +//! This is an **EXPERIMENTAL** feature, API and other major changes are expected.
    +//!
    +//! ## Example
    +//!
    +//! ```no_run
    +//! # use std::sync::Arc;
    +//! # use bitcoin::*;
    +//! # use bdk::*;
    +//! # use bdk::blockchain::compact_filters::*;
    +//! let num_threads = 4;
    +//!
    +//! let mempool = Arc::new(Mempool::default());
    +//! let peers = (0..num_threads)
    +//!     .map(|_| {
    +//!         Peer::connect(
    +//!             "btcd-mainnet.lightning.computer:8333",
    +//!             Arc::clone(&mempool),
    +//!             Network::Bitcoin,
    +//!         )
    +//!     })
    +//!     .collect::<Result<_, _>>()?;
    +//! let blockchain = CompactFiltersBlockchain::new(peers, "./wallet-filters", Some(500_000))?;
    +//! # Ok::<(), CompactFiltersError>(())
    +//! ```
    +
    +use std::collections::HashSet;
    +use std::fmt;
    +use std::path::Path;
    +use std::sync::atomic::{AtomicUsize, Ordering};
    +use std::sync::{Arc, Mutex};
    +
    +#[allow(unused_imports)]
    +use log::{debug, error, info, trace};
    +
    +use bitcoin::network::message_blockdata::Inventory;
    +use bitcoin::{Network, OutPoint, Transaction, Txid};
    +
    +use rocksdb::{Options, SliceTransform, DB};
    +
    +mod peer;
    +mod store;
    +mod sync;
    +
    +use crate::blockchain::*;
    +use crate::database::{BatchDatabase, BatchOperations, DatabaseUtils};
    +use crate::error::Error;
    +use crate::types::{KeychainKind, LocalUtxo, TransactionDetails};
    +use crate::{BlockTime, FeeRate};
    +
    +use peer::*;
    +use store::*;
    +use sync::*;
    +
    +pub use peer::{Mempool, Peer};
    +
    +const SYNC_HEADERS_COST: f32 = 1.0;
    +const SYNC_FILTERS_COST: f32 = 11.6 * 1_000.0;
    +const PROCESS_BLOCKS_COST: f32 = 20_000.0;
    +
    +/// Structure implementing the required blockchain traits
    +///
    +/// ## Example
    +/// See the [`blockchain::compact_filters`](crate::blockchain::compact_filters) module for a usage example.
    +#[derive(Debug)]
    +pub struct CompactFiltersBlockchain {
    +    peers: Vec<Arc<Peer>>,
    +    headers: Arc<ChainStore<Full>>,
    +    skip_blocks: Option<usize>,
     }
     
    -impl CompactFiltersBlockchain {
    -    /// Construct a new instance given a list of peers, a path to store headers and block
    -    /// filters downloaded during the sync and optionally a number of blocks to ignore starting
    -    /// from the genesis while scanning for the wallet's outputs.
    -    ///
    -    /// For each [`Peer`] specified a new thread will be spawned to download and verify the filters
    -    /// in parallel. It's currently recommended to only connect to a single peer to avoid
    -    /// inconsistencies in the data returned, optionally with multiple connections in parallel to
    -    /// speed-up the sync process.
    -    pub fn new<P: AsRef<Path>>(
    -        peers: Vec<Peer>,
    -        storage_dir: P,
    -        skip_blocks: Option<usize>,
    -    ) -> Result<Self, CompactFiltersError> {
    -        if peers.is_empty() {
    -            return Err(CompactFiltersError::NoPeers);
    +impl CompactFiltersBlockchain {
    +    /// Construct a new instance given a list of peers, a path to store headers and block
    +    /// filters downloaded during the sync and optionally a number of blocks to ignore starting
    +    /// from the genesis while scanning for the wallet's outputs.
    +    ///
    +    /// For each [`Peer`] specified a new thread will be spawned to download and verify the filters
    +    /// in parallel. It's currently recommended to only connect to a single peer to avoid
    +    /// inconsistencies in the data returned, optionally with multiple connections in parallel to
    +    /// speed-up the sync process.
    +    pub fn new<P: AsRef<Path>>(
    +        peers: Vec<Peer>,
    +        storage_dir: P,
    +        skip_blocks: Option<usize>,
    +    ) -> Result<Self, CompactFiltersError> {
    +        if peers.is_empty() {
    +            return Err(CompactFiltersError::NoPeers);
             }
     
    -        let mut opts = Options::default();
    -        opts.create_if_missing(true);
    -        opts.set_prefix_extractor(SliceTransform::create_fixed_prefix(16));
    +        let mut opts = Options::default();
    +        opts.create_if_missing(true);
    +        opts.set_prefix_extractor(SliceTransform::create_fixed_prefix(16));
     
    -        let network = peers[0].get_network();
    +        let network = peers[0].get_network();
     
    -        let cfs = DB::list_cf(&opts, &storage_dir).unwrap_or_else(|_| vec!["default".to_string()]);
    -        let db = DB::open_cf(&opts, &storage_dir, &cfs)?;
    -        let headers = Arc::new(ChainStore::new(db, network)?);
    +        let cfs = DB::list_cf(&opts, &storage_dir).unwrap_or_else(|_| vec!["default".to_string()]);
    +        let db = DB::open_cf(&opts, &storage_dir, &cfs)?;
    +        let headers = Arc::new(ChainStore::new(db, network)?);
     
    -        // try to recover partial snapshots
    -        for cf_name in &cfs {
    -            if !cf_name.starts_with("_headers:") {
    +        // try to recover partial snapshots
    +        for cf_name in &cfs {
    +            if !cf_name.starts_with("_headers:") {
                     continue;
                 }
     
    -            info!("Trying to recover: {:?}", cf_name);
    -            headers.recover_snapshot(cf_name)?;
    +            info!("Trying to recover: {:?}", cf_name);
    +            headers.recover_snapshot(cf_name)?;
             }
     
    -        Ok(CompactFiltersBlockchain {
    -            peers: peers.into_iter().map(Arc::new).collect(),
    -            headers,
    -            skip_blocks,
    +        Ok(CompactFiltersBlockchain {
    +            peers: peers.into_iter().map(Arc::new).collect(),
    +            headers,
    +            skip_blocks,
             })
         }
     
    -    /// Process a transaction by looking for inputs that spend from a UTXO in the database or
    -    /// outputs that send funds to a know script_pubkey.
    -    fn process_tx<D: BatchDatabase>(
    +    /// Process a transaction by looking for inputs that spend from a UTXO in the database or
    +    /// outputs that send funds to a know script_pubkey.
    +    fn process_tx<D: BatchDatabase>(
             &self,
    -        database: &mut D,
    -        tx: &Transaction,
    -        height: Option<u32>,
    -        timestamp: Option<u64>,
    -        internal_max_deriv: &mut Option<u32>,
    -        external_max_deriv: &mut Option<u32>,
    -    ) -> Result<(), Error> {
    -        let mut updates = database.begin_batch();
    -
    -        let mut incoming: u64 = 0;
    -        let mut outgoing: u64 = 0;
    -
    -        let mut inputs_sum: u64 = 0;
    -        let mut outputs_sum: u64 = 0;
    -
    -        // look for our own inputs
    -        for (i, input) in tx.input.iter().enumerate() {
    -            if let Some(previous_output) = database.get_previous_output(&input.previous_output)? {
    -                inputs_sum += previous_output.value;
    -
    -                // this output is ours, we have a path to derive it
    -                if let Some((keychain, _)) =
    -                    database.get_path_from_script_pubkey(&previous_output.script_pubkey)?
    -                {
    -                    outgoing += previous_output.value;
    -
    -                    debug!("{} input #{} is mine, setting utxo as spent", tx.txid(), i);
    -                    updates.set_utxo(&LocalUtxo {
    -                        outpoint: input.previous_output,
    -                        txout: previous_output.clone(),
    -                        keychain,
    -                        is_spent: true,
    +        database: &mut D,
    +        tx: &Transaction,
    +        height: Option<u32>,
    +        timestamp: Option<u64>,
    +        internal_max_deriv: &mut Option<u32>,
    +        external_max_deriv: &mut Option<u32>,
    +    ) -> Result<(), Error> {
    +        let mut updates = database.begin_batch();
    +
    +        let mut incoming: u64 = 0;
    +        let mut outgoing: u64 = 0;
    +
    +        let mut inputs_sum: u64 = 0;
    +        let mut outputs_sum: u64 = 0;
    +
    +        // look for our own inputs
    +        for (i, input) in tx.input.iter().enumerate() {
    +            if let Some(previous_output) = database.get_previous_output(&input.previous_output)? {
    +                inputs_sum += previous_output.value;
    +
    +                // this output is ours, we have a path to derive it
    +                if let Some((keychain, _)) =
    +                    database.get_path_from_script_pubkey(&previous_output.script_pubkey)?
    +                {
    +                    outgoing += previous_output.value;
    +
    +                    debug!("{} input #{} is mine, setting utxo as spent", tx.txid(), i);
    +                    updates.set_utxo(&LocalUtxo {
    +                        outpoint: input.previous_output,
    +                        txout: previous_output.clone(),
    +                        keychain,
    +                        is_spent: true,
                         })?;
                     }
                 }
             }
     
    -        for (i, output) in tx.output.iter().enumerate() {
    -            // to compute the fees later
    -            outputs_sum += output.value;
    -
    -            // this output is ours, we have a path to derive it
    -            if let Some((keychain, child)) =
    -                database.get_path_from_script_pubkey(&output.script_pubkey)?
    -            {
    -                debug!("{} output #{} is mine, adding utxo", tx.txid(), i);
    -                updates.set_utxo(&LocalUtxo {
    -                    outpoint: OutPoint::new(tx.txid(), i as u32),
    -                    txout: output.clone(),
    -                    keychain,
    -                    is_spent: false,
    +        for (i, output) in tx.output.iter().enumerate() {
    +            // to compute the fees later
    +            outputs_sum += output.value;
    +
    +            // this output is ours, we have a path to derive it
    +            if let Some((keychain, child)) =
    +                database.get_path_from_script_pubkey(&output.script_pubkey)?
    +            {
    +                debug!("{} output #{} is mine, adding utxo", tx.txid(), i);
    +                updates.set_utxo(&LocalUtxo {
    +                    outpoint: OutPoint::new(tx.txid(), i as u32),
    +                    txout: output.clone(),
    +                    keychain,
    +                    is_spent: false,
                     })?;
    -                incoming += output.value;
    +                incoming += output.value;
     
    -                if keychain == KeychainKind::Internal
    -                    && (internal_max_deriv.is_none() || child > internal_max_deriv.unwrap_or(0))
    +                if keychain == KeychainKind::Internal
    +                    && (internal_max_deriv.is_none() || child > internal_max_deriv.unwrap_or(0))
                     {
    -                    *internal_max_deriv = Some(child);
    -                } else if keychain == KeychainKind::External
    -                    && (external_max_deriv.is_none() || child > external_max_deriv.unwrap_or(0))
    +                    *internal_max_deriv = Some(child);
    +                } else if keychain == KeychainKind::External
    +                    && (external_max_deriv.is_none() || child > external_max_deriv.unwrap_or(0))
                     {
    -                    *external_max_deriv = Some(child);
    +                    *external_max_deriv = Some(child);
                     }
                 }
             }
     
    -        if incoming > 0 || outgoing > 0 {
    -            let tx = TransactionDetails {
    -                txid: tx.txid(),
    -                transaction: Some(tx.clone()),
    -                received: incoming,
    -                sent: outgoing,
    -                confirmation_time: BlockTime::new(height, timestamp),
    -                fee: Some(inputs_sum.saturating_sub(outputs_sum)),
    +        if incoming > 0 || outgoing > 0 {
    +            let tx = TransactionDetails {
    +                txid: tx.txid(),
    +                transaction: Some(tx.clone()),
    +                received: incoming,
    +                sent: outgoing,
    +                confirmation_time: BlockTime::new(height, timestamp),
    +                fee: Some(inputs_sum.saturating_sub(outputs_sum)),
                 };
     
    -            info!("Saving tx {}", tx.txid);
    -            updates.set_tx(&tx)?;
    +            info!("Saving tx {}", tx.txid);
    +            updates.set_tx(&tx)?;
             }
     
    -        database.commit_batch(updates)?;
    +        database.commit_batch(updates)?;
     
             Ok(())
         }
     }
     
    -impl Blockchain for CompactFiltersBlockchain {
    -    fn get_capabilities(&self) -> HashSet<Capability> {
    -        vec![Capability::FullHistory].into_iter().collect()
    +impl Blockchain for CompactFiltersBlockchain {
    +    fn get_capabilities(&self) -> HashSet<Capability> {
    +        vec![Capability::FullHistory].into_iter().collect()
         }
     
    -    fn broadcast(&self, tx: &Transaction) -> Result<(), Error> {
    -        self.peers[0].broadcast_tx(tx.clone())?;
    +    fn broadcast(&self, tx: &Transaction) -> Result<(), Error> {
    +        self.peers[0].broadcast_tx(tx.clone())?;
     
             Ok(())
         }
     
    -    fn estimate_fee(&self, _target: usize) -> Result<FeeRate, Error> {
    -        // TODO
    -        Ok(FeeRate::default())
    +    fn estimate_fee(&self, _target: usize) -> Result<FeeRate, Error> {
    +        // TODO
    +        Ok(FeeRate::default())
         }
     }
     
    -impl GetHeight for CompactFiltersBlockchain {
    -    fn get_height(&self) -> Result<u32, Error> {
    -        Ok(self.headers.get_height()? as u32)
    +impl GetHeight for CompactFiltersBlockchain {
    +    fn get_height(&self) -> Result<u32, Error> {
    +        Ok(self.headers.get_height()? as u32)
         }
     }
     
    -impl GetTx for CompactFiltersBlockchain {
    -    fn get_tx(&self, txid: &Txid) -> Result<Option<Transaction>, Error> {
    -        Ok(self.peers[0]
    -            .get_mempool()
    -            .get_tx(&Inventory::Transaction(*txid)))
    +impl GetTx for CompactFiltersBlockchain {
    +    fn get_tx(&self, txid: &Txid) -> Result<Option<Transaction>, Error> {
    +        Ok(self.peers[0]
    +            .get_mempool()
    +            .get_tx(&Inventory::Transaction(*txid)))
         }
     }
     
    -impl GetBlockHash for CompactFiltersBlockchain {
    -    fn get_block_hash(&self, height: u64) -> Result<BlockHash, Error> {
    -        self.headers
    -            .get_block_hash(height as usize)?
    -            .ok_or(Error::CompactFilters(
    -                CompactFiltersError::BlockHashNotFound,
    +impl GetBlockHash for CompactFiltersBlockchain {
    +    fn get_block_hash(&self, height: u64) -> Result<BlockHash, Error> {
    +        self.headers
    +            .get_block_hash(height as usize)?
    +            .ok_or(Error::CompactFilters(
    +                CompactFiltersError::BlockHashNotFound,
                 ))
         }
     }
     
    -impl WalletSync for CompactFiltersBlockchain {
    -    #[allow(clippy::mutex_atomic)] // Mutex is easier to understand than a CAS loop.
    -    fn wallet_setup<D: BatchDatabase>(
    +impl WalletSync for CompactFiltersBlockchain {
    +    #[allow(clippy::mutex_atomic)] // Mutex is easier to understand than a CAS loop.
    +    fn wallet_setup<D: BatchDatabase>(
             &self,
    -        database: &mut D,
    -        progress_update: Box<dyn Progress>,
    -    ) -> Result<(), Error> {
    -        let first_peer = &self.peers[0];
    -
    -        let skip_blocks = self.skip_blocks.unwrap_or(0);
    -
    -        let cf_sync = Arc::new(CfSync::new(Arc::clone(&self.headers), skip_blocks, 0x00)?);
    -
    -        let initial_height = self.headers.get_height()?;
    -        let total_bundles = (first_peer.get_version().start_height as usize)
    -            .checked_sub(skip_blocks)
    -            .map(|x| x / 1000)
    -            .unwrap_or(0)
    -            + 1;
    -        let expected_bundles_to_sync = total_bundles.saturating_sub(cf_sync.pruned_bundles()?);
    -
    -        let headers_cost = (first_peer.get_version().start_height as usize)
    -            .saturating_sub(initial_height) as f32
    -            * SYNC_HEADERS_COST;
    -        let filters_cost = expected_bundles_to_sync as f32 * SYNC_FILTERS_COST;
    -
    -        let total_cost = headers_cost + filters_cost + PROCESS_BLOCKS_COST;
    -
    -        if let Some(snapshot) = sync::sync_headers(
    -            Arc::clone(first_peer),
    -            Arc::clone(&self.headers),
    -            |new_height| {
    -                let local_headers_cost =
    -                    new_height.saturating_sub(initial_height) as f32 * SYNC_HEADERS_COST;
    -                progress_update.update(
    -                    local_headers_cost / total_cost * 100.0,
    -                    Some(format!("Synced headers to {}", new_height)),
    +        database: &mut D,
    +        progress_update: Box<dyn Progress>,
    +    ) -> Result<(), Error> {
    +        let first_peer = &self.peers[0];
    +
    +        let skip_blocks = self.skip_blocks.unwrap_or(0);
    +
    +        let cf_sync = Arc::new(CfSync::new(Arc::clone(&self.headers), skip_blocks, 0x00)?);
    +
    +        let initial_height = self.headers.get_height()?;
    +        let total_bundles = (first_peer.get_version().start_height as usize)
    +            .checked_sub(skip_blocks)
    +            .map(|x| x / 1000)
    +            .unwrap_or(0)
    +            + 1;
    +        let expected_bundles_to_sync = total_bundles.saturating_sub(cf_sync.pruned_bundles()?);
    +
    +        let headers_cost = (first_peer.get_version().start_height as usize)
    +            .saturating_sub(initial_height) as f32
    +            * SYNC_HEADERS_COST;
    +        let filters_cost = expected_bundles_to_sync as f32 * SYNC_FILTERS_COST;
    +
    +        let total_cost = headers_cost + filters_cost + PROCESS_BLOCKS_COST;
    +
    +        if let Some(snapshot) = sync::sync_headers(
    +            Arc::clone(first_peer),
    +            Arc::clone(&self.headers),
    +            |new_height| {
    +                let local_headers_cost =
    +                    new_height.saturating_sub(initial_height) as f32 * SYNC_HEADERS_COST;
    +                progress_update.update(
    +                    local_headers_cost / total_cost * 100.0,
    +                    Some(format!("Synced headers to {}", new_height)),
                     )
                 },
    -        )? {
    -            if snapshot.work()? > self.headers.work()? {
    -                info!("Applying snapshot with work: {}", snapshot.work()?);
    -                self.headers.apply_snapshot(snapshot)?;
    +        )? {
    +            if snapshot.work()? > self.headers.work()? {
    +                info!("Applying snapshot with work: {}", snapshot.work()?);
    +                self.headers.apply_snapshot(snapshot)?;
                 }
             }
     
    -        let synced_height = self.headers.get_height()?;
    -        let buried_height = synced_height.saturating_sub(sync::BURIED_CONFIRMATIONS);
    -        info!("Synced headers to height: {}", synced_height);
    +        let synced_height = self.headers.get_height()?;
    +        let buried_height = synced_height.saturating_sub(sync::BURIED_CONFIRMATIONS);
    +        info!("Synced headers to height: {}", synced_height);
     
    -        cf_sync.prepare_sync(Arc::clone(first_peer))?;
    +        cf_sync.prepare_sync(Arc::clone(first_peer))?;
     
    -        let all_scripts = Arc::new(
    -            database
    -                .iter_script_pubkeys(None)?
    -                .into_iter()
    -                .map(|s| s.to_bytes())
    -                .collect::<Vec<_>>(),
    +        let all_scripts = Arc::new(
    +            database
    +                .iter_script_pubkeys(None)?
    +                .into_iter()
    +                .map(|s| s.to_bytes())
    +                .collect::<Vec<_>>(),
             );
     
    -        #[allow(clippy::mutex_atomic)]
    -        let last_synced_block = Arc::new(Mutex::new(synced_height));
    -
    -        let synced_bundles = Arc::new(AtomicUsize::new(0));
    -        let progress_update = Arc::new(Mutex::new(progress_update));
    -
    -        let mut threads = Vec::with_capacity(self.peers.len());
    -        for peer in &self.peers {
    -            let cf_sync = Arc::clone(&cf_sync);
    -            let peer = Arc::clone(peer);
    -            let headers = Arc::clone(&self.headers);
    -            let all_scripts = Arc::clone(&all_scripts);
    -            let last_synced_block = Arc::clone(&last_synced_block);
    -            let progress_update = Arc::clone(&progress_update);
    -            let synced_bundles = Arc::clone(&synced_bundles);
    -
    -            let thread = std::thread::spawn(move || {
    -                cf_sync.capture_thread_for_sync(
    -                    peer,
    -                    |block_hash, filter| {
    -                        if !filter
    -                            .match_any(block_hash, &mut all_scripts.iter().map(AsRef::as_ref))?
    -                        {
    -                            return Ok(false);
    +        #[allow(clippy::mutex_atomic)]
    +        let last_synced_block = Arc::new(Mutex::new(synced_height));
    +
    +        let synced_bundles = Arc::new(AtomicUsize::new(0));
    +        let progress_update = Arc::new(Mutex::new(progress_update));
    +
    +        let mut threads = Vec::with_capacity(self.peers.len());
    +        for peer in &self.peers {
    +            let cf_sync = Arc::clone(&cf_sync);
    +            let peer = Arc::clone(peer);
    +            let headers = Arc::clone(&self.headers);
    +            let all_scripts = Arc::clone(&all_scripts);
    +            let last_synced_block = Arc::clone(&last_synced_block);
    +            let progress_update = Arc::clone(&progress_update);
    +            let synced_bundles = Arc::clone(&synced_bundles);
    +
    +            let thread = std::thread::spawn(move || {
    +                cf_sync.capture_thread_for_sync(
    +                    peer,
    +                    |block_hash, filter| {
    +                        if !filter
    +                            .match_any(block_hash, &mut all_scripts.iter().map(AsRef::as_ref))?
    +                        {
    +                            return Ok(false);
                             }
     
    -                        let block_height = headers.get_height_for(block_hash)?.unwrap_or(0);
    -                        let saved_correct_block = matches!(headers.get_full_block(block_height)?, Some(block) if &block.block_hash() == block_hash);
    +                        let block_height = headers.get_height_for(block_hash)?.unwrap_or(0);
    +                        let saved_correct_block = matches!(headers.get_full_block(block_height)?, Some(block) if &block.block_hash() == block_hash);
     
    -                        if saved_correct_block {
    +                        if saved_correct_block {
                                 Ok(false)
    -                        } else {
    -                            let mut last_synced_block = last_synced_block.lock().unwrap();
    +                        } else {
    +                            let mut last_synced_block = last_synced_block.lock().unwrap();
     
    -                            // If we download a block older than `last_synced_block`, we update it so that
    -                            // we know to delete and re-process all txs starting from that height
    -                            if block_height < *last_synced_block {
    -                                *last_synced_block = block_height;
    +                            // If we download a block older than `last_synced_block`, we update it so that
    +                            // we know to delete and re-process all txs starting from that height
    +                            if block_height < *last_synced_block {
    +                                *last_synced_block = block_height;
                                 }
     
                                 Ok(true)
                             }
                         },
    -                    |index| {
    -                        let synced_bundles = synced_bundles.fetch_add(1, Ordering::SeqCst);
    -                        let local_filters_cost = synced_bundles as f32 * SYNC_FILTERS_COST;
    -                        progress_update.lock().unwrap().update(
    -                            (headers_cost + local_filters_cost) / total_cost * 100.0,
    +                    |index| {
    +                        let synced_bundles = synced_bundles.fetch_add(1, Ordering::SeqCst);
    +                        let local_filters_cost = synced_bundles as f32 * SYNC_FILTERS_COST;
    +                        progress_update.lock().unwrap().update(
    +                            (headers_cost + local_filters_cost) / total_cost * 100.0,
                                 Some(format!(
                                     "Synced filters {} - {}",
    -                                index * 1000 + 1,
    -                                (index + 1) * 1000
    -                            )),
    +                                index * 1000 + 1,
    +                                (index + 1) * 1000
    +                            )),
                             )
                         },
                     )
                 });
     
    -            threads.push(thread);
    +            threads.push(thread);
             }
     
    -        for t in threads {
    -            t.join().unwrap()?;
    +        for t in threads {
    +            t.join().unwrap()?;
             }
     
    -        progress_update.lock().unwrap().update(
    -            (headers_cost + filters_cost) / total_cost * 100.0,
    -            Some("Processing downloaded blocks and mempool".into()),
    +        progress_update.lock().unwrap().update(
    +            (headers_cost + filters_cost) / total_cost * 100.0,
    +            Some("Processing downloaded blocks and mempool".into()),
             )?;
     
    -        // delete all txs newer than last_synced_block
    -        let last_synced_block = *last_synced_block.lock().unwrap();
    +        // delete all txs newer than last_synced_block
    +        let last_synced_block = *last_synced_block.lock().unwrap();
             log::debug!(
                 "Dropping transactions newer than `last_synced_block` = {}",
    -            last_synced_block
    +            last_synced_block
             );
    -        let mut updates = database.begin_batch();
    -        for details in database.iter_txs(false)? {
    -            match details.confirmation_time {
    -                Some(c) if (c.height as usize) < last_synced_block => continue,
    -                _ => updates.del_tx(&details.txid, false)?,
    +        let mut updates = database.begin_batch();
    +        for details in database.iter_txs(false)? {
    +            match details.confirmation_time {
    +                Some(c) if (c.height as usize) < last_synced_block => continue,
    +                _ => updates.del_tx(&details.txid, false)?,
                 };
             }
    -        database.commit_batch(updates)?;
    +        database.commit_batch(updates)?;
     
    -        match first_peer.ask_for_mempool() {
    -            Err(CompactFiltersError::PeerBloomDisabled) => {
    +        match first_peer.ask_for_mempool() {
    +            Err(CompactFiltersError::PeerBloomDisabled) => {
                     log::warn!("Peer has BLOOM disabled, we can't ask for the mempool")
                 }
    -            e => e?,
    +            e => e?,
             };
     
    -        let mut internal_max_deriv = None;
    -        let mut external_max_deriv = None;
    +        let mut internal_max_deriv = None;
    +        let mut external_max_deriv = None;
     
    -        for (height, block) in self.headers.iter_full_blocks()? {
    -            for tx in &block.txdata {
    -                self.process_tx(
    -                    database,
    -                    tx,
    -                    Some(height as u32),
    +        for (height, block) in self.headers.iter_full_blocks()? {
    +            for tx in &block.txdata {
    +                self.process_tx(
    +                    database,
    +                    tx,
    +                    Some(height as u32),
                         None,
    -                    &mut internal_max_deriv,
    -                    &mut external_max_deriv,
    +                    &mut internal_max_deriv,
    +                    &mut external_max_deriv,
                     )?;
                 }
             }
    -        for tx in first_peer.get_mempool().iter_txs().iter() {
    -            self.process_tx(
    -                database,
    -                tx,
    +        for tx in first_peer.get_mempool().iter_txs().iter() {
    +            self.process_tx(
    +                database,
    +                tx,
                     None,
                     None,
    -                &mut internal_max_deriv,
    -                &mut external_max_deriv,
    +                &mut internal_max_deriv,
    +                &mut external_max_deriv,
                 )?;
             }
     
    -        let current_ext = database
    -            .get_last_index(KeychainKind::External)?
    -            .unwrap_or(0);
    -        let first_ext_new = external_max_deriv.map(|x| x + 1).unwrap_or(0);
    -        if first_ext_new > current_ext {
    -            info!("Setting external index to {}", first_ext_new);
    -            database.set_last_index(KeychainKind::External, first_ext_new)?;
    +        let current_ext = database
    +            .get_last_index(KeychainKind::External)?
    +            .unwrap_or(0);
    +        let first_ext_new = external_max_deriv.map(|x| x + 1).unwrap_or(0);
    +        if first_ext_new > current_ext {
    +            info!("Setting external index to {}", first_ext_new);
    +            database.set_last_index(KeychainKind::External, first_ext_new)?;
             }
     
    -        let current_int = database
    -            .get_last_index(KeychainKind::Internal)?
    -            .unwrap_or(0);
    -        let first_int_new = internal_max_deriv.map(|x| x + 1).unwrap_or(0);
    -        if first_int_new > current_int {
    -            info!("Setting internal index to {}", first_int_new);
    -            database.set_last_index(KeychainKind::Internal, first_int_new)?;
    +        let current_int = database
    +            .get_last_index(KeychainKind::Internal)?
    +            .unwrap_or(0);
    +        let first_int_new = internal_max_deriv.map(|x| x + 1).unwrap_or(0);
    +        if first_int_new > current_int {
    +            info!("Setting internal index to {}", first_int_new);
    +            database.set_last_index(KeychainKind::Internal, first_int_new)?;
             }
     
    -        info!("Dropping blocks until {}", buried_height);
    -        self.headers.delete_blocks_until(buried_height)?;
    +        info!("Dropping blocks until {}", buried_height);
    +        self.headers.delete_blocks_until(buried_height)?;
     
    -        progress_update
    -            .lock()
    -            .unwrap()
    -            .update(100.0, Some("Done".into()))?;
    +        progress_update
    +            .lock()
    +            .unwrap()
    +            .update(100.0, Some("Done".into()))?;
     
             Ok(())
         }
     }
     
    -/// Data to connect to a Bitcoin P2P peer
    -#[derive(Debug, serde::Deserialize, serde::Serialize, Clone, PartialEq, Eq)]
    -pub struct BitcoinPeerConfig {
    -    /// Peer address such as 127.0.0.1:18333
    -    pub address: String,
    -    /// Optional socks5 proxy
    -    pub socks5: Option<String>,
    -    /// Optional socks5 proxy credentials
    -    pub socks5_credentials: Option<(String, String)>,
    +/// Data to connect to a Bitcoin P2P peer
    +#[derive(Debug, serde::Deserialize, serde::Serialize, Clone, PartialEq, Eq)]
    +pub struct BitcoinPeerConfig {
    +    /// Peer address such as 127.0.0.1:18333
    +    pub address: String,
    +    /// Optional socks5 proxy
    +    pub socks5: Option<String>,
    +    /// Optional socks5 proxy credentials
    +    pub socks5_credentials: Option<(String, String)>,
     }
     
    -/// Configuration for a [`CompactFiltersBlockchain`]
    -#[derive(Debug, serde::Deserialize, serde::Serialize, Clone, PartialEq, Eq)]
    -pub struct CompactFiltersBlockchainConfig {
    -    /// List of peers to try to connect to for asking headers and filters
    -    pub peers: Vec<BitcoinPeerConfig>,
    -    /// Network used
    -    pub network: Network,
    -    /// Storage dir to save partially downloaded headers and full blocks. Should be a separate directory per descriptor. Consider using [crate::wallet::wallet_name_from_descriptor] for this.
    -    pub storage_dir: String,
    -    /// Optionally skip initial `skip_blocks` blocks (default: 0)
    -    pub skip_blocks: Option<usize>,
    +/// Configuration for a [`CompactFiltersBlockchain`]
    +#[derive(Debug, serde::Deserialize, serde::Serialize, Clone, PartialEq, Eq)]
    +pub struct CompactFiltersBlockchainConfig {
    +    /// List of peers to try to connect to for asking headers and filters
    +    pub peers: Vec<BitcoinPeerConfig>,
    +    /// Network used
    +    pub network: Network,
    +    /// Storage dir to save partially downloaded headers and full blocks. Should be a separate directory per descriptor. Consider using [crate::wallet::wallet_name_from_descriptor] for this.
    +    pub storage_dir: String,
    +    /// Optionally skip initial `skip_blocks` blocks (default: 0)
    +    pub skip_blocks: Option<usize>,
     }
     
    -impl ConfigurableBlockchain for CompactFiltersBlockchain {
    -    type Config = CompactFiltersBlockchainConfig;
    -
    -    fn from_config(config: &Self::Config) -> Result<Self, Error> {
    -        let mempool = Arc::new(Mempool::default());
    -        let peers = config
    -            .peers
    -            .iter()
    -            .map(|peer_conf| match &peer_conf.socks5 {
    -                None => Peer::connect(&peer_conf.address, Arc::clone(&mempool), config.network),
    -                Some(proxy) => Peer::connect_proxy(
    -                    peer_conf.address.as_str(),
    -                    proxy,
    -                    peer_conf
    -                        .socks5_credentials
    -                        .as_ref()
    -                        .map(|(a, b)| (a.as_str(), b.as_str())),
    -                    Arc::clone(&mempool),
    -                    config.network,
    +impl ConfigurableBlockchain for CompactFiltersBlockchain {
    +    type Config = CompactFiltersBlockchainConfig;
    +
    +    fn from_config(config: &Self::Config) -> Result<Self, Error> {
    +        let mempool = Arc::new(Mempool::default());
    +        let peers = config
    +            .peers
    +            .iter()
    +            .map(|peer_conf| match &peer_conf.socks5 {
    +                None => Peer::connect(&peer_conf.address, Arc::clone(&mempool), config.network),
    +                Some(proxy) => Peer::connect_proxy(
    +                    peer_conf.address.as_str(),
    +                    proxy,
    +                    peer_conf
    +                        .socks5_credentials
    +                        .as_ref()
    +                        .map(|(a, b)| (a.as_str(), b.as_str())),
    +                    Arc::clone(&mempool),
    +                    config.network,
                     ),
                 })
    -            .collect::<Result<_, _>>()?;
    +            .collect::<Result<_, _>>()?;
     
    -        Ok(CompactFiltersBlockchain::new(
    -            peers,
    -            &config.storage_dir,
    -            config.skip_blocks,
    +        Ok(CompactFiltersBlockchain::new(
    +            peers,
    +            &config.storage_dir,
    +            config.skip_blocks,
             )?)
         }
     }
     
    -/// An error that can occur during sync with a [`CompactFiltersBlockchain`]
    -#[derive(Debug)]
    -pub enum CompactFiltersError {
    -    /// A peer sent an invalid or unexpected response
    -    InvalidResponse,
    -    /// The headers returned are invalid
    -    InvalidHeaders,
    -    /// The compact filter headers returned are invalid
    -    InvalidFilterHeader,
    -    /// The compact filter returned is invalid
    -    InvalidFilter,
    -    /// The peer is missing a block in the valid chain
    -    MissingBlock,
    -    /// Block hash at specified height not found
    -    BlockHashNotFound,
    -    /// The data stored in the block filters storage are corrupted
    -    DataCorruption,
    -
    -    /// A peer is not connected
    -    NotConnected,
    -    /// A peer took too long to reply to one of our messages
    -    Timeout,
    -    /// The peer doesn't advertise the [`BLOOM`](bitcoin::network::constants::ServiceFlags::BLOOM) service flag
    -    PeerBloomDisabled,
    -
    -    /// No peers have been specified
    -    NoPeers,
    -
    -    /// Internal database error
    -    Db(rocksdb::Error),
    -    /// Internal I/O error
    -    Io(std::io::Error),
    -    /// Invalid BIP158 filter
    -    Bip158(bitcoin::util::bip158::Error),
    -    /// Internal system time error
    -    Time(std::time::SystemTimeError),
    -
    -    /// Wrapper for [`crate::error::Error`]
    -    Global(Box<crate::error::Error>),
    +/// An error that can occur during sync with a [`CompactFiltersBlockchain`]
    +#[derive(Debug)]
    +pub enum CompactFiltersError {
    +    /// A peer sent an invalid or unexpected response
    +    InvalidResponse,
    +    /// The headers returned are invalid
    +    InvalidHeaders,
    +    /// The compact filter headers returned are invalid
    +    InvalidFilterHeader,
    +    /// The compact filter returned is invalid
    +    InvalidFilter,
    +    /// The peer is missing a block in the valid chain
    +    MissingBlock,
    +    /// Block hash at specified height not found
    +    BlockHashNotFound,
    +    /// The data stored in the block filters storage are corrupted
    +    DataCorruption,
    +
    +    /// A peer is not connected
    +    NotConnected,
    +    /// A peer took too long to reply to one of our messages
    +    Timeout,
    +    /// The peer doesn't advertise the [`BLOOM`](bitcoin::network::constants::ServiceFlags::BLOOM) service flag
    +    PeerBloomDisabled,
    +
    +    /// No peers have been specified
    +    NoPeers,
    +
    +    /// Internal database error
    +    Db(rocksdb::Error),
    +    /// Internal I/O error
    +    Io(std::io::Error),
    +    /// Invalid BIP158 filter
    +    Bip158(bitcoin::util::bip158::Error),
    +    /// Internal system time error
    +    Time(std::time::SystemTimeError),
    +
    +    /// Wrapper for [`crate::error::Error`]
    +    Global(Box<crate::error::Error>),
     }
     
    -impl fmt::Display for CompactFiltersError {
    -    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
    -        write!(f, "{:?}", self)
    +impl fmt::Display for CompactFiltersError {
    +    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
    +        write!(f, "{:?}", self)
         }
     }
     
    -impl std::error::Error for CompactFiltersError {}
    +impl std::error::Error for CompactFiltersError {}
     
    -impl_error!(rocksdb::Error, Db, CompactFiltersError);
    -impl_error!(std::io::Error, Io, CompactFiltersError);
    -impl_error!(bitcoin::util::bip158::Error, Bip158, CompactFiltersError);
    -impl_error!(std::time::SystemTimeError, Time, CompactFiltersError);
    +impl_error!(rocksdb::Error, Db, CompactFiltersError);
    +impl_error!(std::io::Error, Io, CompactFiltersError);
    +impl_error!(bitcoin::util::bip158::Error, Bip158, CompactFiltersError);
    +impl_error!(std::time::SystemTimeError, Time, CompactFiltersError);
     
    -impl From<crate::error::Error> for CompactFiltersError {
    -    fn from(err: crate::error::Error) -> Self {
    -        CompactFiltersError::Global(Box::new(err))
    +impl From<crate::error::Error> for CompactFiltersError {
    +    fn from(err: crate::error::Error) -> Self {
    +        CompactFiltersError::Global(Box::new(err))
         }
     }
     
    -
    - \ No newline at end of file +
    \ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/src/bdk/blockchain/compact_filters/peer.rs.html b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/src/bdk/blockchain/compact_filters/peer.rs.html index 7138fd99d9..255e246efc 100644 --- a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/src/bdk/blockchain/compact_filters/peer.rs.html +++ b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/src/bdk/blockchain/compact_filters/peer.rs.html @@ -1,911 +1,905 @@ -peer.rs - source - -
      1
    -  2
    -  3
    -  4
    -  5
    -  6
    -  7
    -  8
    -  9
    - 10
    - 11
    - 12
    - 13
    - 14
    - 15
    - 16
    - 17
    - 18
    - 19
    - 20
    - 21
    - 22
    - 23
    - 24
    - 25
    - 26
    - 27
    - 28
    - 29
    - 30
    - 31
    - 32
    - 33
    - 34
    - 35
    - 36
    - 37
    - 38
    - 39
    - 40
    - 41
    - 42
    - 43
    - 44
    - 45
    - 46
    - 47
    - 48
    - 49
    - 50
    - 51
    - 52
    - 53
    - 54
    - 55
    - 56
    - 57
    - 58
    - 59
    - 60
    - 61
    - 62
    - 63
    - 64
    - 65
    - 66
    - 67
    - 68
    - 69
    - 70
    - 71
    - 72
    - 73
    - 74
    - 75
    - 76
    - 77
    - 78
    - 79
    - 80
    - 81
    - 82
    - 83
    - 84
    - 85
    - 86
    - 87
    - 88
    - 89
    - 90
    - 91
    - 92
    - 93
    - 94
    - 95
    - 96
    - 97
    - 98
    - 99
    -100
    -101
    -102
    -103
    -104
    -105
    -106
    -107
    -108
    -109
    -110
    -111
    -112
    -113
    -114
    -115
    -116
    -117
    -118
    -119
    -120
    -121
    -122
    -123
    -124
    -125
    -126
    -127
    -128
    -129
    -130
    -131
    -132
    -133
    -134
    -135
    -136
    -137
    -138
    -139
    -140
    -141
    -142
    -143
    -144
    -145
    -146
    -147
    -148
    -149
    -150
    -151
    -152
    -153
    -154
    -155
    -156
    -157
    -158
    -159
    -160
    -161
    -162
    -163
    -164
    -165
    -166
    -167
    -168
    -169
    -170
    -171
    -172
    -173
    -174
    -175
    -176
    -177
    -178
    -179
    -180
    -181
    -182
    -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
    -245
    -246
    -247
    -248
    -249
    -250
    -251
    -252
    -253
    -254
    -255
    -256
    -257
    -258
    -259
    -260
    -261
    -262
    -263
    -264
    -265
    -266
    -267
    -268
    -269
    -270
    -271
    -272
    -273
    -274
    -275
    -276
    -277
    -278
    -279
    -280
    -281
    -282
    -283
    -284
    -285
    -286
    -287
    -288
    -289
    -290
    -291
    -292
    -293
    -294
    -295
    -296
    -297
    -298
    -299
    -300
    -301
    -302
    -303
    -304
    -305
    -306
    -307
    -308
    -309
    -310
    -311
    -312
    -313
    -314
    -315
    -316
    -317
    -318
    -319
    -320
    -321
    -322
    -323
    -324
    -325
    -326
    -327
    -328
    -329
    -330
    -331
    -332
    -333
    -334
    -335
    -336
    -337
    -338
    -339
    -340
    -341
    -342
    -343
    -344
    -345
    -346
    -347
    -348
    -349
    -350
    -351
    -352
    -353
    -354
    -355
    -356
    -357
    -358
    -359
    -360
    -361
    -362
    -363
    -364
    -365
    -366
    -367
    -368
    -369
    -370
    -371
    -372
    -373
    -374
    -375
    -376
    -377
    -378
    -379
    -380
    -381
    -382
    -383
    -384
    -385
    -386
    -387
    -388
    -389
    -390
    -391
    -392
    -393
    -394
    -395
    -396
    -397
    -398
    -399
    -400
    -401
    -402
    -403
    -404
    -405
    -406
    -407
    -408
    -409
    -410
    -411
    -412
    -413
    -414
    -415
    -416
    -417
    -418
    -419
    -420
    -421
    -422
    -423
    -424
    -425
    -426
    -427
    -428
    -429
    -430
    -431
    -432
    -433
    -434
    -435
    -436
    -437
    -438
    -439
    -440
    -441
    -442
    -443
    -444
    -445
    -446
    -447
    -448
    -449
    -450
    -451
    -452
    -453
    -454
    -455
    -456
    -457
    -458
    -459
    -460
    -461
    -462
    -463
    -464
    -465
    -466
    -467
    -468
    -469
    -470
    -471
    -472
    -473
    -474
    -475
    -476
    -477
    -478
    -479
    -480
    -481
    -482
    -483
    -484
    -485
    -486
    -487
    -488
    -489
    -490
    -491
    -492
    -493
    -494
    -495
    -496
    -497
    -498
    -499
    -500
    -501
    -502
    -503
    -504
    -505
    -506
    -507
    -508
    -509
    -510
    -511
    -512
    -513
    -514
    -515
    -516
    -517
    -518
    -519
    -520
    -521
    -522
    -523
    -524
    -525
    -526
    -527
    -528
    -529
    -530
    -531
    -532
    -533
    -534
    -535
    -536
    -537
    -538
    -539
    -540
    -541
    -542
    -543
    -544
    -545
    -546
    -547
    -548
    -549
    -550
    -551
    -552
    -553
    -554
    -555
    -556
    -557
    -558
    -559
    -560
    -561
    -562
    -563
    -564
    -565
    -566
    -567
    -568
    -569
    -570
    -571
    -572
    -573
    -574
    -575
    -576
    -
    // Bitcoin Dev Kit
    -// Written in 2020 by Alekos Filini <alekos.filini@gmail.com>
    -//
    -// Copyright (c) 2020-2021 Bitcoin Dev Kit Developers
    -//
    -// This file is licensed under the Apache License, Version 2.0 <LICENSE-APACHE
    -// or http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
    -// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your option.
    -// You may not use this file except in accordance with one or both of these
    -// licenses.
    -
    -use std::collections::HashMap;
    -use std::io::BufReader;
    -use std::net::{TcpStream, ToSocketAddrs};
    -use std::sync::{Arc, Condvar, Mutex, RwLock};
    -use std::thread;
    -use std::time::{Duration, SystemTime, UNIX_EPOCH};
    -
    -use socks::{Socks5Stream, ToTargetAddr};
    -
    -use rand::{thread_rng, Rng};
    -
    -use bitcoin::consensus::{Decodable, Encodable};
    -use bitcoin::hash_types::BlockHash;
    -use bitcoin::network::constants::ServiceFlags;
    -use bitcoin::network::message::{NetworkMessage, RawNetworkMessage};
    -use bitcoin::network::message_blockdata::*;
    -use bitcoin::network::message_filter::*;
    -use bitcoin::network::message_network::VersionMessage;
    -use bitcoin::network::Address;
    -use bitcoin::{Block, Network, Transaction, Txid, Wtxid};
    -
    -use super::CompactFiltersError;
    -
    -type ResponsesMap = HashMap<&'static str, Arc<(Mutex<Vec<NetworkMessage>>, Condvar)>>;
    -
    -pub(crate) const TIMEOUT_SECS: u64 = 30;
    -
    -/// Container for unconfirmed, but valid Bitcoin transactions
    -///
    -/// It is normally shared between [`Peer`]s with the use of [`Arc`], so that transactions are not
    -/// duplicated in memory.
    -#[derive(Debug, Default)]
    -pub struct Mempool(RwLock<InnerMempool>);
    -
    -#[derive(Debug, Default)]
    -struct InnerMempool {
    -    txs: HashMap<Txid, Transaction>,
    -    wtxids: HashMap<Wtxid, Txid>,
    +peer.rs - source
    1
    +2
    +3
    +4
    +5
    +6
    +7
    +8
    +9
    +10
    +11
    +12
    +13
    +14
    +15
    +16
    +17
    +18
    +19
    +20
    +21
    +22
    +23
    +24
    +25
    +26
    +27
    +28
    +29
    +30
    +31
    +32
    +33
    +34
    +35
    +36
    +37
    +38
    +39
    +40
    +41
    +42
    +43
    +44
    +45
    +46
    +47
    +48
    +49
    +50
    +51
    +52
    +53
    +54
    +55
    +56
    +57
    +58
    +59
    +60
    +61
    +62
    +63
    +64
    +65
    +66
    +67
    +68
    +69
    +70
    +71
    +72
    +73
    +74
    +75
    +76
    +77
    +78
    +79
    +80
    +81
    +82
    +83
    +84
    +85
    +86
    +87
    +88
    +89
    +90
    +91
    +92
    +93
    +94
    +95
    +96
    +97
    +98
    +99
    +100
    +101
    +102
    +103
    +104
    +105
    +106
    +107
    +108
    +109
    +110
    +111
    +112
    +113
    +114
    +115
    +116
    +117
    +118
    +119
    +120
    +121
    +122
    +123
    +124
    +125
    +126
    +127
    +128
    +129
    +130
    +131
    +132
    +133
    +134
    +135
    +136
    +137
    +138
    +139
    +140
    +141
    +142
    +143
    +144
    +145
    +146
    +147
    +148
    +149
    +150
    +151
    +152
    +153
    +154
    +155
    +156
    +157
    +158
    +159
    +160
    +161
    +162
    +163
    +164
    +165
    +166
    +167
    +168
    +169
    +170
    +171
    +172
    +173
    +174
    +175
    +176
    +177
    +178
    +179
    +180
    +181
    +182
    +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
    +245
    +246
    +247
    +248
    +249
    +250
    +251
    +252
    +253
    +254
    +255
    +256
    +257
    +258
    +259
    +260
    +261
    +262
    +263
    +264
    +265
    +266
    +267
    +268
    +269
    +270
    +271
    +272
    +273
    +274
    +275
    +276
    +277
    +278
    +279
    +280
    +281
    +282
    +283
    +284
    +285
    +286
    +287
    +288
    +289
    +290
    +291
    +292
    +293
    +294
    +295
    +296
    +297
    +298
    +299
    +300
    +301
    +302
    +303
    +304
    +305
    +306
    +307
    +308
    +309
    +310
    +311
    +312
    +313
    +314
    +315
    +316
    +317
    +318
    +319
    +320
    +321
    +322
    +323
    +324
    +325
    +326
    +327
    +328
    +329
    +330
    +331
    +332
    +333
    +334
    +335
    +336
    +337
    +338
    +339
    +340
    +341
    +342
    +343
    +344
    +345
    +346
    +347
    +348
    +349
    +350
    +351
    +352
    +353
    +354
    +355
    +356
    +357
    +358
    +359
    +360
    +361
    +362
    +363
    +364
    +365
    +366
    +367
    +368
    +369
    +370
    +371
    +372
    +373
    +374
    +375
    +376
    +377
    +378
    +379
    +380
    +381
    +382
    +383
    +384
    +385
    +386
    +387
    +388
    +389
    +390
    +391
    +392
    +393
    +394
    +395
    +396
    +397
    +398
    +399
    +400
    +401
    +402
    +403
    +404
    +405
    +406
    +407
    +408
    +409
    +410
    +411
    +412
    +413
    +414
    +415
    +416
    +417
    +418
    +419
    +420
    +421
    +422
    +423
    +424
    +425
    +426
    +427
    +428
    +429
    +430
    +431
    +432
    +433
    +434
    +435
    +436
    +437
    +438
    +439
    +440
    +441
    +442
    +443
    +444
    +445
    +446
    +447
    +448
    +449
    +450
    +451
    +452
    +453
    +454
    +455
    +456
    +457
    +458
    +459
    +460
    +461
    +462
    +463
    +464
    +465
    +466
    +467
    +468
    +469
    +470
    +471
    +472
    +473
    +474
    +475
    +476
    +477
    +478
    +479
    +480
    +481
    +482
    +483
    +484
    +485
    +486
    +487
    +488
    +489
    +490
    +491
    +492
    +493
    +494
    +495
    +496
    +497
    +498
    +499
    +500
    +501
    +502
    +503
    +504
    +505
    +506
    +507
    +508
    +509
    +510
    +511
    +512
    +513
    +514
    +515
    +516
    +517
    +518
    +519
    +520
    +521
    +522
    +523
    +524
    +525
    +526
    +527
    +528
    +529
    +530
    +531
    +532
    +533
    +534
    +535
    +536
    +537
    +538
    +539
    +540
    +541
    +542
    +543
    +544
    +545
    +546
    +547
    +548
    +549
    +550
    +551
    +552
    +553
    +554
    +555
    +556
    +557
    +558
    +559
    +560
    +561
    +562
    +563
    +564
    +565
    +566
    +567
    +568
    +569
    +570
    +571
    +572
    +573
    +574
    +575
    +576
    +
    // Bitcoin Dev Kit
    +// Written in 2020 by Alekos Filini <alekos.filini@gmail.com>
    +//
    +// Copyright (c) 2020-2021 Bitcoin Dev Kit Developers
    +//
    +// This file is licensed under the Apache License, Version 2.0 <LICENSE-APACHE
    +// or http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
    +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your option.
    +// You may not use this file except in accordance with one or both of these
    +// licenses.
    +
    +use std::collections::HashMap;
    +use std::io::BufReader;
    +use std::net::{TcpStream, ToSocketAddrs};
    +use std::sync::{Arc, Condvar, Mutex, RwLock};
    +use std::thread;
    +use std::time::{Duration, SystemTime, UNIX_EPOCH};
    +
    +use socks::{Socks5Stream, ToTargetAddr};
    +
    +use rand::{thread_rng, Rng};
    +
    +use bitcoin::consensus::{Decodable, Encodable};
    +use bitcoin::hash_types::BlockHash;
    +use bitcoin::network::constants::ServiceFlags;
    +use bitcoin::network::message::{NetworkMessage, RawNetworkMessage};
    +use bitcoin::network::message_blockdata::*;
    +use bitcoin::network::message_filter::*;
    +use bitcoin::network::message_network::VersionMessage;
    +use bitcoin::network::Address;
    +use bitcoin::{Block, Network, Transaction, Txid, Wtxid};
    +
    +use super::CompactFiltersError;
    +
    +type ResponsesMap = HashMap<&'static str, Arc<(Mutex<Vec<NetworkMessage>>, Condvar)>>;
    +
    +pub(crate) const TIMEOUT_SECS: u64 = 30;
    +
    +/// Container for unconfirmed, but valid Bitcoin transactions
    +///
    +/// It is normally shared between [`Peer`]s with the use of [`Arc`], so that transactions are not
    +/// duplicated in memory.
    +#[derive(Debug, Default)]
    +pub struct Mempool(RwLock<InnerMempool>);
    +
    +#[derive(Debug, Default)]
    +struct InnerMempool {
    +    txs: HashMap<Txid, Transaction>,
    +    wtxids: HashMap<Wtxid, Txid>,
     }
     
    -#[derive(Debug, Clone, PartialEq, Eq)]
    -enum TxIdentifier {
    -    Wtxid(Wtxid),
    -    Txid(Txid),
    +#[derive(Debug, Clone, PartialEq, Eq)]
    +enum TxIdentifier {
    +    Wtxid(Wtxid),
    +    Txid(Txid),
     }
     
    -impl Mempool {
    -    /// Create a new empty mempool
    -    pub fn new() -> Self {
    -        Self::default()
    +impl Mempool {
    +    /// Create a new empty mempool
    +    pub fn new() -> Self {
    +        Self::default()
         }
     
    -    /// Add a transaction to the mempool
    -    ///
    -    /// Note that this doesn't propagate the transaction to other
    -    /// peers. To do that, [`broadcast`](crate::blockchain::Blockchain::broadcast) should be used.
    -    pub fn add_tx(&self, tx: Transaction) {
    -        let mut guard = self.0.write().unwrap();
    +    /// Add a transaction to the mempool
    +    ///
    +    /// Note that this doesn't propagate the transaction to other
    +    /// peers. To do that, [`broadcast`](crate::blockchain::Blockchain::broadcast) should be used.
    +    pub fn add_tx(&self, tx: Transaction) {
    +        let mut guard = self.0.write().unwrap();
     
    -        guard.wtxids.insert(tx.wtxid(), tx.txid());
    -        guard.txs.insert(tx.txid(), tx);
    +        guard.wtxids.insert(tx.wtxid(), tx.txid());
    +        guard.txs.insert(tx.txid(), tx);
         }
     
    -    /// Look-up a transaction in the mempool given an [`Inventory`] request
    -    pub fn get_tx(&self, inventory: &Inventory) -> Option<Transaction> {
    -        let identifer = match inventory {
    -            Inventory::Error
    -            | Inventory::Block(_)
    -            | Inventory::WitnessBlock(_)
    -            | Inventory::CompactBlock(_) => return None,
    -            Inventory::Transaction(txid) => TxIdentifier::Txid(*txid),
    -            Inventory::WitnessTransaction(txid) => TxIdentifier::Txid(*txid),
    -            Inventory::WTx(wtxid) => TxIdentifier::Wtxid(*wtxid),
    -            Inventory::Unknown { inv_type, hash } => {
    +    /// Look-up a transaction in the mempool given an [`Inventory`] request
    +    pub fn get_tx(&self, inventory: &Inventory) -> Option<Transaction> {
    +        let identifer = match inventory {
    +            Inventory::Error
    +            | Inventory::Block(_)
    +            | Inventory::WitnessBlock(_)
    +            | Inventory::CompactBlock(_) => return None,
    +            Inventory::Transaction(txid) => TxIdentifier::Txid(*txid),
    +            Inventory::WitnessTransaction(txid) => TxIdentifier::Txid(*txid),
    +            Inventory::WTx(wtxid) => TxIdentifier::Wtxid(*wtxid),
    +            Inventory::Unknown { inv_type, hash } => {
                     log::warn!(
                         "Unknown inventory request type `{}`, hash `{:?}`",
    -                    inv_type,
    -                    hash
    +                    inv_type,
    +                    hash
                     );
    -                return None;
    +                return None;
                 }
             };
     
    -        let txid = match identifer {
    -            TxIdentifier::Txid(txid) => Some(txid),
    -            TxIdentifier::Wtxid(wtxid) => self.0.read().unwrap().wtxids.get(&wtxid).cloned(),
    +        let txid = match identifer {
    +            TxIdentifier::Txid(txid) => Some(txid),
    +            TxIdentifier::Wtxid(wtxid) => self.0.read().unwrap().wtxids.get(&wtxid).cloned(),
             };
     
    -        txid.and_then(|txid| self.0.read().unwrap().txs.get(&txid).cloned())
    +        txid.and_then(|txid| self.0.read().unwrap().txs.get(&txid).cloned())
         }
     
    -    /// Return whether or not the mempool contains a transaction with a given txid
    -    pub fn has_tx(&self, txid: &Txid) -> bool {
    -        self.0.read().unwrap().txs.contains_key(txid)
    +    /// Return whether or not the mempool contains a transaction with a given txid
    +    pub fn has_tx(&self, txid: &Txid) -> bool {
    +        self.0.read().unwrap().txs.contains_key(txid)
         }
     
    -    /// Return the list of transactions contained in the mempool
    -    pub fn iter_txs(&self) -> Vec<Transaction> {
    -        self.0.read().unwrap().txs.values().cloned().collect()
    +    /// Return the list of transactions contained in the mempool
    +    pub fn iter_txs(&self) -> Vec<Transaction> {
    +        self.0.read().unwrap().txs.values().cloned().collect()
         }
     }
     
    -/// A Bitcoin peer
    -#[derive(Debug)]
    -#[allow(dead_code)]
    -pub struct Peer {
    -    writer: Arc<Mutex<TcpStream>>,
    -    responses: Arc<RwLock<ResponsesMap>>,
    +/// A Bitcoin peer
    +#[derive(Debug)]
    +#[allow(dead_code)]
    +pub struct Peer {
    +    writer: Arc<Mutex<TcpStream>>,
    +    responses: Arc<RwLock<ResponsesMap>>,
     
    -    reader_thread: thread::JoinHandle<()>,
    -    connected: Arc<RwLock<bool>>,
    +    reader_thread: thread::JoinHandle<()>,
    +    connected: Arc<RwLock<bool>>,
     
    -    mempool: Arc<Mempool>,
    +    mempool: Arc<Mempool>,
     
    -    version: VersionMessage,
    -    network: Network,
    +    version: VersionMessage,
    +    network: Network,
     }
     
    -impl Peer {
    -    /// Connect to a peer over a plaintext TCP connection
    -    ///
    -    /// This function internally spawns a new thread that will monitor incoming messages from the
    -    /// peer, and optionally reply to some of them transparently, like [pings](bitcoin::network::message::NetworkMessage::Ping)
    -    pub fn connect<A: ToSocketAddrs>(
    -        address: A,
    -        mempool: Arc<Mempool>,
    -        network: Network,
    -    ) -> Result<Self, CompactFiltersError> {
    -        let stream = TcpStream::connect(address)?;
    -
    -        Peer::from_stream(stream, mempool, network)
    +impl Peer {
    +    /// Connect to a peer over a plaintext TCP connection
    +    ///
    +    /// This function internally spawns a new thread that will monitor incoming messages from the
    +    /// peer, and optionally reply to some of them transparently, like [pings](bitcoin::network::message::NetworkMessage::Ping)
    +    pub fn connect<A: ToSocketAddrs>(
    +        address: A,
    +        mempool: Arc<Mempool>,
    +        network: Network,
    +    ) -> Result<Self, CompactFiltersError> {
    +        let stream = TcpStream::connect(address)?;
    +
    +        Peer::from_stream(stream, mempool, network)
         }
     
    -    /// Connect to a peer through a SOCKS5 proxy, optionally by using some credentials, specified
    -    /// as a tuple of `(username, password)`
    -    ///
    -    /// This function internally spawns a new thread that will monitor incoming messages from the
    -    /// peer, and optionally reply to some of them transparently, like [pings](NetworkMessage::Ping)
    -    pub fn connect_proxy<T: ToTargetAddr, P: ToSocketAddrs>(
    -        target: T,
    -        proxy: P,
    -        credentials: Option<(&str, &str)>,
    -        mempool: Arc<Mempool>,
    -        network: Network,
    -    ) -> Result<Self, CompactFiltersError> {
    -        let socks_stream = if let Some((username, password)) = credentials {
    -            Socks5Stream::connect_with_password(proxy, target, username, password)?
    -        } else {
    -            Socks5Stream::connect(proxy, target)?
    -        };
    -
    -        Peer::from_stream(socks_stream.into_inner(), mempool, network)
    +    /// Connect to a peer through a SOCKS5 proxy, optionally by using some credentials, specified
    +    /// as a tuple of `(username, password)`
    +    ///
    +    /// This function internally spawns a new thread that will monitor incoming messages from the
    +    /// peer, and optionally reply to some of them transparently, like [pings](NetworkMessage::Ping)
    +    pub fn connect_proxy<T: ToTargetAddr, P: ToSocketAddrs>(
    +        target: T,
    +        proxy: P,
    +        credentials: Option<(&str, &str)>,
    +        mempool: Arc<Mempool>,
    +        network: Network,
    +    ) -> Result<Self, CompactFiltersError> {
    +        let socks_stream = if let Some((username, password)) = credentials {
    +            Socks5Stream::connect_with_password(proxy, target, username, password)?
    +        } else {
    +            Socks5Stream::connect(proxy, target)?
    +        };
    +
    +        Peer::from_stream(socks_stream.into_inner(), mempool, network)
         }
     
    -    /// Create a [`Peer`] from an already connected TcpStream
    -    fn from_stream(
    -        stream: TcpStream,
    -        mempool: Arc<Mempool>,
    -        network: Network,
    -    ) -> Result<Self, CompactFiltersError> {
    -        let writer = Arc::new(Mutex::new(stream.try_clone()?));
    -        let responses: Arc<RwLock<ResponsesMap>> = Arc::new(RwLock::new(HashMap::new()));
    -        let connected = Arc::new(RwLock::new(true));
    -
    -        let mut locked_writer = writer.lock().unwrap();
    -
    -        let reader_thread_responses = Arc::clone(&responses);
    -        let reader_thread_writer = Arc::clone(&writer);
    -        let reader_thread_mempool = Arc::clone(&mempool);
    -        let reader_thread_connected = Arc::clone(&connected);
    -        let reader_thread = thread::spawn(move || {
    -            Self::reader_thread(
    -                network,
    -                stream,
    -                reader_thread_responses,
    -                reader_thread_writer,
    -                reader_thread_mempool,
    -                reader_thread_connected,
    +    /// Create a [`Peer`] from an already connected TcpStream
    +    fn from_stream(
    +        stream: TcpStream,
    +        mempool: Arc<Mempool>,
    +        network: Network,
    +    ) -> Result<Self, CompactFiltersError> {
    +        let writer = Arc::new(Mutex::new(stream.try_clone()?));
    +        let responses: Arc<RwLock<ResponsesMap>> = Arc::new(RwLock::new(HashMap::new()));
    +        let connected = Arc::new(RwLock::new(true));
    +
    +        let mut locked_writer = writer.lock().unwrap();
    +
    +        let reader_thread_responses = Arc::clone(&responses);
    +        let reader_thread_writer = Arc::clone(&writer);
    +        let reader_thread_mempool = Arc::clone(&mempool);
    +        let reader_thread_connected = Arc::clone(&connected);
    +        let reader_thread = thread::spawn(move || {
    +            Self::reader_thread(
    +                network,
    +                stream,
    +                reader_thread_responses,
    +                reader_thread_writer,
    +                reader_thread_mempool,
    +                reader_thread_connected,
                 )
             });
     
    -        let timestamp = SystemTime::now().duration_since(UNIX_EPOCH)?.as_secs() as i64;
    -        let nonce = thread_rng().gen();
    -        let receiver = Address::new(&locked_writer.peer_addr()?, ServiceFlags::NONE);
    -        let sender = Address {
    -            services: ServiceFlags::NONE,
    -            address: [0u16; 8],
    -            port: 0,
    +        let timestamp = SystemTime::now().duration_since(UNIX_EPOCH)?.as_secs() as i64;
    +        let nonce = thread_rng().gen();
    +        let receiver = Address::new(&locked_writer.peer_addr()?, ServiceFlags::NONE);
    +        let sender = Address {
    +            services: ServiceFlags::NONE,
    +            address: [0u16; 8],
    +            port: 0,
             };
     
    -        Self::_send(
    -            &mut locked_writer,
    -            network.magic(),
    -            NetworkMessage::Version(VersionMessage::new(
    -                ServiceFlags::WITNESS,
    -                timestamp,
    -                receiver,
    -                sender,
    -                nonce,
    -                "MagicalBitcoinWallet".into(),
    +        Self::_send(
    +            &mut locked_writer,
    +            network.magic(),
    +            NetworkMessage::Version(VersionMessage::new(
    +                ServiceFlags::WITNESS,
    +                timestamp,
    +                receiver,
    +                sender,
    +                nonce,
    +                "MagicalBitcoinWallet".into(),
                     0,
                 )),
             )?;
    -        let version = if let NetworkMessage::Version(version) =
    -            Self::_recv(&responses, "version", None).unwrap()
    +        let version = if let NetworkMessage::Version(version) =
    +            Self::_recv(&responses, "version", None).unwrap()
             {
    -            version
    -        } else {
    -            return Err(CompactFiltersError::InvalidResponse);
    +            version
    +        } else {
    +            return Err(CompactFiltersError::InvalidResponse);
             };
     
    -        if let NetworkMessage::Verack = Self::_recv(&responses, "verack", None).unwrap() {
    -            Self::_send(&mut locked_writer, network.magic(), NetworkMessage::Verack)?;
    -        } else {
    -            return Err(CompactFiltersError::InvalidResponse);
    +        if let NetworkMessage::Verack = Self::_recv(&responses, "verack", None).unwrap() {
    +            Self::_send(&mut locked_writer, network.magic(), NetworkMessage::Verack)?;
    +        } else {
    +            return Err(CompactFiltersError::InvalidResponse);
             }
     
    -        std::mem::drop(locked_writer);
    +        std::mem::drop(locked_writer);
     
    -        Ok(Peer {
    -            writer,
    -            responses,
    -            reader_thread,
    -            connected,
    -            mempool,
    -            version,
    -            network,
    +        Ok(Peer {
    +            writer,
    +            responses,
    +            reader_thread,
    +            connected,
    +            mempool,
    +            version,
    +            network,
             })
         }
     
    -    /// Send a Bitcoin network message
    -    fn _send(
    -        writer: &mut TcpStream,
    -        magic: u32,
    -        payload: NetworkMessage,
    -    ) -> Result<(), CompactFiltersError> {
    -        log::trace!("==> {:?}", payload);
    +    /// Send a Bitcoin network message
    +    fn _send(
    +        writer: &mut TcpStream,
    +        magic: u32,
    +        payload: NetworkMessage,
    +    ) -> Result<(), CompactFiltersError> {
    +        log::trace!("==> {:?}", payload);
     
    -        let raw_message = RawNetworkMessage { magic, payload };
    +        let raw_message = RawNetworkMessage { magic, payload };
     
    -        raw_message
    -            .consensus_encode(writer)
    -            .map_err(|_| CompactFiltersError::DataCorruption)?;
    +        raw_message
    +            .consensus_encode(writer)
    +            .map_err(|_| CompactFiltersError::DataCorruption)?;
     
             Ok(())
         }
     
    -    /// Wait for a specific incoming Bitcoin message, optionally with a timeout
    -    fn _recv(
    -        responses: &Arc<RwLock<ResponsesMap>>,
    -        wait_for: &'static str,
    -        timeout: Option<Duration>,
    -    ) -> Option<NetworkMessage> {
    -        let message_resp = {
    -            let mut lock = responses.write().unwrap();
    -            let message_resp = lock.entry(wait_for).or_default();
    -            Arc::clone(message_resp)
    +    /// Wait for a specific incoming Bitcoin message, optionally with a timeout
    +    fn _recv(
    +        responses: &Arc<RwLock<ResponsesMap>>,
    +        wait_for: &'static str,
    +        timeout: Option<Duration>,
    +    ) -> Option<NetworkMessage> {
    +        let message_resp = {
    +            let mut lock = responses.write().unwrap();
    +            let message_resp = lock.entry(wait_for).or_default();
    +            Arc::clone(message_resp)
             };
     
    -        let (lock, cvar) = &*message_resp;
    +        let (lock, cvar) = &*message_resp;
     
    -        let mut messages = lock.lock().unwrap();
    -        while messages.is_empty() {
    -            match timeout {
    -                None => messages = cvar.wait(messages).unwrap(),
    -                Some(t) => {
    -                    let result = cvar.wait_timeout(messages, t).unwrap();
    -                    if result.1.timed_out() {
    -                        return None;
    +        let mut messages = lock.lock().unwrap();
    +        while messages.is_empty() {
    +            match timeout {
    +                None => messages = cvar.wait(messages).unwrap(),
    +                Some(t) => {
    +                    let result = cvar.wait_timeout(messages, t).unwrap();
    +                    if result.1.timed_out() {
    +                        return None;
                         }
    -                    messages = result.0;
    +                    messages = result.0;
                     }
                 }
             }
     
    -        messages.pop()
    +        messages.pop()
         }
     
    -    /// Return the [`VersionMessage`] sent by the peer
    -    pub fn get_version(&self) -> &VersionMessage {
    -        &self.version
    +    /// Return the [`VersionMessage`] sent by the peer
    +    pub fn get_version(&self) -> &VersionMessage {
    +        &self.version
         }
     
    -    /// Return the Bitcoin [`Network`] in use
    -    pub fn get_network(&self) -> Network {
    -        self.network
    +    /// Return the Bitcoin [`Network`] in use
    +    pub fn get_network(&self) -> Network {
    +        self.network
         }
     
    -    /// Return the mempool used by this peer
    -    pub fn get_mempool(&self) -> Arc<Mempool> {
    -        Arc::clone(&self.mempool)
    +    /// Return the mempool used by this peer
    +    pub fn get_mempool(&self) -> Arc<Mempool> {
    +        Arc::clone(&self.mempool)
         }
     
    -    /// Return whether or not the peer is still connected
    -    pub fn is_connected(&self) -> bool {
    -        *self.connected.read().unwrap()
    +    /// Return whether or not the peer is still connected
    +    pub fn is_connected(&self) -> bool {
    +        *self.connected.read().unwrap()
         }
     
    -    /// Internal function called once the `reader_thread` is spawned
    -    fn reader_thread(
    -        network: Network,
    -        connection: TcpStream,
    -        reader_thread_responses: Arc<RwLock<ResponsesMap>>,
    -        reader_thread_writer: Arc<Mutex<TcpStream>>,
    -        reader_thread_mempool: Arc<Mempool>,
    -        reader_thread_connected: Arc<RwLock<bool>>,
    +    /// Internal function called once the `reader_thread` is spawned
    +    fn reader_thread(
    +        network: Network,
    +        connection: TcpStream,
    +        reader_thread_responses: Arc<RwLock<ResponsesMap>>,
    +        reader_thread_writer: Arc<Mutex<TcpStream>>,
    +        reader_thread_mempool: Arc<Mempool>,
    +        reader_thread_connected: Arc<RwLock<bool>>,
         ) {
    -        macro_rules! check_disconnect {
    -            ($call:expr) => {
    -                match $call {
    -                    Ok(good) => good,
    -                    Err(e) => {
    -                        log::debug!("Error {:?}", e);
    -                        *reader_thread_connected.write().unwrap() = false;
    +        macro_rules! check_disconnect {
    +            ($call:expr) => {
    +                match $call {
    +                    Ok(good) => good,
    +                    Err(e) => {
    +                        log::debug!("Error {:?}", e);
    +                        *reader_thread_connected.write().unwrap() = false;
     
                             break;
                         }
    @@ -913,250 +907,249 @@
                 };
             }
     
    -        let mut reader = BufReader::new(connection);
    -        loop {
    -            let raw_message: RawNetworkMessage =
    -                check_disconnect!(Decodable::consensus_decode(&mut reader));
    +        let mut reader = BufReader::new(connection);
    +        loop {
    +            let raw_message: RawNetworkMessage =
    +                check_disconnect!(Decodable::consensus_decode(&mut reader));
     
    -            let in_message = if raw_message.magic != network.magic() {
    +            let in_message = if raw_message.magic != network.magic() {
                     continue;
    -            } else {
    -                raw_message.payload
    +            } else {
    +                raw_message.payload
                 };
     
    -            log::trace!("<== {:?}", in_message);
    +            log::trace!("<== {:?}", in_message);
     
    -            match in_message {
    -                NetworkMessage::Ping(nonce) => {
    -                    check_disconnect!(Self::_send(
    -                        &mut reader_thread_writer.lock().unwrap(),
    -                        network.magic(),
    -                        NetworkMessage::Pong(nonce),
    +            match in_message {
    +                NetworkMessage::Ping(nonce) => {
    +                    check_disconnect!(Self::_send(
    +                        &mut reader_thread_writer.lock().unwrap(),
    +                        network.magic(),
    +                        NetworkMessage::Pong(nonce),
                         ));
     
                         continue;
                     }
    -                NetworkMessage::Alert(_) => continue,
    -                NetworkMessage::GetData(ref inv) => {
    -                    let (found, not_found): (Vec<_>, Vec<_>) = inv
    -                        .iter()
    -                        .map(|item| (*item, reader_thread_mempool.get_tx(item)))
    -                        .partition(|(_, d)| d.is_some());
    -                    for (_, found_tx) in found {
    -                        check_disconnect!(Self::_send(
    -                            &mut reader_thread_writer.lock().unwrap(),
    -                            network.magic(),
    -                            NetworkMessage::Tx(found_tx.unwrap()),
    +                NetworkMessage::Alert(_) => continue,
    +                NetworkMessage::GetData(ref inv) => {
    +                    let (found, not_found): (Vec<_>, Vec<_>) = inv
    +                        .iter()
    +                        .map(|item| (*item, reader_thread_mempool.get_tx(item)))
    +                        .partition(|(_, d)| d.is_some());
    +                    for (_, found_tx) in found {
    +                        check_disconnect!(Self::_send(
    +                            &mut reader_thread_writer.lock().unwrap(),
    +                            network.magic(),
    +                            NetworkMessage::Tx(found_tx.unwrap()),
                             ));
                         }
     
    -                    if !not_found.is_empty() {
    -                        check_disconnect!(Self::_send(
    -                            &mut reader_thread_writer.lock().unwrap(),
    -                            network.magic(),
    -                            NetworkMessage::NotFound(
    -                                not_found.into_iter().map(|(i, _)| i).collect(),
    +                    if !not_found.is_empty() {
    +                        check_disconnect!(Self::_send(
    +                            &mut reader_thread_writer.lock().unwrap(),
    +                            network.magic(),
    +                            NetworkMessage::NotFound(
    +                                not_found.into_iter().map(|(i, _)| i).collect(),
                                 ),
                             ));
                         }
                     }
    -                _ => {}
    +                _ => {}
                 }
     
    -            let message_resp = {
    -                let mut lock = reader_thread_responses.write().unwrap();
    -                let message_resp = lock.entry(in_message.cmd()).or_default();
    -                Arc::clone(message_resp)
    +            let message_resp = {
    +                let mut lock = reader_thread_responses.write().unwrap();
    +                let message_resp = lock.entry(in_message.cmd()).or_default();
    +                Arc::clone(message_resp)
                 };
     
    -            let (lock, cvar) = &*message_resp;
    -            let mut messages = lock.lock().unwrap();
    -            messages.push(in_message);
    -            cvar.notify_all();
    +            let (lock, cvar) = &*message_resp;
    +            let mut messages = lock.lock().unwrap();
    +            messages.push(in_message);
    +            cvar.notify_all();
             }
         }
     
    -    /// Send a raw Bitcoin message to the peer
    -    pub fn send(&self, payload: NetworkMessage) -> Result<(), CompactFiltersError> {
    -        let mut writer = self.writer.lock().unwrap();
    -        Self::_send(&mut writer, self.network.magic(), payload)
    +    /// Send a raw Bitcoin message to the peer
    +    pub fn send(&self, payload: NetworkMessage) -> Result<(), CompactFiltersError> {
    +        let mut writer = self.writer.lock().unwrap();
    +        Self::_send(&mut writer, self.network.magic(), payload)
         }
     
    -    /// Waits for a specific incoming Bitcoin message, optionally with a timeout
    -    pub fn recv(
    +    /// Waits for a specific incoming Bitcoin message, optionally with a timeout
    +    pub fn recv(
             &self,
    -        wait_for: &'static str,
    -        timeout: Option<Duration>,
    -    ) -> Result<Option<NetworkMessage>, CompactFiltersError> {
    -        Ok(Self::_recv(&self.responses, wait_for, timeout))
    +        wait_for: &'static str,
    +        timeout: Option<Duration>,
    +    ) -> Result<Option<NetworkMessage>, CompactFiltersError> {
    +        Ok(Self::_recv(&self.responses, wait_for, timeout))
         }
     }
     
    -pub trait CompactFiltersPeer {
    -    fn get_cf_checkpt(
    +pub trait CompactFiltersPeer {
    +    fn get_cf_checkpt(
             &self,
    -        filter_type: u8,
    -        stop_hash: BlockHash,
    -    ) -> Result<CFCheckpt, CompactFiltersError>;
    -    fn get_cf_headers(
    +        filter_type: u8,
    +        stop_hash: BlockHash,
    +    ) -> Result<CFCheckpt, CompactFiltersError>;
    +    fn get_cf_headers(
             &self,
    -        filter_type: u8,
    -        start_height: u32,
    -        stop_hash: BlockHash,
    -    ) -> Result<CFHeaders, CompactFiltersError>;
    -    fn get_cf_filters(
    +        filter_type: u8,
    +        start_height: u32,
    +        stop_hash: BlockHash,
    +    ) -> Result<CFHeaders, CompactFiltersError>;
    +    fn get_cf_filters(
             &self,
    -        filter_type: u8,
    -        start_height: u32,
    -        stop_hash: BlockHash,
    -    ) -> Result<(), CompactFiltersError>;
    -    fn pop_cf_filter_resp(&self) -> Result<CFilter, CompactFiltersError>;
    +        filter_type: u8,
    +        start_height: u32,
    +        stop_hash: BlockHash,
    +    ) -> Result<(), CompactFiltersError>;
    +    fn pop_cf_filter_resp(&self) -> Result<CFilter, CompactFiltersError>;
     }
     
    -impl CompactFiltersPeer for Peer {
    -    fn get_cf_checkpt(
    +impl CompactFiltersPeer for Peer {
    +    fn get_cf_checkpt(
             &self,
    -        filter_type: u8,
    -        stop_hash: BlockHash,
    -    ) -> Result<CFCheckpt, CompactFiltersError> {
    -        self.send(NetworkMessage::GetCFCheckpt(GetCFCheckpt {
    -            filter_type,
    -            stop_hash,
    +        filter_type: u8,
    +        stop_hash: BlockHash,
    +    ) -> Result<CFCheckpt, CompactFiltersError> {
    +        self.send(NetworkMessage::GetCFCheckpt(GetCFCheckpt {
    +            filter_type,
    +            stop_hash,
             }))?;
     
    -        let response = self
    -            .recv("cfcheckpt", Some(Duration::from_secs(TIMEOUT_SECS)))?
    -            .ok_or(CompactFiltersError::Timeout)?;
    -        let response = match response {
    -            NetworkMessage::CFCheckpt(response) => response,
    -            _ => return Err(CompactFiltersError::InvalidResponse),
    +        let response = self
    +            .recv("cfcheckpt", Some(Duration::from_secs(TIMEOUT_SECS)))?
    +            .ok_or(CompactFiltersError::Timeout)?;
    +        let response = match response {
    +            NetworkMessage::CFCheckpt(response) => response,
    +            _ => return Err(CompactFiltersError::InvalidResponse),
             };
     
    -        if response.filter_type != filter_type {
    -            return Err(CompactFiltersError::InvalidResponse);
    +        if response.filter_type != filter_type {
    +            return Err(CompactFiltersError::InvalidResponse);
             }
     
    -        Ok(response)
    +        Ok(response)
         }
     
    -    fn get_cf_headers(
    +    fn get_cf_headers(
             &self,
    -        filter_type: u8,
    -        start_height: u32,
    -        stop_hash: BlockHash,
    -    ) -> Result<CFHeaders, CompactFiltersError> {
    -        self.send(NetworkMessage::GetCFHeaders(GetCFHeaders {
    -            filter_type,
    -            start_height,
    -            stop_hash,
    +        filter_type: u8,
    +        start_height: u32,
    +        stop_hash: BlockHash,
    +    ) -> Result<CFHeaders, CompactFiltersError> {
    +        self.send(NetworkMessage::GetCFHeaders(GetCFHeaders {
    +            filter_type,
    +            start_height,
    +            stop_hash,
             }))?;
     
    -        let response = self
    -            .recv("cfheaders", Some(Duration::from_secs(TIMEOUT_SECS)))?
    -            .ok_or(CompactFiltersError::Timeout)?;
    -        let response = match response {
    -            NetworkMessage::CFHeaders(response) => response,
    -            _ => return Err(CompactFiltersError::InvalidResponse),
    +        let response = self
    +            .recv("cfheaders", Some(Duration::from_secs(TIMEOUT_SECS)))?
    +            .ok_or(CompactFiltersError::Timeout)?;
    +        let response = match response {
    +            NetworkMessage::CFHeaders(response) => response,
    +            _ => return Err(CompactFiltersError::InvalidResponse),
             };
     
    -        if response.filter_type != filter_type {
    -            return Err(CompactFiltersError::InvalidResponse);
    +        if response.filter_type != filter_type {
    +            return Err(CompactFiltersError::InvalidResponse);
             }
     
    -        Ok(response)
    +        Ok(response)
         }
     
    -    fn pop_cf_filter_resp(&self) -> Result<CFilter, CompactFiltersError> {
    -        let response = self
    -            .recv("cfilter", Some(Duration::from_secs(TIMEOUT_SECS)))?
    -            .ok_or(CompactFiltersError::Timeout)?;
    -        let response = match response {
    -            NetworkMessage::CFilter(response) => response,
    -            _ => return Err(CompactFiltersError::InvalidResponse),
    +    fn pop_cf_filter_resp(&self) -> Result<CFilter, CompactFiltersError> {
    +        let response = self
    +            .recv("cfilter", Some(Duration::from_secs(TIMEOUT_SECS)))?
    +            .ok_or(CompactFiltersError::Timeout)?;
    +        let response = match response {
    +            NetworkMessage::CFilter(response) => response,
    +            _ => return Err(CompactFiltersError::InvalidResponse),
             };
     
    -        Ok(response)
    +        Ok(response)
         }
     
    -    fn get_cf_filters(
    +    fn get_cf_filters(
             &self,
    -        filter_type: u8,
    -        start_height: u32,
    -        stop_hash: BlockHash,
    -    ) -> Result<(), CompactFiltersError> {
    -        self.send(NetworkMessage::GetCFilters(GetCFilters {
    -            filter_type,
    -            start_height,
    -            stop_hash,
    +        filter_type: u8,
    +        start_height: u32,
    +        stop_hash: BlockHash,
    +    ) -> Result<(), CompactFiltersError> {
    +        self.send(NetworkMessage::GetCFilters(GetCFilters {
    +            filter_type,
    +            start_height,
    +            stop_hash,
             }))?;
     
             Ok(())
         }
     }
     
    -pub trait InvPeer {
    -    fn get_block(&self, block_hash: BlockHash) -> Result<Option<Block>, CompactFiltersError>;
    -    fn ask_for_mempool(&self) -> Result<(), CompactFiltersError>;
    -    fn broadcast_tx(&self, tx: Transaction) -> Result<(), CompactFiltersError>;
    +pub trait InvPeer {
    +    fn get_block(&self, block_hash: BlockHash) -> Result<Option<Block>, CompactFiltersError>;
    +    fn ask_for_mempool(&self) -> Result<(), CompactFiltersError>;
    +    fn broadcast_tx(&self, tx: Transaction) -> Result<(), CompactFiltersError>;
     }
     
    -impl InvPeer for Peer {
    -    fn get_block(&self, block_hash: BlockHash) -> Result<Option<Block>, CompactFiltersError> {
    -        self.send(NetworkMessage::GetData(vec![Inventory::WitnessBlock(
    -            block_hash,
    +impl InvPeer for Peer {
    +    fn get_block(&self, block_hash: BlockHash) -> Result<Option<Block>, CompactFiltersError> {
    +        self.send(NetworkMessage::GetData(vec![Inventory::WitnessBlock(
    +            block_hash,
             )]))?;
     
    -        match self.recv("block", Some(Duration::from_secs(TIMEOUT_SECS)))? {
    -            None => Ok(None),
    -            Some(NetworkMessage::Block(response)) => Ok(Some(response)),
    -            _ => Err(CompactFiltersError::InvalidResponse),
    +        match self.recv("block", Some(Duration::from_secs(TIMEOUT_SECS)))? {
    +            None => Ok(None),
    +            Some(NetworkMessage::Block(response)) => Ok(Some(response)),
    +            _ => Err(CompactFiltersError::InvalidResponse),
             }
         }
     
    -    fn ask_for_mempool(&self) -> Result<(), CompactFiltersError> {
    -        if !self.version.services.has(ServiceFlags::BLOOM) {
    -            return Err(CompactFiltersError::PeerBloomDisabled);
    +    fn ask_for_mempool(&self) -> Result<(), CompactFiltersError> {
    +        if !self.version.services.has(ServiceFlags::BLOOM) {
    +            return Err(CompactFiltersError::PeerBloomDisabled);
             }
     
    -        self.send(NetworkMessage::MemPool)?;
    -        let inv = match self.recv("inv", Some(Duration::from_secs(5)))? {
    -            None => return Ok(()), // empty mempool
    -            Some(NetworkMessage::Inv(inv)) => inv,
    -            _ => return Err(CompactFiltersError::InvalidResponse),
    +        self.send(NetworkMessage::MemPool)?;
    +        let inv = match self.recv("inv", Some(Duration::from_secs(5)))? {
    +            None => return Ok(()), // empty mempool
    +            Some(NetworkMessage::Inv(inv)) => inv,
    +            _ => return Err(CompactFiltersError::InvalidResponse),
             };
     
    -        let getdata = inv
    -            .iter()
    -            .cloned()
    -            .filter(
    -                |item| matches!(item, Inventory::Transaction(txid) if !self.mempool.has_tx(txid)),
    +        let getdata = inv
    +            .iter()
    +            .cloned()
    +            .filter(
    +                |item| matches!(item, Inventory::Transaction(txid) if !self.mempool.has_tx(txid)),
                 )
    -            .collect::<Vec<_>>();
    -        let num_txs = getdata.len();
    -        self.send(NetworkMessage::GetData(getdata))?;
    -
    -        for _ in 0..num_txs {
    -            let tx = self
    -                .recv("tx", Some(Duration::from_secs(TIMEOUT_SECS)))?
    -                .ok_or(CompactFiltersError::Timeout)?;
    -            let tx = match tx {
    -                NetworkMessage::Tx(tx) => tx,
    -                _ => return Err(CompactFiltersError::InvalidResponse),
    +            .collect::<Vec<_>>();
    +        let num_txs = getdata.len();
    +        self.send(NetworkMessage::GetData(getdata))?;
    +
    +        for _ in 0..num_txs {
    +            let tx = self
    +                .recv("tx", Some(Duration::from_secs(TIMEOUT_SECS)))?
    +                .ok_or(CompactFiltersError::Timeout)?;
    +            let tx = match tx {
    +                NetworkMessage::Tx(tx) => tx,
    +                _ => return Err(CompactFiltersError::InvalidResponse),
                 };
     
    -            self.mempool.add_tx(tx);
    +            self.mempool.add_tx(tx);
             }
     
             Ok(())
         }
     
    -    fn broadcast_tx(&self, tx: Transaction) -> Result<(), CompactFiltersError> {
    -        self.mempool.add_tx(tx.clone());
    -        self.send(NetworkMessage::Tx(tx))?;
    +    fn broadcast_tx(&self, tx: Transaction) -> Result<(), CompactFiltersError> {
    +        self.mempool.add_tx(tx.clone());
    +        self.send(NetworkMessage::Tx(tx))?;
     
             Ok(())
         }
     }
     
    -
    - \ No newline at end of file +
    \ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/src/bdk/blockchain/compact_filters/store.rs.html b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/src/bdk/blockchain/compact_filters/store.rs.html index adadb39924..249f825dac 100644 --- a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/src/bdk/blockchain/compact_filters/store.rs.html +++ b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/src/bdk/blockchain/compact_filters/store.rs.html @@ -1,1682 +1,1675 @@ -store.rs - source - -
      1
    -  2
    -  3
    -  4
    -  5
    -  6
    -  7
    -  8
    -  9
    - 10
    - 11
    - 12
    - 13
    - 14
    - 15
    - 16
    - 17
    - 18
    - 19
    - 20
    - 21
    - 22
    - 23
    - 24
    - 25
    - 26
    - 27
    - 28
    - 29
    - 30
    - 31
    - 32
    - 33
    - 34
    - 35
    - 36
    - 37
    - 38
    - 39
    - 40
    - 41
    - 42
    - 43
    - 44
    - 45
    - 46
    - 47
    - 48
    - 49
    - 50
    - 51
    - 52
    - 53
    - 54
    - 55
    - 56
    - 57
    - 58
    - 59
    - 60
    - 61
    - 62
    - 63
    - 64
    - 65
    - 66
    - 67
    - 68
    - 69
    - 70
    - 71
    - 72
    - 73
    - 74
    - 75
    - 76
    - 77
    - 78
    - 79
    - 80
    - 81
    - 82
    - 83
    - 84
    - 85
    - 86
    - 87
    - 88
    - 89
    - 90
    - 91
    - 92
    - 93
    - 94
    - 95
    - 96
    - 97
    - 98
    - 99
    -100
    -101
    -102
    -103
    -104
    -105
    -106
    -107
    -108
    -109
    -110
    -111
    -112
    -113
    -114
    -115
    -116
    -117
    -118
    -119
    -120
    -121
    -122
    -123
    -124
    -125
    -126
    -127
    -128
    -129
    -130
    -131
    -132
    -133
    -134
    -135
    -136
    -137
    -138
    -139
    -140
    -141
    -142
    -143
    -144
    -145
    -146
    -147
    -148
    -149
    -150
    -151
    -152
    -153
    -154
    -155
    -156
    -157
    -158
    -159
    -160
    -161
    -162
    -163
    -164
    -165
    -166
    -167
    -168
    -169
    -170
    -171
    -172
    -173
    -174
    -175
    -176
    -177
    -178
    -179
    -180
    -181
    -182
    -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
    -245
    -246
    -247
    -248
    -249
    -250
    -251
    -252
    -253
    -254
    -255
    -256
    -257
    -258
    -259
    -260
    -261
    -262
    -263
    -264
    -265
    -266
    -267
    -268
    -269
    -270
    -271
    -272
    -273
    -274
    -275
    -276
    -277
    -278
    -279
    -280
    -281
    -282
    -283
    -284
    -285
    -286
    -287
    -288
    -289
    -290
    -291
    -292
    -293
    -294
    -295
    -296
    -297
    -298
    -299
    -300
    -301
    -302
    -303
    -304
    -305
    -306
    -307
    -308
    -309
    -310
    -311
    -312
    -313
    -314
    -315
    -316
    -317
    -318
    -319
    -320
    -321
    -322
    -323
    -324
    -325
    -326
    -327
    -328
    -329
    -330
    -331
    -332
    -333
    -334
    -335
    -336
    -337
    -338
    -339
    -340
    -341
    -342
    -343
    -344
    -345
    -346
    -347
    -348
    -349
    -350
    -351
    -352
    -353
    -354
    -355
    -356
    -357
    -358
    -359
    -360
    -361
    -362
    -363
    -364
    -365
    -366
    -367
    -368
    -369
    -370
    -371
    -372
    -373
    -374
    -375
    -376
    -377
    -378
    -379
    -380
    -381
    -382
    -383
    -384
    -385
    -386
    -387
    -388
    -389
    -390
    -391
    -392
    -393
    -394
    -395
    -396
    -397
    -398
    -399
    -400
    -401
    -402
    -403
    -404
    -405
    -406
    -407
    -408
    -409
    -410
    -411
    -412
    -413
    -414
    -415
    -416
    -417
    -418
    -419
    -420
    -421
    -422
    -423
    -424
    -425
    -426
    -427
    -428
    -429
    -430
    -431
    -432
    -433
    -434
    -435
    -436
    -437
    -438
    -439
    -440
    -441
    -442
    -443
    -444
    -445
    -446
    -447
    -448
    -449
    -450
    -451
    -452
    -453
    -454
    -455
    -456
    -457
    -458
    -459
    -460
    -461
    -462
    -463
    -464
    -465
    -466
    -467
    -468
    -469
    -470
    -471
    -472
    -473
    -474
    -475
    -476
    -477
    -478
    -479
    -480
    -481
    -482
    -483
    -484
    -485
    -486
    -487
    -488
    -489
    -490
    -491
    -492
    -493
    -494
    -495
    -496
    -497
    -498
    -499
    -500
    -501
    -502
    -503
    -504
    -505
    -506
    -507
    -508
    -509
    -510
    -511
    -512
    -513
    -514
    -515
    -516
    -517
    -518
    -519
    -520
    -521
    -522
    -523
    -524
    -525
    -526
    -527
    -528
    -529
    -530
    -531
    -532
    -533
    -534
    -535
    -536
    -537
    -538
    -539
    -540
    -541
    -542
    -543
    -544
    -545
    -546
    -547
    -548
    -549
    -550
    -551
    -552
    -553
    -554
    -555
    -556
    -557
    -558
    -559
    -560
    -561
    -562
    -563
    -564
    -565
    -566
    -567
    -568
    -569
    -570
    -571
    -572
    -573
    -574
    -575
    -576
    -577
    -578
    -579
    -580
    -581
    -582
    -583
    -584
    -585
    -586
    -587
    -588
    -589
    -590
    -591
    -592
    -593
    -594
    -595
    -596
    -597
    -598
    -599
    -600
    -601
    -602
    -603
    -604
    -605
    -606
    -607
    -608
    -609
    -610
    -611
    -612
    -613
    -614
    -615
    -616
    -617
    -618
    -619
    -620
    -621
    -622
    -623
    -624
    -625
    -626
    -627
    -628
    -629
    -630
    -631
    -632
    -633
    -634
    -635
    -636
    -637
    -638
    -639
    -640
    -641
    -642
    -643
    -644
    -645
    -646
    -647
    -648
    -649
    -650
    -651
    -652
    -653
    -654
    -655
    -656
    -657
    -658
    -659
    -660
    -661
    -662
    -663
    -664
    -665
    -666
    -667
    -668
    -669
    -670
    -671
    -672
    -673
    -674
    -675
    -676
    -677
    -678
    -679
    -680
    -681
    -682
    -683
    -684
    -685
    -686
    -687
    -688
    -689
    -690
    -691
    -692
    -693
    -694
    -695
    -696
    -697
    -698
    -699
    -700
    -701
    -702
    -703
    -704
    -705
    -706
    -707
    -708
    -709
    -710
    -711
    -712
    -713
    -714
    -715
    -716
    -717
    -718
    -719
    -720
    -721
    -722
    -723
    -724
    -725
    -726
    -727
    -728
    -729
    -730
    -731
    -732
    -733
    -734
    -735
    -736
    -737
    -738
    -739
    -740
    -741
    -742
    -743
    -744
    -745
    -746
    -747
    -748
    -749
    -750
    -751
    -752
    -753
    -754
    -755
    -756
    -757
    -758
    -759
    -760
    -761
    -762
    -763
    -764
    -765
    -766
    -767
    -768
    -769
    -770
    -771
    -772
    -773
    -774
    -775
    -776
    -777
    -778
    -779
    -780
    -781
    -782
    -783
    -784
    -785
    -786
    -787
    -788
    -789
    -790
    -791
    -792
    -793
    -794
    -795
    -796
    -797
    -798
    -799
    -800
    -801
    -802
    -803
    -804
    -805
    -806
    -807
    -808
    -809
    -810
    -811
    -812
    -813
    -814
    -815
    -816
    -817
    -818
    -819
    -820
    -821
    -822
    -823
    -824
    -825
    -826
    -827
    -828
    -829
    -830
    -831
    -832
    -833
    -834
    -835
    -836
    -
    // Bitcoin Dev Kit
    -// Written in 2020 by Alekos Filini <alekos.filini@gmail.com>
    -//
    -// Copyright (c) 2020-2021 Bitcoin Dev Kit Developers
    -//
    -// This file is licensed under the Apache License, Version 2.0 <LICENSE-APACHE
    -// or http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
    -// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your option.
    -// You may not use this file except in accordance with one or both of these
    -// licenses.
    -
    -use std::convert::TryInto;
    -use std::fmt;
    -use std::io::{Read, Write};
    -use std::marker::PhantomData;
    -use std::sync::Arc;
    -use std::sync::RwLock;
    -
    -use rand::distributions::Alphanumeric;
    -use rand::{thread_rng, Rng};
    -
    -use rocksdb::{Direction, IteratorMode, ReadOptions, WriteBatch, DB};
    -
    -use bitcoin::blockdata::constants::genesis_block;
    -use bitcoin::consensus::{deserialize, encode::VarInt, serialize, Decodable, Encodable};
    -use bitcoin::hash_types::{FilterHash, FilterHeader};
    -use bitcoin::hashes::Hash;
    -use bitcoin::util::bip158::BlockFilter;
    -use bitcoin::util::uint::Uint256;
    -use bitcoin::Block;
    -use bitcoin::BlockHash;
    -use bitcoin::BlockHeader;
    -use bitcoin::Network;
    -
    -use super::CompactFiltersError;
    -
    -pub trait StoreType: Default + fmt::Debug {}
    -
    -#[derive(Default, Debug)]
    -pub struct Full;
    -impl StoreType for Full {}
    -#[derive(Default, Debug)]
    -pub struct Snapshot;
    -impl StoreType for Snapshot {}
    -
    -pub enum StoreEntry {
    -    BlockHeader(Option<usize>),
    -    Block(Option<usize>),
    -    BlockHeaderIndex(Option<BlockHash>),
    -    CFilterTable((u8, Option<usize>)),
    +store.rs - source
    1
    +2
    +3
    +4
    +5
    +6
    +7
    +8
    +9
    +10
    +11
    +12
    +13
    +14
    +15
    +16
    +17
    +18
    +19
    +20
    +21
    +22
    +23
    +24
    +25
    +26
    +27
    +28
    +29
    +30
    +31
    +32
    +33
    +34
    +35
    +36
    +37
    +38
    +39
    +40
    +41
    +42
    +43
    +44
    +45
    +46
    +47
    +48
    +49
    +50
    +51
    +52
    +53
    +54
    +55
    +56
    +57
    +58
    +59
    +60
    +61
    +62
    +63
    +64
    +65
    +66
    +67
    +68
    +69
    +70
    +71
    +72
    +73
    +74
    +75
    +76
    +77
    +78
    +79
    +80
    +81
    +82
    +83
    +84
    +85
    +86
    +87
    +88
    +89
    +90
    +91
    +92
    +93
    +94
    +95
    +96
    +97
    +98
    +99
    +100
    +101
    +102
    +103
    +104
    +105
    +106
    +107
    +108
    +109
    +110
    +111
    +112
    +113
    +114
    +115
    +116
    +117
    +118
    +119
    +120
    +121
    +122
    +123
    +124
    +125
    +126
    +127
    +128
    +129
    +130
    +131
    +132
    +133
    +134
    +135
    +136
    +137
    +138
    +139
    +140
    +141
    +142
    +143
    +144
    +145
    +146
    +147
    +148
    +149
    +150
    +151
    +152
    +153
    +154
    +155
    +156
    +157
    +158
    +159
    +160
    +161
    +162
    +163
    +164
    +165
    +166
    +167
    +168
    +169
    +170
    +171
    +172
    +173
    +174
    +175
    +176
    +177
    +178
    +179
    +180
    +181
    +182
    +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
    +245
    +246
    +247
    +248
    +249
    +250
    +251
    +252
    +253
    +254
    +255
    +256
    +257
    +258
    +259
    +260
    +261
    +262
    +263
    +264
    +265
    +266
    +267
    +268
    +269
    +270
    +271
    +272
    +273
    +274
    +275
    +276
    +277
    +278
    +279
    +280
    +281
    +282
    +283
    +284
    +285
    +286
    +287
    +288
    +289
    +290
    +291
    +292
    +293
    +294
    +295
    +296
    +297
    +298
    +299
    +300
    +301
    +302
    +303
    +304
    +305
    +306
    +307
    +308
    +309
    +310
    +311
    +312
    +313
    +314
    +315
    +316
    +317
    +318
    +319
    +320
    +321
    +322
    +323
    +324
    +325
    +326
    +327
    +328
    +329
    +330
    +331
    +332
    +333
    +334
    +335
    +336
    +337
    +338
    +339
    +340
    +341
    +342
    +343
    +344
    +345
    +346
    +347
    +348
    +349
    +350
    +351
    +352
    +353
    +354
    +355
    +356
    +357
    +358
    +359
    +360
    +361
    +362
    +363
    +364
    +365
    +366
    +367
    +368
    +369
    +370
    +371
    +372
    +373
    +374
    +375
    +376
    +377
    +378
    +379
    +380
    +381
    +382
    +383
    +384
    +385
    +386
    +387
    +388
    +389
    +390
    +391
    +392
    +393
    +394
    +395
    +396
    +397
    +398
    +399
    +400
    +401
    +402
    +403
    +404
    +405
    +406
    +407
    +408
    +409
    +410
    +411
    +412
    +413
    +414
    +415
    +416
    +417
    +418
    +419
    +420
    +421
    +422
    +423
    +424
    +425
    +426
    +427
    +428
    +429
    +430
    +431
    +432
    +433
    +434
    +435
    +436
    +437
    +438
    +439
    +440
    +441
    +442
    +443
    +444
    +445
    +446
    +447
    +448
    +449
    +450
    +451
    +452
    +453
    +454
    +455
    +456
    +457
    +458
    +459
    +460
    +461
    +462
    +463
    +464
    +465
    +466
    +467
    +468
    +469
    +470
    +471
    +472
    +473
    +474
    +475
    +476
    +477
    +478
    +479
    +480
    +481
    +482
    +483
    +484
    +485
    +486
    +487
    +488
    +489
    +490
    +491
    +492
    +493
    +494
    +495
    +496
    +497
    +498
    +499
    +500
    +501
    +502
    +503
    +504
    +505
    +506
    +507
    +508
    +509
    +510
    +511
    +512
    +513
    +514
    +515
    +516
    +517
    +518
    +519
    +520
    +521
    +522
    +523
    +524
    +525
    +526
    +527
    +528
    +529
    +530
    +531
    +532
    +533
    +534
    +535
    +536
    +537
    +538
    +539
    +540
    +541
    +542
    +543
    +544
    +545
    +546
    +547
    +548
    +549
    +550
    +551
    +552
    +553
    +554
    +555
    +556
    +557
    +558
    +559
    +560
    +561
    +562
    +563
    +564
    +565
    +566
    +567
    +568
    +569
    +570
    +571
    +572
    +573
    +574
    +575
    +576
    +577
    +578
    +579
    +580
    +581
    +582
    +583
    +584
    +585
    +586
    +587
    +588
    +589
    +590
    +591
    +592
    +593
    +594
    +595
    +596
    +597
    +598
    +599
    +600
    +601
    +602
    +603
    +604
    +605
    +606
    +607
    +608
    +609
    +610
    +611
    +612
    +613
    +614
    +615
    +616
    +617
    +618
    +619
    +620
    +621
    +622
    +623
    +624
    +625
    +626
    +627
    +628
    +629
    +630
    +631
    +632
    +633
    +634
    +635
    +636
    +637
    +638
    +639
    +640
    +641
    +642
    +643
    +644
    +645
    +646
    +647
    +648
    +649
    +650
    +651
    +652
    +653
    +654
    +655
    +656
    +657
    +658
    +659
    +660
    +661
    +662
    +663
    +664
    +665
    +666
    +667
    +668
    +669
    +670
    +671
    +672
    +673
    +674
    +675
    +676
    +677
    +678
    +679
    +680
    +681
    +682
    +683
    +684
    +685
    +686
    +687
    +688
    +689
    +690
    +691
    +692
    +693
    +694
    +695
    +696
    +697
    +698
    +699
    +700
    +701
    +702
    +703
    +704
    +705
    +706
    +707
    +708
    +709
    +710
    +711
    +712
    +713
    +714
    +715
    +716
    +717
    +718
    +719
    +720
    +721
    +722
    +723
    +724
    +725
    +726
    +727
    +728
    +729
    +730
    +731
    +732
    +733
    +734
    +735
    +736
    +737
    +738
    +739
    +740
    +741
    +742
    +743
    +744
    +745
    +746
    +747
    +748
    +749
    +750
    +751
    +752
    +753
    +754
    +755
    +756
    +757
    +758
    +759
    +760
    +761
    +762
    +763
    +764
    +765
    +766
    +767
    +768
    +769
    +770
    +771
    +772
    +773
    +774
    +775
    +776
    +777
    +778
    +779
    +780
    +781
    +782
    +783
    +784
    +785
    +786
    +787
    +788
    +789
    +790
    +791
    +792
    +793
    +794
    +795
    +796
    +797
    +798
    +799
    +800
    +801
    +802
    +803
    +804
    +805
    +806
    +807
    +808
    +809
    +810
    +811
    +812
    +813
    +814
    +815
    +816
    +817
    +818
    +819
    +820
    +821
    +822
    +823
    +824
    +825
    +826
    +827
    +828
    +829
    +830
    +831
    +832
    +833
    +834
    +835
    +836
    +
    // Bitcoin Dev Kit
    +// Written in 2020 by Alekos Filini <alekos.filini@gmail.com>
    +//
    +// Copyright (c) 2020-2021 Bitcoin Dev Kit Developers
    +//
    +// This file is licensed under the Apache License, Version 2.0 <LICENSE-APACHE
    +// or http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
    +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your option.
    +// You may not use this file except in accordance with one or both of these
    +// licenses.
    +
    +use std::convert::TryInto;
    +use std::fmt;
    +use std::io::{Read, Write};
    +use std::marker::PhantomData;
    +use std::sync::Arc;
    +use std::sync::RwLock;
    +
    +use rand::distributions::Alphanumeric;
    +use rand::{thread_rng, Rng};
    +
    +use rocksdb::{Direction, IteratorMode, ReadOptions, WriteBatch, DB};
    +
    +use bitcoin::blockdata::constants::genesis_block;
    +use bitcoin::consensus::{deserialize, encode::VarInt, serialize, Decodable, Encodable};
    +use bitcoin::hash_types::{FilterHash, FilterHeader};
    +use bitcoin::hashes::Hash;
    +use bitcoin::util::bip158::BlockFilter;
    +use bitcoin::util::uint::Uint256;
    +use bitcoin::Block;
    +use bitcoin::BlockHash;
    +use bitcoin::BlockHeader;
    +use bitcoin::Network;
    +
    +use super::CompactFiltersError;
    +
    +pub trait StoreType: Default + fmt::Debug {}
    +
    +#[derive(Default, Debug)]
    +pub struct Full;
    +impl StoreType for Full {}
    +#[derive(Default, Debug)]
    +pub struct Snapshot;
    +impl StoreType for Snapshot {}
    +
    +pub enum StoreEntry {
    +    BlockHeader(Option<usize>),
    +    Block(Option<usize>),
    +    BlockHeaderIndex(Option<BlockHash>),
    +    CFilterTable((u8, Option<usize>)),
     }
     
    -impl StoreEntry {
    -    pub fn get_prefix(&self) -> Vec<u8> {
    -        match self {
    -            StoreEntry::BlockHeader(_) => b"z",
    -            StoreEntry::Block(_) => b"x",
    -            StoreEntry::BlockHeaderIndex(_) => b"i",
    -            StoreEntry::CFilterTable(_) => b"t",
    +impl StoreEntry {
    +    pub fn get_prefix(&self) -> Vec<u8> {
    +        match self {
    +            StoreEntry::BlockHeader(_) => b"z",
    +            StoreEntry::Block(_) => b"x",
    +            StoreEntry::BlockHeaderIndex(_) => b"i",
    +            StoreEntry::CFilterTable(_) => b"t",
             }
    -        .to_vec()
    +        .to_vec()
         }
     
    -    pub fn get_key(&self) -> Vec<u8> {
    -        let mut prefix = self.get_prefix();
    -        match self {
    -            StoreEntry::BlockHeader(Some(height)) => {
    -                prefix.extend_from_slice(&height.to_be_bytes())
    +    pub fn get_key(&self) -> Vec<u8> {
    +        let mut prefix = self.get_prefix();
    +        match self {
    +            StoreEntry::BlockHeader(Some(height)) => {
    +                prefix.extend_from_slice(&height.to_be_bytes())
                 }
    -            StoreEntry::Block(Some(height)) => prefix.extend_from_slice(&height.to_be_bytes()),
    -            StoreEntry::BlockHeaderIndex(Some(hash)) => {
    -                prefix.extend_from_slice(&hash.into_inner())
    +            StoreEntry::Block(Some(height)) => prefix.extend_from_slice(&height.to_be_bytes()),
    +            StoreEntry::BlockHeaderIndex(Some(hash)) => {
    +                prefix.extend_from_slice(&hash.into_inner())
                 }
    -            StoreEntry::CFilterTable((filter_type, bundle_index)) => {
    -                prefix.push(*filter_type);
    -                if let Some(bundle_index) = bundle_index {
    -                    prefix.extend_from_slice(&bundle_index.to_be_bytes());
    +            StoreEntry::CFilterTable((filter_type, bundle_index)) => {
    +                prefix.push(*filter_type);
    +                if let Some(bundle_index) = bundle_index {
    +                    prefix.extend_from_slice(&bundle_index.to_be_bytes());
                     }
                 }
    -            _ => {}
    +            _ => {}
             }
     
    -        prefix
    +        prefix
         }
     }
     
    -pub trait SerializeDb: Sized {
    -    fn serialize(&self) -> Vec<u8>;
    -    fn deserialize(data: &[u8]) -> Result<Self, CompactFiltersError>;
    +pub trait SerializeDb: Sized {
    +    fn serialize(&self) -> Vec<u8>;
    +    fn deserialize(data: &[u8]) -> Result<Self, CompactFiltersError>;
     }
     
    -impl<T> SerializeDb for T
    -where
    -    T: Encodable + Decodable,
    +impl<T> SerializeDb for T
    +where
    +    T: Encodable + Decodable,
     {
    -    fn serialize(&self) -> Vec<u8> {
    -        serialize(self)
    +    fn serialize(&self) -> Vec<u8> {
    +        serialize(self)
         }
     
    -    fn deserialize(data: &[u8]) -> Result<Self, CompactFiltersError> {
    -        deserialize(data).map_err(|_| CompactFiltersError::DataCorruption)
    +    fn deserialize(data: &[u8]) -> Result<Self, CompactFiltersError> {
    +        deserialize(data).map_err(|_| CompactFiltersError::DataCorruption)
         }
     }
     
    -impl Encodable for BundleStatus {
    -    fn consensus_encode<W: Write + ?Sized>(&self, e: &mut W) -> Result<usize, std::io::Error> {
    -        let mut written = 0;
    +impl Encodable for BundleStatus {
    +    fn consensus_encode<W: Write + ?Sized>(&self, e: &mut W) -> Result<usize, std::io::Error> {
    +        let mut written = 0;
     
    -        match self {
    -            BundleStatus::Init => {
    -                written += 0x00u8.consensus_encode(e)?;
    +        match self {
    +            BundleStatus::Init => {
    +                written += 0x00u8.consensus_encode(e)?;
                 }
    -            BundleStatus::CfHeaders { cf_headers } => {
    -                written += 0x01u8.consensus_encode(e)?;
    -                written += VarInt(cf_headers.len() as u64).consensus_encode(e)?;
    -                for header in cf_headers {
    -                    written += header.consensus_encode(e)?;
    +            BundleStatus::CfHeaders { cf_headers } => {
    +                written += 0x01u8.consensus_encode(e)?;
    +                written += VarInt(cf_headers.len() as u64).consensus_encode(e)?;
    +                for header in cf_headers {
    +                    written += header.consensus_encode(e)?;
                     }
                 }
    -            BundleStatus::CFilters { cf_filters } => {
    -                written += 0x02u8.consensus_encode(e)?;
    -                written += VarInt(cf_filters.len() as u64).consensus_encode(e)?;
    -                for filter in cf_filters {
    -                    written += filter.consensus_encode(e)?;
    +            BundleStatus::CFilters { cf_filters } => {
    +                written += 0x02u8.consensus_encode(e)?;
    +                written += VarInt(cf_filters.len() as u64).consensus_encode(e)?;
    +                for filter in cf_filters {
    +                    written += filter.consensus_encode(e)?;
                     }
                 }
    -            BundleStatus::Processed { cf_filters } => {
    -                written += 0x03u8.consensus_encode(e)?;
    -                written += VarInt(cf_filters.len() as u64).consensus_encode(e)?;
    -                for filter in cf_filters {
    -                    written += filter.consensus_encode(e)?;
    +            BundleStatus::Processed { cf_filters } => {
    +                written += 0x03u8.consensus_encode(e)?;
    +                written += VarInt(cf_filters.len() as u64).consensus_encode(e)?;
    +                for filter in cf_filters {
    +                    written += filter.consensus_encode(e)?;
                     }
                 }
    -            BundleStatus::Pruned => {
    -                written += 0x04u8.consensus_encode(e)?;
    +            BundleStatus::Pruned => {
    +                written += 0x04u8.consensus_encode(e)?;
                 }
    -            BundleStatus::Tip { cf_filters } => {
    -                written += 0x05u8.consensus_encode(e)?;
    -                written += VarInt(cf_filters.len() as u64).consensus_encode(e)?;
    -                for filter in cf_filters {
    -                    written += filter.consensus_encode(e)?;
    +            BundleStatus::Tip { cf_filters } => {
    +                written += 0x05u8.consensus_encode(e)?;
    +                written += VarInt(cf_filters.len() as u64).consensus_encode(e)?;
    +                for filter in cf_filters {
    +                    written += filter.consensus_encode(e)?;
                     }
                 }
             }
     
    -        Ok(written)
    +        Ok(written)
         }
     }
     
    -impl Decodable for BundleStatus {
    -    fn consensus_decode<D: Read + ?Sized>(
    -        d: &mut D,
    -    ) -> Result<Self, bitcoin::consensus::encode::Error> {
    -        let byte_type = u8::consensus_decode(d)?;
    -        match byte_type {
    -            0x00 => Ok(BundleStatus::Init),
    -            0x01 => {
    -                let num = VarInt::consensus_decode(d)?;
    -                let num = num.0 as usize;
    -
    -                let mut cf_headers = Vec::with_capacity(num);
    -                for _ in 0..num {
    -                    cf_headers.push(FilterHeader::consensus_decode(d)?);
    +impl Decodable for BundleStatus {
    +    fn consensus_decode<D: Read + ?Sized>(
    +        d: &mut D,
    +    ) -> Result<Self, bitcoin::consensus::encode::Error> {
    +        let byte_type = u8::consensus_decode(d)?;
    +        match byte_type {
    +            0x00 => Ok(BundleStatus::Init),
    +            0x01 => {
    +                let num = VarInt::consensus_decode(d)?;
    +                let num = num.0 as usize;
    +
    +                let mut cf_headers = Vec::with_capacity(num);
    +                for _ in 0..num {
    +                    cf_headers.push(FilterHeader::consensus_decode(d)?);
                     }
     
    -                Ok(BundleStatus::CfHeaders { cf_headers })
    +                Ok(BundleStatus::CfHeaders { cf_headers })
                 }
    -            0x02 => {
    -                let num = VarInt::consensus_decode(d)?;
    -                let num = num.0 as usize;
    +            0x02 => {
    +                let num = VarInt::consensus_decode(d)?;
    +                let num = num.0 as usize;
     
    -                let mut cf_filters = Vec::with_capacity(num);
    -                for _ in 0..num {
    -                    cf_filters.push(Vec::<u8>::consensus_decode(d)?);
    +                let mut cf_filters = Vec::with_capacity(num);
    +                for _ in 0..num {
    +                    cf_filters.push(Vec::<u8>::consensus_decode(d)?);
                     }
     
    -                Ok(BundleStatus::CFilters { cf_filters })
    +                Ok(BundleStatus::CFilters { cf_filters })
                 }
    -            0x03 => {
    -                let num = VarInt::consensus_decode(d)?;
    -                let num = num.0 as usize;
    +            0x03 => {
    +                let num = VarInt::consensus_decode(d)?;
    +                let num = num.0 as usize;
     
    -                let mut cf_filters = Vec::with_capacity(num);
    -                for _ in 0..num {
    -                    cf_filters.push(Vec::<u8>::consensus_decode(d)?);
    +                let mut cf_filters = Vec::with_capacity(num);
    +                for _ in 0..num {
    +                    cf_filters.push(Vec::<u8>::consensus_decode(d)?);
                     }
     
    -                Ok(BundleStatus::Processed { cf_filters })
    +                Ok(BundleStatus::Processed { cf_filters })
                 }
    -            0x04 => Ok(BundleStatus::Pruned),
    -            0x05 => {
    -                let num = VarInt::consensus_decode(d)?;
    -                let num = num.0 as usize;
    -
    -                let mut cf_filters = Vec::with_capacity(num);
    -                for _ in 0..num {
    -                    cf_filters.push(Vec::<u8>::consensus_decode(d)?);
    +            0x04 => Ok(BundleStatus::Pruned),
    +            0x05 => {
    +                let num = VarInt::consensus_decode(d)?;
    +                let num = num.0 as usize;
    +
    +                let mut cf_filters = Vec::with_capacity(num);
    +                for _ in 0..num {
    +                    cf_filters.push(Vec::<u8>::consensus_decode(d)?);
                     }
     
    -                Ok(BundleStatus::Tip { cf_filters })
    +                Ok(BundleStatus::Tip { cf_filters })
                 }
    -            _ => Err(bitcoin::consensus::encode::Error::ParseFailed(
    +            _ => Err(bitcoin::consensus::encode::Error::ParseFailed(
                     "Invalid byte type",
                 )),
             }
         }
     }
     
    -pub struct ChainStore<T: StoreType> {
    -    store: Arc<RwLock<DB>>,
    -    cf_name: String,
    -    min_height: usize,
    -    network: Network,
    -    phantom: PhantomData<T>,
    +pub struct ChainStore<T: StoreType> {
    +    store: Arc<RwLock<DB>>,
    +    cf_name: String,
    +    min_height: usize,
    +    network: Network,
    +    phantom: PhantomData<T>,
     }
     
    -impl ChainStore<Full> {
    -    pub fn new(store: DB, network: Network) -> Result<Self, CompactFiltersError> {
    -        let genesis = genesis_block(network);
    +impl ChainStore<Full> {
    +    pub fn new(store: DB, network: Network) -> Result<Self, CompactFiltersError> {
    +        let genesis = genesis_block(network);
     
    -        let cf_name = "default".to_string();
    -        let cf_handle = store.cf_handle(&cf_name).unwrap();
    +        let cf_name = "default".to_string();
    +        let cf_handle = store.cf_handle(&cf_name).unwrap();
     
    -        let genesis_key = StoreEntry::BlockHeader(Some(0)).get_key();
    +        let genesis_key = StoreEntry::BlockHeader(Some(0)).get_key();
     
    -        if store.get_pinned_cf(cf_handle, &genesis_key)?.is_none() {
    -            let mut batch = WriteBatch::default();
    -            batch.put_cf(
    -                cf_handle,
    -                genesis_key,
    -                (genesis.header, genesis.header.work()).serialize(),
    +        if store.get_pinned_cf(cf_handle, &genesis_key)?.is_none() {
    +            let mut batch = WriteBatch::default();
    +            batch.put_cf(
    +                cf_handle,
    +                genesis_key,
    +                (genesis.header, genesis.header.work()).serialize(),
                 );
    -            batch.put_cf(
    -                cf_handle,
    -                StoreEntry::BlockHeaderIndex(Some(genesis.block_hash())).get_key(),
    -                &0usize.to_be_bytes(),
    +            batch.put_cf(
    +                cf_handle,
    +                StoreEntry::BlockHeaderIndex(Some(genesis.block_hash())).get_key(),
    +                &0usize.to_be_bytes(),
                 );
    -            store.write(batch)?;
    +            store.write(batch)?;
             }
     
    -        Ok(ChainStore {
    -            store: Arc::new(RwLock::new(store)),
    -            cf_name,
    -            min_height: 0,
    -            network,
    -            phantom: PhantomData,
    +        Ok(ChainStore {
    +            store: Arc::new(RwLock::new(store)),
    +            cf_name,
    +            min_height: 0,
    +            network,
    +            phantom: PhantomData,
             })
         }
     
    -    pub fn get_locators(&self) -> Result<Vec<(BlockHash, usize)>, CompactFiltersError> {
    -        let mut step = 1;
    -        let mut index = self.get_height()?;
    -        let mut answer = Vec::new();
    +    pub fn get_locators(&self) -> Result<Vec<(BlockHash, usize)>, CompactFiltersError> {
    +        let mut step = 1;
    +        let mut index = self.get_height()?;
    +        let mut answer = Vec::new();
     
    -        let store_read = self.store.read().unwrap();
    -        let cf_handle = store_read.cf_handle(&self.cf_name).unwrap();
    +        let store_read = self.store.read().unwrap();
    +        let cf_handle = store_read.cf_handle(&self.cf_name).unwrap();
     
    -        loop {
    -            if answer.len() > 10 {
    -                step *= 2;
    +        loop {
    +            if answer.len() > 10 {
    +                step *= 2;
                 }
     
    -            let (header, _): (BlockHeader, Uint256) = SerializeDb::deserialize(
    -                &store_read
    -                    .get_pinned_cf(cf_handle, StoreEntry::BlockHeader(Some(index)).get_key())?
    -                    .unwrap(),
    +            let (header, _): (BlockHeader, Uint256) = SerializeDb::deserialize(
    +                &store_read
    +                    .get_pinned_cf(cf_handle, StoreEntry::BlockHeader(Some(index)).get_key())?
    +                    .unwrap(),
                 )?;
    -            answer.push((header.block_hash(), index));
    +            answer.push((header.block_hash(), index));
     
    -            if let Some(new_index) = index.checked_sub(step) {
    -                index = new_index;
    -            } else {
    +            if let Some(new_index) = index.checked_sub(step) {
    +                index = new_index;
    +            } else {
                     break;
                 }
             }
     
    -        Ok(answer)
    +        Ok(answer)
         }
     
    -    pub fn start_snapshot(&self, from: usize) -> Result<ChainStore<Snapshot>, CompactFiltersError> {
    -        let new_cf_name: String = thread_rng()
    -            .sample_iter(&Alphanumeric)
    -            .map(|byte| byte as char)
    -            .take(16)
    -            .collect();
    -        let new_cf_name = format!("_headers:{}", new_cf_name);
    +    pub fn start_snapshot(&self, from: usize) -> Result<ChainStore<Snapshot>, CompactFiltersError> {
    +        let new_cf_name: String = thread_rng()
    +            .sample_iter(&Alphanumeric)
    +            .map(|byte| byte as char)
    +            .take(16)
    +            .collect();
    +        let new_cf_name = format!("_headers:{}", new_cf_name);
     
    -        let mut write_store = self.store.write().unwrap();
    +        let mut write_store = self.store.write().unwrap();
     
    -        write_store.create_cf(&new_cf_name, &Default::default())?;
    +        write_store.create_cf(&new_cf_name, &Default::default())?;
     
    -        let cf_handle = write_store.cf_handle(&self.cf_name).unwrap();
    -        let new_cf_handle = write_store.cf_handle(&new_cf_name).unwrap();
    +        let cf_handle = write_store.cf_handle(&self.cf_name).unwrap();
    +        let new_cf_handle = write_store.cf_handle(&new_cf_name).unwrap();
     
    -        let (header, work): (BlockHeader, Uint256) = SerializeDb::deserialize(
    -            &write_store
    -                .get_pinned_cf(cf_handle, StoreEntry::BlockHeader(Some(from)).get_key())?
    -                .ok_or(CompactFiltersError::DataCorruption)?,
    +        let (header, work): (BlockHeader, Uint256) = SerializeDb::deserialize(
    +            &write_store
    +                .get_pinned_cf(cf_handle, StoreEntry::BlockHeader(Some(from)).get_key())?
    +                .ok_or(CompactFiltersError::DataCorruption)?,
             )?;
     
    -        let mut batch = WriteBatch::default();
    -        batch.put_cf(
    -            new_cf_handle,
    -            StoreEntry::BlockHeaderIndex(Some(header.block_hash())).get_key(),
    -            &from.to_be_bytes(),
    +        let mut batch = WriteBatch::default();
    +        batch.put_cf(
    +            new_cf_handle,
    +            StoreEntry::BlockHeaderIndex(Some(header.block_hash())).get_key(),
    +            &from.to_be_bytes(),
             );
    -        batch.put_cf(
    -            new_cf_handle,
    -            StoreEntry::BlockHeader(Some(from)).get_key(),
    -            (header, work).serialize(),
    +        batch.put_cf(
    +            new_cf_handle,
    +            StoreEntry::BlockHeader(Some(from)).get_key(),
    +            (header, work).serialize(),
             );
    -        write_store.write(batch)?;
    -
    -        let store = Arc::clone(&self.store);
    -        Ok(ChainStore {
    -            store,
    -            cf_name: new_cf_name,
    -            min_height: from,
    -            network: self.network,
    -            phantom: PhantomData,
    +        write_store.write(batch)?;
    +
    +        let store = Arc::clone(&self.store);
    +        Ok(ChainStore {
    +            store,
    +            cf_name: new_cf_name,
    +            min_height: from,
    +            network: self.network,
    +            phantom: PhantomData,
             })
         }
     
    -    pub fn recover_snapshot(&self, cf_name: &str) -> Result<(), CompactFiltersError> {
    -        let mut write_store = self.store.write().unwrap();
    -        let snapshot_cf_handle = write_store.cf_handle(cf_name).unwrap();
    +    pub fn recover_snapshot(&self, cf_name: &str) -> Result<(), CompactFiltersError> {
    +        let mut write_store = self.store.write().unwrap();
    +        let snapshot_cf_handle = write_store.cf_handle(cf_name).unwrap();
     
    -        let prefix = StoreEntry::BlockHeader(None).get_key();
    -        let mut iterator = write_store.prefix_iterator_cf(snapshot_cf_handle, prefix);
    +        let prefix = StoreEntry::BlockHeader(None).get_key();
    +        let mut iterator = write_store.prefix_iterator_cf(snapshot_cf_handle, prefix);
     
    -        let min_height = match iterator
    -            .next()
    -            .and_then(|(k, _)| k[1..].try_into().ok())
    -            .map(usize::from_be_bytes)
    +        let min_height = match iterator
    +            .next()
    +            .and_then(|(k, _)| k[1..].try_into().ok())
    +            .map(usize::from_be_bytes)
             {
    -            None => {
    -                std::mem::drop(iterator);
    -                write_store.drop_cf(cf_name).ok();
    +            None => {
    +                std::mem::drop(iterator);
    +                write_store.drop_cf(cf_name).ok();
     
    -                return Ok(());
    +                return Ok(());
                 }
    -            Some(x) => x,
    +            Some(x) => x,
             };
    -        std::mem::drop(iterator);
    -        std::mem::drop(write_store);
    -
    -        let snapshot = ChainStore {
    -            store: Arc::clone(&self.store),
    -            cf_name: cf_name.into(),
    -            min_height,
    -            network: self.network,
    -            phantom: PhantomData,
    +        std::mem::drop(iterator);
    +        std::mem::drop(write_store);
    +
    +        let snapshot = ChainStore {
    +            store: Arc::clone(&self.store),
    +            cf_name: cf_name.into(),
    +            min_height,
    +            network: self.network,
    +            phantom: PhantomData,
             };
    -        if snapshot.work()? > self.work()? {
    -            self.apply_snapshot(snapshot)?;
    +        if snapshot.work()? > self.work()? {
    +            self.apply_snapshot(snapshot)?;
             }
     
             Ok(())
         }
     
    -    pub fn apply_snapshot(
    +    pub fn apply_snapshot(
             &self,
    -        snaphost: ChainStore<Snapshot>,
    -    ) -> Result<(), CompactFiltersError> {
    -        let mut batch = WriteBatch::default();
    +        snaphost: ChainStore<Snapshot>,
    +    ) -> Result<(), CompactFiltersError> {
    +        let mut batch = WriteBatch::default();
     
    -        let read_store = self.store.read().unwrap();
    -        let cf_handle = read_store.cf_handle(&self.cf_name).unwrap();
    -        let snapshot_cf_handle = read_store.cf_handle(&snaphost.cf_name).unwrap();
    +        let read_store = self.store.read().unwrap();
    +        let cf_handle = read_store.cf_handle(&self.cf_name).unwrap();
    +        let snapshot_cf_handle = read_store.cf_handle(&snaphost.cf_name).unwrap();
     
    -        let from_key = StoreEntry::BlockHeader(Some(snaphost.min_height)).get_key();
    -        let to_key = StoreEntry::BlockHeader(Some(usize::MAX)).get_key();
    +        let from_key = StoreEntry::BlockHeader(Some(snaphost.min_height)).get_key();
    +        let to_key = StoreEntry::BlockHeader(Some(usize::MAX)).get_key();
     
    -        let mut opts = ReadOptions::default();
    -        opts.set_iterate_upper_bound(to_key.clone());
    +        let mut opts = ReadOptions::default();
    +        opts.set_iterate_upper_bound(to_key.clone());
     
             log::debug!("Removing items");
    -        batch.delete_range_cf(cf_handle, &from_key, &to_key);
    -        for (_, v) in read_store.iterator_cf_opt(
    -            cf_handle,
    -            opts,
    -            IteratorMode::From(&from_key, Direction::Forward),
    +        batch.delete_range_cf(cf_handle, &from_key, &to_key);
    +        for (_, v) in read_store.iterator_cf_opt(
    +            cf_handle,
    +            opts,
    +            IteratorMode::From(&from_key, Direction::Forward),
             ) {
    -            let (header, _): (BlockHeader, Uint256) = SerializeDb::deserialize(&v)?;
    +            let (header, _): (BlockHeader, Uint256) = SerializeDb::deserialize(&v)?;
     
    -            batch.delete_cf(
    -                cf_handle,
    -                StoreEntry::BlockHeaderIndex(Some(header.block_hash())).get_key(),
    +            batch.delete_cf(
    +                cf_handle,
    +                StoreEntry::BlockHeaderIndex(Some(header.block_hash())).get_key(),
                 );
             }
     
    -        // Delete full blocks overridden by snapshot
    -        let from_key = StoreEntry::Block(Some(snaphost.min_height)).get_key();
    -        let to_key = StoreEntry::Block(Some(usize::MAX)).get_key();
    -        batch.delete_range(&from_key, &to_key);
    +        // Delete full blocks overridden by snapshot
    +        let from_key = StoreEntry::Block(Some(snaphost.min_height)).get_key();
    +        let to_key = StoreEntry::Block(Some(usize::MAX)).get_key();
    +        batch.delete_range(&from_key, &to_key);
     
             log::debug!("Copying over new items");
    -        for (k, v) in read_store.iterator_cf(snapshot_cf_handle, IteratorMode::Start) {
    -            batch.put_cf(cf_handle, k, v);
    +        for (k, v) in read_store.iterator_cf(snapshot_cf_handle, IteratorMode::Start) {
    +            batch.put_cf(cf_handle, k, v);
             }
     
    -        read_store.write(batch)?;
    -        std::mem::drop(read_store);
    +        read_store.write(batch)?;
    +        std::mem::drop(read_store);
     
    -        self.store.write().unwrap().drop_cf(&snaphost.cf_name)?;
    +        self.store.write().unwrap().drop_cf(&snaphost.cf_name)?;
     
             Ok(())
         }
     
    -    pub fn get_height_for(
    +    pub fn get_height_for(
             &self,
    -        block_hash: &BlockHash,
    -    ) -> Result<Option<usize>, CompactFiltersError> {
    -        let read_store = self.store.read().unwrap();
    -        let cf_handle = read_store.cf_handle(&self.cf_name).unwrap();
    -
    -        let key = StoreEntry::BlockHeaderIndex(Some(*block_hash)).get_key();
    -        let data = read_store.get_pinned_cf(cf_handle, key)?;
    -        data.map(|data| {
    -            Ok::<_, CompactFiltersError>(usize::from_be_bytes(
    -                data.as_ref()
    -                    .try_into()
    -                    .map_err(|_| CompactFiltersError::DataCorruption)?,
    +        block_hash: &BlockHash,
    +    ) -> Result<Option<usize>, CompactFiltersError> {
    +        let read_store = self.store.read().unwrap();
    +        let cf_handle = read_store.cf_handle(&self.cf_name).unwrap();
    +
    +        let key = StoreEntry::BlockHeaderIndex(Some(*block_hash)).get_key();
    +        let data = read_store.get_pinned_cf(cf_handle, key)?;
    +        data.map(|data| {
    +            Ok::<_, CompactFiltersError>(usize::from_be_bytes(
    +                data.as_ref()
    +                    .try_into()
    +                    .map_err(|_| CompactFiltersError::DataCorruption)?,
                 ))
             })
    -        .transpose()
    +        .transpose()
         }
     
    -    pub fn get_block_hash(&self, height: usize) -> Result<Option<BlockHash>, CompactFiltersError> {
    -        let read_store = self.store.read().unwrap();
    -        let cf_handle = read_store.cf_handle(&self.cf_name).unwrap();
    +    pub fn get_block_hash(&self, height: usize) -> Result<Option<BlockHash>, CompactFiltersError> {
    +        let read_store = self.store.read().unwrap();
    +        let cf_handle = read_store.cf_handle(&self.cf_name).unwrap();
     
    -        let key = StoreEntry::BlockHeader(Some(height)).get_key();
    -        let data = read_store.get_pinned_cf(cf_handle, key)?;
    -        data.map(|data| {
    -            let (header, _): (BlockHeader, Uint256) =
    -                deserialize(&data).map_err(|_| CompactFiltersError::DataCorruption)?;
    -            Ok::<_, CompactFiltersError>(header.block_hash())
    +        let key = StoreEntry::BlockHeader(Some(height)).get_key();
    +        let data = read_store.get_pinned_cf(cf_handle, key)?;
    +        data.map(|data| {
    +            let (header, _): (BlockHeader, Uint256) =
    +                deserialize(&data).map_err(|_| CompactFiltersError::DataCorruption)?;
    +            Ok::<_, CompactFiltersError>(header.block_hash())
             })
    -        .transpose()
    +        .transpose()
         }
     
    -    pub fn save_full_block(&self, block: &Block, height: usize) -> Result<(), CompactFiltersError> {
    -        let key = StoreEntry::Block(Some(height)).get_key();
    -        self.store.read().unwrap().put(key, block.serialize())?;
    +    pub fn save_full_block(&self, block: &Block, height: usize) -> Result<(), CompactFiltersError> {
    +        let key = StoreEntry::Block(Some(height)).get_key();
    +        self.store.read().unwrap().put(key, block.serialize())?;
     
             Ok(())
         }
     
    -    pub fn get_full_block(&self, height: usize) -> Result<Option<Block>, CompactFiltersError> {
    -        let read_store = self.store.read().unwrap();
    +    pub fn get_full_block(&self, height: usize) -> Result<Option<Block>, CompactFiltersError> {
    +        let read_store = self.store.read().unwrap();
     
    -        let key = StoreEntry::Block(Some(height)).get_key();
    -        let opt_block = read_store.get_pinned(key)?;
    +        let key = StoreEntry::Block(Some(height)).get_key();
    +        let opt_block = read_store.get_pinned(key)?;
     
    -        opt_block
    -            .map(|data| deserialize(&data))
    -            .transpose()
    -            .map_err(|_| CompactFiltersError::DataCorruption)
    +        opt_block
    +            .map(|data| deserialize(&data))
    +            .transpose()
    +            .map_err(|_| CompactFiltersError::DataCorruption)
         }
     
    -    pub fn delete_blocks_until(&self, height: usize) -> Result<(), CompactFiltersError> {
    -        let from_key = StoreEntry::Block(Some(0)).get_key();
    -        let to_key = StoreEntry::Block(Some(height)).get_key();
    +    pub fn delete_blocks_until(&self, height: usize) -> Result<(), CompactFiltersError> {
    +        let from_key = StoreEntry::Block(Some(0)).get_key();
    +        let to_key = StoreEntry::Block(Some(height)).get_key();
     
    -        let mut batch = WriteBatch::default();
    -        batch.delete_range(&from_key, &to_key);
    +        let mut batch = WriteBatch::default();
    +        batch.delete_range(&from_key, &to_key);
     
    -        self.store.read().unwrap().write(batch)?;
    +        self.store.read().unwrap().write(batch)?;
     
             Ok(())
         }
     
    -    pub fn iter_full_blocks(&self) -> Result<Vec<(usize, Block)>, CompactFiltersError> {
    -        let read_store = self.store.read().unwrap();
    -
    -        let prefix = StoreEntry::Block(None).get_key();
    -
    -        let iterator = read_store.prefix_iterator(&prefix);
    -        // FIXME: we have to filter manually because rocksdb sometimes returns stuff that doesn't
    -        // have the right prefix
    -        iterator
    -            .filter(|(k, _)| k.starts_with(&prefix))
    -            .map(|(k, v)| {
    -                let height: usize = usize::from_be_bytes(
    -                    k[1..]
    -                        .try_into()
    -                        .map_err(|_| CompactFiltersError::DataCorruption)?,
    +    pub fn iter_full_blocks(&self) -> Result<Vec<(usize, Block)>, CompactFiltersError> {
    +        let read_store = self.store.read().unwrap();
    +
    +        let prefix = StoreEntry::Block(None).get_key();
    +
    +        let iterator = read_store.prefix_iterator(&prefix);
    +        // FIXME: we have to filter manually because rocksdb sometimes returns stuff that doesn't
    +        // have the right prefix
    +        iterator
    +            .filter(|(k, _)| k.starts_with(&prefix))
    +            .map(|(k, v)| {
    +                let height: usize = usize::from_be_bytes(
    +                    k[1..]
    +                        .try_into()
    +                        .map_err(|_| CompactFiltersError::DataCorruption)?,
                     );
    -                let block = SerializeDb::deserialize(&v)?;
    +                let block = SerializeDb::deserialize(&v)?;
     
    -                Ok((height, block))
    +                Ok((height, block))
                 })
    -            .collect::<Result<_, _>>()
    +            .collect::<Result<_, _>>()
         }
     }
     
    -impl<T: StoreType> ChainStore<T> {
    -    pub fn work(&self) -> Result<Uint256, CompactFiltersError> {
    -        let read_store = self.store.read().unwrap();
    -        let cf_handle = read_store.cf_handle(&self.cf_name).unwrap();
    +impl<T: StoreType> ChainStore<T> {
    +    pub fn work(&self) -> Result<Uint256, CompactFiltersError> {
    +        let read_store = self.store.read().unwrap();
    +        let cf_handle = read_store.cf_handle(&self.cf_name).unwrap();
     
    -        let prefix = StoreEntry::BlockHeader(None).get_key();
    -        let iterator = read_store.prefix_iterator_cf(cf_handle, prefix);
    +        let prefix = StoreEntry::BlockHeader(None).get_key();
    +        let iterator = read_store.prefix_iterator_cf(cf_handle, prefix);
     
    -        Ok(iterator
    -            .last()
    -            .map(|(_, v)| -> Result<_, CompactFiltersError> {
    -                let (_, work): (BlockHeader, Uint256) = SerializeDb::deserialize(&v)?;
    +        Ok(iterator
    +            .last()
    +            .map(|(_, v)| -> Result<_, CompactFiltersError> {
    +                let (_, work): (BlockHeader, Uint256) = SerializeDb::deserialize(&v)?;
     
    -                Ok(work)
    +                Ok(work)
                 })
    -            .transpose()?
    -            .unwrap_or_default())
    +            .transpose()?
    +            .unwrap_or_default())
         }
     
    -    pub fn get_height(&self) -> Result<usize, CompactFiltersError> {
    -        let read_store = self.store.read().unwrap();
    -        let cf_handle = read_store.cf_handle(&self.cf_name).unwrap();
    +    pub fn get_height(&self) -> Result<usize, CompactFiltersError> {
    +        let read_store = self.store.read().unwrap();
    +        let cf_handle = read_store.cf_handle(&self.cf_name).unwrap();
     
    -        let prefix = StoreEntry::BlockHeader(None).get_key();
    -        let iterator = read_store.prefix_iterator_cf(cf_handle, prefix);
    +        let prefix = StoreEntry::BlockHeader(None).get_key();
    +        let iterator = read_store.prefix_iterator_cf(cf_handle, prefix);
     
    -        Ok(iterator
    -            .last()
    -            .map(|(k, _)| -> Result<_, CompactFiltersError> {
    -                let height = usize::from_be_bytes(
    -                    k[1..]
    -                        .try_into()
    -                        .map_err(|_| CompactFiltersError::DataCorruption)?,
    +        Ok(iterator
    +            .last()
    +            .map(|(k, _)| -> Result<_, CompactFiltersError> {
    +                let height = usize::from_be_bytes(
    +                    k[1..]
    +                        .try_into()
    +                        .map_err(|_| CompactFiltersError::DataCorruption)?,
                     );
     
    -                Ok(height)
    +                Ok(height)
                 })
    -            .transpose()?
    -            .unwrap_or_default())
    +            .transpose()?
    +            .unwrap_or_default())
         }
     
    -    pub fn get_tip_hash(&self) -> Result<Option<BlockHash>, CompactFiltersError> {
    -        let read_store = self.store.read().unwrap();
    -        let cf_handle = read_store.cf_handle(&self.cf_name).unwrap();
    +    pub fn get_tip_hash(&self) -> Result<Option<BlockHash>, CompactFiltersError> {
    +        let read_store = self.store.read().unwrap();
    +        let cf_handle = read_store.cf_handle(&self.cf_name).unwrap();
     
    -        let prefix = StoreEntry::BlockHeader(None).get_key();
    -        let iterator = read_store.prefix_iterator_cf(cf_handle, prefix);
    +        let prefix = StoreEntry::BlockHeader(None).get_key();
    +        let iterator = read_store.prefix_iterator_cf(cf_handle, prefix);
     
    -        iterator
    -            .last()
    -            .map(|(_, v)| -> Result<_, CompactFiltersError> {
    -                let (header, _): (BlockHeader, Uint256) = SerializeDb::deserialize(&v)?;
    +        iterator
    +            .last()
    +            .map(|(_, v)| -> Result<_, CompactFiltersError> {
    +                let (header, _): (BlockHeader, Uint256) = SerializeDb::deserialize(&v)?;
     
    -                Ok(header.block_hash())
    +                Ok(header.block_hash())
                 })
    -            .transpose()
    +            .transpose()
         }
     
    -    pub fn apply(
    -        &mut self,
    -        from: usize,
    -        headers: Vec<BlockHeader>,
    -    ) -> Result<BlockHash, CompactFiltersError> {
    -        let mut batch = WriteBatch::default();
    -
    -        let read_store = self.store.read().unwrap();
    -        let cf_handle = read_store.cf_handle(&self.cf_name).unwrap();
    -
    -        let (mut last_hash, mut accumulated_work) = read_store
    -            .get_pinned_cf(cf_handle, StoreEntry::BlockHeader(Some(from)).get_key())?
    -            .map(|result| {
    -                let (header, work): (BlockHeader, Uint256) = SerializeDb::deserialize(&result)?;
    -                Ok::<_, CompactFiltersError>((header.block_hash(), work))
    +    pub fn apply(
    +        &mut self,
    +        from: usize,
    +        headers: Vec<BlockHeader>,
    +    ) -> Result<BlockHash, CompactFiltersError> {
    +        let mut batch = WriteBatch::default();
    +
    +        let read_store = self.store.read().unwrap();
    +        let cf_handle = read_store.cf_handle(&self.cf_name).unwrap();
    +
    +        let (mut last_hash, mut accumulated_work) = read_store
    +            .get_pinned_cf(cf_handle, StoreEntry::BlockHeader(Some(from)).get_key())?
    +            .map(|result| {
    +                let (header, work): (BlockHeader, Uint256) = SerializeDb::deserialize(&result)?;
    +                Ok::<_, CompactFiltersError>((header.block_hash(), work))
                 })
    -            .transpose()?
    -            .ok_or(CompactFiltersError::DataCorruption)?;
    +            .transpose()?
    +            .ok_or(CompactFiltersError::DataCorruption)?;
     
    -        for (index, header) in headers.into_iter().enumerate() {
    -            if header.prev_blockhash != last_hash {
    -                return Err(CompactFiltersError::InvalidHeaders);
    +        for (index, header) in headers.into_iter().enumerate() {
    +            if header.prev_blockhash != last_hash {
    +                return Err(CompactFiltersError::InvalidHeaders);
                 }
     
    -            last_hash = header.block_hash();
    -            accumulated_work = accumulated_work + header.work();
    +            last_hash = header.block_hash();
    +            accumulated_work = accumulated_work + header.work();
     
    -            let height = from + index + 1;
    -            batch.put_cf(
    -                cf_handle,
    -                StoreEntry::BlockHeaderIndex(Some(header.block_hash())).get_key(),
    -                &(height).to_be_bytes(),
    +            let height = from + index + 1;
    +            batch.put_cf(
    +                cf_handle,
    +                StoreEntry::BlockHeaderIndex(Some(header.block_hash())).get_key(),
    +                &(height).to_be_bytes(),
                 );
    -            batch.put_cf(
    -                cf_handle,
    -                StoreEntry::BlockHeader(Some(height)).get_key(),
    -                (header, accumulated_work).serialize(),
    +            batch.put_cf(
    +                cf_handle,
    +                StoreEntry::BlockHeader(Some(height)).get_key(),
    +                (header, accumulated_work).serialize(),
                 );
             }
     
    -        std::mem::drop(read_store);
    +        std::mem::drop(read_store);
     
    -        self.store.write().unwrap().write(batch)?;
    -        Ok(last_hash)
    +        self.store.write().unwrap().write(batch)?;
    +        Ok(last_hash)
         }
     }
     
    -impl<T: StoreType> fmt::Debug for ChainStore<T> {
    -    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
    -        f.debug_struct(&format!("ChainStore<{:?}>", T::default()))
    -            .field("cf_name", &self.cf_name)
    -            .field("min_height", &self.min_height)
    -            .field("network", &self.network)
    -            .field("headers_height", &self.get_height())
    -            .field("tip_hash", &self.get_tip_hash())
    -            .finish()
    +impl<T: StoreType> fmt::Debug for ChainStore<T> {
    +    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
    +        f.debug_struct(&format!("ChainStore<{:?}>", T::default()))
    +            .field("cf_name", &self.cf_name)
    +            .field("min_height", &self.min_height)
    +            .field("network", &self.network)
    +            .field("headers_height", &self.get_height())
    +            .field("tip_hash", &self.get_tip_hash())
    +            .finish()
         }
     }
     
    -pub enum BundleStatus {
    -    Init,
    -    CfHeaders { cf_headers: Vec<FilterHeader> },
    -    CFilters { cf_filters: Vec<Vec<u8>> },
    -    Processed { cf_filters: Vec<Vec<u8>> },
    -    Tip { cf_filters: Vec<Vec<u8>> },
    -    Pruned,
    +pub enum BundleStatus {
    +    Init,
    +    CfHeaders { cf_headers: Vec<FilterHeader> },
    +    CFilters { cf_filters: Vec<Vec<u8>> },
    +    Processed { cf_filters: Vec<Vec<u8>> },
    +    Tip { cf_filters: Vec<Vec<u8>> },
    +    Pruned,
     }
     
    -pub struct CfStore {
    -    store: Arc<RwLock<DB>>,
    -    filter_type: u8,
    +pub struct CfStore {
    +    store: Arc<RwLock<DB>>,
    +    filter_type: u8,
     }
     
    -type BundleEntry = (BundleStatus, FilterHeader);
    +type BundleEntry = (BundleStatus, FilterHeader);
     
    -impl CfStore {
    -    pub fn new(
    -        headers_store: &ChainStore<Full>,
    -        filter_type: u8,
    -    ) -> Result<Self, CompactFiltersError> {
    -        let cf_store = CfStore {
    -            store: Arc::clone(&headers_store.store),
    -            filter_type,
    +impl CfStore {
    +    pub fn new(
    +        headers_store: &ChainStore<Full>,
    +        filter_type: u8,
    +    ) -> Result<Self, CompactFiltersError> {
    +        let cf_store = CfStore {
    +            store: Arc::clone(&headers_store.store),
    +            filter_type,
             };
     
    -        let genesis = genesis_block(headers_store.network);
    +        let genesis = genesis_block(headers_store.network);
     
    -        let filter = BlockFilter::new_script_filter(&genesis, |utxo| {
    -            Err(bitcoin::util::bip158::Error::UtxoMissing(*utxo))
    +        let filter = BlockFilter::new_script_filter(&genesis, |utxo| {
    +            Err(bitcoin::util::bip158::Error::UtxoMissing(*utxo))
             })?;
    -        let first_key = StoreEntry::CFilterTable((filter_type, Some(0))).get_key();
    -
    -        // Add the genesis' filter
    -        {
    -            let read_store = cf_store.store.read().unwrap();
    -            if read_store.get_pinned(&first_key)?.is_none() {
    -                read_store.put(
    -                    &first_key,
    +        let first_key = StoreEntry::CFilterTable((filter_type, Some(0))).get_key();
    +
    +        // Add the genesis' filter
    +        {
    +            let read_store = cf_store.store.read().unwrap();
    +            if read_store.get_pinned(&first_key)?.is_none() {
    +                read_store.put(
    +                    &first_key,
                         (
    -                        BundleStatus::Init,
    -                        filter.filter_header(&FilterHeader::from_hash(Hash::all_zeros())),
    +                        BundleStatus::Init,
    +                        filter.filter_header(&FilterHeader::from_hash(Hash::all_zeros())),
                         )
    -                        .serialize(),
    +                        .serialize(),
                     )?;
                 }
             }
     
    -        Ok(cf_store)
    +        Ok(cf_store)
         }
     
    -    pub fn get_filter_type(&self) -> u8 {
    -        self.filter_type
    +    pub fn get_filter_type(&self) -> u8 {
    +        self.filter_type
         }
     
    -    pub fn get_bundles(&self) -> Result<Vec<BundleEntry>, CompactFiltersError> {
    -        let read_store = self.store.read().unwrap();
    +    pub fn get_bundles(&self) -> Result<Vec<BundleEntry>, CompactFiltersError> {
    +        let read_store = self.store.read().unwrap();
     
    -        let prefix = StoreEntry::CFilterTable((self.filter_type, None)).get_key();
    -        let iterator = read_store.prefix_iterator(&prefix);
    +        let prefix = StoreEntry::CFilterTable((self.filter_type, None)).get_key();
    +        let iterator = read_store.prefix_iterator(&prefix);
     
    -        // FIXME: we have to filter manually because rocksdb sometimes returns stuff that doesn't
    -        // have the right prefix
    -        iterator
    -            .filter(|(k, _)| k.starts_with(&prefix))
    -            .map(|(_, data)| BundleEntry::deserialize(&data))
    -            .collect::<Result<_, _>>()
    +        // FIXME: we have to filter manually because rocksdb sometimes returns stuff that doesn't
    +        // have the right prefix
    +        iterator
    +            .filter(|(k, _)| k.starts_with(&prefix))
    +            .map(|(_, data)| BundleEntry::deserialize(&data))
    +            .collect::<Result<_, _>>()
         }
     
    -    pub fn get_checkpoints(&self) -> Result<Vec<FilterHeader>, CompactFiltersError> {
    -        let read_store = self.store.read().unwrap();
    +    pub fn get_checkpoints(&self) -> Result<Vec<FilterHeader>, CompactFiltersError> {
    +        let read_store = self.store.read().unwrap();
     
    -        let prefix = StoreEntry::CFilterTable((self.filter_type, None)).get_key();
    -        let iterator = read_store.prefix_iterator(&prefix);
    +        let prefix = StoreEntry::CFilterTable((self.filter_type, None)).get_key();
    +        let iterator = read_store.prefix_iterator(&prefix);
     
    -        // FIXME: we have to filter manually because rocksdb sometimes returns stuff that doesn't
    -        // have the right prefix
    -        iterator
    -            .filter(|(k, _)| k.starts_with(&prefix))
    -            .skip(1)
    -            .map(|(_, data)| Ok::<_, CompactFiltersError>(BundleEntry::deserialize(&data)?.1))
    -            .collect::<Result<_, _>>()
    +        // FIXME: we have to filter manually because rocksdb sometimes returns stuff that doesn't
    +        // have the right prefix
    +        iterator
    +            .filter(|(k, _)| k.starts_with(&prefix))
    +            .skip(1)
    +            .map(|(_, data)| Ok::<_, CompactFiltersError>(BundleEntry::deserialize(&data)?.1))
    +            .collect::<Result<_, _>>()
         }
     
    -    pub fn replace_checkpoints(
    +    pub fn replace_checkpoints(
             &self,
    -        checkpoints: Vec<FilterHeader>,
    -    ) -> Result<(), CompactFiltersError> {
    -        let current_checkpoints = self.get_checkpoints()?;
    -
    -        let mut equal_bundles = 0;
    -        for (index, (our, their)) in current_checkpoints
    -            .iter()
    -            .zip(checkpoints.iter())
    -            .enumerate()
    +        checkpoints: Vec<FilterHeader>,
    +    ) -> Result<(), CompactFiltersError> {
    +        let current_checkpoints = self.get_checkpoints()?;
    +
    +        let mut equal_bundles = 0;
    +        for (index, (our, their)) in current_checkpoints
    +            .iter()
    +            .zip(checkpoints.iter())
    +            .enumerate()
             {
    -            equal_bundles = index;
    +            equal_bundles = index;
     
    -            if our != their {
    +            if our != their {
                     break;
                 }
             }
     
    -        let read_store = self.store.read().unwrap();
    -        let mut batch = WriteBatch::default();
    +        let read_store = self.store.read().unwrap();
    +        let mut batch = WriteBatch::default();
     
    -        for (index, filter_hash) in checkpoints.iter().enumerate().skip(equal_bundles) {
    -            let key = StoreEntry::CFilterTable((self.filter_type, Some(index + 1))).get_key(); // +1 to skip the genesis' filter
    +        for (index, filter_hash) in checkpoints.iter().enumerate().skip(equal_bundles) {
    +            let key = StoreEntry::CFilterTable((self.filter_type, Some(index + 1))).get_key(); // +1 to skip the genesis' filter
     
    -            if let Some((BundleStatus::Tip { .. }, _)) = read_store
    -                .get_pinned(&key)?
    -                .map(|data| BundleEntry::deserialize(&data))
    -                .transpose()?
    -            {
    -                println!("Keeping bundle #{} as Tip", index);
    -            } else {
    -                batch.put(&key, (BundleStatus::Init, *filter_hash).serialize());
    +            if let Some((BundleStatus::Tip { .. }, _)) = read_store
    +                .get_pinned(&key)?
    +                .map(|data| BundleEntry::deserialize(&data))
    +                .transpose()?
    +            {
    +                println!("Keeping bundle #{} as Tip", index);
    +            } else {
    +                batch.put(&key, (BundleStatus::Init, *filter_hash).serialize());
                 }
             }
     
    -        read_store.write(batch)?;
    +        read_store.write(batch)?;
     
             Ok(())
         }
     
    -    pub fn advance_to_cf_headers(
    +    pub fn advance_to_cf_headers(
             &self,
    -        bundle: usize,
    -        checkpoint: FilterHeader,
    -        filter_hashes: Vec<FilterHash>,
    -    ) -> Result<BundleStatus, CompactFiltersError> {
    -        let cf_headers: Vec<FilterHeader> = filter_hashes
    -            .into_iter()
    -            .scan(checkpoint, |prev_header, filter_hash| {
    -                let filter_header = filter_hash.filter_header(prev_header);
    -                *prev_header = filter_header;
    -
    -                Some(filter_header)
    +        bundle: usize,
    +        checkpoint: FilterHeader,
    +        filter_hashes: Vec<FilterHash>,
    +    ) -> Result<BundleStatus, CompactFiltersError> {
    +        let cf_headers: Vec<FilterHeader> = filter_hashes
    +            .into_iter()
    +            .scan(checkpoint, |prev_header, filter_hash| {
    +                let filter_header = filter_hash.filter_header(prev_header);
    +                *prev_header = filter_header;
    +
    +                Some(filter_header)
                 })
    -            .collect();
    -
    -        let read_store = self.store.read().unwrap();
    -
    -        let next_key = StoreEntry::CFilterTable((self.filter_type, Some(bundle + 1))).get_key(); // +1 to skip the genesis' filter
    -        if let Some((_, next_checkpoint)) = read_store
    -            .get_pinned(&next_key)?
    -            .map(|data| BundleEntry::deserialize(&data))
    -            .transpose()?
    -        {
    -            // check connection with the next bundle if present
    -            if cf_headers.iter().last() != Some(&next_checkpoint) {
    -                return Err(CompactFiltersError::InvalidFilterHeader);
    +            .collect();
    +
    +        let read_store = self.store.read().unwrap();
    +
    +        let next_key = StoreEntry::CFilterTable((self.filter_type, Some(bundle + 1))).get_key(); // +1 to skip the genesis' filter
    +        if let Some((_, next_checkpoint)) = read_store
    +            .get_pinned(&next_key)?
    +            .map(|data| BundleEntry::deserialize(&data))
    +            .transpose()?
    +        {
    +            // check connection with the next bundle if present
    +            if cf_headers.iter().last() != Some(&next_checkpoint) {
    +                return Err(CompactFiltersError::InvalidFilterHeader);
                 }
             }
     
    -        let key = StoreEntry::CFilterTable((self.filter_type, Some(bundle))).get_key();
    -        let value = (BundleStatus::CfHeaders { cf_headers }, checkpoint);
    +        let key = StoreEntry::CFilterTable((self.filter_type, Some(bundle))).get_key();
    +        let value = (BundleStatus::CfHeaders { cf_headers }, checkpoint);
     
    -        read_store.put(key, value.serialize())?;
    +        read_store.put(key, value.serialize())?;
     
    -        Ok(value.0)
    +        Ok(value.0)
         }
     
    -    pub fn advance_to_cf_filters(
    +    pub fn advance_to_cf_filters(
             &self,
    -        bundle: usize,
    -        checkpoint: FilterHeader,
    -        headers: Vec<FilterHeader>,
    -        filters: Vec<(usize, Vec<u8>)>,
    -    ) -> Result<BundleStatus, CompactFiltersError> {
    -        let cf_filters = filters
    -            .into_iter()
    -            .zip(headers.into_iter())
    -            .scan(checkpoint, |prev_header, ((_, filter_content), header)| {
    -                let filter = BlockFilter::new(&filter_content);
    -                if header != filter.filter_header(prev_header) {
    -                    return Some(Err(CompactFiltersError::InvalidFilter));
    +        bundle: usize,
    +        checkpoint: FilterHeader,
    +        headers: Vec<FilterHeader>,
    +        filters: Vec<(usize, Vec<u8>)>,
    +    ) -> Result<BundleStatus, CompactFiltersError> {
    +        let cf_filters = filters
    +            .into_iter()
    +            .zip(headers.into_iter())
    +            .scan(checkpoint, |prev_header, ((_, filter_content), header)| {
    +                let filter = BlockFilter::new(&filter_content);
    +                if header != filter.filter_header(prev_header) {
    +                    return Some(Err(CompactFiltersError::InvalidFilter));
                     }
    -                *prev_header = header;
    +                *prev_header = header;
     
    -                Some(Ok::<_, CompactFiltersError>(filter_content))
    +                Some(Ok::<_, CompactFiltersError>(filter_content))
                 })
    -            .collect::<Result<_, _>>()?;
    +            .collect::<Result<_, _>>()?;
     
    -        let key = StoreEntry::CFilterTable((self.filter_type, Some(bundle))).get_key();
    -        let value = (BundleStatus::CFilters { cf_filters }, checkpoint);
    +        let key = StoreEntry::CFilterTable((self.filter_type, Some(bundle))).get_key();
    +        let value = (BundleStatus::CFilters { cf_filters }, checkpoint);
     
    -        let read_store = self.store.read().unwrap();
    -        read_store.put(key, value.serialize())?;
    +        let read_store = self.store.read().unwrap();
    +        read_store.put(key, value.serialize())?;
     
    -        Ok(value.0)
    +        Ok(value.0)
         }
     
    -    pub fn prune_filters(
    +    pub fn prune_filters(
             &self,
    -        bundle: usize,
    -        checkpoint: FilterHeader,
    -    ) -> Result<BundleStatus, CompactFiltersError> {
    -        let key = StoreEntry::CFilterTable((self.filter_type, Some(bundle))).get_key();
    -        let value = (BundleStatus::Pruned, checkpoint);
    +        bundle: usize,
    +        checkpoint: FilterHeader,
    +    ) -> Result<BundleStatus, CompactFiltersError> {
    +        let key = StoreEntry::CFilterTable((self.filter_type, Some(bundle))).get_key();
    +        let value = (BundleStatus::Pruned, checkpoint);
     
    -        let read_store = self.store.read().unwrap();
    -        read_store.put(key, value.serialize())?;
    +        let read_store = self.store.read().unwrap();
    +        read_store.put(key, value.serialize())?;
     
    -        Ok(value.0)
    +        Ok(value.0)
         }
     
    -    pub fn mark_as_tip(
    +    pub fn mark_as_tip(
             &self,
    -        bundle: usize,
    -        cf_filters: Vec<Vec<u8>>,
    -        checkpoint: FilterHeader,
    -    ) -> Result<BundleStatus, CompactFiltersError> {
    -        let key = StoreEntry::CFilterTable((self.filter_type, Some(bundle))).get_key();
    -        let value = (BundleStatus::Tip { cf_filters }, checkpoint);
    +        bundle: usize,
    +        cf_filters: Vec<Vec<u8>>,
    +        checkpoint: FilterHeader,
    +    ) -> Result<BundleStatus, CompactFiltersError> {
    +        let key = StoreEntry::CFilterTable((self.filter_type, Some(bundle))).get_key();
    +        let value = (BundleStatus::Tip { cf_filters }, checkpoint);
     
    -        let read_store = self.store.read().unwrap();
    -        read_store.put(key, value.serialize())?;
    +        let read_store = self.store.read().unwrap();
    +        read_store.put(key, value.serialize())?;
     
    -        Ok(value.0)
    +        Ok(value.0)
         }
     }
     
    -
    - \ No newline at end of file +
    \ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/src/bdk/blockchain/compact_filters/sync.rs.html b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/src/bdk/blockchain/compact_filters/sync.rs.html index 367f9e9571..08aece0178 100644 --- a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/src/bdk/blockchain/compact_filters/sync.rs.html +++ b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/src/bdk/blockchain/compact_filters/sync.rs.html @@ -1,542 +1,536 @@ -sync.rs - source - -
      1
    -  2
    -  3
    -  4
    -  5
    -  6
    -  7
    -  8
    -  9
    - 10
    - 11
    - 12
    - 13
    - 14
    - 15
    - 16
    - 17
    - 18
    - 19
    - 20
    - 21
    - 22
    - 23
    - 24
    - 25
    - 26
    - 27
    - 28
    - 29
    - 30
    - 31
    - 32
    - 33
    - 34
    - 35
    - 36
    - 37
    - 38
    - 39
    - 40
    - 41
    - 42
    - 43
    - 44
    - 45
    - 46
    - 47
    - 48
    - 49
    - 50
    - 51
    - 52
    - 53
    - 54
    - 55
    - 56
    - 57
    - 58
    - 59
    - 60
    - 61
    - 62
    - 63
    - 64
    - 65
    - 66
    - 67
    - 68
    - 69
    - 70
    - 71
    - 72
    - 73
    - 74
    - 75
    - 76
    - 77
    - 78
    - 79
    - 80
    - 81
    - 82
    - 83
    - 84
    - 85
    - 86
    - 87
    - 88
    - 89
    - 90
    - 91
    - 92
    - 93
    - 94
    - 95
    - 96
    - 97
    - 98
    - 99
    -100
    -101
    -102
    -103
    -104
    -105
    -106
    -107
    -108
    -109
    -110
    -111
    -112
    -113
    -114
    -115
    -116
    -117
    -118
    -119
    -120
    -121
    -122
    -123
    -124
    -125
    -126
    -127
    -128
    -129
    -130
    -131
    -132
    -133
    -134
    -135
    -136
    -137
    -138
    -139
    -140
    -141
    -142
    -143
    -144
    -145
    -146
    -147
    -148
    -149
    -150
    -151
    -152
    -153
    -154
    -155
    -156
    -157
    -158
    -159
    -160
    -161
    -162
    -163
    -164
    -165
    -166
    -167
    -168
    -169
    -170
    -171
    -172
    -173
    -174
    -175
    -176
    -177
    -178
    -179
    -180
    -181
    -182
    -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
    -245
    -246
    -247
    -248
    -249
    -250
    -251
    -252
    -253
    -254
    -255
    -256
    -257
    -258
    -259
    -260
    -261
    -262
    -263
    -264
    -265
    -266
    -267
    -268
    -269
    -270
    -271
    -272
    -273
    -274
    -275
    -276
    -277
    -278
    -279
    -280
    -281
    -282
    -283
    -284
    -285
    -286
    -287
    -288
    -289
    -290
    -291
    -292
    -293
    -294
    -295
    -296
    -297
    -
    // Bitcoin Dev Kit
    -// Written in 2020 by Alekos Filini <alekos.filini@gmail.com>
    -//
    -// Copyright (c) 2020-2021 Bitcoin Dev Kit Developers
    -//
    -// This file is licensed under the Apache License, Version 2.0 <LICENSE-APACHE
    -// or http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
    -// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your option.
    -// You may not use this file except in accordance with one or both of these
    -// licenses.
    -
    -use std::collections::{BTreeMap, HashMap, VecDeque};
    -use std::sync::{Arc, Mutex};
    -use std::time::Duration;
    -
    -use bitcoin::hash_types::{BlockHash, FilterHeader};
    -use bitcoin::hashes::Hash;
    -use bitcoin::network::message::NetworkMessage;
    -use bitcoin::network::message_blockdata::GetHeadersMessage;
    -use bitcoin::util::bip158::BlockFilter;
    -
    -use super::peer::*;
    -use super::store::*;
    -use super::CompactFiltersError;
    -use crate::error::Error;
    -
    -pub(crate) const BURIED_CONFIRMATIONS: usize = 100;
    -
    -pub struct CfSync {
    -    headers_store: Arc<ChainStore<Full>>,
    -    cf_store: Arc<CfStore>,
    -    skip_blocks: usize,
    -    bundles: Mutex<VecDeque<(BundleStatus, FilterHeader, usize)>>,
    +sync.rs - source
    1
    +2
    +3
    +4
    +5
    +6
    +7
    +8
    +9
    +10
    +11
    +12
    +13
    +14
    +15
    +16
    +17
    +18
    +19
    +20
    +21
    +22
    +23
    +24
    +25
    +26
    +27
    +28
    +29
    +30
    +31
    +32
    +33
    +34
    +35
    +36
    +37
    +38
    +39
    +40
    +41
    +42
    +43
    +44
    +45
    +46
    +47
    +48
    +49
    +50
    +51
    +52
    +53
    +54
    +55
    +56
    +57
    +58
    +59
    +60
    +61
    +62
    +63
    +64
    +65
    +66
    +67
    +68
    +69
    +70
    +71
    +72
    +73
    +74
    +75
    +76
    +77
    +78
    +79
    +80
    +81
    +82
    +83
    +84
    +85
    +86
    +87
    +88
    +89
    +90
    +91
    +92
    +93
    +94
    +95
    +96
    +97
    +98
    +99
    +100
    +101
    +102
    +103
    +104
    +105
    +106
    +107
    +108
    +109
    +110
    +111
    +112
    +113
    +114
    +115
    +116
    +117
    +118
    +119
    +120
    +121
    +122
    +123
    +124
    +125
    +126
    +127
    +128
    +129
    +130
    +131
    +132
    +133
    +134
    +135
    +136
    +137
    +138
    +139
    +140
    +141
    +142
    +143
    +144
    +145
    +146
    +147
    +148
    +149
    +150
    +151
    +152
    +153
    +154
    +155
    +156
    +157
    +158
    +159
    +160
    +161
    +162
    +163
    +164
    +165
    +166
    +167
    +168
    +169
    +170
    +171
    +172
    +173
    +174
    +175
    +176
    +177
    +178
    +179
    +180
    +181
    +182
    +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
    +245
    +246
    +247
    +248
    +249
    +250
    +251
    +252
    +253
    +254
    +255
    +256
    +257
    +258
    +259
    +260
    +261
    +262
    +263
    +264
    +265
    +266
    +267
    +268
    +269
    +270
    +271
    +272
    +273
    +274
    +275
    +276
    +277
    +278
    +279
    +280
    +281
    +282
    +283
    +284
    +285
    +286
    +287
    +288
    +289
    +290
    +291
    +292
    +293
    +294
    +295
    +296
    +297
    +
    // Bitcoin Dev Kit
    +// Written in 2020 by Alekos Filini <alekos.filini@gmail.com>
    +//
    +// Copyright (c) 2020-2021 Bitcoin Dev Kit Developers
    +//
    +// This file is licensed under the Apache License, Version 2.0 <LICENSE-APACHE
    +// or http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
    +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your option.
    +// You may not use this file except in accordance with one or both of these
    +// licenses.
    +
    +use std::collections::{BTreeMap, HashMap, VecDeque};
    +use std::sync::{Arc, Mutex};
    +use std::time::Duration;
    +
    +use bitcoin::hash_types::{BlockHash, FilterHeader};
    +use bitcoin::hashes::Hash;
    +use bitcoin::network::message::NetworkMessage;
    +use bitcoin::network::message_blockdata::GetHeadersMessage;
    +use bitcoin::util::bip158::BlockFilter;
    +
    +use super::peer::*;
    +use super::store::*;
    +use super::CompactFiltersError;
    +use crate::error::Error;
    +
    +pub(crate) const BURIED_CONFIRMATIONS: usize = 100;
    +
    +pub struct CfSync {
    +    headers_store: Arc<ChainStore<Full>>,
    +    cf_store: Arc<CfStore>,
    +    skip_blocks: usize,
    +    bundles: Mutex<VecDeque<(BundleStatus, FilterHeader, usize)>>,
     }
     
    -impl CfSync {
    -    pub fn new(
    -        headers_store: Arc<ChainStore<Full>>,
    -        skip_blocks: usize,
    -        filter_type: u8,
    -    ) -> Result<Self, CompactFiltersError> {
    -        let cf_store = Arc::new(CfStore::new(&headers_store, filter_type)?);
    -
    -        Ok(CfSync {
    -            headers_store,
    -            cf_store,
    -            skip_blocks,
    -            bundles: Mutex::new(VecDeque::new()),
    +impl CfSync {
    +    pub fn new(
    +        headers_store: Arc<ChainStore<Full>>,
    +        skip_blocks: usize,
    +        filter_type: u8,
    +    ) -> Result<Self, CompactFiltersError> {
    +        let cf_store = Arc::new(CfStore::new(&headers_store, filter_type)?);
    +
    +        Ok(CfSync {
    +            headers_store,
    +            cf_store,
    +            skip_blocks,
    +            bundles: Mutex::new(VecDeque::new()),
             })
         }
     
    -    pub fn pruned_bundles(&self) -> Result<usize, CompactFiltersError> {
    -        Ok(self
    -            .cf_store
    -            .get_bundles()?
    -            .into_iter()
    -            .skip(self.skip_blocks / 1000)
    -            .fold(0, |acc, (status, _)| match status {
    -                BundleStatus::Pruned => acc + 1,
    -                _ => acc,
    +    pub fn pruned_bundles(&self) -> Result<usize, CompactFiltersError> {
    +        Ok(self
    +            .cf_store
    +            .get_bundles()?
    +            .into_iter()
    +            .skip(self.skip_blocks / 1000)
    +            .fold(0, |acc, (status, _)| match status {
    +                BundleStatus::Pruned => acc + 1,
    +                _ => acc,
                 }))
         }
     
    -    pub fn prepare_sync(&self, peer: Arc<Peer>) -> Result<(), CompactFiltersError> {
    -        let mut bundles_lock = self.bundles.lock().unwrap();
    +    pub fn prepare_sync(&self, peer: Arc<Peer>) -> Result<(), CompactFiltersError> {
    +        let mut bundles_lock = self.bundles.lock().unwrap();
     
    -        let resp = peer.get_cf_checkpt(
    -            self.cf_store.get_filter_type(),
    -            self.headers_store.get_tip_hash()?.unwrap(),
    +        let resp = peer.get_cf_checkpt(
    +            self.cf_store.get_filter_type(),
    +            self.headers_store.get_tip_hash()?.unwrap(),
             )?;
    -        self.cf_store.replace_checkpoints(resp.filter_headers)?;
    +        self.cf_store.replace_checkpoints(resp.filter_headers)?;
     
    -        bundles_lock.clear();
    -        for (index, (status, checkpoint)) in self.cf_store.get_bundles()?.into_iter().enumerate() {
    -            bundles_lock.push_back((status, checkpoint, index));
    +        bundles_lock.clear();
    +        for (index, (status, checkpoint)) in self.cf_store.get_bundles()?.into_iter().enumerate() {
    +            bundles_lock.push_back((status, checkpoint, index));
             }
     
             Ok(())
         }
     
    -    pub fn capture_thread_for_sync<F, Q>(
    +    pub fn capture_thread_for_sync<F, Q>(
             &self,
    -        peer: Arc<Peer>,
    -        process: F,
    -        completed_bundle: Q,
    -    ) -> Result<(), CompactFiltersError>
    -    where
    -        F: Fn(&BlockHash, &BlockFilter) -> Result<bool, CompactFiltersError>,
    -        Q: Fn(usize) -> Result<(), Error>,
    +        peer: Arc<Peer>,
    +        process: F,
    +        completed_bundle: Q,
    +    ) -> Result<(), CompactFiltersError>
    +    where
    +        F: Fn(&BlockHash, &BlockFilter) -> Result<bool, CompactFiltersError>,
    +        Q: Fn(usize) -> Result<(), Error>,
         {
    -        let current_height = self.headers_store.get_height()?; // TODO: we should update it in case headers_store is also updated
    +        let current_height = self.headers_store.get_height()?; // TODO: we should update it in case headers_store is also updated
     
    -        loop {
    -            let (mut status, checkpoint, index) = match self.bundles.lock().unwrap().pop_front() {
    -                None => break,
    -                Some(x) => x,
    +        loop {
    +            let (mut status, checkpoint, index) = match self.bundles.lock().unwrap().pop_front() {
    +                None => break,
    +                Some(x) => x,
                 };
     
                 log::debug!(
                     "Processing bundle #{} - height {} to {}",
    -                index,
    -                index * 1000 + 1,
    -                (index + 1) * 1000
    -            );
    -
    -            let process_received_filters =
    -                |expected_filters| -> Result<BTreeMap<usize, Vec<u8>>, CompactFiltersError> {
    -                    let mut filters_map = BTreeMap::new();
    -                    for _ in 0..expected_filters {
    -                        let filter = peer.pop_cf_filter_resp()?;
    -                        if filter.filter_type != self.cf_store.get_filter_type() {
    -                            return Err(CompactFiltersError::InvalidResponse);
    +                index,
    +                index * 1000 + 1,
    +                (index + 1) * 1000
    +            );
    +
    +            let process_received_filters =
    +                |expected_filters| -> Result<BTreeMap<usize, Vec<u8>>, CompactFiltersError> {
    +                    let mut filters_map = BTreeMap::new();
    +                    for _ in 0..expected_filters {
    +                        let filter = peer.pop_cf_filter_resp()?;
    +                        if filter.filter_type != self.cf_store.get_filter_type() {
    +                            return Err(CompactFiltersError::InvalidResponse);
                             }
     
    -                        match self.headers_store.get_height_for(&filter.block_hash)? {
    -                            Some(height) => filters_map.insert(height, filter.filter),
    -                            None => return Err(CompactFiltersError::InvalidFilter),
    +                        match self.headers_store.get_height_for(&filter.block_hash)? {
    +                            Some(height) => filters_map.insert(height, filter.filter),
    +                            None => return Err(CompactFiltersError::InvalidFilter),
                             };
                         }
     
    -                    Ok(filters_map)
    +                    Ok(filters_map)
                     };
     
    -            let start_height = index * 1000 + 1;
    -            let mut already_processed = 0;
    +            let start_height = index * 1000 + 1;
    +            let mut already_processed = 0;
     
    -            if start_height < self.skip_blocks {
    -                status = self.cf_store.prune_filters(index, checkpoint)?;
    +            if start_height < self.skip_blocks {
    +                status = self.cf_store.prune_filters(index, checkpoint)?;
                 }
     
    -            let stop_height = std::cmp::min(current_height, start_height + 999);
    -            let stop_hash = self.headers_store.get_block_hash(stop_height)?.unwrap();
    +            let stop_height = std::cmp::min(current_height, start_height + 999);
    +            let stop_hash = self.headers_store.get_block_hash(stop_height)?.unwrap();
     
    -            if let BundleStatus::Init = status {
    +            if let BundleStatus::Init = status {
                     log::trace!("status: Init");
     
    -                let resp = peer.get_cf_headers(0x00, start_height as u32, stop_hash)?;
    +                let resp = peer.get_cf_headers(0x00, start_height as u32, stop_hash)?;
     
    -                assert!(resp.previous_filter_header == checkpoint);
    -                status =
    -                    self.cf_store
    -                        .advance_to_cf_headers(index, checkpoint, resp.filter_hashes)?;
    +                assert!(resp.previous_filter_header == checkpoint);
    +                status =
    +                    self.cf_store
    +                        .advance_to_cf_headers(index, checkpoint, resp.filter_hashes)?;
                 }
    -            if let BundleStatus::Tip { cf_filters } = status {
    +            if let BundleStatus::Tip { cf_filters } = status {
                     log::trace!("status: Tip (beginning) ");
     
    -                already_processed = cf_filters.len();
    -                let headers_resp = peer.get_cf_headers(0x00, start_height as u32, stop_hash)?;
    +                already_processed = cf_filters.len();
    +                let headers_resp = peer.get_cf_headers(0x00, start_height as u32, stop_hash)?;
     
    -                let cf_headers = match self.cf_store.advance_to_cf_headers(
    -                    index,
    -                    checkpoint,
    -                    headers_resp.filter_hashes,
    -                )? {
    -                    BundleStatus::CfHeaders { cf_headers } => cf_headers,
    -                    _ => return Err(CompactFiltersError::InvalidResponse),
    +                let cf_headers = match self.cf_store.advance_to_cf_headers(
    +                    index,
    +                    checkpoint,
    +                    headers_resp.filter_hashes,
    +                )? {
    +                    BundleStatus::CfHeaders { cf_headers } => cf_headers,
    +                    _ => return Err(CompactFiltersError::InvalidResponse),
                     };
     
    -                peer.get_cf_filters(
    -                    self.cf_store.get_filter_type(),
    -                    (start_height + cf_filters.len()) as u32,
    -                    stop_hash,
    +                peer.get_cf_filters(
    +                    self.cf_store.get_filter_type(),
    +                    (start_height + cf_filters.len()) as u32,
    +                    stop_hash,
                     )?;
    -                let expected_filters = stop_height - start_height + 1 - cf_filters.len();
    -                let filters_map = process_received_filters(expected_filters)?;
    -                let filters = cf_filters
    -                    .into_iter()
    -                    .enumerate()
    -                    .chain(filters_map.into_iter())
    -                    .collect();
    -                status = self
    -                    .cf_store
    -                    .advance_to_cf_filters(index, checkpoint, cf_headers, filters)?;
    +                let expected_filters = stop_height - start_height + 1 - cf_filters.len();
    +                let filters_map = process_received_filters(expected_filters)?;
    +                let filters = cf_filters
    +                    .into_iter()
    +                    .enumerate()
    +                    .chain(filters_map.into_iter())
    +                    .collect();
    +                status = self
    +                    .cf_store
    +                    .advance_to_cf_filters(index, checkpoint, cf_headers, filters)?;
                 }
    -            if let BundleStatus::CfHeaders { cf_headers } = status {
    +            if let BundleStatus::CfHeaders { cf_headers } = status {
                     log::trace!("status: CFHeaders");
     
    -                peer.get_cf_filters(
    -                    self.cf_store.get_filter_type(),
    -                    start_height as u32,
    -                    stop_hash,
    +                peer.get_cf_filters(
    +                    self.cf_store.get_filter_type(),
    +                    start_height as u32,
    +                    stop_hash,
                     )?;
    -                let expected_filters = stop_height - start_height + 1;
    -                let filters_map = process_received_filters(expected_filters)?;
    -                status = self.cf_store.advance_to_cf_filters(
    -                    index,
    -                    checkpoint,
    -                    cf_headers,
    -                    filters_map.into_iter().collect(),
    +                let expected_filters = stop_height - start_height + 1;
    +                let filters_map = process_received_filters(expected_filters)?;
    +                status = self.cf_store.advance_to_cf_filters(
    +                    index,
    +                    checkpoint,
    +                    cf_headers,
    +                    filters_map.into_iter().collect(),
                     )?;
                 }
    -            if let BundleStatus::CFilters { cf_filters } = status {
    +            if let BundleStatus::CFilters { cf_filters } = status {
                     log::trace!("status: CFilters");
     
    -                let last_sync_buried_height =
    -                    (start_height + already_processed).saturating_sub(BURIED_CONFIRMATIONS);
    +                let last_sync_buried_height =
    +                    (start_height + already_processed).saturating_sub(BURIED_CONFIRMATIONS);
     
    -                for (filter_index, filter) in cf_filters.iter().enumerate() {
    -                    let height = filter_index + start_height;
    +                for (filter_index, filter) in cf_filters.iter().enumerate() {
    +                    let height = filter_index + start_height;
     
    -                    // do not download blocks that were already "buried" since the last sync
    -                    if height < last_sync_buried_height {
    +                    // do not download blocks that were already "buried" since the last sync
    +                    if height < last_sync_buried_height {
                             continue;
                         }
     
    -                    let block_hash = self.headers_store.get_block_hash(height)?.unwrap();
    +                    let block_hash = self.headers_store.get_block_hash(height)?.unwrap();
     
    -                    // TODO: also download random blocks?
    -                    if process(&block_hash, &BlockFilter::new(filter))? {
    -                        log::debug!("Downloading block {}", block_hash);
    +                    // TODO: also download random blocks?
    +                    if process(&block_hash, &BlockFilter::new(filter))? {
    +                        log::debug!("Downloading block {}", block_hash);
     
    -                        let block = peer
    -                            .get_block(block_hash)?
    -                            .ok_or(CompactFiltersError::MissingBlock)?;
    -                        self.headers_store.save_full_block(&block, height)?;
    +                        let block = peer
    +                            .get_block(block_hash)?
    +                            .ok_or(CompactFiltersError::MissingBlock)?;
    +                        self.headers_store.save_full_block(&block, height)?;
                         }
                     }
     
    -                status = BundleStatus::Processed { cf_filters };
    +                status = BundleStatus::Processed { cf_filters };
                 }
    -            if let BundleStatus::Processed { cf_filters } = status {
    +            if let BundleStatus::Processed { cf_filters } = status {
                     log::trace!("status: Processed");
     
    -                if current_height - stop_height > 1000 {
    -                    status = self.cf_store.prune_filters(index, checkpoint)?;
    -                } else {
    -                    status = self.cf_store.mark_as_tip(index, cf_filters, checkpoint)?;
    +                if current_height - stop_height > 1000 {
    +                    status = self.cf_store.prune_filters(index, checkpoint)?;
    +                } else {
    +                    status = self.cf_store.mark_as_tip(index, cf_filters, checkpoint)?;
                     }
     
    -                completed_bundle(index)?;
    +                completed_bundle(index)?;
                 }
    -            if let BundleStatus::Pruned = status {
    +            if let BundleStatus::Pruned = status {
                     log::trace!("status: Pruned");
                 }
    -            if let BundleStatus::Tip { .. } = status {
    +            if let BundleStatus::Tip { .. } = status {
                     log::trace!("status: Tip");
                 }
             }
    @@ -545,60 +539,59 @@
         }
     }
     
    -pub fn sync_headers<F>(
    -    peer: Arc<Peer>,
    -    store: Arc<ChainStore<Full>>,
    -    sync_fn: F,
    -) -> Result<Option<ChainStore<Snapshot>>, CompactFiltersError>
    -where
    -    F: Fn(usize) -> Result<(), Error>,
    +pub fn sync_headers<F>(
    +    peer: Arc<Peer>,
    +    store: Arc<ChainStore<Full>>,
    +    sync_fn: F,
    +) -> Result<Option<ChainStore<Snapshot>>, CompactFiltersError>
    +where
    +    F: Fn(usize) -> Result<(), Error>,
     {
    -    let locators = store.get_locators()?;
    -    let locators_vec = locators.iter().map(|(hash, _)| hash).cloned().collect();
    -    let locators_map: HashMap<_, _> = locators.into_iter().collect();
    +    let locators = store.get_locators()?;
    +    let locators_vec = locators.iter().map(|(hash, _)| hash).cloned().collect();
    +    let locators_map: HashMap<_, _> = locators.into_iter().collect();
     
    -    peer.send(NetworkMessage::GetHeaders(GetHeadersMessage::new(
    -        locators_vec,
    -        Hash::all_zeros(),
    +    peer.send(NetworkMessage::GetHeaders(GetHeadersMessage::new(
    +        locators_vec,
    +        Hash::all_zeros(),
         )))?;
    -    let (mut snapshot, mut last_hash) = if let NetworkMessage::Headers(headers) = peer
    -        .recv("headers", Some(Duration::from_secs(TIMEOUT_SECS)))?
    -        .ok_or(CompactFiltersError::Timeout)?
    -    {
    -        if headers.is_empty() {
    -            return Ok(None);
    +    let (mut snapshot, mut last_hash) = if let NetworkMessage::Headers(headers) = peer
    +        .recv("headers", Some(Duration::from_secs(TIMEOUT_SECS)))?
    +        .ok_or(CompactFiltersError::Timeout)?
    +    {
    +        if headers.is_empty() {
    +            return Ok(None);
             }
     
    -        match locators_map.get(&headers[0].prev_blockhash) {
    -            None => return Err(CompactFiltersError::InvalidHeaders),
    -            Some(from) => (store.start_snapshot(*from)?, headers[0].prev_blockhash),
    +        match locators_map.get(&headers[0].prev_blockhash) {
    +            None => return Err(CompactFiltersError::InvalidHeaders),
    +            Some(from) => (store.start_snapshot(*from)?, headers[0].prev_blockhash),
             }
    -    } else {
    -        return Err(CompactFiltersError::InvalidResponse);
    +    } else {
    +        return Err(CompactFiltersError::InvalidResponse);
         };
     
    -    let mut sync_height = store.get_height()?;
    -    while sync_height < peer.get_version().start_height as usize {
    -        peer.send(NetworkMessage::GetHeaders(GetHeadersMessage::new(
    -            vec![last_hash],
    -            Hash::all_zeros(),
    +    let mut sync_height = store.get_height()?;
    +    while sync_height < peer.get_version().start_height as usize {
    +        peer.send(NetworkMessage::GetHeaders(GetHeadersMessage::new(
    +            vec![last_hash],
    +            Hash::all_zeros(),
             )))?;
    -        if let NetworkMessage::Headers(headers) = peer
    -            .recv("headers", Some(Duration::from_secs(TIMEOUT_SECS)))?
    -            .ok_or(CompactFiltersError::Timeout)?
    -        {
    -            let batch_len = headers.len();
    -            last_hash = snapshot.apply(sync_height, headers)?;
    -
    -            sync_height += batch_len;
    -            sync_fn(sync_height)?;
    -        } else {
    -            return Err(CompactFiltersError::InvalidResponse);
    +        if let NetworkMessage::Headers(headers) = peer
    +            .recv("headers", Some(Duration::from_secs(TIMEOUT_SECS)))?
    +            .ok_or(CompactFiltersError::Timeout)?
    +        {
    +            let batch_len = headers.len();
    +            last_hash = snapshot.apply(sync_height, headers)?;
    +
    +            sync_height += batch_len;
    +            sync_fn(sync_height)?;
    +        } else {
    +            return Err(CompactFiltersError::InvalidResponse);
             }
         }
     
    -    Ok(Some(snapshot))
    +    Ok(Some(snapshot))
     }
     
    -
    - \ No newline at end of file +
    \ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/src/bdk/blockchain/electrum.rs.html b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/src/bdk/blockchain/electrum.rs.html index 706341a3ea..3aee1b8519 100644 --- a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/src/bdk/blockchain/electrum.rs.html +++ b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/src/bdk/blockchain/electrum.rs.html @@ -1,858 +1,851 @@ -electrum.rs - source - -
      1
    -  2
    -  3
    -  4
    -  5
    -  6
    -  7
    -  8
    -  9
    - 10
    - 11
    - 12
    - 13
    - 14
    - 15
    - 16
    - 17
    - 18
    - 19
    - 20
    - 21
    - 22
    - 23
    - 24
    - 25
    - 26
    - 27
    - 28
    - 29
    - 30
    - 31
    - 32
    - 33
    - 34
    - 35
    - 36
    - 37
    - 38
    - 39
    - 40
    - 41
    - 42
    - 43
    - 44
    - 45
    - 46
    - 47
    - 48
    - 49
    - 50
    - 51
    - 52
    - 53
    - 54
    - 55
    - 56
    - 57
    - 58
    - 59
    - 60
    - 61
    - 62
    - 63
    - 64
    - 65
    - 66
    - 67
    - 68
    - 69
    - 70
    - 71
    - 72
    - 73
    - 74
    - 75
    - 76
    - 77
    - 78
    - 79
    - 80
    - 81
    - 82
    - 83
    - 84
    - 85
    - 86
    - 87
    - 88
    - 89
    - 90
    - 91
    - 92
    - 93
    - 94
    - 95
    - 96
    - 97
    - 98
    - 99
    -100
    -101
    -102
    -103
    -104
    -105
    -106
    -107
    -108
    -109
    -110
    -111
    -112
    -113
    -114
    -115
    -116
    -117
    -118
    -119
    -120
    -121
    -122
    -123
    -124
    -125
    -126
    -127
    -128
    -129
    -130
    -131
    -132
    -133
    -134
    -135
    -136
    -137
    -138
    -139
    -140
    -141
    -142
    -143
    -144
    -145
    -146
    -147
    -148
    -149
    -150
    -151
    -152
    -153
    -154
    -155
    -156
    -157
    -158
    -159
    -160
    -161
    -162
    -163
    -164
    -165
    -166
    -167
    -168
    -169
    -170
    -171
    -172
    -173
    -174
    -175
    -176
    -177
    -178
    -179
    -180
    -181
    -182
    -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
    -245
    -246
    -247
    -248
    -249
    -250
    -251
    -252
    -253
    -254
    -255
    -256
    -257
    -258
    -259
    -260
    -261
    -262
    -263
    -264
    -265
    -266
    -267
    -268
    -269
    -270
    -271
    -272
    -273
    -274
    -275
    -276
    -277
    -278
    -279
    -280
    -281
    -282
    -283
    -284
    -285
    -286
    -287
    -288
    -289
    -290
    -291
    -292
    -293
    -294
    -295
    -296
    -297
    -298
    -299
    -300
    -301
    -302
    -303
    -304
    -305
    -306
    -307
    -308
    -309
    -310
    -311
    -312
    -313
    -314
    -315
    -316
    -317
    -318
    -319
    -320
    -321
    -322
    -323
    -324
    -325
    -326
    -327
    -328
    -329
    -330
    -331
    -332
    -333
    -334
    -335
    -336
    -337
    -338
    -339
    -340
    -341
    -342
    -343
    -344
    -345
    -346
    -347
    -348
    -349
    -350
    -351
    -352
    -353
    -354
    -355
    -356
    -357
    -358
    -359
    -360
    -361
    -362
    -363
    -364
    -365
    -366
    -367
    -368
    -369
    -370
    -371
    -372
    -373
    -374
    -375
    -376
    -377
    -378
    -379
    -380
    -381
    -382
    -383
    -384
    -385
    -386
    -387
    -388
    -389
    -390
    -391
    -392
    -393
    -394
    -395
    -396
    -397
    -398
    -399
    -400
    -401
    -402
    -403
    -404
    -405
    -406
    -407
    -408
    -409
    -410
    -411
    -412
    -413
    -414
    -415
    -416
    -417
    -418
    -419
    -420
    -421
    -422
    -423
    -424
    -
    // Bitcoin Dev Kit
    -// Written in 2020 by Alekos Filini <alekos.filini@gmail.com>
    -//
    -// Copyright (c) 2020-2021 Bitcoin Dev Kit Developers
    -//
    -// This file is licensed under the Apache License, Version 2.0 <LICENSE-APACHE
    -// or http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
    -// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your option.
    -// You may not use this file except in accordance with one or both of these
    -// licenses.
    -
    -//! Electrum
    -//!
    -//! This module defines a [`Blockchain`] struct that wraps an [`electrum_client::Client`]
    -//! and implements the logic required to populate the wallet's [database](crate::database::Database) by
    -//! querying the inner client.
    -//!
    -//! ## Example
    -//!
    -//! ```no_run
    -//! # use bdk::blockchain::electrum::ElectrumBlockchain;
    -//! let client = electrum_client::Client::new("ssl://electrum.blockstream.info:50002")?;
    -//! let blockchain = ElectrumBlockchain::from(client);
    -//! # Ok::<(), bdk::Error>(())
    -//! ```
    -
    -use std::collections::{HashMap, HashSet};
    -use std::ops::Deref;
    -
    -#[allow(unused_imports)]
    -use log::{debug, error, info, trace};
    -
    -use bitcoin::{Transaction, Txid};
    -
    -use electrum_client::{Client, ConfigBuilder, ElectrumApi, Socks5Config};
    -
    -use super::script_sync::Request;
    -use super::*;
    -use crate::database::{BatchDatabase, Database};
    -use crate::error::Error;
    -use crate::{BlockTime, FeeRate};
    -
    -/// Wrapper over an Electrum Client that implements the required blockchain traits
    -///
    -/// ## Example
    -/// See the [`blockchain::electrum`](crate::blockchain::electrum) module for a usage example.
    -pub struct ElectrumBlockchain {
    -    client: Client,
    -    stop_gap: usize,
    +electrum.rs - source
    1
    +2
    +3
    +4
    +5
    +6
    +7
    +8
    +9
    +10
    +11
    +12
    +13
    +14
    +15
    +16
    +17
    +18
    +19
    +20
    +21
    +22
    +23
    +24
    +25
    +26
    +27
    +28
    +29
    +30
    +31
    +32
    +33
    +34
    +35
    +36
    +37
    +38
    +39
    +40
    +41
    +42
    +43
    +44
    +45
    +46
    +47
    +48
    +49
    +50
    +51
    +52
    +53
    +54
    +55
    +56
    +57
    +58
    +59
    +60
    +61
    +62
    +63
    +64
    +65
    +66
    +67
    +68
    +69
    +70
    +71
    +72
    +73
    +74
    +75
    +76
    +77
    +78
    +79
    +80
    +81
    +82
    +83
    +84
    +85
    +86
    +87
    +88
    +89
    +90
    +91
    +92
    +93
    +94
    +95
    +96
    +97
    +98
    +99
    +100
    +101
    +102
    +103
    +104
    +105
    +106
    +107
    +108
    +109
    +110
    +111
    +112
    +113
    +114
    +115
    +116
    +117
    +118
    +119
    +120
    +121
    +122
    +123
    +124
    +125
    +126
    +127
    +128
    +129
    +130
    +131
    +132
    +133
    +134
    +135
    +136
    +137
    +138
    +139
    +140
    +141
    +142
    +143
    +144
    +145
    +146
    +147
    +148
    +149
    +150
    +151
    +152
    +153
    +154
    +155
    +156
    +157
    +158
    +159
    +160
    +161
    +162
    +163
    +164
    +165
    +166
    +167
    +168
    +169
    +170
    +171
    +172
    +173
    +174
    +175
    +176
    +177
    +178
    +179
    +180
    +181
    +182
    +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
    +245
    +246
    +247
    +248
    +249
    +250
    +251
    +252
    +253
    +254
    +255
    +256
    +257
    +258
    +259
    +260
    +261
    +262
    +263
    +264
    +265
    +266
    +267
    +268
    +269
    +270
    +271
    +272
    +273
    +274
    +275
    +276
    +277
    +278
    +279
    +280
    +281
    +282
    +283
    +284
    +285
    +286
    +287
    +288
    +289
    +290
    +291
    +292
    +293
    +294
    +295
    +296
    +297
    +298
    +299
    +300
    +301
    +302
    +303
    +304
    +305
    +306
    +307
    +308
    +309
    +310
    +311
    +312
    +313
    +314
    +315
    +316
    +317
    +318
    +319
    +320
    +321
    +322
    +323
    +324
    +325
    +326
    +327
    +328
    +329
    +330
    +331
    +332
    +333
    +334
    +335
    +336
    +337
    +338
    +339
    +340
    +341
    +342
    +343
    +344
    +345
    +346
    +347
    +348
    +349
    +350
    +351
    +352
    +353
    +354
    +355
    +356
    +357
    +358
    +359
    +360
    +361
    +362
    +363
    +364
    +365
    +366
    +367
    +368
    +369
    +370
    +371
    +372
    +373
    +374
    +375
    +376
    +377
    +378
    +379
    +380
    +381
    +382
    +383
    +384
    +385
    +386
    +387
    +388
    +389
    +390
    +391
    +392
    +393
    +394
    +395
    +396
    +397
    +398
    +399
    +400
    +401
    +402
    +403
    +404
    +405
    +406
    +407
    +408
    +409
    +410
    +411
    +412
    +413
    +414
    +415
    +416
    +417
    +418
    +419
    +420
    +421
    +422
    +423
    +424
    +
    // Bitcoin Dev Kit
    +// Written in 2020 by Alekos Filini <alekos.filini@gmail.com>
    +//
    +// Copyright (c) 2020-2021 Bitcoin Dev Kit Developers
    +//
    +// This file is licensed under the Apache License, Version 2.0 <LICENSE-APACHE
    +// or http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
    +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your option.
    +// You may not use this file except in accordance with one or both of these
    +// licenses.
    +
    +//! Electrum
    +//!
    +//! This module defines a [`Blockchain`] struct that wraps an [`electrum_client::Client`]
    +//! and implements the logic required to populate the wallet's [database](crate::database::Database) by
    +//! querying the inner client.
    +//!
    +//! ## Example
    +//!
    +//! ```no_run
    +//! # use bdk::blockchain::electrum::ElectrumBlockchain;
    +//! let client = electrum_client::Client::new("ssl://electrum.blockstream.info:50002")?;
    +//! let blockchain = ElectrumBlockchain::from(client);
    +//! # Ok::<(), bdk::Error>(())
    +//! ```
    +
    +use std::collections::{HashMap, HashSet};
    +use std::ops::Deref;
    +
    +#[allow(unused_imports)]
    +use log::{debug, error, info, trace};
    +
    +use bitcoin::{Transaction, Txid};
    +
    +use electrum_client::{Client, ConfigBuilder, ElectrumApi, Socks5Config};
    +
    +use super::script_sync::Request;
    +use super::*;
    +use crate::database::{BatchDatabase, Database};
    +use crate::error::Error;
    +use crate::{BlockTime, FeeRate};
    +
    +/// Wrapper over an Electrum Client that implements the required blockchain traits
    +///
    +/// ## Example
    +/// See the [`blockchain::electrum`](crate::blockchain::electrum) module for a usage example.
    +pub struct ElectrumBlockchain {
    +    client: Client,
    +    stop_gap: usize,
     }
     
    -impl std::convert::From<Client> for ElectrumBlockchain {
    -    fn from(client: Client) -> Self {
    -        ElectrumBlockchain {
    -            client,
    -            stop_gap: 20,
    +impl std::convert::From<Client> for ElectrumBlockchain {
    +    fn from(client: Client) -> Self {
    +        ElectrumBlockchain {
    +            client,
    +            stop_gap: 20,
             }
         }
     }
     
    -impl Blockchain for ElectrumBlockchain {
    -    fn get_capabilities(&self) -> HashSet<Capability> {
    +impl Blockchain for ElectrumBlockchain {
    +    fn get_capabilities(&self) -> HashSet<Capability> {
             vec![
    -            Capability::FullHistory,
    -            Capability::GetAnyTx,
    -            Capability::AccurateFees,
    +            Capability::FullHistory,
    +            Capability::GetAnyTx,
    +            Capability::AccurateFees,
             ]
    -        .into_iter()
    -        .collect()
    +        .into_iter()
    +        .collect()
         }
     
    -    fn broadcast(&self, tx: &Transaction) -> Result<(), Error> {
    -        Ok(self.client.transaction_broadcast(tx).map(|_| ())?)
    +    fn broadcast(&self, tx: &Transaction) -> Result<(), Error> {
    +        Ok(self.client.transaction_broadcast(tx).map(|_| ())?)
         }
     
    -    fn estimate_fee(&self, target: usize) -> Result<FeeRate, Error> {
    -        Ok(FeeRate::from_btc_per_kvb(
    -            self.client.estimate_fee(target)? as f32
    +    fn estimate_fee(&self, target: usize) -> Result<FeeRate, Error> {
    +        Ok(FeeRate::from_btc_per_kvb(
    +            self.client.estimate_fee(target)? as f32
             ))
         }
     }
     
    -impl Deref for ElectrumBlockchain {
    -    type Target = Client;
    +impl Deref for ElectrumBlockchain {
    +    type Target = Client;
     
    -    fn deref(&self) -> &Self::Target {
    -        &self.client
    +    fn deref(&self) -> &Self::Target {
    +        &self.client
         }
     }
     
    -impl StatelessBlockchain for ElectrumBlockchain {}
    +impl StatelessBlockchain for ElectrumBlockchain {}
     
    -impl GetHeight for ElectrumBlockchain {
    -    fn get_height(&self) -> Result<u32, Error> {
    -        // TODO: unsubscribe when added to the client, or is there a better call to use here?
    +impl GetHeight for ElectrumBlockchain {
    +    fn get_height(&self) -> Result<u32, Error> {
    +        // TODO: unsubscribe when added to the client, or is there a better call to use here?
     
    -        Ok(self
    -            .client
    -            .block_headers_subscribe()
    -            .map(|data| data.height as u32)?)
    +        Ok(self
    +            .client
    +            .block_headers_subscribe()
    +            .map(|data| data.height as u32)?)
         }
     }
     
    -impl GetTx for ElectrumBlockchain {
    -    fn get_tx(&self, txid: &Txid) -> Result<Option<Transaction>, Error> {
    -        Ok(self.client.transaction_get(txid).map(Option::Some)?)
    +impl GetTx for ElectrumBlockchain {
    +    fn get_tx(&self, txid: &Txid) -> Result<Option<Transaction>, Error> {
    +        Ok(self.client.transaction_get(txid).map(Option::Some)?)
         }
     }
     
    -impl GetBlockHash for ElectrumBlockchain {
    -    fn get_block_hash(&self, height: u64) -> Result<BlockHash, Error> {
    -        let block_header = self.client.block_header(height as usize)?;
    -        Ok(block_header.block_hash())
    +impl GetBlockHash for ElectrumBlockchain {
    +    fn get_block_hash(&self, height: u64) -> Result<BlockHash, Error> {
    +        let block_header = self.client.block_header(height as usize)?;
    +        Ok(block_header.block_hash())
         }
     }
     
    -impl WalletSync for ElectrumBlockchain {
    -    fn wallet_setup<D: BatchDatabase>(
    +impl WalletSync for ElectrumBlockchain {
    +    fn wallet_setup<D: BatchDatabase>(
             &self,
    -        database: &mut D,
    -        _progress_update: Box<dyn Progress>,
    -    ) -> Result<(), Error> {
    -        let mut request = script_sync::start(database, self.stop_gap)?;
    -        let mut block_times = HashMap::<u32, u32>::new();
    -        let mut txid_to_height = HashMap::<Txid, u32>::new();
    -        let mut tx_cache = TxCache::new(database, &self.client);
    -
    -        // Set chunk_size to the smallest value capable of finding a gap greater than stop_gap.
    -        let chunk_size = self.stop_gap + 1;
    -
    -        // The electrum server has been inconsistent somehow in its responses during sync. For
    -        // example, we do a batch request of transactions and the response contains less
    -        // tranascations than in the request. This should never happen but we don't want to panic.
    -        let electrum_goof = || Error::Generic("electrum server misbehaving".to_string());
    -
    -        let batch_update = loop {
    -            request = match request {
    -                Request::Script(script_req) => {
    -                    let scripts = script_req.request().take(chunk_size);
    -                    let txids_per_script: Vec<Vec<_>> = self
    -                        .client
    -                        .batch_script_get_history(scripts)
    -                        .map_err(Error::Electrum)?
    -                        .into_iter()
    -                        .map(|txs| {
    -                            txs.into_iter()
    -                                .map(|tx| {
    -                                    let tx_height = match tx.height {
    -                                        none if none <= 0 => None,
    -                                        height => {
    -                                            txid_to_height.insert(tx.tx_hash, height as u32);
    -                                            Some(height as u32)
    +        database: &mut D,
    +        _progress_update: Box<dyn Progress>,
    +    ) -> Result<(), Error> {
    +        let mut request = script_sync::start(database, self.stop_gap)?;
    +        let mut block_times = HashMap::<u32, u32>::new();
    +        let mut txid_to_height = HashMap::<Txid, u32>::new();
    +        let mut tx_cache = TxCache::new(database, &self.client);
    +
    +        // Set chunk_size to the smallest value capable of finding a gap greater than stop_gap.
    +        let chunk_size = self.stop_gap + 1;
    +
    +        // The electrum server has been inconsistent somehow in its responses during sync. For
    +        // example, we do a batch request of transactions and the response contains less
    +        // tranascations than in the request. This should never happen but we don't want to panic.
    +        let electrum_goof = || Error::Generic("electrum server misbehaving".to_string());
    +
    +        let batch_update = loop {
    +            request = match request {
    +                Request::Script(script_req) => {
    +                    let scripts = script_req.request().take(chunk_size);
    +                    let txids_per_script: Vec<Vec<_>> = self
    +                        .client
    +                        .batch_script_get_history(scripts)
    +                        .map_err(Error::Electrum)?
    +                        .into_iter()
    +                        .map(|txs| {
    +                            txs.into_iter()
    +                                .map(|tx| {
    +                                    let tx_height = match tx.height {
    +                                        none if none <= 0 => None,
    +                                        height => {
    +                                            txid_to_height.insert(tx.tx_hash, height as u32);
    +                                            Some(height as u32)
                                             }
                                         };
    -                                    (tx.tx_hash, tx_height)
    +                                    (tx.tx_hash, tx_height)
                                     })
    -                                .collect()
    +                                .collect()
                             })
    -                        .collect();
    -
    -                    script_req.satisfy(txids_per_script)?
    -                }
    -
    -                Request::Conftime(conftime_req) => {
    -                    // collect up to chunk_size heights to fetch from electrum
    -                    let needs_block_height = conftime_req
    -                        .request()
    -                        .filter_map(|txid| txid_to_height.get(txid).cloned())
    -                        .filter(|height| block_times.get(height).is_none())
    -                        .take(chunk_size)
    -                        .collect::<HashSet<u32>>();
    -
    -                    let new_block_headers = self
    -                        .client
    -                        .batch_block_header(needs_block_height.iter().cloned())?;
    -
    -                    for (height, header) in needs_block_height.into_iter().zip(new_block_headers) {
    -                        block_times.insert(height, header.time);
    +                        .collect();
    +
    +                    script_req.satisfy(txids_per_script)?
    +                }
    +
    +                Request::Conftime(conftime_req) => {
    +                    // collect up to chunk_size heights to fetch from electrum
    +                    let needs_block_height = conftime_req
    +                        .request()
    +                        .filter_map(|txid| txid_to_height.get(txid).cloned())
    +                        .filter(|height| block_times.get(height).is_none())
    +                        .take(chunk_size)
    +                        .collect::<HashSet<u32>>();
    +
    +                    let new_block_headers = self
    +                        .client
    +                        .batch_block_header(needs_block_height.iter().cloned())?;
    +
    +                    for (height, header) in needs_block_height.into_iter().zip(new_block_headers) {
    +                        block_times.insert(height, header.time);
                         }
     
    -                    let conftimes = conftime_req
    -                        .request()
    -                        .take(chunk_size)
    -                        .map(|txid| {
    -                            let confirmation_time = txid_to_height
    -                                .get(txid)
    -                                .map(|height| {
    -                                    let timestamp =
    -                                        *block_times.get(height).ok_or_else(electrum_goof)?;
    -                                    Result::<_, Error>::Ok(BlockTime {
    -                                        height: *height,
    -                                        timestamp: timestamp.into(),
    +                    let conftimes = conftime_req
    +                        .request()
    +                        .take(chunk_size)
    +                        .map(|txid| {
    +                            let confirmation_time = txid_to_height
    +                                .get(txid)
    +                                .map(|height| {
    +                                    let timestamp =
    +                                        *block_times.get(height).ok_or_else(electrum_goof)?;
    +                                    Result::<_, Error>::Ok(BlockTime {
    +                                        height: *height,
    +                                        timestamp: timestamp.into(),
                                         })
                                     })
    -                                .transpose()?;
    -                            Ok(confirmation_time)
    +                                .transpose()?;
    +                            Ok(confirmation_time)
                             })
    -                        .collect::<Result<_, Error>>()?;
    -
    -                    conftime_req.satisfy(conftimes)?
    -                }
    -                Request::Tx(tx_req) => {
    -                    let needs_full = tx_req.request().take(chunk_size);
    -                    tx_cache.save_txs(needs_full.clone())?;
    -                    let full_transactions = needs_full
    -                        .map(|txid| tx_cache.get(*txid).ok_or_else(electrum_goof))
    -                        .collect::<Result<Vec<_>, _>>()?;
    -                    let input_txs = full_transactions.iter().flat_map(|tx| {
    -                        tx.input
    -                            .iter()
    -                            .filter(|input| !input.previous_output.is_null())
    -                            .map(|input| &input.previous_output.txid)
    +                        .collect::<Result<_, Error>>()?;
    +
    +                    conftime_req.satisfy(conftimes)?
    +                }
    +                Request::Tx(tx_req) => {
    +                    let needs_full = tx_req.request().take(chunk_size);
    +                    tx_cache.save_txs(needs_full.clone())?;
    +                    let full_transactions = needs_full
    +                        .map(|txid| tx_cache.get(*txid).ok_or_else(electrum_goof))
    +                        .collect::<Result<Vec<_>, _>>()?;
    +                    let input_txs = full_transactions.iter().flat_map(|tx| {
    +                        tx.input
    +                            .iter()
    +                            .filter(|input| !input.previous_output.is_null())
    +                            .map(|input| &input.previous_output.txid)
                         });
    -                    tx_cache.save_txs(input_txs)?;
    -
    -                    let full_details = full_transactions
    -                        .into_iter()
    -                        .map(|tx| {
    -                            let mut input_index = 0usize;
    -                            let prev_outputs = tx
    -                                .input
    -                                .iter()
    -                                .map(|input| {
    -                                    if input.previous_output.is_null() {
    -                                        return Ok(None);
    +                    tx_cache.save_txs(input_txs)?;
    +
    +                    let full_details = full_transactions
    +                        .into_iter()
    +                        .map(|tx| {
    +                            let mut input_index = 0usize;
    +                            let prev_outputs = tx
    +                                .input
    +                                .iter()
    +                                .map(|input| {
    +                                    if input.previous_output.is_null() {
    +                                        return Ok(None);
                                         }
    -                                    let prev_tx = tx_cache
    -                                        .get(input.previous_output.txid)
    -                                        .ok_or_else(electrum_goof)?;
    -                                    let txout = prev_tx
    -                                        .output
    -                                        .get(input.previous_output.vout as usize)
    -                                        .ok_or_else(electrum_goof)?;
    -                                    input_index += 1;
    -                                    Ok(Some(txout.clone()))
    +                                    let prev_tx = tx_cache
    +                                        .get(input.previous_output.txid)
    +                                        .ok_or_else(electrum_goof)?;
    +                                    let txout = prev_tx
    +                                        .output
    +                                        .get(input.previous_output.vout as usize)
    +                                        .ok_or_else(electrum_goof)?;
    +                                    input_index += 1;
    +                                    Ok(Some(txout.clone()))
                                     })
    -                                .collect::<Result<Vec<_>, Error>>()?;
    -                            Ok((prev_outputs, tx))
    +                                .collect::<Result<Vec<_>, Error>>()?;
    +                            Ok((prev_outputs, tx))
                             })
    -                        .collect::<Result<Vec<_>, Error>>()?;
    +                        .collect::<Result<Vec<_>, Error>>()?;
     
    -                    tx_req.satisfy(full_details)?
    -                }
    -                Request::Finish(batch_update) => break batch_update,
    +                    tx_req.satisfy(full_details)?
    +                }
    +                Request::Finish(batch_update) => break batch_update,
                 }
             };
     
    -        database.commit_batch(batch_update)?;
    +        database.commit_batch(batch_update)?;
             Ok(())
         }
     }
     
    -struct TxCache<'a, 'b, D> {
    -    db: &'a D,
    -    client: &'b Client,
    -    cache: HashMap<Txid, Transaction>,
    +struct TxCache<'a, 'b, D> {
    +    db: &'a D,
    +    client: &'b Client,
    +    cache: HashMap<Txid, Transaction>,
     }
     
    -impl<'a, 'b, D: Database> TxCache<'a, 'b, D> {
    -    fn new(db: &'a D, client: &'b Client) -> Self {
    -        TxCache {
    -            db,
    -            client,
    -            cache: HashMap::default(),
    +impl<'a, 'b, D: Database> TxCache<'a, 'b, D> {
    +    fn new(db: &'a D, client: &'b Client) -> Self {
    +        TxCache {
    +            db,
    +            client,
    +            cache: HashMap::default(),
             }
         }
    -    fn save_txs<'c>(&mut self, txids: impl Iterator<Item = &'c Txid>) -> Result<(), Error> {
    -        let mut need_fetch = vec![];
    -        for txid in txids {
    -            if self.cache.get(txid).is_some() {
    +    fn save_txs<'c>(&mut self, txids: impl Iterator<Item = &'c Txid>) -> Result<(), Error> {
    +        let mut need_fetch = vec![];
    +        for txid in txids {
    +            if self.cache.get(txid).is_some() {
                     continue;
    -            } else if let Some(transaction) = self.db.get_raw_tx(txid)? {
    -                self.cache.insert(*txid, transaction);
    -            } else {
    -                need_fetch.push(txid);
    +            } else if let Some(transaction) = self.db.get_raw_tx(txid)? {
    +                self.cache.insert(*txid, transaction);
    +            } else {
    +                need_fetch.push(txid);
                 }
             }
     
    -        if !need_fetch.is_empty() {
    -            let txs = self
    -                .client
    -                .batch_transaction_get(need_fetch.clone())
    -                .map_err(Error::Electrum)?;
    -            for (tx, _txid) in txs.into_iter().zip(need_fetch) {
    -                debug_assert_eq!(*_txid, tx.txid());
    -                self.cache.insert(tx.txid(), tx);
    +        if !need_fetch.is_empty() {
    +            let txs = self
    +                .client
    +                .batch_transaction_get(need_fetch.clone())
    +                .map_err(Error::Electrum)?;
    +            for (tx, _txid) in txs.into_iter().zip(need_fetch) {
    +                debug_assert_eq!(*_txid, tx.txid());
    +                self.cache.insert(tx.txid(), tx);
                 }
             }
     
             Ok(())
         }
     
    -    fn get(&self, txid: Txid) -> Option<Transaction> {
    -        self.cache.get(&txid).map(Clone::clone)
    +    fn get(&self, txid: Txid) -> Option<Transaction> {
    +        self.cache.get(&txid).map(Clone::clone)
         }
     }
     
    -/// Configuration for an [`ElectrumBlockchain`]
    -#[derive(Debug, serde::Deserialize, serde::Serialize, Clone, PartialEq, Eq)]
    -pub struct ElectrumBlockchainConfig {
    -    /// URL of the Electrum server (such as ElectrumX, Esplora, BWT) may start with `ssl://` or `tcp://` and include a port
    -    ///
    -    /// eg. `ssl://electrum.blockstream.info:60002`
    -    pub url: String,
    -    /// URL of the socks5 proxy server or a Tor service
    -    pub socks5: Option<String>,
    -    /// Request retry count
    -    pub retry: u8,
    -    /// Request timeout (seconds)
    -    pub timeout: Option<u8>,
    -    /// Stop searching addresses for transactions after finding an unused gap of this length
    -    pub stop_gap: usize,
    +/// Configuration for an [`ElectrumBlockchain`]
    +#[derive(Debug, serde::Deserialize, serde::Serialize, Clone, PartialEq, Eq)]
    +pub struct ElectrumBlockchainConfig {
    +    /// URL of the Electrum server (such as ElectrumX, Esplora, BWT) may start with `ssl://` or `tcp://` and include a port
    +    ///
    +    /// eg. `ssl://electrum.blockstream.info:60002`
    +    pub url: String,
    +    /// URL of the socks5 proxy server or a Tor service
    +    pub socks5: Option<String>,
    +    /// Request retry count
    +    pub retry: u8,
    +    /// Request timeout (seconds)
    +    pub timeout: Option<u8>,
    +    /// Stop searching addresses for transactions after finding an unused gap of this length
    +    pub stop_gap: usize,
     }
     
    -impl ConfigurableBlockchain for ElectrumBlockchain {
    -    type Config = ElectrumBlockchainConfig;
    +impl ConfigurableBlockchain for ElectrumBlockchain {
    +    type Config = ElectrumBlockchainConfig;
     
    -    fn from_config(config: &Self::Config) -> Result<Self, Error> {
    -        let socks5 = config.socks5.as_ref().map(Socks5Config::new);
    -        let electrum_config = ConfigBuilder::new()
    -            .retry(config.retry)
    -            .timeout(config.timeout)?
    -            .socks5(socks5)?
    -            .build();
    +    fn from_config(config: &Self::Config) -> Result<Self, Error> {
    +        let socks5 = config.socks5.as_ref().map(Socks5Config::new);
    +        let electrum_config = ConfigBuilder::new()
    +            .retry(config.retry)
    +            .timeout(config.timeout)?
    +            .socks5(socks5)?
    +            .build();
     
    -        Ok(ElectrumBlockchain {
    -            client: Client::from_config(config.url.as_str(), electrum_config)?,
    -            stop_gap: config.stop_gap,
    +        Ok(ElectrumBlockchain {
    +            client: Client::from_config(config.url.as_str(), electrum_config)?,
    +            stop_gap: config.stop_gap,
             })
         }
     }
     
    -#[cfg(test)]
    -#[cfg(feature = "test-electrum")]
    -mod test {
    -    use std::sync::Arc;
    +#[cfg(test)]
    +#[cfg(feature = "test-electrum")]
    +mod test {
    +    use std::sync::Arc;
     
    -    use super::*;
    -    use crate::database::MemoryDatabase;
    -    use crate::testutils::blockchain_tests::TestClient;
    -    use crate::testutils::configurable_blockchain_tests::ConfigurableBlockchainTester;
    -    use crate::wallet::{AddressIndex, Wallet};
    +    use super::*;
    +    use crate::database::MemoryDatabase;
    +    use crate::testutils::blockchain_tests::TestClient;
    +    use crate::testutils::configurable_blockchain_tests::ConfigurableBlockchainTester;
    +    use crate::wallet::{AddressIndex, Wallet};
     
    -    crate::bdk_blockchain_tests! {
    -        fn test_instance(test_client: &TestClient) -> ElectrumBlockchain {
    -            ElectrumBlockchain::from(Client::new(&test_client.electrsd.electrum_url).unwrap())
    +    crate::bdk_blockchain_tests! {
    +        fn test_instance(test_client: &TestClient) -> ElectrumBlockchain {
    +            ElectrumBlockchain::from(Client::new(&test_client.electrsd.electrum_url).unwrap())
             }
         }
     
    -    fn get_factory() -> (TestClient, Arc<ElectrumBlockchain>) {
    -        let test_client = TestClient::default();
    +    fn get_factory() -> (TestClient, Arc<ElectrumBlockchain>) {
    +        let test_client = TestClient::default();
     
    -        let factory = Arc::new(ElectrumBlockchain::from(
    -            Client::new(&test_client.electrsd.electrum_url).unwrap(),
    +        let factory = Arc::new(ElectrumBlockchain::from(
    +            Client::new(&test_client.electrsd.electrum_url).unwrap(),
             ));
     
    -        (test_client, factory)
    +        (test_client, factory)
         }
     
    -    #[test]
    -    fn test_electrum_blockchain_factory() {
    -        let (_test_client, factory) = get_factory();
    +    #[test]
    +    fn test_electrum_blockchain_factory() {
    +        let (_test_client, factory) = get_factory();
     
    -        let a = factory.build("aaaaaa", None).unwrap();
    -        let b = factory.build("bbbbbb", None).unwrap();
    +        let a = factory.build("aaaaaa", None).unwrap();
    +        let b = factory.build("bbbbbb", None).unwrap();
     
             assert_eq!(
    -            a.client.block_headers_subscribe().unwrap().height,
    -            b.client.block_headers_subscribe().unwrap().height
    +            a.client.block_headers_subscribe().unwrap().height,
    +            b.client.block_headers_subscribe().unwrap().height
             );
         }
     
    -    #[test]
    -    fn test_electrum_blockchain_factory_sync_wallet() {
    -        let (mut test_client, factory) = get_factory();
    +    #[test]
    +    fn test_electrum_blockchain_factory_sync_wallet() {
    +        let (mut test_client, factory) = get_factory();
     
    -        let db = MemoryDatabase::new();
    -        let wallet = Wallet::new(
    +        let db = MemoryDatabase::new();
    +        let wallet = Wallet::new(
                 "wpkh(L5EZftvrYaSudiozVRzTqLcHLNDoVn7H5HSfM9BAN6tMJX8oTWz6)",
                 None,
    -            bitcoin::Network::Regtest,
    -            db,
    +            bitcoin::Network::Regtest,
    +            db,
             )
    -        .unwrap();
    +        .unwrap();
     
    -        let address = wallet.get_address(AddressIndex::New).unwrap();
    +        let address = wallet.get_address(AddressIndex::New).unwrap();
     
    -        let tx = testutils! {
    -            @tx ( (@addr address.address) => 50_000 )
    +        let tx = testutils! {
    +            @tx ( (@addr address.address) => 50_000 )
             };
    -        test_client.receive(tx);
    +        test_client.receive(tx);
     
    -        factory
    -            .sync_wallet(&wallet, None, Default::default())
    -            .unwrap();
    +        factory
    +            .sync_wallet(&wallet, None, Default::default())
    +            .unwrap();
     
    -        assert_eq!(wallet.get_balance().unwrap().untrusted_pending, 50_000);
    +        assert_eq!(wallet.get_balance().unwrap().untrusted_pending, 50_000);
         }
     
    -    #[test]
    -    fn test_electrum_with_variable_configs() {
    -        struct ElectrumTester;
    +    #[test]
    +    fn test_electrum_with_variable_configs() {
    +        struct ElectrumTester;
     
    -        impl ConfigurableBlockchainTester<ElectrumBlockchain> for ElectrumTester {
    -            const BLOCKCHAIN_NAME: &'static str = "Electrum";
    +        impl ConfigurableBlockchainTester<ElectrumBlockchain> for ElectrumTester {
    +            const BLOCKCHAIN_NAME: &'static str = "Electrum";
     
    -            fn config_with_stop_gap(
    +            fn config_with_stop_gap(
                     &self,
    -                test_client: &mut TestClient,
    -                stop_gap: usize,
    -            ) -> Option<ElectrumBlockchainConfig> {
    -                Some(ElectrumBlockchainConfig {
    -                    url: test_client.electrsd.electrum_url.clone(),
    -                    socks5: None,
    -                    retry: 0,
    -                    timeout: None,
    -                    stop_gap: stop_gap,
    +                test_client: &mut TestClient,
    +                stop_gap: usize,
    +            ) -> Option<ElectrumBlockchainConfig> {
    +                Some(ElectrumBlockchainConfig {
    +                    url: test_client.electrsd.electrum_url.clone(),
    +                    socks5: None,
    +                    retry: 0,
    +                    timeout: None,
    +                    stop_gap: stop_gap,
                     })
                 }
             }
     
    -        ElectrumTester.run();
    +        ElectrumTester.run();
         }
     }
     
    -
    - \ No newline at end of file +
    \ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/src/bdk/blockchain/esplora/blocking.rs.html b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/src/bdk/blockchain/esplora/blocking.rs.html index bf23bbbe25..339e5ad55a 100644 --- a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/src/bdk/blockchain/esplora/blocking.rs.html +++ b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/src/bdk/blockchain/esplora/blocking.rs.html @@ -1,486 +1,479 @@ -blocking.rs - source - -
      1
    -  2
    -  3
    -  4
    -  5
    -  6
    -  7
    -  8
    -  9
    - 10
    - 11
    - 12
    - 13
    - 14
    - 15
    - 16
    - 17
    - 18
    - 19
    - 20
    - 21
    - 22
    - 23
    - 24
    - 25
    - 26
    - 27
    - 28
    - 29
    - 30
    - 31
    - 32
    - 33
    - 34
    - 35
    - 36
    - 37
    - 38
    - 39
    - 40
    - 41
    - 42
    - 43
    - 44
    - 45
    - 46
    - 47
    - 48
    - 49
    - 50
    - 51
    - 52
    - 53
    - 54
    - 55
    - 56
    - 57
    - 58
    - 59
    - 60
    - 61
    - 62
    - 63
    - 64
    - 65
    - 66
    - 67
    - 68
    - 69
    - 70
    - 71
    - 72
    - 73
    - 74
    - 75
    - 76
    - 77
    - 78
    - 79
    - 80
    - 81
    - 82
    - 83
    - 84
    - 85
    - 86
    - 87
    - 88
    - 89
    - 90
    - 91
    - 92
    - 93
    - 94
    - 95
    - 96
    - 97
    - 98
    - 99
    -100
    -101
    -102
    -103
    -104
    -105
    -106
    -107
    -108
    -109
    -110
    -111
    -112
    -113
    -114
    -115
    -116
    -117
    -118
    -119
    -120
    -121
    -122
    -123
    -124
    -125
    -126
    -127
    -128
    -129
    -130
    -131
    -132
    -133
    -134
    -135
    -136
    -137
    -138
    -139
    -140
    -141
    -142
    -143
    -144
    -145
    -146
    -147
    -148
    -149
    -150
    -151
    -152
    -153
    -154
    -155
    -156
    -157
    -158
    -159
    -160
    -161
    -162
    -163
    -164
    -165
    -166
    -167
    -168
    -169
    -170
    -171
    -172
    -173
    -174
    -175
    -176
    -177
    -178
    -179
    -180
    -181
    -182
    -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
    -
    // Bitcoin Dev Kit
    -// Written in 2020 by Alekos Filini <alekos.filini@gmail.com>
    -//
    -// Copyright (c) 2020-2021 Bitcoin Dev Kit Developers
    -//
    -// This file is licensed under the Apache License, Version 2.0 <LICENSE-APACHE
    -// or http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
    -// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your option.
    -// You may not use this file except in accordance with one or both of these
    -// licenses.
    -
    -//! Esplora by way of `ureq` HTTP client.
    -
    -use std::collections::{HashMap, HashSet};
    -
    -#[allow(unused_imports)]
    -use log::{debug, error, info, trace};
    -
    -use bitcoin::{Transaction, Txid};
    -
    -use esplora_client::{convert_fee_rate, BlockingClient, Builder, Tx};
    -
    -use crate::blockchain::*;
    -use crate::database::BatchDatabase;
    -use crate::error::Error;
    -use crate::FeeRate;
    -
    -/// Structure that implements the logic to sync with Esplora
    -///
    -/// ## Example
    -/// See the [`blockchain::esplora`](crate::blockchain::esplora) module for a usage example.
    -#[derive(Debug)]
    -pub struct EsploraBlockchain {
    -    url_client: BlockingClient,
    -    stop_gap: usize,
    -    concurrency: u8,
    +blocking.rs - source
    1
    +2
    +3
    +4
    +5
    +6
    +7
    +8
    +9
    +10
    +11
    +12
    +13
    +14
    +15
    +16
    +17
    +18
    +19
    +20
    +21
    +22
    +23
    +24
    +25
    +26
    +27
    +28
    +29
    +30
    +31
    +32
    +33
    +34
    +35
    +36
    +37
    +38
    +39
    +40
    +41
    +42
    +43
    +44
    +45
    +46
    +47
    +48
    +49
    +50
    +51
    +52
    +53
    +54
    +55
    +56
    +57
    +58
    +59
    +60
    +61
    +62
    +63
    +64
    +65
    +66
    +67
    +68
    +69
    +70
    +71
    +72
    +73
    +74
    +75
    +76
    +77
    +78
    +79
    +80
    +81
    +82
    +83
    +84
    +85
    +86
    +87
    +88
    +89
    +90
    +91
    +92
    +93
    +94
    +95
    +96
    +97
    +98
    +99
    +100
    +101
    +102
    +103
    +104
    +105
    +106
    +107
    +108
    +109
    +110
    +111
    +112
    +113
    +114
    +115
    +116
    +117
    +118
    +119
    +120
    +121
    +122
    +123
    +124
    +125
    +126
    +127
    +128
    +129
    +130
    +131
    +132
    +133
    +134
    +135
    +136
    +137
    +138
    +139
    +140
    +141
    +142
    +143
    +144
    +145
    +146
    +147
    +148
    +149
    +150
    +151
    +152
    +153
    +154
    +155
    +156
    +157
    +158
    +159
    +160
    +161
    +162
    +163
    +164
    +165
    +166
    +167
    +168
    +169
    +170
    +171
    +172
    +173
    +174
    +175
    +176
    +177
    +178
    +179
    +180
    +181
    +182
    +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
    +
    // Bitcoin Dev Kit
    +// Written in 2020 by Alekos Filini <alekos.filini@gmail.com>
    +//
    +// Copyright (c) 2020-2021 Bitcoin Dev Kit Developers
    +//
    +// This file is licensed under the Apache License, Version 2.0 <LICENSE-APACHE
    +// or http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
    +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your option.
    +// You may not use this file except in accordance with one or both of these
    +// licenses.
    +
    +//! Esplora by way of `ureq` HTTP client.
    +
    +use std::collections::{HashMap, HashSet};
    +
    +#[allow(unused_imports)]
    +use log::{debug, error, info, trace};
    +
    +use bitcoin::{Transaction, Txid};
    +
    +use esplora_client::{convert_fee_rate, BlockingClient, Builder, Tx};
    +
    +use crate::blockchain::*;
    +use crate::database::BatchDatabase;
    +use crate::error::Error;
    +use crate::FeeRate;
    +
    +/// Structure that implements the logic to sync with Esplora
    +///
    +/// ## Example
    +/// See the [`blockchain::esplora`](crate::blockchain::esplora) module for a usage example.
    +#[derive(Debug)]
    +pub struct EsploraBlockchain {
    +    url_client: BlockingClient,
    +    stop_gap: usize,
    +    concurrency: u8,
     }
     
    -impl EsploraBlockchain {
    -    /// Create a new instance of the client from a base URL and the `stop_gap`.
    -    pub fn new(base_url: &str, stop_gap: usize) -> Self {
    -        let url_client = Builder::new(base_url)
    -            .build_blocking()
    -            .expect("Should never fail with no proxy and timeout");
    +impl EsploraBlockchain {
    +    /// Create a new instance of the client from a base URL and the `stop_gap`.
    +    pub fn new(base_url: &str, stop_gap: usize) -> Self {
    +        let url_client = Builder::new(base_url)
    +            .build_blocking()
    +            .expect("Should never fail with no proxy and timeout");
     
    -        Self::from_client(url_client, stop_gap)
    +        Self::from_client(url_client, stop_gap)
         }
     
    -    /// Build a new instance given a client
    -    pub fn from_client(url_client: BlockingClient, stop_gap: usize) -> Self {
    -        EsploraBlockchain {
    -            url_client,
    -            concurrency: super::DEFAULT_CONCURRENT_REQUESTS,
    -            stop_gap,
    +    /// Build a new instance given a client
    +    pub fn from_client(url_client: BlockingClient, stop_gap: usize) -> Self {
    +        EsploraBlockchain {
    +            url_client,
    +            concurrency: super::DEFAULT_CONCURRENT_REQUESTS,
    +            stop_gap,
             }
         }
     
    -    /// Set the number of parallel requests the client can make.
    -    pub fn with_concurrency(mut self, concurrency: u8) -> Self {
    -        self.concurrency = concurrency;
    -        self
    -    }
    +    /// Set the number of parallel requests the client can make.
    +    pub fn with_concurrency(mut self, concurrency: u8) -> Self {
    +        self.concurrency = concurrency;
    +        self
    +    }
     }
     
    -impl Blockchain for EsploraBlockchain {
    -    fn get_capabilities(&self) -> HashSet<Capability> {
    +impl Blockchain for EsploraBlockchain {
    +    fn get_capabilities(&self) -> HashSet<Capability> {
             vec![
    -            Capability::FullHistory,
    -            Capability::GetAnyTx,
    -            Capability::AccurateFees,
    +            Capability::FullHistory,
    +            Capability::GetAnyTx,
    +            Capability::AccurateFees,
             ]
    -        .into_iter()
    -        .collect()
    +        .into_iter()
    +        .collect()
         }
     
    -    fn broadcast(&self, tx: &Transaction) -> Result<(), Error> {
    -        self.url_client.broadcast(tx)?;
    +    fn broadcast(&self, tx: &Transaction) -> Result<(), Error> {
    +        self.url_client.broadcast(tx)?;
             Ok(())
         }
     
    -    fn estimate_fee(&self, target: usize) -> Result<FeeRate, Error> {
    -        let estimates = self.url_client.get_fee_estimates()?;
    -        Ok(FeeRate::from_sat_per_vb(convert_fee_rate(
    -            target, estimates,
    +    fn estimate_fee(&self, target: usize) -> Result<FeeRate, Error> {
    +        let estimates = self.url_client.get_fee_estimates()?;
    +        Ok(FeeRate::from_sat_per_vb(convert_fee_rate(
    +            target, estimates,
             )?))
         }
     }
     
    -impl Deref for EsploraBlockchain {
    -    type Target = BlockingClient;
    +impl Deref for EsploraBlockchain {
    +    type Target = BlockingClient;
     
    -    fn deref(&self) -> &Self::Target {
    -        &self.url_client
    +    fn deref(&self) -> &Self::Target {
    +        &self.url_client
         }
     }
     
    -impl StatelessBlockchain for EsploraBlockchain {}
    +impl StatelessBlockchain for EsploraBlockchain {}
     
    -impl GetHeight for EsploraBlockchain {
    -    fn get_height(&self) -> Result<u32, Error> {
    -        Ok(self.url_client.get_height()?)
    +impl GetHeight for EsploraBlockchain {
    +    fn get_height(&self) -> Result<u32, Error> {
    +        Ok(self.url_client.get_height()?)
         }
     }
     
    -impl GetTx for EsploraBlockchain {
    -    fn get_tx(&self, txid: &Txid) -> Result<Option<Transaction>, Error> {
    -        Ok(self.url_client.get_tx(txid)?)
    +impl GetTx for EsploraBlockchain {
    +    fn get_tx(&self, txid: &Txid) -> Result<Option<Transaction>, Error> {
    +        Ok(self.url_client.get_tx(txid)?)
         }
     }
     
    -impl GetBlockHash for EsploraBlockchain {
    -    fn get_block_hash(&self, height: u64) -> Result<BlockHash, Error> {
    -        Ok(self.url_client.get_block_hash(height as u32)?)
    +impl GetBlockHash for EsploraBlockchain {
    +    fn get_block_hash(&self, height: u64) -> Result<BlockHash, Error> {
    +        Ok(self.url_client.get_block_hash(height as u32)?)
         }
     }
     
    -impl WalletSync for EsploraBlockchain {
    -    fn wallet_setup<D: BatchDatabase>(
    +impl WalletSync for EsploraBlockchain {
    +    fn wallet_setup<D: BatchDatabase>(
             &self,
    -        database: &mut D,
    -        _progress_update: Box<dyn Progress>,
    -    ) -> Result<(), Error> {
    -        use crate::blockchain::script_sync::Request;
    -        let mut request = script_sync::start(database, self.stop_gap)?;
    -        let mut tx_index: HashMap<Txid, Tx> = HashMap::new();
    -        let batch_update = loop {
    -            request = match request {
    -                Request::Script(script_req) => {
    -                    let scripts = script_req
    -                        .request()
    -                        .take(self.concurrency as usize)
    -                        .cloned();
    -
    -                    let mut handles = vec![];
    -                    for script in scripts {
    -                        let client = self.url_client.clone();
    -                        // make each request in its own thread.
    -                        handles.push(std::thread::spawn(move || {
    -                            let mut related_txs: Vec<Tx> = client.scripthash_txs(&script, None)?;
    -
    -                            let n_confirmed =
    -                                related_txs.iter().filter(|tx| tx.status.confirmed).count();
    -                            // esplora pages on 25 confirmed transactions. If there's 25 or more we
    -                            // keep requesting to see if there's more.
    -                            if n_confirmed >= 25 {
    -                                loop {
    -                                    let new_related_txs: Vec<Tx> = client.scripthash_txs(
    -                                        &script,
    -                                        Some(related_txs.last().unwrap().txid),
    +        database: &mut D,
    +        _progress_update: Box<dyn Progress>,
    +    ) -> Result<(), Error> {
    +        use crate::blockchain::script_sync::Request;
    +        let mut request = script_sync::start(database, self.stop_gap)?;
    +        let mut tx_index: HashMap<Txid, Tx> = HashMap::new();
    +        let batch_update = loop {
    +            request = match request {
    +                Request::Script(script_req) => {
    +                    let scripts = script_req
    +                        .request()
    +                        .take(self.concurrency as usize)
    +                        .cloned();
    +
    +                    let mut handles = vec![];
    +                    for script in scripts {
    +                        let client = self.url_client.clone();
    +                        // make each request in its own thread.
    +                        handles.push(std::thread::spawn(move || {
    +                            let mut related_txs: Vec<Tx> = client.scripthash_txs(&script, None)?;
    +
    +                            let n_confirmed =
    +                                related_txs.iter().filter(|tx| tx.status.confirmed).count();
    +                            // esplora pages on 25 confirmed transactions. If there's 25 or more we
    +                            // keep requesting to see if there's more.
    +                            if n_confirmed >= 25 {
    +                                loop {
    +                                    let new_related_txs: Vec<Tx> = client.scripthash_txs(
    +                                        &script,
    +                                        Some(related_txs.last().unwrap().txid),
                                         )?;
    -                                    let n = new_related_txs.len();
    -                                    related_txs.extend(new_related_txs);
    -                                    // we've reached the end
    -                                    if n < 25 {
    +                                    let n = new_related_txs.len();
    +                                    related_txs.extend(new_related_txs);
    +                                    // we've reached the end
    +                                    if n < 25 {
                                             break;
                                         }
                                     }
                                 }
    -                            Result::<_, Error>::Ok(related_txs)
    +                            Result::<_, Error>::Ok(related_txs)
                             }));
                         }
     
    -                    let txs_per_script: Vec<Vec<Tx>> = handles
    -                        .into_iter()
    -                        .map(|handle| handle.join().unwrap())
    -                        .collect::<Result<_, _>>()?;
    -                    let mut satisfaction = vec![];
    -
    -                    for txs in txs_per_script {
    -                        satisfaction.push(
    -                            txs.iter()
    -                                .map(|tx| (tx.txid, tx.status.block_height))
    -                                .collect(),
    +                    let txs_per_script: Vec<Vec<Tx>> = handles
    +                        .into_iter()
    +                        .map(|handle| handle.join().unwrap())
    +                        .collect::<Result<_, _>>()?;
    +                    let mut satisfaction = vec![];
    +
    +                    for txs in txs_per_script {
    +                        satisfaction.push(
    +                            txs.iter()
    +                                .map(|tx| (tx.txid, tx.status.block_height))
    +                                .collect(),
                             );
    -                        for tx in txs {
    -                            tx_index.insert(tx.txid, tx);
    +                        for tx in txs {
    +                            tx_index.insert(tx.txid, tx);
                             }
                         }
     
    -                    script_req.satisfy(satisfaction)?
    -                }
    -                Request::Conftime(conftime_req) => {
    -                    let conftimes = conftime_req
    -                        .request()
    -                        .map(|txid| {
    -                            tx_index
    -                                .get(txid)
    -                                .expect("must be in index")
    -                                .confirmation_time()
    -                                .map(Into::into)
    +                    script_req.satisfy(satisfaction)?
    +                }
    +                Request::Conftime(conftime_req) => {
    +                    let conftimes = conftime_req
    +                        .request()
    +                        .map(|txid| {
    +                            tx_index
    +                                .get(txid)
    +                                .expect("must be in index")
    +                                .confirmation_time()
    +                                .map(Into::into)
                             })
    -                        .collect();
    -                    conftime_req.satisfy(conftimes)?
    -                }
    -                Request::Tx(tx_req) => {
    -                    let full_txs = tx_req
    -                        .request()
    -                        .map(|txid| {
    -                            let tx = tx_index.get(txid).expect("must be in index");
    -                            Ok((tx.previous_outputs(), tx.to_tx()))
    +                        .collect();
    +                    conftime_req.satisfy(conftimes)?
    +                }
    +                Request::Tx(tx_req) => {
    +                    let full_txs = tx_req
    +                        .request()
    +                        .map(|txid| {
    +                            let tx = tx_index.get(txid).expect("must be in index");
    +                            Ok((tx.previous_outputs(), tx.to_tx()))
                             })
    -                        .collect::<Result<_, Error>>()?;
    -                    tx_req.satisfy(full_txs)?
    -                }
    -                Request::Finish(batch_update) => break batch_update,
    +                        .collect::<Result<_, Error>>()?;
    +                    tx_req.satisfy(full_txs)?
    +                }
    +                Request::Finish(batch_update) => break batch_update,
                 }
             };
     
    -        database.commit_batch(batch_update)?;
    +        database.commit_batch(batch_update)?;
     
             Ok(())
         }
     }
     
    -impl ConfigurableBlockchain for EsploraBlockchain {
    -    type Config = super::EsploraBlockchainConfig;
    +impl ConfigurableBlockchain for EsploraBlockchain {
    +    type Config = super::EsploraBlockchainConfig;
     
    -    fn from_config(config: &Self::Config) -> Result<Self, Error> {
    -        let mut builder = Builder::new(config.base_url.as_str());
    +    fn from_config(config: &Self::Config) -> Result<Self, Error> {
    +        let mut builder = Builder::new(config.base_url.as_str());
     
    -        if let Some(timeout) = config.timeout {
    -            builder = builder.timeout(timeout);
    +        if let Some(timeout) = config.timeout {
    +            builder = builder.timeout(timeout);
             }
     
    -        if let Some(proxy) = &config.proxy {
    -            builder = builder.proxy(proxy);
    +        if let Some(proxy) = &config.proxy {
    +            builder = builder.proxy(proxy);
             }
     
    -        let mut blockchain =
    -            EsploraBlockchain::from_client(builder.build_blocking()?, config.stop_gap);
    +        let mut blockchain =
    +            EsploraBlockchain::from_client(builder.build_blocking()?, config.stop_gap);
     
    -        if let Some(concurrency) = config.concurrency {
    -            blockchain = blockchain.with_concurrency(concurrency);
    +        if let Some(concurrency) = config.concurrency {
    +            blockchain = blockchain.with_concurrency(concurrency);
             }
     
    -        Ok(blockchain)
    +        Ok(blockchain)
         }
     }
     
    -
    - \ No newline at end of file +
    \ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/src/bdk/blockchain/esplora/mod.rs.html b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/src/bdk/blockchain/esplora/mod.rs.html index 608f4677ba..dcda425833 100644 --- a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/src/bdk/blockchain/esplora/mod.rs.html +++ b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/src/bdk/blockchain/esplora/mod.rs.html @@ -1,270 +1,263 @@ -mod.rs - source - -
      1
    -  2
    -  3
    -  4
    -  5
    -  6
    -  7
    -  8
    -  9
    - 10
    - 11
    - 12
    - 13
    - 14
    - 15
    - 16
    - 17
    - 18
    - 19
    - 20
    - 21
    - 22
    - 23
    - 24
    - 25
    - 26
    - 27
    - 28
    - 29
    - 30
    - 31
    - 32
    - 33
    - 34
    - 35
    - 36
    - 37
    - 38
    - 39
    - 40
    - 41
    - 42
    - 43
    - 44
    - 45
    - 46
    - 47
    - 48
    - 49
    - 50
    - 51
    - 52
    - 53
    - 54
    - 55
    - 56
    - 57
    - 58
    - 59
    - 60
    - 61
    - 62
    - 63
    - 64
    - 65
    - 66
    - 67
    - 68
    - 69
    - 70
    - 71
    - 72
    - 73
    - 74
    - 75
    - 76
    - 77
    - 78
    - 79
    - 80
    - 81
    - 82
    - 83
    - 84
    - 85
    - 86
    - 87
    - 88
    - 89
    - 90
    - 91
    - 92
    - 93
    - 94
    - 95
    - 96
    - 97
    - 98
    - 99
    -100
    -101
    -102
    -103
    -104
    -105
    -106
    -107
    -108
    -109
    -110
    -111
    -112
    -113
    -114
    -115
    -116
    -117
    -118
    -119
    -120
    -121
    -122
    -123
    -124
    -125
    -126
    -127
    -128
    -129
    -130
    -
    //! Esplora
    -//!
    -//! This module defines a [`EsploraBlockchain`] struct that can query an Esplora
    -//! backend populate the wallet's [database](crate::database::Database) by:
    -//!
    -//! ## Example
    -//!
    -//! ```no_run
    -//! # use bdk::blockchain::esplora::EsploraBlockchain;
    -//! let blockchain = EsploraBlockchain::new("https://blockstream.info/testnet/api", 20);
    -//! # Ok::<(), bdk::Error>(())
    -//! ```
    -//!
    -//! Esplora blockchain can use either `ureq` or `reqwest` for the HTTP client
    -//! depending on your needs (blocking or async respectively).
    -//!
    -//! Please note, to configure the Esplora HTTP client correctly use one of:
    -//! Blocking:  --features='use-esplora-blocking'
    -//! Async:     --features='async-interface,use-esplora-async' --no-default-features
    +mod.rs - source
    1
    +2
    +3
    +4
    +5
    +6
    +7
    +8
    +9
    +10
    +11
    +12
    +13
    +14
    +15
    +16
    +17
    +18
    +19
    +20
    +21
    +22
    +23
    +24
    +25
    +26
    +27
    +28
    +29
    +30
    +31
    +32
    +33
    +34
    +35
    +36
    +37
    +38
    +39
    +40
    +41
    +42
    +43
    +44
    +45
    +46
    +47
    +48
    +49
    +50
    +51
    +52
    +53
    +54
    +55
    +56
    +57
    +58
    +59
    +60
    +61
    +62
    +63
    +64
    +65
    +66
    +67
    +68
    +69
    +70
    +71
    +72
    +73
    +74
    +75
    +76
    +77
    +78
    +79
    +80
    +81
    +82
    +83
    +84
    +85
    +86
    +87
    +88
    +89
    +90
    +91
    +92
    +93
    +94
    +95
    +96
    +97
    +98
    +99
    +100
    +101
    +102
    +103
    +104
    +105
    +106
    +107
    +108
    +109
    +110
    +111
    +112
    +113
    +114
    +115
    +116
    +117
    +118
    +119
    +120
    +121
    +122
    +123
    +124
    +125
    +126
    +127
    +128
    +129
    +130
    +
    //! Esplora
    +//!
    +//! This module defines a [`EsploraBlockchain`] struct that can query an Esplora
    +//! backend populate the wallet's [database](crate::database::Database) by:
    +//!
    +//! ## Example
    +//!
    +//! ```no_run
    +//! # use bdk::blockchain::esplora::EsploraBlockchain;
    +//! let blockchain = EsploraBlockchain::new("https://blockstream.info/testnet/api", 20);
    +//! # Ok::<(), bdk::Error>(())
    +//! ```
    +//!
    +//! Esplora blockchain can use either `ureq` or `reqwest` for the HTTP client
    +//! depending on your needs (blocking or async respectively).
    +//!
    +//! Please note, to configure the Esplora HTTP client correctly use one of:
    +//! Blocking:  --features='use-esplora-blocking'
    +//! Async:     --features='async-interface,use-esplora-async' --no-default-features
     
    -pub use esplora_client::Error as EsploraError;
    +pub use esplora_client::Error as EsploraError;
     
    -#[cfg(feature = "use-esplora-async")]
    -mod r#async;
    +#[cfg(feature = "use-esplora-async")]
    +mod r#async;
     
    -#[cfg(feature = "use-esplora-async")]
    -pub use self::r#async::*;
    +#[cfg(feature = "use-esplora-async")]
    +pub use self::r#async::*;
     
    -#[cfg(feature = "use-esplora-blocking")]
    -mod blocking;
    +#[cfg(feature = "use-esplora-blocking")]
    +mod blocking;
     
    -#[cfg(feature = "use-esplora-blocking")]
    -pub use self::blocking::*;
    +#[cfg(feature = "use-esplora-blocking")]
    +pub use self::blocking::*;
     
    -/// Configuration for an [`EsploraBlockchain`]
    -#[derive(Debug, serde::Deserialize, serde::Serialize, Clone, PartialEq, Eq)]
    -pub struct EsploraBlockchainConfig {
    -    /// Base URL of the esplora service
    -    ///
    -    /// eg. `https://blockstream.info/api/`
    -    pub base_url: String,
    -    /// Optional URL of the proxy to use to make requests to the Esplora server
    -    ///
    -    /// The string should be formatted as: `<protocol>://<user>:<password>@host:<port>`.
    -    ///
    -    /// Note that the format of this value and the supported protocols change slightly between the
    -    /// sync version of esplora (using `ureq`) and the async version (using `reqwest`). For more
    -    /// details check with the documentation of the two crates. Both of them are compiled with
    -    /// the `socks` feature enabled.
    -    ///
    -    /// The proxy is ignored when targeting `wasm32`.
    -    #[serde(skip_serializing_if = "Option::is_none")]
    -    pub proxy: Option<String>,
    -    /// Number of parallel requests sent to the esplora service (default: 4)
    -    #[serde(skip_serializing_if = "Option::is_none")]
    -    pub concurrency: Option<u8>,
    -    /// Stop searching addresses for transactions after finding an unused gap of this length.
    -    pub stop_gap: usize,
    -    /// Socket timeout.
    -    #[serde(skip_serializing_if = "Option::is_none")]
    -    pub timeout: Option<u64>,
    +/// Configuration for an [`EsploraBlockchain`]
    +#[derive(Debug, serde::Deserialize, serde::Serialize, Clone, PartialEq, Eq)]
    +pub struct EsploraBlockchainConfig {
    +    /// Base URL of the esplora service
    +    ///
    +    /// eg. `https://blockstream.info/api/`
    +    pub base_url: String,
    +    /// Optional URL of the proxy to use to make requests to the Esplora server
    +    ///
    +    /// The string should be formatted as: `<protocol>://<user>:<password>@host:<port>`.
    +    ///
    +    /// Note that the format of this value and the supported protocols change slightly between the
    +    /// sync version of esplora (using `ureq`) and the async version (using `reqwest`). For more
    +    /// details check with the documentation of the two crates. Both of them are compiled with
    +    /// the `socks` feature enabled.
    +    ///
    +    /// The proxy is ignored when targeting `wasm32`.
    +    #[serde(skip_serializing_if = "Option::is_none")]
    +    pub proxy: Option<String>,
    +    /// Number of parallel requests sent to the esplora service (default: 4)
    +    #[serde(skip_serializing_if = "Option::is_none")]
    +    pub concurrency: Option<u8>,
    +    /// Stop searching addresses for transactions after finding an unused gap of this length.
    +    pub stop_gap: usize,
    +    /// Socket timeout.
    +    #[serde(skip_serializing_if = "Option::is_none")]
    +    pub timeout: Option<u64>,
     }
     
    -impl EsploraBlockchainConfig {
    -    /// create a config with default values given the base url and stop gap
    -    pub fn new(base_url: String, stop_gap: usize) -> Self {
    -        Self {
    -            base_url,
    -            proxy: None,
    -            timeout: None,
    -            stop_gap,
    -            concurrency: None,
    +impl EsploraBlockchainConfig {
    +    /// create a config with default values given the base url and stop gap
    +    pub fn new(base_url: String, stop_gap: usize) -> Self {
    +        Self {
    +            base_url,
    +            proxy: None,
    +            timeout: None,
    +            stop_gap,
    +            concurrency: None,
             }
         }
     }
     
    -impl From<esplora_client::BlockTime> for crate::BlockTime {
    -    fn from(esplora_client::BlockTime { timestamp, height }: esplora_client::BlockTime) -> Self {
    -        Self { timestamp, height }
    +impl From<esplora_client::BlockTime> for crate::BlockTime {
    +    fn from(esplora_client::BlockTime { timestamp, height }: esplora_client::BlockTime) -> Self {
    +        Self { timestamp, height }
         }
     }
     
    -#[cfg(test)]
    -#[cfg(feature = "test-esplora")]
    -crate::bdk_blockchain_tests! {
    -    fn test_instance(test_client: &TestClient) -> EsploraBlockchain {
    -        EsploraBlockchain::new(&format!("http://{}",test_client.electrsd.esplora_url.as_ref().unwrap()), 20)
    +#[cfg(test)]
    +#[cfg(feature = "test-esplora")]
    +crate::bdk_blockchain_tests! {
    +    fn test_instance(test_client: &TestClient) -> EsploraBlockchain {
    +        EsploraBlockchain::new(&format!("http://{}",test_client.electrsd.esplora_url.as_ref().unwrap()), 20)
         }
     }
     
    -const DEFAULT_CONCURRENT_REQUESTS: u8 = 4;
    +const DEFAULT_CONCURRENT_REQUESTS: u8 = 4;
     
    -#[cfg(test)]
    -mod test {
    -    #[test]
    -    #[cfg(feature = "test-esplora")]
    -    fn test_esplora_with_variable_configs() {
    -        use super::*;
    +#[cfg(test)]
    +mod test {
    +    #[test]
    +    #[cfg(feature = "test-esplora")]
    +    fn test_esplora_with_variable_configs() {
    +        use super::*;
     
    -        use crate::testutils::{
    -            blockchain_tests::TestClient,
    -            configurable_blockchain_tests::ConfigurableBlockchainTester,
    +        use crate::testutils::{
    +            blockchain_tests::TestClient,
    +            configurable_blockchain_tests::ConfigurableBlockchainTester,
             };
     
    -        struct EsploraTester;
    +        struct EsploraTester;
     
    -        impl ConfigurableBlockchainTester<EsploraBlockchain> for EsploraTester {
    -            const BLOCKCHAIN_NAME: &'static str = "Esplora";
    +        impl ConfigurableBlockchainTester<EsploraBlockchain> for EsploraTester {
    +            const BLOCKCHAIN_NAME: &'static str = "Esplora";
     
    -            fn config_with_stop_gap(
    +            fn config_with_stop_gap(
                     &self,
    -                test_client: &mut TestClient,
    -                stop_gap: usize,
    -            ) -> Option<EsploraBlockchainConfig> {
    -                Some(EsploraBlockchainConfig {
    -                    base_url: format!(
    +                test_client: &mut TestClient,
    +                stop_gap: usize,
    +            ) -> Option<EsploraBlockchainConfig> {
    +                Some(EsploraBlockchainConfig {
    +                    base_url: format!(
                             "http://{}",
    -                        test_client.electrsd.esplora_url.as_ref().unwrap()
    +                        test_client.electrsd.esplora_url.as_ref().unwrap()
                         ),
    -                    proxy: None,
    -                    concurrency: None,
    -                    stop_gap: stop_gap,
    -                    timeout: None,
    +                    proxy: None,
    +                    concurrency: None,
    +                    stop_gap: stop_gap,
    +                    timeout: None,
                     })
                 }
             }
     
    -        EsploraTester.run();
    +        EsploraTester.run();
         }
     }
     
    -
    - \ No newline at end of file +
    \ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/src/bdk/blockchain/mod.rs.html b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/src/bdk/blockchain/mod.rs.html index 230d13a881..ac6814266f 100644 --- a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/src/bdk/blockchain/mod.rs.html +++ b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/src/bdk/blockchain/mod.rs.html @@ -1,589 +1,583 @@ -mod.rs - source - -
      1
    -  2
    -  3
    -  4
    -  5
    -  6
    -  7
    -  8
    -  9
    - 10
    - 11
    - 12
    - 13
    - 14
    - 15
    - 16
    - 17
    - 18
    - 19
    - 20
    - 21
    - 22
    - 23
    - 24
    - 25
    - 26
    - 27
    - 28
    - 29
    - 30
    - 31
    - 32
    - 33
    - 34
    - 35
    - 36
    - 37
    - 38
    - 39
    - 40
    - 41
    - 42
    - 43
    - 44
    - 45
    - 46
    - 47
    - 48
    - 49
    - 50
    - 51
    - 52
    - 53
    - 54
    - 55
    - 56
    - 57
    - 58
    - 59
    - 60
    - 61
    - 62
    - 63
    - 64
    - 65
    - 66
    - 67
    - 68
    - 69
    - 70
    - 71
    - 72
    - 73
    - 74
    - 75
    - 76
    - 77
    - 78
    - 79
    - 80
    - 81
    - 82
    - 83
    - 84
    - 85
    - 86
    - 87
    - 88
    - 89
    - 90
    - 91
    - 92
    - 93
    - 94
    - 95
    - 96
    - 97
    - 98
    - 99
    -100
    -101
    -102
    -103
    -104
    -105
    -106
    -107
    -108
    -109
    -110
    -111
    -112
    -113
    -114
    -115
    -116
    -117
    -118
    -119
    -120
    -121
    -122
    -123
    -124
    -125
    -126
    -127
    -128
    -129
    -130
    -131
    -132
    -133
    -134
    -135
    -136
    -137
    -138
    -139
    -140
    -141
    -142
    -143
    -144
    -145
    -146
    -147
    -148
    -149
    -150
    -151
    -152
    -153
    -154
    -155
    -156
    -157
    -158
    -159
    -160
    -161
    -162
    -163
    -164
    -165
    -166
    -167
    -168
    -169
    -170
    -171
    -172
    -173
    -174
    -175
    -176
    -177
    -178
    -179
    -180
    -181
    -182
    -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
    -245
    -246
    -247
    -248
    -249
    -250
    -251
    -252
    -253
    -254
    -255
    -256
    -257
    -258
    -259
    -260
    -261
    -262
    -263
    -264
    -265
    -266
    -267
    -268
    -269
    -270
    -271
    -272
    -273
    -274
    -275
    -276
    -277
    -278
    -279
    -280
    -281
    -282
    -283
    -284
    -285
    -286
    -287
    -288
    -289
    -290
    -291
    -292
    -293
    -294
    -295
    -296
    -297
    -298
    -299
    -300
    -301
    -302
    -303
    -304
    -305
    -306
    -307
    -308
    -309
    -310
    -311
    -312
    -313
    -314
    -315
    -316
    -317
    -318
    -319
    -320
    -321
    -322
    -323
    -324
    -325
    -326
    -327
    -328
    -329
    -330
    -331
    -332
    -333
    -334
    -335
    -336
    -337
    -338
    -339
    -340
    -341
    -342
    -343
    -344
    -345
    -346
    -347
    -348
    -349
    -350
    -351
    -352
    -353
    -354
    -355
    -356
    -357
    -358
    -359
    -360
    -361
    -362
    -363
    -364
    -365
    -366
    -367
    -368
    -369
    -370
    -371
    -372
    -373
    -374
    -375
    -376
    -377
    -378
    -379
    -380
    -381
    -382
    -383
    -384
    -385
    -386
    -387
    -388
    -389
    -390
    -391
    -392
    -393
    -
    // Bitcoin Dev Kit
    -// Written in 2020 by Alekos Filini <alekos.filini@gmail.com>
    -//
    -// Copyright (c) 2020-2021 Bitcoin Dev Kit Developers
    -//
    -// This file is licensed under the Apache License, Version 2.0 <LICENSE-APACHE
    -// or http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
    -// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your option.
    -// You may not use this file except in accordance with one or both of these
    -// licenses.
    -
    -//! Blockchain backends
    -//!
    -//! This module provides the implementation of a few commonly-used backends like
    -//! [Electrum](crate::blockchain::electrum), [Esplora](crate::blockchain::esplora) and
    -//! [Compact Filters/Neutrino](crate::blockchain::compact_filters), along with a generalized trait
    -//! [`Blockchain`] that can be implemented to build customized backends.
    -
    -use std::collections::HashSet;
    -use std::ops::Deref;
    -use std::sync::mpsc::{channel, Receiver, Sender};
    -use std::sync::Arc;
    -
    -use bitcoin::{BlockHash, Transaction, Txid};
    -
    -use crate::database::BatchDatabase;
    -use crate::error::Error;
    -use crate::wallet::{wallet_name_from_descriptor, Wallet};
    -use crate::{FeeRate, KeychainKind};
    -
    -#[cfg(any(
    -    feature = "electrum",
    -    feature = "esplora",
    -    feature = "compact_filters",
    -    feature = "rpc"
    -))]
    -pub mod any;
    -mod script_sync;
    -
    -#[cfg(any(
    -    feature = "electrum",
    -    feature = "esplora",
    -    feature = "compact_filters",
    -    feature = "rpc"
    -))]
    -pub use any::{AnyBlockchain, AnyBlockchainConfig};
    -
    -#[cfg(feature = "electrum")]
    -#[cfg_attr(docsrs, doc(cfg(feature = "electrum")))]
    -pub mod electrum;
    -#[cfg(feature = "electrum")]
    -pub use self::electrum::ElectrumBlockchain;
    -#[cfg(feature = "electrum")]
    -pub use self::electrum::ElectrumBlockchainConfig;
    -
    -#[cfg(feature = "rpc")]
    -#[cfg_attr(docsrs, doc(cfg(feature = "rpc")))]
    -pub mod rpc;
    -#[cfg(feature = "rpc")]
    -pub use self::rpc::RpcBlockchain;
    -#[cfg(feature = "rpc")]
    -pub use self::rpc::RpcConfig;
    -
    -#[cfg(feature = "esplora")]
    -#[cfg_attr(docsrs, doc(cfg(feature = "esplora")))]
    -pub mod esplora;
    -#[cfg(feature = "esplora")]
    -pub use self::esplora::EsploraBlockchain;
    -
    -#[cfg(feature = "compact_filters")]
    -#[cfg_attr(docsrs, doc(cfg(feature = "compact_filters")))]
    -pub mod compact_filters;
    -
    -#[cfg(feature = "compact_filters")]
    -pub use self::compact_filters::CompactFiltersBlockchain;
    -
    -/// Capabilities that can be supported by a [`Blockchain`] backend
    -#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
    -pub enum Capability {
    -    /// Can recover the full history of a wallet and not only the set of currently spendable UTXOs
    -    FullHistory,
    -    /// Can fetch any historical transaction given its txid
    -    GetAnyTx,
    -    /// Can compute accurate fees for the transactions found during sync
    -    AccurateFees,
    +mod.rs - source
    1
    +2
    +3
    +4
    +5
    +6
    +7
    +8
    +9
    +10
    +11
    +12
    +13
    +14
    +15
    +16
    +17
    +18
    +19
    +20
    +21
    +22
    +23
    +24
    +25
    +26
    +27
    +28
    +29
    +30
    +31
    +32
    +33
    +34
    +35
    +36
    +37
    +38
    +39
    +40
    +41
    +42
    +43
    +44
    +45
    +46
    +47
    +48
    +49
    +50
    +51
    +52
    +53
    +54
    +55
    +56
    +57
    +58
    +59
    +60
    +61
    +62
    +63
    +64
    +65
    +66
    +67
    +68
    +69
    +70
    +71
    +72
    +73
    +74
    +75
    +76
    +77
    +78
    +79
    +80
    +81
    +82
    +83
    +84
    +85
    +86
    +87
    +88
    +89
    +90
    +91
    +92
    +93
    +94
    +95
    +96
    +97
    +98
    +99
    +100
    +101
    +102
    +103
    +104
    +105
    +106
    +107
    +108
    +109
    +110
    +111
    +112
    +113
    +114
    +115
    +116
    +117
    +118
    +119
    +120
    +121
    +122
    +123
    +124
    +125
    +126
    +127
    +128
    +129
    +130
    +131
    +132
    +133
    +134
    +135
    +136
    +137
    +138
    +139
    +140
    +141
    +142
    +143
    +144
    +145
    +146
    +147
    +148
    +149
    +150
    +151
    +152
    +153
    +154
    +155
    +156
    +157
    +158
    +159
    +160
    +161
    +162
    +163
    +164
    +165
    +166
    +167
    +168
    +169
    +170
    +171
    +172
    +173
    +174
    +175
    +176
    +177
    +178
    +179
    +180
    +181
    +182
    +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
    +245
    +246
    +247
    +248
    +249
    +250
    +251
    +252
    +253
    +254
    +255
    +256
    +257
    +258
    +259
    +260
    +261
    +262
    +263
    +264
    +265
    +266
    +267
    +268
    +269
    +270
    +271
    +272
    +273
    +274
    +275
    +276
    +277
    +278
    +279
    +280
    +281
    +282
    +283
    +284
    +285
    +286
    +287
    +288
    +289
    +290
    +291
    +292
    +293
    +294
    +295
    +296
    +297
    +298
    +299
    +300
    +301
    +302
    +303
    +304
    +305
    +306
    +307
    +308
    +309
    +310
    +311
    +312
    +313
    +314
    +315
    +316
    +317
    +318
    +319
    +320
    +321
    +322
    +323
    +324
    +325
    +326
    +327
    +328
    +329
    +330
    +331
    +332
    +333
    +334
    +335
    +336
    +337
    +338
    +339
    +340
    +341
    +342
    +343
    +344
    +345
    +346
    +347
    +348
    +349
    +350
    +351
    +352
    +353
    +354
    +355
    +356
    +357
    +358
    +359
    +360
    +361
    +362
    +363
    +364
    +365
    +366
    +367
    +368
    +369
    +370
    +371
    +372
    +373
    +374
    +375
    +376
    +377
    +378
    +379
    +380
    +381
    +382
    +383
    +384
    +385
    +386
    +387
    +388
    +389
    +390
    +391
    +392
    +393
    +
    // Bitcoin Dev Kit
    +// Written in 2020 by Alekos Filini <alekos.filini@gmail.com>
    +//
    +// Copyright (c) 2020-2021 Bitcoin Dev Kit Developers
    +//
    +// This file is licensed under the Apache License, Version 2.0 <LICENSE-APACHE
    +// or http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
    +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your option.
    +// You may not use this file except in accordance with one or both of these
    +// licenses.
    +
    +//! Blockchain backends
    +//!
    +//! This module provides the implementation of a few commonly-used backends like
    +//! [Electrum](crate::blockchain::electrum), [Esplora](crate::blockchain::esplora) and
    +//! [Compact Filters/Neutrino](crate::blockchain::compact_filters), along with a generalized trait
    +//! [`Blockchain`] that can be implemented to build customized backends.
    +
    +use std::collections::HashSet;
    +use std::ops::Deref;
    +use std::sync::mpsc::{channel, Receiver, Sender};
    +use std::sync::Arc;
    +
    +use bitcoin::{BlockHash, Transaction, Txid};
    +
    +use crate::database::BatchDatabase;
    +use crate::error::Error;
    +use crate::wallet::{wallet_name_from_descriptor, Wallet};
    +use crate::{FeeRate, KeychainKind};
    +
    +#[cfg(any(
    +    feature = "electrum",
    +    feature = "esplora",
    +    feature = "compact_filters",
    +    feature = "rpc"
    +))]
    +pub mod any;
    +mod script_sync;
    +
    +#[cfg(any(
    +    feature = "electrum",
    +    feature = "esplora",
    +    feature = "compact_filters",
    +    feature = "rpc"
    +))]
    +pub use any::{AnyBlockchain, AnyBlockchainConfig};
    +
    +#[cfg(feature = "electrum")]
    +#[cfg_attr(docsrs, doc(cfg(feature = "electrum")))]
    +pub mod electrum;
    +#[cfg(feature = "electrum")]
    +pub use self::electrum::ElectrumBlockchain;
    +#[cfg(feature = "electrum")]
    +pub use self::electrum::ElectrumBlockchainConfig;
    +
    +#[cfg(feature = "rpc")]
    +#[cfg_attr(docsrs, doc(cfg(feature = "rpc")))]
    +pub mod rpc;
    +#[cfg(feature = "rpc")]
    +pub use self::rpc::RpcBlockchain;
    +#[cfg(feature = "rpc")]
    +pub use self::rpc::RpcConfig;
    +
    +#[cfg(feature = "esplora")]
    +#[cfg_attr(docsrs, doc(cfg(feature = "esplora")))]
    +pub mod esplora;
    +#[cfg(feature = "esplora")]
    +pub use self::esplora::EsploraBlockchain;
    +
    +#[cfg(feature = "compact_filters")]
    +#[cfg_attr(docsrs, doc(cfg(feature = "compact_filters")))]
    +pub mod compact_filters;
    +
    +#[cfg(feature = "compact_filters")]
    +pub use self::compact_filters::CompactFiltersBlockchain;
    +
    +/// Capabilities that can be supported by a [`Blockchain`] backend
    +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
    +pub enum Capability {
    +    /// Can recover the full history of a wallet and not only the set of currently spendable UTXOs
    +    FullHistory,
    +    /// Can fetch any historical transaction given its txid
    +    GetAnyTx,
    +    /// Can compute accurate fees for the transactions found during sync
    +    AccurateFees,
     }
     
    -/// Trait that defines the actions that must be supported by a blockchain backend
    -#[maybe_async]
    -pub trait Blockchain: WalletSync + GetHeight + GetTx + GetBlockHash {
    -    /// Return the set of [`Capability`] supported by this backend
    -    fn get_capabilities(&self) -> HashSet<Capability>;
    -    /// Broadcast a transaction
    -    fn broadcast(&self, tx: &Transaction) -> Result<(), Error>;
    -    /// Estimate the fee rate required to confirm a transaction in a given `target` of blocks
    -    fn estimate_fee(&self, target: usize) -> Result<FeeRate, Error>;
    +/// Trait that defines the actions that must be supported by a blockchain backend
    +#[maybe_async]
    +pub trait Blockchain: WalletSync + GetHeight + GetTx + GetBlockHash {
    +    /// Return the set of [`Capability`] supported by this backend
    +    fn get_capabilities(&self) -> HashSet<Capability>;
    +    /// Broadcast a transaction
    +    fn broadcast(&self, tx: &Transaction) -> Result<(), Error>;
    +    /// Estimate the fee rate required to confirm a transaction in a given `target` of blocks
    +    fn estimate_fee(&self, target: usize) -> Result<FeeRate, Error>;
     }
     
    -/// Trait for getting the current height of the blockchain.
    -#[maybe_async]
    -pub trait GetHeight {
    -    /// Return the current height
    -    fn get_height(&self) -> Result<u32, Error>;
    +/// Trait for getting the current height of the blockchain.
    +#[maybe_async]
    +pub trait GetHeight {
    +    /// Return the current height
    +    fn get_height(&self) -> Result<u32, Error>;
     }
     
    -#[maybe_async]
    -/// Trait for getting a transaction by txid
    -pub trait GetTx {
    -    /// Fetch a transaction given its txid
    -    fn get_tx(&self, txid: &Txid) -> Result<Option<Transaction>, Error>;
    +#[maybe_async]
    +/// Trait for getting a transaction by txid
    +pub trait GetTx {
    +    /// Fetch a transaction given its txid
    +    fn get_tx(&self, txid: &Txid) -> Result<Option<Transaction>, Error>;
     }
     
    -#[maybe_async]
    -/// Trait for getting block hash by block height
    -pub trait GetBlockHash {
    -    /// fetch block hash given its height
    -    fn get_block_hash(&self, height: u64) -> Result<BlockHash, Error>;
    +#[maybe_async]
    +/// Trait for getting block hash by block height
    +pub trait GetBlockHash {
    +    /// fetch block hash given its height
    +    fn get_block_hash(&self, height: u64) -> Result<BlockHash, Error>;
     }
     
    -/// Trait for blockchains that can sync by updating the database directly.
    -#[maybe_async]
    -pub trait WalletSync {
    -    /// Setup the backend and populate the internal database for the first time
    -    ///
    -    /// This method is the equivalent of [`Self::wallet_sync`], but it's guaranteed to only be
    -    /// called once, at the first [`Wallet::sync`](crate::wallet::Wallet::sync).
    -    ///
    -    /// The rationale behind the distinction between `sync` and `setup` is that some custom backends
    -    /// might need to perform specific actions only the first time they are synced.
    -    ///
    -    /// For types that do not have that distinction, only this method can be implemented, since
    -    /// [`WalletSync::wallet_sync`] defaults to calling this internally if not overridden.
    -    /// Populate the internal database with transactions and UTXOs
    -    fn wallet_setup<D: BatchDatabase>(
    +/// Trait for blockchains that can sync by updating the database directly.
    +#[maybe_async]
    +pub trait WalletSync {
    +    /// Setup the backend and populate the internal database for the first time
    +    ///
    +    /// This method is the equivalent of [`Self::wallet_sync`], but it's guaranteed to only be
    +    /// called once, at the first [`Wallet::sync`](crate::wallet::Wallet::sync).
    +    ///
    +    /// The rationale behind the distinction between `sync` and `setup` is that some custom backends
    +    /// might need to perform specific actions only the first time they are synced.
    +    ///
    +    /// For types that do not have that distinction, only this method can be implemented, since
    +    /// [`WalletSync::wallet_sync`] defaults to calling this internally if not overridden.
    +    /// Populate the internal database with transactions and UTXOs
    +    fn wallet_setup<D: BatchDatabase>(
             &self,
    -        database: &mut D,
    -        progress_update: Box<dyn Progress>,
    -    ) -> Result<(), Error>;
    -
    -    /// If not overridden, it defaults to calling [`Self::wallet_setup`] internally.
    -    ///
    -    /// This method should implement the logic required to iterate over the list of the wallet's
    -    /// script_pubkeys using [`Database::iter_script_pubkeys`] and look for relevant transactions
    -    /// in the blockchain to populate the database with [`BatchOperations::set_tx`] and
    -    /// [`BatchOperations::set_utxo`].
    -    ///
    -    /// This method should also take care of removing UTXOs that are seen as spent in the
    -    /// blockchain, using [`BatchOperations::del_utxo`].
    -    ///
    -    /// The `progress_update` object can be used to give the caller updates about the progress by using
    -    /// [`Progress::update`].
    -    ///
    -    /// [`Database::iter_script_pubkeys`]: crate::database::Database::iter_script_pubkeys
    -    /// [`BatchOperations::set_tx`]: crate::database::BatchOperations::set_tx
    -    /// [`BatchOperations::set_utxo`]: crate::database::BatchOperations::set_utxo
    -    /// [`BatchOperations::del_utxo`]: crate::database::BatchOperations::del_utxo
    -    fn wallet_sync<D: BatchDatabase>(
    +        database: &mut D,
    +        progress_update: Box<dyn Progress>,
    +    ) -> Result<(), Error>;
    +
    +    /// If not overridden, it defaults to calling [`Self::wallet_setup`] internally.
    +    ///
    +    /// This method should implement the logic required to iterate over the list of the wallet's
    +    /// script_pubkeys using [`Database::iter_script_pubkeys`] and look for relevant transactions
    +    /// in the blockchain to populate the database with [`BatchOperations::set_tx`] and
    +    /// [`BatchOperations::set_utxo`].
    +    ///
    +    /// This method should also take care of removing UTXOs that are seen as spent in the
    +    /// blockchain, using [`BatchOperations::del_utxo`].
    +    ///
    +    /// The `progress_update` object can be used to give the caller updates about the progress by using
    +    /// [`Progress::update`].
    +    ///
    +    /// [`Database::iter_script_pubkeys`]: crate::database::Database::iter_script_pubkeys
    +    /// [`BatchOperations::set_tx`]: crate::database::BatchOperations::set_tx
    +    /// [`BatchOperations::set_utxo`]: crate::database::BatchOperations::set_utxo
    +    /// [`BatchOperations::del_utxo`]: crate::database::BatchOperations::del_utxo
    +    fn wallet_sync<D: BatchDatabase>(
             &self,
    -        database: &mut D,
    -        progress_update: Box<dyn Progress>,
    -    ) -> Result<(), Error> {
    -        maybe_await!(self.wallet_setup(database, progress_update))
    +        database: &mut D,
    +        progress_update: Box<dyn Progress>,
    +    ) -> Result<(), Error> {
    +        maybe_await!(self.wallet_setup(database, progress_update))
         }
     }
     
    -/// Trait for [`Blockchain`] types that can be created given a configuration
    -pub trait ConfigurableBlockchain: Blockchain + Sized {
    -    /// Type that contains the configuration
    -    type Config: std::fmt::Debug;
    +/// Trait for [`Blockchain`] types that can be created given a configuration
    +pub trait ConfigurableBlockchain: Blockchain + Sized {
    +    /// Type that contains the configuration
    +    type Config: std::fmt::Debug;
     
    -    /// Create a new instance given a configuration
    -    fn from_config(config: &Self::Config) -> Result<Self, Error>;
    +    /// Create a new instance given a configuration
    +    fn from_config(config: &Self::Config) -> Result<Self, Error>;
     }
     
    -/// Trait for blockchains that don't contain any state
    -///
    -/// Statless blockchains can be used to sync multiple wallets with different descriptors.
    -///
    -/// [`BlockchainFactory`] is automatically implemented for `Arc<T>` where `T` is a stateless
    -/// blockchain.
    -pub trait StatelessBlockchain: Blockchain {}
    -
    -/// Trait for a factory of blockchains that share the underlying connection or configuration
    -#[cfg_attr(
    -    not(feature = "async-interface"),
    -    doc = r##"
    +/// Trait for blockchains that don't contain any state
    +///
    +/// Statless blockchains can be used to sync multiple wallets with different descriptors.
    +///
    +/// [`BlockchainFactory`] is automatically implemented for `Arc<T>` where `T` is a stateless
    +/// blockchain.
    +pub trait StatelessBlockchain: Blockchain {}
    +
    +/// Trait for a factory of blockchains that share the underlying connection or configuration
    +#[cfg_attr(
    +    not(feature = "async-interface"),
    +    doc = r##"
     ## Example
     
     This example shows how to sync multiple walles and return the sum of their balances
    @@ -606,191 +600,190 @@ fn sum_of_balances<B: BlockchainFactory>(blockchain_factory: B, wallets: &
             .sum())
     }
     ```
    -"##
    -)]
    -pub trait BlockchainFactory {
    -    /// The type returned when building a blockchain from this factory
    -    type Inner: Blockchain;
    -
    -    /// Build a new blockchain for the given descriptor wallet_name
    -    ///
    -    /// If `override_skip_blocks` is `None`, the returned blockchain will inherit the number of blocks
    -    /// from the factory. Since it's not possible to override the value to `None`, set it to
    -    /// `Some(0)` to rescan from the genesis.
    -    fn build(
    +"##
    +)]
    +pub trait BlockchainFactory {
    +    /// The type returned when building a blockchain from this factory
    +    type Inner: Blockchain;
    +
    +    /// Build a new blockchain for the given descriptor wallet_name
    +    ///
    +    /// If `override_skip_blocks` is `None`, the returned blockchain will inherit the number of blocks
    +    /// from the factory. Since it's not possible to override the value to `None`, set it to
    +    /// `Some(0)` to rescan from the genesis.
    +    fn build(
             &self,
    -        wallet_name: &str,
    -        override_skip_blocks: Option<u32>,
    -    ) -> Result<Self::Inner, Error>;
    -
    -    /// Build a new blockchain for a given wallet
    -    ///
    -    /// Internally uses [`wallet_name_from_descriptor`] to derive the name, and then calls
    -    /// [`BlockchainFactory::build`] to create the blockchain instance.
    -    fn build_for_wallet<D: BatchDatabase>(
    +        wallet_name: &str,
    +        override_skip_blocks: Option<u32>,
    +    ) -> Result<Self::Inner, Error>;
    +
    +    /// Build a new blockchain for a given wallet
    +    ///
    +    /// Internally uses [`wallet_name_from_descriptor`] to derive the name, and then calls
    +    /// [`BlockchainFactory::build`] to create the blockchain instance.
    +    fn build_for_wallet<D: BatchDatabase>(
             &self,
    -        wallet: &Wallet<D>,
    -        override_skip_blocks: Option<u32>,
    -    ) -> Result<Self::Inner, Error> {
    -        let wallet_name = wallet_name_from_descriptor(
    -            wallet.public_descriptor(KeychainKind::External)?.unwrap(),
    -            wallet.public_descriptor(KeychainKind::Internal)?,
    -            wallet.network(),
    -            wallet.secp_ctx(),
    +        wallet: &Wallet<D>,
    +        override_skip_blocks: Option<u32>,
    +    ) -> Result<Self::Inner, Error> {
    +        let wallet_name = wallet_name_from_descriptor(
    +            wallet.public_descriptor(KeychainKind::External)?.unwrap(),
    +            wallet.public_descriptor(KeychainKind::Internal)?,
    +            wallet.network(),
    +            wallet.secp_ctx(),
             )?;
    -        self.build(&wallet_name, override_skip_blocks)
    +        self.build(&wallet_name, override_skip_blocks)
         }
     
    -    /// Use [`BlockchainFactory::build_for_wallet`] to get a blockchain, then sync the wallet
    -    ///
    -    /// This can be used when a new blockchain would only be used to sync a wallet and then
    -    /// immediately dropped. Keep in mind that specific blockchain factories may perform slow
    -    /// operations to build a blockchain for a given wallet, so if a wallet needs to be synced
    -    /// often it's recommended to use [`BlockchainFactory::build_for_wallet`] to reuse the same
    -    /// blockchain multiple times.
    -    #[cfg(not(any(target_arch = "wasm32", feature = "async-interface")))]
    -    #[cfg_attr(
    -        docsrs,
    -        doc(cfg(not(any(target_arch = "wasm32", feature = "async-interface"))))
    -    )]
    -    fn sync_wallet<D: BatchDatabase>(
    +    /// Use [`BlockchainFactory::build_for_wallet`] to get a blockchain, then sync the wallet
    +    ///
    +    /// This can be used when a new blockchain would only be used to sync a wallet and then
    +    /// immediately dropped. Keep in mind that specific blockchain factories may perform slow
    +    /// operations to build a blockchain for a given wallet, so if a wallet needs to be synced
    +    /// often it's recommended to use [`BlockchainFactory::build_for_wallet`] to reuse the same
    +    /// blockchain multiple times.
    +    #[cfg(not(any(target_arch = "wasm32", feature = "async-interface")))]
    +    #[cfg_attr(
    +        docsrs,
    +        doc(cfg(not(any(target_arch = "wasm32", feature = "async-interface"))))
    +    )]
    +    fn sync_wallet<D: BatchDatabase>(
             &self,
    -        wallet: &Wallet<D>,
    -        override_skip_blocks: Option<u32>,
    -        sync_options: crate::wallet::SyncOptions,
    -    ) -> Result<(), Error> {
    -        let blockchain = self.build_for_wallet(wallet, override_skip_blocks)?;
    -        wallet.sync(&blockchain, sync_options)
    +        wallet: &Wallet<D>,
    +        override_skip_blocks: Option<u32>,
    +        sync_options: crate::wallet::SyncOptions,
    +    ) -> Result<(), Error> {
    +        let blockchain = self.build_for_wallet(wallet, override_skip_blocks)?;
    +        wallet.sync(&blockchain, sync_options)
         }
     }
     
    -impl<T: StatelessBlockchain> BlockchainFactory for Arc<T> {
    -    type Inner = Self;
    +impl<T: StatelessBlockchain> BlockchainFactory for Arc<T> {
    +    type Inner = Self;
     
    -    fn build(&self, _wallet_name: &str, _override_skip_blocks: Option<u32>) -> Result<Self, Error> {
    -        Ok(Arc::clone(self))
    +    fn build(&self, _wallet_name: &str, _override_skip_blocks: Option<u32>) -> Result<Self, Error> {
    +        Ok(Arc::clone(self))
         }
     }
     
    -/// Data sent with a progress update over a [`channel`]
    -pub type ProgressData = (f32, Option<String>);
    -
    -/// Trait for types that can receive and process progress updates during [`WalletSync::wallet_sync`] and
    -/// [`WalletSync::wallet_setup`]
    -pub trait Progress: Send + 'static + core::fmt::Debug {
    -    /// Send a new progress update
    -    ///
    -    /// The `progress` value should be in the range 0.0 - 100.0, and the `message` value is an
    -    /// optional text message that can be displayed to the user.
    -    fn update(&self, progress: f32, message: Option<String>) -> Result<(), Error>;
    +/// Data sent with a progress update over a [`channel`]
    +pub type ProgressData = (f32, Option<String>);
    +
    +/// Trait for types that can receive and process progress updates during [`WalletSync::wallet_sync`] and
    +/// [`WalletSync::wallet_setup`]
    +pub trait Progress: Send + 'static + core::fmt::Debug {
    +    /// Send a new progress update
    +    ///
    +    /// The `progress` value should be in the range 0.0 - 100.0, and the `message` value is an
    +    /// optional text message that can be displayed to the user.
    +    fn update(&self, progress: f32, message: Option<String>) -> Result<(), Error>;
     }
     
    -/// Shortcut to create a [`channel`] (pair of [`Sender`] and [`Receiver`]) that can transport [`ProgressData`]
    -pub fn progress() -> (Sender<ProgressData>, Receiver<ProgressData>) {
    -    channel()
    +/// Shortcut to create a [`channel`] (pair of [`Sender`] and [`Receiver`]) that can transport [`ProgressData`]
    +pub fn progress() -> (Sender<ProgressData>, Receiver<ProgressData>) {
    +    channel()
     }
     
    -impl Progress for Sender<ProgressData> {
    -    fn update(&self, progress: f32, message: Option<String>) -> Result<(), Error> {
    -        if !(0.0..=100.0).contains(&progress) {
    -            return Err(Error::InvalidProgressValue(progress));
    +impl Progress for Sender<ProgressData> {
    +    fn update(&self, progress: f32, message: Option<String>) -> Result<(), Error> {
    +        if !(0.0..=100.0).contains(&progress) {
    +            return Err(Error::InvalidProgressValue(progress));
             }
     
    -        self.send((progress, message))
    -            .map_err(|_| Error::ProgressUpdateError)
    +        self.send((progress, message))
    +            .map_err(|_| Error::ProgressUpdateError)
         }
     }
     
    -/// Type that implements [`Progress`] and drops every update received
    -#[derive(Clone, Copy, Default, Debug)]
    -pub struct NoopProgress;
    +/// Type that implements [`Progress`] and drops every update received
    +#[derive(Clone, Copy, Default, Debug)]
    +pub struct NoopProgress;
     
    -/// Create a new instance of [`NoopProgress`]
    -pub fn noop_progress() -> NoopProgress {
    -    NoopProgress
    +/// Create a new instance of [`NoopProgress`]
    +pub fn noop_progress() -> NoopProgress {
    +    NoopProgress
     }
     
    -impl Progress for NoopProgress {
    -    fn update(&self, _progress: f32, _message: Option<String>) -> Result<(), Error> {
    +impl Progress for NoopProgress {
    +    fn update(&self, _progress: f32, _message: Option<String>) -> Result<(), Error> {
             Ok(())
         }
     }
     
    -/// Type that implements [`Progress`] and logs at level `INFO` every update received
    -#[derive(Clone, Copy, Default, Debug)]
    -pub struct LogProgress;
    +/// Type that implements [`Progress`] and logs at level `INFO` every update received
    +#[derive(Clone, Copy, Default, Debug)]
    +pub struct LogProgress;
     
    -/// Create a new instance of [`LogProgress`]
    -pub fn log_progress() -> LogProgress {
    -    LogProgress
    +/// Create a new instance of [`LogProgress`]
    +pub fn log_progress() -> LogProgress {
    +    LogProgress
     }
     
    -impl Progress for LogProgress {
    -    fn update(&self, progress: f32, message: Option<String>) -> Result<(), Error> {
    +impl Progress for LogProgress {
    +    fn update(&self, progress: f32, message: Option<String>) -> Result<(), Error> {
             log::info!(
                 "Sync {:.3}%: `{}`",
    -            progress,
    -            message.unwrap_or_else(|| "".into())
    +            progress,
    +            message.unwrap_or_else(|| "".into())
             );
     
             Ok(())
         }
     }
     
    -#[maybe_async]
    -impl<T: Blockchain> Blockchain for Arc<T> {
    -    fn get_capabilities(&self) -> HashSet<Capability> {
    -        maybe_await!(self.deref().get_capabilities())
    +#[maybe_async]
    +impl<T: Blockchain> Blockchain for Arc<T> {
    +    fn get_capabilities(&self) -> HashSet<Capability> {
    +        maybe_await!(self.deref().get_capabilities())
         }
     
    -    fn broadcast(&self, tx: &Transaction) -> Result<(), Error> {
    -        maybe_await!(self.deref().broadcast(tx))
    +    fn broadcast(&self, tx: &Transaction) -> Result<(), Error> {
    +        maybe_await!(self.deref().broadcast(tx))
         }
     
    -    fn estimate_fee(&self, target: usize) -> Result<FeeRate, Error> {
    -        maybe_await!(self.deref().estimate_fee(target))
    +    fn estimate_fee(&self, target: usize) -> Result<FeeRate, Error> {
    +        maybe_await!(self.deref().estimate_fee(target))
         }
     }
     
    -#[maybe_async]
    -impl<T: GetTx> GetTx for Arc<T> {
    -    fn get_tx(&self, txid: &Txid) -> Result<Option<Transaction>, Error> {
    -        maybe_await!(self.deref().get_tx(txid))
    +#[maybe_async]
    +impl<T: GetTx> GetTx for Arc<T> {
    +    fn get_tx(&self, txid: &Txid) -> Result<Option<Transaction>, Error> {
    +        maybe_await!(self.deref().get_tx(txid))
         }
     }
     
    -#[maybe_async]
    -impl<T: GetHeight> GetHeight for Arc<T> {
    -    fn get_height(&self) -> Result<u32, Error> {
    -        maybe_await!(self.deref().get_height())
    +#[maybe_async]
    +impl<T: GetHeight> GetHeight for Arc<T> {
    +    fn get_height(&self) -> Result<u32, Error> {
    +        maybe_await!(self.deref().get_height())
         }
     }
     
    -#[maybe_async]
    -impl<T: GetBlockHash> GetBlockHash for Arc<T> {
    -    fn get_block_hash(&self, height: u64) -> Result<BlockHash, Error> {
    -        maybe_await!(self.deref().get_block_hash(height))
    +#[maybe_async]
    +impl<T: GetBlockHash> GetBlockHash for Arc<T> {
    +    fn get_block_hash(&self, height: u64) -> Result<BlockHash, Error> {
    +        maybe_await!(self.deref().get_block_hash(height))
         }
     }
     
    -#[maybe_async]
    -impl<T: WalletSync> WalletSync for Arc<T> {
    -    fn wallet_setup<D: BatchDatabase>(
    +#[maybe_async]
    +impl<T: WalletSync> WalletSync for Arc<T> {
    +    fn wallet_setup<D: BatchDatabase>(
             &self,
    -        database: &mut D,
    -        progress_update: Box<dyn Progress>,
    -    ) -> Result<(), Error> {
    -        maybe_await!(self.deref().wallet_setup(database, progress_update))
    +        database: &mut D,
    +        progress_update: Box<dyn Progress>,
    +    ) -> Result<(), Error> {
    +        maybe_await!(self.deref().wallet_setup(database, progress_update))
         }
     
    -    fn wallet_sync<D: BatchDatabase>(
    +    fn wallet_sync<D: BatchDatabase>(
             &self,
    -        database: &mut D,
    -        progress_update: Box<dyn Progress>,
    -    ) -> Result<(), Error> {
    -        maybe_await!(self.deref().wallet_sync(database, progress_update))
    +        database: &mut D,
    +        progress_update: Box<dyn Progress>,
    +    ) -> Result<(), Error> {
    +        maybe_await!(self.deref().wallet_sync(database, progress_update))
         }
     }
     
    -
    - \ No newline at end of file +
    \ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/src/bdk/blockchain/rpc.rs.html b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/src/bdk/blockchain/rpc.rs.html index 84bda780b4..a77365653f 100644 --- a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/src/bdk/blockchain/rpc.rs.html +++ b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/src/bdk/blockchain/rpc.rs.html @@ -1,2010 +1,2003 @@ -rpc.rs - source - -
       1
    -   2
    -   3
    -   4
    -   5
    -   6
    -   7
    -   8
    -   9
    -  10
    -  11
    -  12
    -  13
    -  14
    -  15
    -  16
    -  17
    -  18
    -  19
    -  20
    -  21
    -  22
    -  23
    -  24
    -  25
    -  26
    -  27
    -  28
    -  29
    -  30
    -  31
    -  32
    -  33
    -  34
    -  35
    -  36
    -  37
    -  38
    -  39
    -  40
    -  41
    -  42
    -  43
    -  44
    -  45
    -  46
    -  47
    -  48
    -  49
    -  50
    -  51
    -  52
    -  53
    -  54
    -  55
    -  56
    -  57
    -  58
    -  59
    -  60
    -  61
    -  62
    -  63
    -  64
    -  65
    -  66
    -  67
    -  68
    -  69
    -  70
    -  71
    -  72
    -  73
    -  74
    -  75
    -  76
    -  77
    -  78
    -  79
    -  80
    -  81
    -  82
    -  83
    -  84
    -  85
    -  86
    -  87
    -  88
    -  89
    -  90
    -  91
    -  92
    -  93
    -  94
    -  95
    -  96
    -  97
    -  98
    -  99
    - 100
    - 101
    - 102
    - 103
    - 104
    - 105
    - 106
    - 107
    - 108
    - 109
    - 110
    - 111
    - 112
    - 113
    - 114
    - 115
    - 116
    - 117
    - 118
    - 119
    - 120
    - 121
    - 122
    - 123
    - 124
    - 125
    - 126
    - 127
    - 128
    - 129
    - 130
    - 131
    - 132
    - 133
    - 134
    - 135
    - 136
    - 137
    - 138
    - 139
    - 140
    - 141
    - 142
    - 143
    - 144
    - 145
    - 146
    - 147
    - 148
    - 149
    - 150
    - 151
    - 152
    - 153
    - 154
    - 155
    - 156
    - 157
    - 158
    - 159
    - 160
    - 161
    - 162
    - 163
    - 164
    - 165
    - 166
    - 167
    - 168
    - 169
    - 170
    - 171
    - 172
    - 173
    - 174
    - 175
    - 176
    - 177
    - 178
    - 179
    - 180
    - 181
    - 182
    - 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
    - 245
    - 246
    - 247
    - 248
    - 249
    - 250
    - 251
    - 252
    - 253
    - 254
    - 255
    - 256
    - 257
    - 258
    - 259
    - 260
    - 261
    - 262
    - 263
    - 264
    - 265
    - 266
    - 267
    - 268
    - 269
    - 270
    - 271
    - 272
    - 273
    - 274
    - 275
    - 276
    - 277
    - 278
    - 279
    - 280
    - 281
    - 282
    - 283
    - 284
    - 285
    - 286
    - 287
    - 288
    - 289
    - 290
    - 291
    - 292
    - 293
    - 294
    - 295
    - 296
    - 297
    - 298
    - 299
    - 300
    - 301
    - 302
    - 303
    - 304
    - 305
    - 306
    - 307
    - 308
    - 309
    - 310
    - 311
    - 312
    - 313
    - 314
    - 315
    - 316
    - 317
    - 318
    - 319
    - 320
    - 321
    - 322
    - 323
    - 324
    - 325
    - 326
    - 327
    - 328
    - 329
    - 330
    - 331
    - 332
    - 333
    - 334
    - 335
    - 336
    - 337
    - 338
    - 339
    - 340
    - 341
    - 342
    - 343
    - 344
    - 345
    - 346
    - 347
    - 348
    - 349
    - 350
    - 351
    - 352
    - 353
    - 354
    - 355
    - 356
    - 357
    - 358
    - 359
    - 360
    - 361
    - 362
    - 363
    - 364
    - 365
    - 366
    - 367
    - 368
    - 369
    - 370
    - 371
    - 372
    - 373
    - 374
    - 375
    - 376
    - 377
    - 378
    - 379
    - 380
    - 381
    - 382
    - 383
    - 384
    - 385
    - 386
    - 387
    - 388
    - 389
    - 390
    - 391
    - 392
    - 393
    - 394
    - 395
    - 396
    - 397
    - 398
    - 399
    - 400
    - 401
    - 402
    - 403
    - 404
    - 405
    - 406
    - 407
    - 408
    - 409
    - 410
    - 411
    - 412
    - 413
    - 414
    - 415
    - 416
    - 417
    - 418
    - 419
    - 420
    - 421
    - 422
    - 423
    - 424
    - 425
    - 426
    - 427
    - 428
    - 429
    - 430
    - 431
    - 432
    - 433
    - 434
    - 435
    - 436
    - 437
    - 438
    - 439
    - 440
    - 441
    - 442
    - 443
    - 444
    - 445
    - 446
    - 447
    - 448
    - 449
    - 450
    - 451
    - 452
    - 453
    - 454
    - 455
    - 456
    - 457
    - 458
    - 459
    - 460
    - 461
    - 462
    - 463
    - 464
    - 465
    - 466
    - 467
    - 468
    - 469
    - 470
    - 471
    - 472
    - 473
    - 474
    - 475
    - 476
    - 477
    - 478
    - 479
    - 480
    - 481
    - 482
    - 483
    - 484
    - 485
    - 486
    - 487
    - 488
    - 489
    - 490
    - 491
    - 492
    - 493
    - 494
    - 495
    - 496
    - 497
    - 498
    - 499
    - 500
    - 501
    - 502
    - 503
    - 504
    - 505
    - 506
    - 507
    - 508
    - 509
    - 510
    - 511
    - 512
    - 513
    - 514
    - 515
    - 516
    - 517
    - 518
    - 519
    - 520
    - 521
    - 522
    - 523
    - 524
    - 525
    - 526
    - 527
    - 528
    - 529
    - 530
    - 531
    - 532
    - 533
    - 534
    - 535
    - 536
    - 537
    - 538
    - 539
    - 540
    - 541
    - 542
    - 543
    - 544
    - 545
    - 546
    - 547
    - 548
    - 549
    - 550
    - 551
    - 552
    - 553
    - 554
    - 555
    - 556
    - 557
    - 558
    - 559
    - 560
    - 561
    - 562
    - 563
    - 564
    - 565
    - 566
    - 567
    - 568
    - 569
    - 570
    - 571
    - 572
    - 573
    - 574
    - 575
    - 576
    - 577
    - 578
    - 579
    - 580
    - 581
    - 582
    - 583
    - 584
    - 585
    - 586
    - 587
    - 588
    - 589
    - 590
    - 591
    - 592
    - 593
    - 594
    - 595
    - 596
    - 597
    - 598
    - 599
    - 600
    - 601
    - 602
    - 603
    - 604
    - 605
    - 606
    - 607
    - 608
    - 609
    - 610
    - 611
    - 612
    - 613
    - 614
    - 615
    - 616
    - 617
    - 618
    - 619
    - 620
    - 621
    - 622
    - 623
    - 624
    - 625
    - 626
    - 627
    - 628
    - 629
    - 630
    - 631
    - 632
    - 633
    - 634
    - 635
    - 636
    - 637
    - 638
    - 639
    - 640
    - 641
    - 642
    - 643
    - 644
    - 645
    - 646
    - 647
    - 648
    - 649
    - 650
    - 651
    - 652
    - 653
    - 654
    - 655
    - 656
    - 657
    - 658
    - 659
    - 660
    - 661
    - 662
    - 663
    - 664
    - 665
    - 666
    - 667
    - 668
    - 669
    - 670
    - 671
    - 672
    - 673
    - 674
    - 675
    - 676
    - 677
    - 678
    - 679
    - 680
    - 681
    - 682
    - 683
    - 684
    - 685
    - 686
    - 687
    - 688
    - 689
    - 690
    - 691
    - 692
    - 693
    - 694
    - 695
    - 696
    - 697
    - 698
    - 699
    - 700
    - 701
    - 702
    - 703
    - 704
    - 705
    - 706
    - 707
    - 708
    - 709
    - 710
    - 711
    - 712
    - 713
    - 714
    - 715
    - 716
    - 717
    - 718
    - 719
    - 720
    - 721
    - 722
    - 723
    - 724
    - 725
    - 726
    - 727
    - 728
    - 729
    - 730
    - 731
    - 732
    - 733
    - 734
    - 735
    - 736
    - 737
    - 738
    - 739
    - 740
    - 741
    - 742
    - 743
    - 744
    - 745
    - 746
    - 747
    - 748
    - 749
    - 750
    - 751
    - 752
    - 753
    - 754
    - 755
    - 756
    - 757
    - 758
    - 759
    - 760
    - 761
    - 762
    - 763
    - 764
    - 765
    - 766
    - 767
    - 768
    - 769
    - 770
    - 771
    - 772
    - 773
    - 774
    - 775
    - 776
    - 777
    - 778
    - 779
    - 780
    - 781
    - 782
    - 783
    - 784
    - 785
    - 786
    - 787
    - 788
    - 789
    - 790
    - 791
    - 792
    - 793
    - 794
    - 795
    - 796
    - 797
    - 798
    - 799
    - 800
    - 801
    - 802
    - 803
    - 804
    - 805
    - 806
    - 807
    - 808
    - 809
    - 810
    - 811
    - 812
    - 813
    - 814
    - 815
    - 816
    - 817
    - 818
    - 819
    - 820
    - 821
    - 822
    - 823
    - 824
    - 825
    - 826
    - 827
    - 828
    - 829
    - 830
    - 831
    - 832
    - 833
    - 834
    - 835
    - 836
    - 837
    - 838
    - 839
    - 840
    - 841
    - 842
    - 843
    - 844
    - 845
    - 846
    - 847
    - 848
    - 849
    - 850
    - 851
    - 852
    - 853
    - 854
    - 855
    - 856
    - 857
    - 858
    - 859
    - 860
    - 861
    - 862
    - 863
    - 864
    - 865
    - 866
    - 867
    - 868
    - 869
    - 870
    - 871
    - 872
    - 873
    - 874
    - 875
    - 876
    - 877
    - 878
    - 879
    - 880
    - 881
    - 882
    - 883
    - 884
    - 885
    - 886
    - 887
    - 888
    - 889
    - 890
    - 891
    - 892
    - 893
    - 894
    - 895
    - 896
    - 897
    - 898
    - 899
    - 900
    - 901
    - 902
    - 903
    - 904
    - 905
    - 906
    - 907
    - 908
    - 909
    - 910
    - 911
    - 912
    - 913
    - 914
    - 915
    - 916
    - 917
    - 918
    - 919
    - 920
    - 921
    - 922
    - 923
    - 924
    - 925
    - 926
    - 927
    - 928
    - 929
    - 930
    - 931
    - 932
    - 933
    - 934
    - 935
    - 936
    - 937
    - 938
    - 939
    - 940
    - 941
    - 942
    - 943
    - 944
    - 945
    - 946
    - 947
    - 948
    - 949
    - 950
    - 951
    - 952
    - 953
    - 954
    - 955
    - 956
    - 957
    - 958
    - 959
    - 960
    - 961
    - 962
    - 963
    - 964
    - 965
    - 966
    - 967
    - 968
    - 969
    - 970
    - 971
    - 972
    - 973
    - 974
    - 975
    - 976
    - 977
    - 978
    - 979
    - 980
    - 981
    - 982
    - 983
    - 984
    - 985
    - 986
    - 987
    - 988
    - 989
    - 990
    - 991
    - 992
    - 993
    - 994
    - 995
    - 996
    - 997
    - 998
    - 999
    -1000
    -
    // Bitcoin Dev Kit
    -// Written in 2021 by Riccardo Casatta <riccardo@casatta.it>
    -//
    -// Copyright (c) 2020-2021 Bitcoin Dev Kit Developers
    -//
    -// This file is licensed under the Apache License, Version 2.0 <LICENSE-APACHE
    -// or http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
    -// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your option.
    -// You may not use this file except in accordance with one or both of these
    -// licenses.
    -
    -//! Rpc Blockchain
    -//!
    -//! Backend that gets blockchain data from Bitcoin Core RPC
    -//!
    -//! This is an **EXPERIMENTAL** feature, API and other major changes are expected.
    -//!
    -//! ## Example
    -//!
    -//! ```no_run
    -//! # use bdk::blockchain::{RpcConfig, RpcBlockchain, ConfigurableBlockchain, rpc::Auth};
    -//! let config = RpcConfig {
    -//!     url: "127.0.0.1:18332".to_string(),
    -//!     auth: Auth::Cookie {
    -//!         file: "/home/user/.bitcoin/.cookie".into(),
    -//!     },
    -//!     network: bdk::bitcoin::Network::Testnet,
    -//!     wallet_name: "wallet_name".to_string(),
    -//!     sync_params: None,
    -//! };
    -//! let blockchain = RpcBlockchain::from_config(&config);
    -//! ```
    -
    -use crate::bitcoin::hashes::hex::ToHex;
    -use crate::bitcoin::{Network, OutPoint, Transaction, TxOut, Txid};
    -use crate::blockchain::*;
    -use crate::database::{BatchDatabase, BatchOperations, DatabaseUtils};
    -use crate::descriptor::calc_checksum;
    -use crate::error::MissingCachedScripts;
    -use crate::{BlockTime, Error, FeeRate, KeychainKind, LocalUtxo, TransactionDetails};
    -use bitcoin::Script;
    -use bitcoincore_rpc::json::{
    -    GetTransactionResultDetailCategory, ImportMultiOptions, ImportMultiRequest,
    -    ImportMultiRequestScriptPubkey, ImportMultiRescanSince, ListTransactionResult,
    -    ListUnspentResultEntry, ScanningDetails,
    +rpc.rs - source
    1
    +2
    +3
    +4
    +5
    +6
    +7
    +8
    +9
    +10
    +11
    +12
    +13
    +14
    +15
    +16
    +17
    +18
    +19
    +20
    +21
    +22
    +23
    +24
    +25
    +26
    +27
    +28
    +29
    +30
    +31
    +32
    +33
    +34
    +35
    +36
    +37
    +38
    +39
    +40
    +41
    +42
    +43
    +44
    +45
    +46
    +47
    +48
    +49
    +50
    +51
    +52
    +53
    +54
    +55
    +56
    +57
    +58
    +59
    +60
    +61
    +62
    +63
    +64
    +65
    +66
    +67
    +68
    +69
    +70
    +71
    +72
    +73
    +74
    +75
    +76
    +77
    +78
    +79
    +80
    +81
    +82
    +83
    +84
    +85
    +86
    +87
    +88
    +89
    +90
    +91
    +92
    +93
    +94
    +95
    +96
    +97
    +98
    +99
    +100
    +101
    +102
    +103
    +104
    +105
    +106
    +107
    +108
    +109
    +110
    +111
    +112
    +113
    +114
    +115
    +116
    +117
    +118
    +119
    +120
    +121
    +122
    +123
    +124
    +125
    +126
    +127
    +128
    +129
    +130
    +131
    +132
    +133
    +134
    +135
    +136
    +137
    +138
    +139
    +140
    +141
    +142
    +143
    +144
    +145
    +146
    +147
    +148
    +149
    +150
    +151
    +152
    +153
    +154
    +155
    +156
    +157
    +158
    +159
    +160
    +161
    +162
    +163
    +164
    +165
    +166
    +167
    +168
    +169
    +170
    +171
    +172
    +173
    +174
    +175
    +176
    +177
    +178
    +179
    +180
    +181
    +182
    +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
    +245
    +246
    +247
    +248
    +249
    +250
    +251
    +252
    +253
    +254
    +255
    +256
    +257
    +258
    +259
    +260
    +261
    +262
    +263
    +264
    +265
    +266
    +267
    +268
    +269
    +270
    +271
    +272
    +273
    +274
    +275
    +276
    +277
    +278
    +279
    +280
    +281
    +282
    +283
    +284
    +285
    +286
    +287
    +288
    +289
    +290
    +291
    +292
    +293
    +294
    +295
    +296
    +297
    +298
    +299
    +300
    +301
    +302
    +303
    +304
    +305
    +306
    +307
    +308
    +309
    +310
    +311
    +312
    +313
    +314
    +315
    +316
    +317
    +318
    +319
    +320
    +321
    +322
    +323
    +324
    +325
    +326
    +327
    +328
    +329
    +330
    +331
    +332
    +333
    +334
    +335
    +336
    +337
    +338
    +339
    +340
    +341
    +342
    +343
    +344
    +345
    +346
    +347
    +348
    +349
    +350
    +351
    +352
    +353
    +354
    +355
    +356
    +357
    +358
    +359
    +360
    +361
    +362
    +363
    +364
    +365
    +366
    +367
    +368
    +369
    +370
    +371
    +372
    +373
    +374
    +375
    +376
    +377
    +378
    +379
    +380
    +381
    +382
    +383
    +384
    +385
    +386
    +387
    +388
    +389
    +390
    +391
    +392
    +393
    +394
    +395
    +396
    +397
    +398
    +399
    +400
    +401
    +402
    +403
    +404
    +405
    +406
    +407
    +408
    +409
    +410
    +411
    +412
    +413
    +414
    +415
    +416
    +417
    +418
    +419
    +420
    +421
    +422
    +423
    +424
    +425
    +426
    +427
    +428
    +429
    +430
    +431
    +432
    +433
    +434
    +435
    +436
    +437
    +438
    +439
    +440
    +441
    +442
    +443
    +444
    +445
    +446
    +447
    +448
    +449
    +450
    +451
    +452
    +453
    +454
    +455
    +456
    +457
    +458
    +459
    +460
    +461
    +462
    +463
    +464
    +465
    +466
    +467
    +468
    +469
    +470
    +471
    +472
    +473
    +474
    +475
    +476
    +477
    +478
    +479
    +480
    +481
    +482
    +483
    +484
    +485
    +486
    +487
    +488
    +489
    +490
    +491
    +492
    +493
    +494
    +495
    +496
    +497
    +498
    +499
    +500
    +501
    +502
    +503
    +504
    +505
    +506
    +507
    +508
    +509
    +510
    +511
    +512
    +513
    +514
    +515
    +516
    +517
    +518
    +519
    +520
    +521
    +522
    +523
    +524
    +525
    +526
    +527
    +528
    +529
    +530
    +531
    +532
    +533
    +534
    +535
    +536
    +537
    +538
    +539
    +540
    +541
    +542
    +543
    +544
    +545
    +546
    +547
    +548
    +549
    +550
    +551
    +552
    +553
    +554
    +555
    +556
    +557
    +558
    +559
    +560
    +561
    +562
    +563
    +564
    +565
    +566
    +567
    +568
    +569
    +570
    +571
    +572
    +573
    +574
    +575
    +576
    +577
    +578
    +579
    +580
    +581
    +582
    +583
    +584
    +585
    +586
    +587
    +588
    +589
    +590
    +591
    +592
    +593
    +594
    +595
    +596
    +597
    +598
    +599
    +600
    +601
    +602
    +603
    +604
    +605
    +606
    +607
    +608
    +609
    +610
    +611
    +612
    +613
    +614
    +615
    +616
    +617
    +618
    +619
    +620
    +621
    +622
    +623
    +624
    +625
    +626
    +627
    +628
    +629
    +630
    +631
    +632
    +633
    +634
    +635
    +636
    +637
    +638
    +639
    +640
    +641
    +642
    +643
    +644
    +645
    +646
    +647
    +648
    +649
    +650
    +651
    +652
    +653
    +654
    +655
    +656
    +657
    +658
    +659
    +660
    +661
    +662
    +663
    +664
    +665
    +666
    +667
    +668
    +669
    +670
    +671
    +672
    +673
    +674
    +675
    +676
    +677
    +678
    +679
    +680
    +681
    +682
    +683
    +684
    +685
    +686
    +687
    +688
    +689
    +690
    +691
    +692
    +693
    +694
    +695
    +696
    +697
    +698
    +699
    +700
    +701
    +702
    +703
    +704
    +705
    +706
    +707
    +708
    +709
    +710
    +711
    +712
    +713
    +714
    +715
    +716
    +717
    +718
    +719
    +720
    +721
    +722
    +723
    +724
    +725
    +726
    +727
    +728
    +729
    +730
    +731
    +732
    +733
    +734
    +735
    +736
    +737
    +738
    +739
    +740
    +741
    +742
    +743
    +744
    +745
    +746
    +747
    +748
    +749
    +750
    +751
    +752
    +753
    +754
    +755
    +756
    +757
    +758
    +759
    +760
    +761
    +762
    +763
    +764
    +765
    +766
    +767
    +768
    +769
    +770
    +771
    +772
    +773
    +774
    +775
    +776
    +777
    +778
    +779
    +780
    +781
    +782
    +783
    +784
    +785
    +786
    +787
    +788
    +789
    +790
    +791
    +792
    +793
    +794
    +795
    +796
    +797
    +798
    +799
    +800
    +801
    +802
    +803
    +804
    +805
    +806
    +807
    +808
    +809
    +810
    +811
    +812
    +813
    +814
    +815
    +816
    +817
    +818
    +819
    +820
    +821
    +822
    +823
    +824
    +825
    +826
    +827
    +828
    +829
    +830
    +831
    +832
    +833
    +834
    +835
    +836
    +837
    +838
    +839
    +840
    +841
    +842
    +843
    +844
    +845
    +846
    +847
    +848
    +849
    +850
    +851
    +852
    +853
    +854
    +855
    +856
    +857
    +858
    +859
    +860
    +861
    +862
    +863
    +864
    +865
    +866
    +867
    +868
    +869
    +870
    +871
    +872
    +873
    +874
    +875
    +876
    +877
    +878
    +879
    +880
    +881
    +882
    +883
    +884
    +885
    +886
    +887
    +888
    +889
    +890
    +891
    +892
    +893
    +894
    +895
    +896
    +897
    +898
    +899
    +900
    +901
    +902
    +903
    +904
    +905
    +906
    +907
    +908
    +909
    +910
    +911
    +912
    +913
    +914
    +915
    +916
    +917
    +918
    +919
    +920
    +921
    +922
    +923
    +924
    +925
    +926
    +927
    +928
    +929
    +930
    +931
    +932
    +933
    +934
    +935
    +936
    +937
    +938
    +939
    +940
    +941
    +942
    +943
    +944
    +945
    +946
    +947
    +948
    +949
    +950
    +951
    +952
    +953
    +954
    +955
    +956
    +957
    +958
    +959
    +960
    +961
    +962
    +963
    +964
    +965
    +966
    +967
    +968
    +969
    +970
    +971
    +972
    +973
    +974
    +975
    +976
    +977
    +978
    +979
    +980
    +981
    +982
    +983
    +984
    +985
    +986
    +987
    +988
    +989
    +990
    +991
    +992
    +993
    +994
    +995
    +996
    +997
    +998
    +999
    +1000
    +
    // Bitcoin Dev Kit
    +// Written in 2021 by Riccardo Casatta <riccardo@casatta.it>
    +//
    +// Copyright (c) 2020-2021 Bitcoin Dev Kit Developers
    +//
    +// This file is licensed under the Apache License, Version 2.0 <LICENSE-APACHE
    +// or http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
    +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your option.
    +// You may not use this file except in accordance with one or both of these
    +// licenses.
    +
    +//! Rpc Blockchain
    +//!
    +//! Backend that gets blockchain data from Bitcoin Core RPC
    +//!
    +//! This is an **EXPERIMENTAL** feature, API and other major changes are expected.
    +//!
    +//! ## Example
    +//!
    +//! ```no_run
    +//! # use bdk::blockchain::{RpcConfig, RpcBlockchain, ConfigurableBlockchain, rpc::Auth};
    +//! let config = RpcConfig {
    +//!     url: "127.0.0.1:18332".to_string(),
    +//!     auth: Auth::Cookie {
    +//!         file: "/home/user/.bitcoin/.cookie".into(),
    +//!     },
    +//!     network: bdk::bitcoin::Network::Testnet,
    +//!     wallet_name: "wallet_name".to_string(),
    +//!     sync_params: None,
    +//! };
    +//! let blockchain = RpcBlockchain::from_config(&config);
    +//! ```
    +
    +use crate::bitcoin::hashes::hex::ToHex;
    +use crate::bitcoin::{Network, OutPoint, Transaction, TxOut, Txid};
    +use crate::blockchain::*;
    +use crate::database::{BatchDatabase, BatchOperations, DatabaseUtils};
    +use crate::descriptor::calc_checksum;
    +use crate::error::MissingCachedScripts;
    +use crate::{BlockTime, Error, FeeRate, KeychainKind, LocalUtxo, TransactionDetails};
    +use bitcoin::Script;
    +use bitcoincore_rpc::json::{
    +    GetTransactionResultDetailCategory, ImportMultiOptions, ImportMultiRequest,
    +    ImportMultiRequestScriptPubkey, ImportMultiRescanSince, ListTransactionResult,
    +    ListUnspentResultEntry, ScanningDetails,
     };
    -use bitcoincore_rpc::jsonrpc::serde_json::{json, Value};
    -use bitcoincore_rpc::Auth as RpcAuth;
    -use bitcoincore_rpc::{Client, RpcApi};
    -use log::{debug, info};
    -use serde::{Deserialize, Serialize};
    -use std::collections::{HashMap, HashSet};
    -use std::ops::Deref;
    -use std::path::PathBuf;
    -use std::thread;
    -use std::time::Duration;
    -
    -/// The main struct for RPC backend implementing the [crate::blockchain::Blockchain] trait
    -#[derive(Debug)]
    -pub struct RpcBlockchain {
    -    /// Rpc client to the node, includes the wallet name
    -    client: Client,
    -    /// Whether the wallet is a "descriptor" or "legacy" wallet in Core
    -    is_descriptors: bool,
    -    /// Blockchain capabilities, cached here at startup
    -    capabilities: HashSet<Capability>,
    -    /// Sync parameters.
    -    sync_params: RpcSyncParams,
    +use bitcoincore_rpc::jsonrpc::serde_json::{json, Value};
    +use bitcoincore_rpc::Auth as RpcAuth;
    +use bitcoincore_rpc::{Client, RpcApi};
    +use log::{debug, info};
    +use serde::{Deserialize, Serialize};
    +use std::collections::{HashMap, HashSet};
    +use std::ops::Deref;
    +use std::path::PathBuf;
    +use std::thread;
    +use std::time::Duration;
    +
    +/// The main struct for RPC backend implementing the [crate::blockchain::Blockchain] trait
    +#[derive(Debug)]
    +pub struct RpcBlockchain {
    +    /// Rpc client to the node, includes the wallet name
    +    client: Client,
    +    /// Whether the wallet is a "descriptor" or "legacy" wallet in Core
    +    is_descriptors: bool,
    +    /// Blockchain capabilities, cached here at startup
    +    capabilities: HashSet<Capability>,
    +    /// Sync parameters.
    +    sync_params: RpcSyncParams,
     }
     
    -impl Deref for RpcBlockchain {
    -    type Target = Client;
    +impl Deref for RpcBlockchain {
    +    type Target = Client;
     
    -    fn deref(&self) -> &Self::Target {
    -        &self.client
    +    fn deref(&self) -> &Self::Target {
    +        &self.client
         }
     }
     
    -/// RpcBlockchain configuration options
    -#[derive(Debug, Serialize, Deserialize, Clone, PartialEq, Eq)]
    -pub struct RpcConfig {
    -    /// The bitcoin node url
    -    pub url: String,
    -    /// The bitcoin node authentication mechanism
    -    pub auth: Auth,
    -    /// The network we are using (it will be checked the bitcoin node network matches this)
    -    pub network: Network,
    -    /// The wallet name in the bitcoin node, consider using [crate::wallet::wallet_name_from_descriptor] for this
    -    pub wallet_name: String,
    -    /// Sync parameters
    -    pub sync_params: Option<RpcSyncParams>,
    +/// RpcBlockchain configuration options
    +#[derive(Debug, Serialize, Deserialize, Clone, PartialEq, Eq)]
    +pub struct RpcConfig {
    +    /// The bitcoin node url
    +    pub url: String,
    +    /// The bitcoin node authentication mechanism
    +    pub auth: Auth,
    +    /// The network we are using (it will be checked the bitcoin node network matches this)
    +    pub network: Network,
    +    /// The wallet name in the bitcoin node, consider using [crate::wallet::wallet_name_from_descriptor] for this
    +    pub wallet_name: String,
    +    /// Sync parameters
    +    pub sync_params: Option<RpcSyncParams>,
     }
     
    -/// Sync parameters for Bitcoin Core RPC.
    -///
    -/// In general, BDK tries to sync `scriptPubKey`s cached in [`crate::database::Database`] with
    -/// `scriptPubKey`s imported in the Bitcoin Core Wallet. These parameters are used for determining
    -/// how the `importdescriptors` RPC calls are to be made.
    -#[derive(Debug, Serialize, Deserialize, Clone, PartialEq, Eq)]
    -pub struct RpcSyncParams {
    -    /// The minimum number of scripts to scan for on initial sync.
    -    pub start_script_count: usize,
    -    /// Time in unix seconds in which initial sync will start scanning from (0 to start from genesis).
    -    pub start_time: u64,
    -    /// Forces every sync to use `start_time` as import timestamp.
    -    pub force_start_time: bool,
    -    /// RPC poll rate (in seconds) to get state updates.
    -    pub poll_rate_sec: u64,
    +/// Sync parameters for Bitcoin Core RPC.
    +///
    +/// In general, BDK tries to sync `scriptPubKey`s cached in [`crate::database::Database`] with
    +/// `scriptPubKey`s imported in the Bitcoin Core Wallet. These parameters are used for determining
    +/// how the `importdescriptors` RPC calls are to be made.
    +#[derive(Debug, Serialize, Deserialize, Clone, PartialEq, Eq)]
    +pub struct RpcSyncParams {
    +    /// The minimum number of scripts to scan for on initial sync.
    +    pub start_script_count: usize,
    +    /// Time in unix seconds in which initial sync will start scanning from (0 to start from genesis).
    +    pub start_time: u64,
    +    /// Forces every sync to use `start_time` as import timestamp.
    +    pub force_start_time: bool,
    +    /// RPC poll rate (in seconds) to get state updates.
    +    pub poll_rate_sec: u64,
     }
     
    -impl Default for RpcSyncParams {
    -    fn default() -> Self {
    -        Self {
    -            start_script_count: 100,
    -            start_time: 0,
    -            force_start_time: false,
    -            poll_rate_sec: 3,
    +impl Default for RpcSyncParams {
    +    fn default() -> Self {
    +        Self {
    +            start_script_count: 100,
    +            start_time: 0,
    +            force_start_time: false,
    +            poll_rate_sec: 3,
             }
         }
     }
     
    -/// This struct is equivalent to [bitcoincore_rpc::Auth] but it implements [serde::Serialize]
    -/// To be removed once upstream equivalent is implementing Serialize (json serialization format
    -/// should be the same), see [rust-bitcoincore-rpc/pull/181](https://github.com/rust-bitcoin/rust-bitcoincore-rpc/pull/181)
    -#[derive(Clone, Debug, Hash, Eq, PartialEq, Ord, PartialOrd, Serialize, Deserialize)]
    -#[serde(rename_all = "snake_case")]
    -#[serde(untagged)]
    -pub enum Auth {
    -    /// None authentication
    -    None,
    -    /// Authentication with username and password, usually [Auth::Cookie] should be preferred
    -    UserPass {
    -        /// Username
    -        username: String,
    -        /// Password
    -        password: String,
    +/// This struct is equivalent to [bitcoincore_rpc::Auth] but it implements [serde::Serialize]
    +/// To be removed once upstream equivalent is implementing Serialize (json serialization format
    +/// should be the same), see [rust-bitcoincore-rpc/pull/181](https://github.com/rust-bitcoin/rust-bitcoincore-rpc/pull/181)
    +#[derive(Clone, Debug, Hash, Eq, PartialEq, Ord, PartialOrd, Serialize, Deserialize)]
    +#[serde(rename_all = "snake_case")]
    +#[serde(untagged)]
    +pub enum Auth {
    +    /// None authentication
    +    None,
    +    /// Authentication with username and password, usually [Auth::Cookie] should be preferred
    +    UserPass {
    +        /// Username
    +        username: String,
    +        /// Password
    +        password: String,
         },
    -    /// Authentication with a cookie file
    -    Cookie {
    -        /// Cookie file
    -        file: PathBuf,
    +    /// Authentication with a cookie file
    +    Cookie {
    +        /// Cookie file
    +        file: PathBuf,
         },
     }
     
    -impl From<Auth> for RpcAuth {
    -    fn from(auth: Auth) -> Self {
    -        match auth {
    -            Auth::None => RpcAuth::None,
    -            Auth::UserPass { username, password } => RpcAuth::UserPass(username, password),
    -            Auth::Cookie { file } => RpcAuth::CookieFile(file),
    +impl From<Auth> for RpcAuth {
    +    fn from(auth: Auth) -> Self {
    +        match auth {
    +            Auth::None => RpcAuth::None,
    +            Auth::UserPass { username, password } => RpcAuth::UserPass(username, password),
    +            Auth::Cookie { file } => RpcAuth::CookieFile(file),
             }
         }
     }
     
    -impl Blockchain for RpcBlockchain {
    -    fn get_capabilities(&self) -> HashSet<Capability> {
    -        self.capabilities.clone()
    +impl Blockchain for RpcBlockchain {
    +    fn get_capabilities(&self) -> HashSet<Capability> {
    +        self.capabilities.clone()
         }
     
    -    fn broadcast(&self, tx: &Transaction) -> Result<(), Error> {
    -        Ok(self.client.send_raw_transaction(tx).map(|_| ())?)
    +    fn broadcast(&self, tx: &Transaction) -> Result<(), Error> {
    +        Ok(self.client.send_raw_transaction(tx).map(|_| ())?)
         }
     
    -    fn estimate_fee(&self, target: usize) -> Result<FeeRate, Error> {
    -        let sat_per_kb = self
    -            .client
    -            .estimate_smart_fee(target as u16, None)?
    -            .fee_rate
    -            .ok_or(Error::FeeRateUnavailable)?
    -            .to_sat() as f64;
    +    fn estimate_fee(&self, target: usize) -> Result<FeeRate, Error> {
    +        let sat_per_kb = self
    +            .client
    +            .estimate_smart_fee(target as u16, None)?
    +            .fee_rate
    +            .ok_or(Error::FeeRateUnavailable)?
    +            .to_sat() as f64;
     
    -        Ok(FeeRate::from_sat_per_vb((sat_per_kb / 1000f64) as f32))
    +        Ok(FeeRate::from_sat_per_vb((sat_per_kb / 1000f64) as f32))
         }
     }
     
    -impl GetTx for RpcBlockchain {
    -    fn get_tx(&self, txid: &Txid) -> Result<Option<Transaction>, Error> {
    -        Ok(Some(self.client.get_raw_transaction(txid, None)?))
    +impl GetTx for RpcBlockchain {
    +    fn get_tx(&self, txid: &Txid) -> Result<Option<Transaction>, Error> {
    +        Ok(Some(self.client.get_raw_transaction(txid, None)?))
         }
     }
     
    -impl GetHeight for RpcBlockchain {
    -    fn get_height(&self) -> Result<u32, Error> {
    -        Ok(self.client.get_blockchain_info().map(|i| i.blocks as u32)?)
    +impl GetHeight for RpcBlockchain {
    +    fn get_height(&self) -> Result<u32, Error> {
    +        Ok(self.client.get_blockchain_info().map(|i| i.blocks as u32)?)
         }
     }
     
    -impl GetBlockHash for RpcBlockchain {
    -    fn get_block_hash(&self, height: u64) -> Result<BlockHash, Error> {
    -        Ok(self.client.get_block_hash(height)?)
    +impl GetBlockHash for RpcBlockchain {
    +    fn get_block_hash(&self, height: u64) -> Result<BlockHash, Error> {
    +        Ok(self.client.get_block_hash(height)?)
         }
     }
     
    -impl WalletSync for RpcBlockchain {
    -    fn wallet_setup<D>(&self, db: &mut D, prog: Box<dyn Progress>) -> Result<(), Error>
    -    where
    -        D: BatchDatabase,
    +impl WalletSync for RpcBlockchain {
    +    fn wallet_setup<D>(&self, db: &mut D, prog: Box<dyn Progress>) -> Result<(), Error>
    +    where
    +        D: BatchDatabase,
         {
    -        let batch = DbState::new(db, &self.sync_params, &*prog)?
    -            .sync_with_core(&self.client, self.is_descriptors)?
    -            .as_db_batch()?;
    +        let batch = DbState::new(db, &self.sync_params, &*prog)?
    +            .sync_with_core(&self.client, self.is_descriptors)?
    +            .as_db_batch()?;
     
    -        db.commit_batch(batch)
    +        db.commit_batch(batch)
         }
     }
     
    -impl ConfigurableBlockchain for RpcBlockchain {
    -    type Config = RpcConfig;
    -
    -    /// Returns RpcBlockchain backend creating an RPC client to a specific wallet named as the descriptor's checksum
    -    /// if it's the first time it creates the wallet in the node and upon return is granted the wallet is loaded
    -    fn from_config(config: &Self::Config) -> Result<Self, Error> {
    -        let wallet_url = format!("{}/wallet/{}", config.url, &config.wallet_name);
    -
    -        let client = Client::new(wallet_url.as_str(), config.auth.clone().into())?;
    -        let rpc_version = client.version()?;
    -
    -        info!("connected to '{}' with auth: {:?}", wallet_url, config.auth);
    -
    -        if client.list_wallets()?.contains(&config.wallet_name) {
    -            info!("wallet already loaded: {}", config.wallet_name);
    -        } else if list_wallet_dir(&client)?.contains(&config.wallet_name) {
    -            client.load_wallet(&config.wallet_name)?;
    -            info!("wallet loaded: {}", config.wallet_name);
    -        } else {
    -            // pre-0.21 use legacy wallets
    -            if rpc_version < 210_000 {
    -                client.create_wallet(&config.wallet_name, Some(true), None, None, None)?;
    -            } else {
    -                // TODO: move back to api call when https://github.com/rust-bitcoin/rust-bitcoincore-rpc/issues/225 is closed
    -                let args = [
    -                    Value::String(config.wallet_name.clone()),
    -                    Value::Bool(true),
    -                    Value::Bool(false),
    -                    Value::Null,
    -                    Value::Bool(false),
    -                    Value::Bool(true),
    +impl ConfigurableBlockchain for RpcBlockchain {
    +    type Config = RpcConfig;
    +
    +    /// Returns RpcBlockchain backend creating an RPC client to a specific wallet named as the descriptor's checksum
    +    /// if it's the first time it creates the wallet in the node and upon return is granted the wallet is loaded
    +    fn from_config(config: &Self::Config) -> Result<Self, Error> {
    +        let wallet_url = format!("{}/wallet/{}", config.url, &config.wallet_name);
    +
    +        let client = Client::new(wallet_url.as_str(), config.auth.clone().into())?;
    +        let rpc_version = client.version()?;
    +
    +        info!("connected to '{}' with auth: {:?}", wallet_url, config.auth);
    +
    +        if client.list_wallets()?.contains(&config.wallet_name) {
    +            info!("wallet already loaded: {}", config.wallet_name);
    +        } else if list_wallet_dir(&client)?.contains(&config.wallet_name) {
    +            client.load_wallet(&config.wallet_name)?;
    +            info!("wallet loaded: {}", config.wallet_name);
    +        } else {
    +            // pre-0.21 use legacy wallets
    +            if rpc_version < 210_000 {
    +                client.create_wallet(&config.wallet_name, Some(true), None, None, None)?;
    +            } else {
    +                // TODO: move back to api call when https://github.com/rust-bitcoin/rust-bitcoincore-rpc/issues/225 is closed
    +                let args = [
    +                    Value::String(config.wallet_name.clone()),
    +                    Value::Bool(true),
    +                    Value::Bool(false),
    +                    Value::Null,
    +                    Value::Bool(false),
    +                    Value::Bool(true),
                     ];
    -                let _: Value = client.call("createwallet", &args)?;
    +                let _: Value = client.call("createwallet", &args)?;
                 }
     
    -            info!("wallet created: {}", config.wallet_name);
    +            info!("wallet created: {}", config.wallet_name);
             }
     
    -        let is_descriptors = is_wallet_descriptor(&client)?;
    +        let is_descriptors = is_wallet_descriptor(&client)?;
     
    -        let blockchain_info = client.get_blockchain_info()?;
    -        let network = match blockchain_info.chain.as_str() {
    -            "main" => Network::Bitcoin,
    -            "test" => Network::Testnet,
    -            "regtest" => Network::Regtest,
    -            "signet" => Network::Signet,
    -            _ => return Err(Error::Generic("Invalid network".to_string())),
    +        let blockchain_info = client.get_blockchain_info()?;
    +        let network = match blockchain_info.chain.as_str() {
    +            "main" => Network::Bitcoin,
    +            "test" => Network::Testnet,
    +            "regtest" => Network::Regtest,
    +            "signet" => Network::Signet,
    +            _ => return Err(Error::Generic("Invalid network".to_string())),
             };
    -        if network != config.network {
    -            return Err(Error::InvalidNetwork {
    -                requested: config.network,
    -                found: network,
    +        if network != config.network {
    +            return Err(Error::InvalidNetwork {
    +                requested: config.network,
    +                found: network,
                 });
             }
     
    -        let mut capabilities: HashSet<_> = vec![Capability::FullHistory].into_iter().collect();
    -        if rpc_version >= 210_000 {
    -            let info: HashMap<String, Value> = client.call("getindexinfo", &[]).unwrap();
    -            if info.contains_key("txindex") {
    -                capabilities.insert(Capability::GetAnyTx);
    -                capabilities.insert(Capability::AccurateFees);
    +        let mut capabilities: HashSet<_> = vec![Capability::FullHistory].into_iter().collect();
    +        if rpc_version >= 210_000 {
    +            let info: HashMap<String, Value> = client.call("getindexinfo", &[]).unwrap();
    +            if info.contains_key("txindex") {
    +                capabilities.insert(Capability::GetAnyTx);
    +                capabilities.insert(Capability::AccurateFees);
                 }
             }
     
    -        Ok(RpcBlockchain {
    -            client,
    -            capabilities,
    -            is_descriptors,
    -            sync_params: config.sync_params.clone().unwrap_or_default(),
    +        Ok(RpcBlockchain {
    +            client,
    +            capabilities,
    +            is_descriptors,
    +            sync_params: config.sync_params.clone().unwrap_or_default(),
             })
         }
     }
     
    -/// return the wallets available in default wallet directory
    -//TODO use bitcoincore_rpc method when PR #179 lands
    -fn list_wallet_dir(client: &Client) -> Result<Vec<String>, Error> {
    -    #[derive(Deserialize)]
    -    struct Name {
    -        name: String,
    +/// return the wallets available in default wallet directory
    +//TODO use bitcoincore_rpc method when PR #179 lands
    +fn list_wallet_dir(client: &Client) -> Result<Vec<String>, Error> {
    +    #[derive(Deserialize)]
    +    struct Name {
    +        name: String,
         }
    -    #[derive(Deserialize)]
    -    struct CallResult {
    -        wallets: Vec<Name>,
    +    #[derive(Deserialize)]
    +    struct CallResult {
    +        wallets: Vec<Name>,
         }
     
    -    let result: CallResult = client.call("listwalletdir", &[])?;
    -    Ok(result.wallets.into_iter().map(|n| n.name).collect())
    +    let result: CallResult = client.call("listwalletdir", &[])?;
    +    Ok(result.wallets.into_iter().map(|n| n.name).collect())
     }
     
    -/// Represents the state of the [`crate::database::Database`].
    -struct DbState<'a, D> {
    -    db: &'a D,
    -    params: &'a RpcSyncParams,
    -    prog: &'a dyn Progress,
    -
    -    ext_spks: Vec<Script>,
    -    int_spks: Vec<Script>,
    -    txs: HashMap<Txid, TransactionDetails>,
    -    utxos: HashSet<LocalUtxo>,
    -    last_indexes: HashMap<KeychainKind, u32>,
    -
    -    // "deltas" to apply to database
    -    retained_txs: HashSet<Txid>, // txs to retain (everything else should be deleted)
    -    updated_txs: HashSet<Txid>,  // txs to update
    -    updated_utxos: HashSet<LocalUtxo>, // utxos to update
    -}
    -
    -impl<'a, D: BatchDatabase> DbState<'a, D> {
    -    /// Obtain [DbState] from [crate::database::Database].
    -    fn new(db: &'a D, params: &'a RpcSyncParams, prog: &'a dyn Progress) -> Result<Self, Error> {
    -        let ext_spks = db.iter_script_pubkeys(Some(KeychainKind::External))?;
    -        let int_spks = db.iter_script_pubkeys(Some(KeychainKind::Internal))?;
    -
    -        // This is a hack to see whether atleast one of the keychains comes from a derivable
    -        // descriptor. We assume that non-derivable descriptors always has a script count of 1.
    -        let last_count = std::cmp::max(ext_spks.len(), int_spks.len());
    -        let has_derivable = last_count > 1;
    -
    -        // If at least one descriptor is derivable, we need to ensure scriptPubKeys are sufficiently
    -        // cached.
    -        if has_derivable && last_count < params.start_script_count {
    -            let inner_err = MissingCachedScripts {
    -                last_count,
    -                missing_count: params.start_script_count - last_count,
    +/// Represents the state of the [`crate::database::Database`].
    +struct DbState<'a, D> {
    +    db: &'a D,
    +    params: &'a RpcSyncParams,
    +    prog: &'a dyn Progress,
    +
    +    ext_spks: Vec<Script>,
    +    int_spks: Vec<Script>,
    +    txs: HashMap<Txid, TransactionDetails>,
    +    utxos: HashSet<LocalUtxo>,
    +    last_indexes: HashMap<KeychainKind, u32>,
    +
    +    // "deltas" to apply to database
    +    retained_txs: HashSet<Txid>, // txs to retain (everything else should be deleted)
    +    updated_txs: HashSet<Txid>,  // txs to update
    +    updated_utxos: HashSet<LocalUtxo>, // utxos to update
    +}
    +
    +impl<'a, D: BatchDatabase> DbState<'a, D> {
    +    /// Obtain [DbState] from [crate::database::Database].
    +    fn new(db: &'a D, params: &'a RpcSyncParams, prog: &'a dyn Progress) -> Result<Self, Error> {
    +        let ext_spks = db.iter_script_pubkeys(Some(KeychainKind::External))?;
    +        let int_spks = db.iter_script_pubkeys(Some(KeychainKind::Internal))?;
    +
    +        // This is a hack to see whether atleast one of the keychains comes from a derivable
    +        // descriptor. We assume that non-derivable descriptors always has a script count of 1.
    +        let last_count = std::cmp::max(ext_spks.len(), int_spks.len());
    +        let has_derivable = last_count > 1;
    +
    +        // If at least one descriptor is derivable, we need to ensure scriptPubKeys are sufficiently
    +        // cached.
    +        if has_derivable && last_count < params.start_script_count {
    +            let inner_err = MissingCachedScripts {
    +                last_count,
    +                missing_count: params.start_script_count - last_count,
                 };
    -            debug!("requesting more spks with: {:?}", inner_err);
    -            return Err(Error::MissingCachedScripts(inner_err));
    +            debug!("requesting more spks with: {:?}", inner_err);
    +            return Err(Error::MissingCachedScripts(inner_err));
             }
     
    -        let txs = db
    -            .iter_txs(true)?
    -            .into_iter()
    -            .map(|tx| (tx.txid, tx))
    -            .collect::<HashMap<_, _>>();
    +        let txs = db
    +            .iter_txs(true)?
    +            .into_iter()
    +            .map(|tx| (tx.txid, tx))
    +            .collect::<HashMap<_, _>>();
     
    -        let utxos = db.iter_utxos()?.into_iter().collect::<HashSet<_>>();
    +        let utxos = db.iter_utxos()?.into_iter().collect::<HashSet<_>>();
     
    -        let last_indexes = [KeychainKind::External, KeychainKind::Internal]
    -            .iter()
    -            .filter_map(|keychain| match db.get_last_index(*keychain) {
    -                Ok(li_opt) => li_opt.map(|li| Ok((*keychain, li))),
    -                Err(err) => Some(Err(err)),
    +        let last_indexes = [KeychainKind::External, KeychainKind::Internal]
    +            .iter()
    +            .filter_map(|keychain| match db.get_last_index(*keychain) {
    +                Ok(li_opt) => li_opt.map(|li| Ok((*keychain, li))),
    +                Err(err) => Some(Err(err)),
                 })
    -            .collect::<Result<HashMap<_, _>, Error>>()?;
    -
    -        info!("initial db state: txs={} utxos={}", txs.len(), utxos.len());
    -
    -        // "delta" fields
    -        let retained_txs = HashSet::with_capacity(txs.len());
    -        let updated_txs = HashSet::with_capacity(txs.len());
    -        let updated_utxos = HashSet::with_capacity(utxos.len());
    -
    -        Ok(Self {
    -            db,
    -            params,
    -            prog,
    -            ext_spks,
    -            int_spks,
    -            txs,
    -            utxos,
    -            last_indexes,
    -            retained_txs,
    -            updated_txs,
    -            updated_utxos,
    +            .collect::<Result<HashMap<_, _>, Error>>()?;
    +
    +        info!("initial db state: txs={} utxos={}", txs.len(), utxos.len());
    +
    +        // "delta" fields
    +        let retained_txs = HashSet::with_capacity(txs.len());
    +        let updated_txs = HashSet::with_capacity(txs.len());
    +        let updated_utxos = HashSet::with_capacity(utxos.len());
    +
    +        Ok(Self {
    +            db,
    +            params,
    +            prog,
    +            ext_spks,
    +            int_spks,
    +            txs,
    +            utxos,
    +            last_indexes,
    +            retained_txs,
    +            updated_txs,
    +            updated_utxos,
             })
         }
     
    -    /// Sync states of [BatchDatabase] and Core wallet.
    -    /// First we import all `scriptPubKey`s from database into core wallet
    -    fn sync_with_core(&mut self, client: &Client, is_descriptor: bool) -> Result<&mut Self, Error> {
    -        // this tells Core wallet where to sync from for imported scripts
    -        let start_epoch = if self.params.force_start_time {
    -            self.params.start_time
    -        } else {
    -            self.db
    -                .get_sync_time()?
    -                .map_or(self.params.start_time, |st| st.block_time.timestamp)
    +    /// Sync states of [BatchDatabase] and Core wallet.
    +    /// First we import all `scriptPubKey`s from database into core wallet
    +    fn sync_with_core(&mut self, client: &Client, is_descriptor: bool) -> Result<&mut Self, Error> {
    +        // this tells Core wallet where to sync from for imported scripts
    +        let start_epoch = if self.params.force_start_time {
    +            self.params.start_time
    +        } else {
    +            self.db
    +                .get_sync_time()?
    +                .map_or(self.params.start_time, |st| st.block_time.timestamp)
             };
     
    -        // sync scriptPubKeys from Database to Core wallet
    -        let scripts_iter = self.ext_spks.iter().chain(&self.int_spks);
    -        if is_descriptor {
    -            import_descriptors(client, start_epoch, scripts_iter)?;
    -        } else {
    -            import_multi(client, start_epoch, scripts_iter)?;
    +        // sync scriptPubKeys from Database to Core wallet
    +        let scripts_iter = self.ext_spks.iter().chain(&self.int_spks);
    +        if is_descriptor {
    +            import_descriptors(client, start_epoch, scripts_iter)?;
    +        } else {
    +            import_multi(client, start_epoch, scripts_iter)?;
             }
     
    -        // wait for Core wallet to rescan (TODO: maybe make this async)
    -        await_wallet_scan(client, self.params.poll_rate_sec, self.prog)?;
    +        // wait for Core wallet to rescan (TODO: maybe make this async)
    +        await_wallet_scan(client, self.params.poll_rate_sec, self.prog)?;
     
    -        // obtain iterator of pagenated `listtransactions` RPC calls
    -        const LIST_TX_PAGE_SIZE: usize = 100; // item count per page
    -        let tx_iter = list_transactions(client, LIST_TX_PAGE_SIZE)?.filter(|item| {
    -            // filter out conflicting transactions - only accept transactions that are already
    -            // confirmed, or exists in mempool
    -            item.info.confirmations > 0 || client.get_mempool_entry(&item.info.txid).is_ok()
    +        // obtain iterator of pagenated `listtransactions` RPC calls
    +        const LIST_TX_PAGE_SIZE: usize = 100; // item count per page
    +        let tx_iter = list_transactions(client, LIST_TX_PAGE_SIZE)?.filter(|item| {
    +            // filter out conflicting transactions - only accept transactions that are already
    +            // confirmed, or exists in mempool
    +            item.info.confirmations > 0 || client.get_mempool_entry(&item.info.txid).is_ok()
             });
     
    -        // iterate through chronological results of `listtransactions`
    -        for tx_res in tx_iter {
    -            let mut updated = false;
    +        // iterate through chronological results of `listtransactions`
    +        for tx_res in tx_iter {
    +            let mut updated = false;
     
    -            let db_tx = self.txs.entry(tx_res.info.txid).or_insert_with(|| {
    -                updated = true;
    -                TransactionDetails {
    -                    txid: tx_res.info.txid,
    -                    transaction: None,
    +            let db_tx = self.txs.entry(tx_res.info.txid).or_insert_with(|| {
    +                updated = true;
    +                TransactionDetails {
    +                    txid: tx_res.info.txid,
    +                    transaction: None,
     
    -                    received: 0,
    -                    sent: 0,
    -                    fee: None,
    -                    confirmation_time: None,
    +                    received: 0,
    +                    sent: 0,
    +                    fee: None,
    +                    confirmation_time: None,
                     }
                 });
     
    -            // update raw tx (if needed)
    -            let raw_tx =
    -                &*match &mut db_tx.transaction {
    -                    Some(raw_tx) => raw_tx,
    -                    db_tx_opt => {
    -                        updated = true;
    -                        db_tx_opt.insert(client.get_raw_transaction(
    -                            &tx_res.info.txid,
    -                            tx_res.info.blockhash.as_ref(),
    +            // update raw tx (if needed)
    +            let raw_tx =
    +                &*match &mut db_tx.transaction {
    +                    Some(raw_tx) => raw_tx,
    +                    db_tx_opt => {
    +                        updated = true;
    +                        db_tx_opt.insert(client.get_raw_transaction(
    +                            &tx_res.info.txid,
    +                            tx_res.info.blockhash.as_ref(),
                             )?)
                         }
                     };
     
    -            // update fee (if needed)
    -            if let (None, Some(new_fee)) = (db_tx.fee, tx_res.detail.fee) {
    -                updated = true;
    -                db_tx.fee = Some(new_fee.to_sat().unsigned_abs());
    +            // update fee (if needed)
    +            if let (None, Some(new_fee)) = (db_tx.fee, tx_res.detail.fee) {
    +                updated = true;
    +                db_tx.fee = Some(new_fee.to_sat().unsigned_abs());
                 }
     
    -            // update confirmation time (if needed)
    -            let conf_time = BlockTime::new(tx_res.info.blockheight, tx_res.info.blocktime);
    -            if db_tx.confirmation_time != conf_time {
    -                updated = true;
    -                db_tx.confirmation_time = conf_time;
    +            // update confirmation time (if needed)
    +            let conf_time = BlockTime::new(tx_res.info.blockheight, tx_res.info.blocktime);
    +            if db_tx.confirmation_time != conf_time {
    +                updated = true;
    +                db_tx.confirmation_time = conf_time;
                 }
     
    -            // update received (if needed)
    -            let received = Self::received_from_raw_tx(self.db, raw_tx)?;
    -            if db_tx.received != received {
    -                updated = true;
    -                db_tx.received = received;
    +            // update received (if needed)
    +            let received = Self::received_from_raw_tx(self.db, raw_tx)?;
    +            if db_tx.received != received {
    +                updated = true;
    +                db_tx.received = received;
                 }
     
    -            // check if tx has an immature coinbase output (add to updated UTXOs)
    -            // this is required because `listunspent` does not include immature coinbase outputs
    -            if tx_res.detail.category == GetTransactionResultDetailCategory::Immature {
    -                let txout = raw_tx
    -                    .output
    -                    .get(tx_res.detail.vout as usize)
    -                    .cloned()
    -                    .ok_or_else(|| {
    -                        Error::Generic(format!(
    +            // check if tx has an immature coinbase output (add to updated UTXOs)
    +            // this is required because `listunspent` does not include immature coinbase outputs
    +            if tx_res.detail.category == GetTransactionResultDetailCategory::Immature {
    +                let txout = raw_tx
    +                    .output
    +                    .get(tx_res.detail.vout as usize)
    +                    .cloned()
    +                    .ok_or_else(|| {
    +                        Error::Generic(format!(
                                 "Core RPC returned detail with invalid vout '{}' for tx '{}'",
    -                            tx_res.detail.vout, tx_res.info.txid,
    +                            tx_res.detail.vout, tx_res.info.txid,
                             ))
                         })?;
     
    -                if let Some((keychain, index)) =
    -                    self.db.get_path_from_script_pubkey(&txout.script_pubkey)?
    -                {
    -                    let utxo = LocalUtxo {
    -                        outpoint: OutPoint::new(tx_res.info.txid, tx_res.detail.vout),
    -                        txout,
    -                        keychain,
    -                        is_spent: false,
    +                if let Some((keychain, index)) =
    +                    self.db.get_path_from_script_pubkey(&txout.script_pubkey)?
    +                {
    +                    let utxo = LocalUtxo {
    +                        outpoint: OutPoint::new(tx_res.info.txid, tx_res.detail.vout),
    +                        txout,
    +                        keychain,
    +                        is_spent: false,
                         };
    -                    self.updated_utxos.insert(utxo);
    -                    self.update_last_index(keychain, index);
    +                    self.updated_utxos.insert(utxo);
    +                    self.update_last_index(keychain, index);
                     }
                 }
     
    -            // update tx deltas
    -            self.retained_txs.insert(tx_res.info.txid);
    -            if updated {
    -                self.updated_txs.insert(tx_res.info.txid);
    +            // update tx deltas
    +            self.retained_txs.insert(tx_res.info.txid);
    +            if updated {
    +                self.updated_txs.insert(tx_res.info.txid);
                 }
             }
     
    -        // obtain vector of `TransactionDetails::sent` changes
    -        let sent_updates = self
    -            .txs
    -            .values()
    -            // only bother to update txs that are retained
    -            .filter(|db_tx| self.retained_txs.contains(&db_tx.txid))
    -            // only bother to update txs where the raw tx is accessable
    -            .filter_map(|db_tx| (db_tx.transaction.as_ref().map(|tx| (tx, db_tx.sent))))
    -            // recalcuate sent value, only update txs in which sent value is changed
    -            .filter_map(|(raw_tx, old_sent)| {
    -                self.sent_from_raw_tx(raw_tx)
    -                    .map(|sent| {
    -                        if sent != old_sent {
    -                            Some((raw_tx.txid(), sent))
    -                        } else {
    -                            None
    -                        }
    +        // obtain vector of `TransactionDetails::sent` changes
    +        let sent_updates = self
    +            .txs
    +            .values()
    +            // only bother to update txs that are retained
    +            .filter(|db_tx| self.retained_txs.contains(&db_tx.txid))
    +            // only bother to update txs where the raw tx is accessable
    +            .filter_map(|db_tx| (db_tx.transaction.as_ref().map(|tx| (tx, db_tx.sent))))
    +            // recalcuate sent value, only update txs in which sent value is changed
    +            .filter_map(|(raw_tx, old_sent)| {
    +                self.sent_from_raw_tx(raw_tx)
    +                    .map(|sent| {
    +                        if sent != old_sent {
    +                            Some((raw_tx.txid(), sent))
    +                        } else {
    +                            None
    +                        }
                         })
    -                    .transpose()
    +                    .transpose()
                 })
    -            .collect::<Result<Vec<_>, _>>()?;
    -
    -        // record send updates
    -        sent_updates.iter().for_each(|&(txid, sent)| {
    -            // apply sent field changes
    -            self.txs.entry(txid).and_modify(|db_tx| db_tx.sent = sent);
    -            // mark tx as modified
    -            self.updated_txs.insert(txid);
    +            .collect::<Result<Vec<_>, _>>()?;
    +
    +        // record send updates
    +        sent_updates.iter().for_each(|&(txid, sent)| {
    +            // apply sent field changes
    +            self.txs.entry(txid).and_modify(|db_tx| db_tx.sent = sent);
    +            // mark tx as modified
    +            self.updated_txs.insert(txid);
             });
     
    -        // obtain UTXOs from Core wallet
    -        let core_utxos = client
    -            .list_unspent(Some(0), None, None, Some(true), None)?
    -            .into_iter()
    -            .filter_map(|utxo_entry| {
    -                let path_result = self
    -                    .db
    -                    .get_path_from_script_pubkey(&utxo_entry.script_pub_key)
    -                    .transpose()?;
    -
    -                let utxo_result = match path_result {
    -                    Ok((keychain, index)) => {
    -                        self.update_last_index(keychain, index);
    -                        Ok(Self::make_local_utxo(utxo_entry, keychain, false))
    +        // obtain UTXOs from Core wallet
    +        let core_utxos = client
    +            .list_unspent(Some(0), None, None, Some(true), None)?
    +            .into_iter()
    +            .filter_map(|utxo_entry| {
    +                let path_result = self
    +                    .db
    +                    .get_path_from_script_pubkey(&utxo_entry.script_pub_key)
    +                    .transpose()?;
    +
    +                let utxo_result = match path_result {
    +                    Ok((keychain, index)) => {
    +                        self.update_last_index(keychain, index);
    +                        Ok(Self::make_local_utxo(utxo_entry, keychain, false))
                         }
    -                    Err(err) => Err(err),
    +                    Err(err) => Err(err),
                     };
     
    -                Some(utxo_result)
    +                Some(utxo_result)
                 })
    -            .collect::<Result<HashSet<_>, Error>>()?;
    +            .collect::<Result<HashSet<_>, Error>>()?;
     
    -        // mark "spent utxos" to be updated in database
    -        let spent_utxos = self.utxos.difference(&core_utxos).cloned().map(|mut utxo| {
    -            utxo.is_spent = true;
    -            utxo
    +        // mark "spent utxos" to be updated in database
    +        let spent_utxos = self.utxos.difference(&core_utxos).cloned().map(|mut utxo| {
    +            utxo.is_spent = true;
    +            utxo
             });
     
    -        // mark new utxos to be added in database
    -        let new_utxos = core_utxos.difference(&self.utxos).cloned();
    +        // mark new utxos to be added in database
    +        let new_utxos = core_utxos.difference(&self.utxos).cloned();
     
    -        // add to updated utxos
    -        self.updated_utxos.extend(spent_utxos.chain(new_utxos));
    +        // add to updated utxos
    +        self.updated_utxos.extend(spent_utxos.chain(new_utxos));
     
             Ok(self)
         }
     
    -    /// Calculates received amount from raw tx.
    -    fn received_from_raw_tx(db: &D, raw_tx: &Transaction) -> Result<u64, Error> {
    -        raw_tx.output.iter().try_fold(0_u64, |recv, txo| {
    -            let v = if db.is_mine(&txo.script_pubkey)? {
    -                txo.value
    -            } else {
    -                0
    -            };
    -            Ok(recv + v)
    +    /// Calculates received amount from raw tx.
    +    fn received_from_raw_tx(db: &D, raw_tx: &Transaction) -> Result<u64, Error> {
    +        raw_tx.output.iter().try_fold(0_u64, |recv, txo| {
    +            let v = if db.is_mine(&txo.script_pubkey)? {
    +                txo.value
    +            } else {
    +                0
    +            };
    +            Ok(recv + v)
             })
         }
     
    -    /// Calculates sent from raw tx.
    -    fn sent_from_raw_tx(&self, raw_tx: &Transaction) -> Result<u64, Error> {
    -        let get_output = |outpoint: &OutPoint| {
    -            let raw_tx = self.txs.get(&outpoint.txid)?.transaction.as_ref()?;
    -            raw_tx.output.get(outpoint.vout as usize)
    +    /// Calculates sent from raw tx.
    +    fn sent_from_raw_tx(&self, raw_tx: &Transaction) -> Result<u64, Error> {
    +        let get_output = |outpoint: &OutPoint| {
    +            let raw_tx = self.txs.get(&outpoint.txid)?.transaction.as_ref()?;
    +            raw_tx.output.get(outpoint.vout as usize)
             };
     
    -        raw_tx.input.iter().try_fold(0_u64, |sent, txin| {
    -            let v = match get_output(&txin.previous_output) {
    -                Some(prev_txo) => {
    -                    if self.db.is_mine(&prev_txo.script_pubkey)? {
    -                        prev_txo.value
    -                    } else {
    -                        0
    -                    }
    +        raw_tx.input.iter().try_fold(0_u64, |sent, txin| {
    +            let v = match get_output(&txin.previous_output) {
    +                Some(prev_txo) => {
    +                    if self.db.is_mine(&prev_txo.script_pubkey)? {
    +                        prev_txo.value
    +                    } else {
    +                        0
    +                    }
                     }
    -                None => 0_u64,
    +                None => 0_u64,
                 };
    -            Ok(sent + v)
    +            Ok(sent + v)
             })
         }
     
    -    // updates the db state's last_index for the given keychain (if larger than current last_index)
    -    fn update_last_index(&mut self, keychain: KeychainKind, index: u32) {
    -        self.last_indexes
    -            .entry(keychain)
    -            .and_modify(|last| {
    -                if *last < index {
    -                    *last = index;
    +    // updates the db state's last_index for the given keychain (if larger than current last_index)
    +    fn update_last_index(&mut self, keychain: KeychainKind, index: u32) {
    +        self.last_indexes
    +            .entry(keychain)
    +            .and_modify(|last| {
    +                if *last < index {
    +                    *last = index;
                     }
                 })
    -            .or_insert_with(|| index);
    +            .or_insert_with(|| index);
         }
     
    -    fn make_local_utxo(
    -        entry: ListUnspentResultEntry,
    -        keychain: KeychainKind,
    -        is_spent: bool,
    -    ) -> LocalUtxo {
    -        LocalUtxo {
    -            outpoint: OutPoint::new(entry.txid, entry.vout),
    -            txout: TxOut {
    -                value: entry.amount.to_sat(),
    -                script_pubkey: entry.script_pub_key,
    +    fn make_local_utxo(
    +        entry: ListUnspentResultEntry,
    +        keychain: KeychainKind,
    +        is_spent: bool,
    +    ) -> LocalUtxo {
    +        LocalUtxo {
    +            outpoint: OutPoint::new(entry.txid, entry.vout),
    +            txout: TxOut {
    +                value: entry.amount.to_sat(),
    +                script_pubkey: entry.script_pub_key,
                 },
    -            keychain,
    -            is_spent,
    +            keychain,
    +            is_spent,
             }
         }
     
    -    /// Prepare db batch operations.
    -    fn as_db_batch(&self) -> Result<D::Batch, Error> {
    -        let mut batch = self.db.begin_batch();
    -        let mut del_txs = 0_u32;
    -
    -        // delete stale (not retained) txs from db
    -        self.txs
    -            .keys()
    -            .filter(|&txid| !self.retained_txs.contains(txid))
    -            .try_for_each(|txid| -> Result<(), Error> {
    -                batch.del_tx(txid, false)?;
    -                del_txs += 1;
    +    /// Prepare db batch operations.
    +    fn as_db_batch(&self) -> Result<D::Batch, Error> {
    +        let mut batch = self.db.begin_batch();
    +        let mut del_txs = 0_u32;
    +
    +        // delete stale (not retained) txs from db
    +        self.txs
    +            .keys()
    +            .filter(|&txid| !self.retained_txs.contains(txid))
    +            .try_for_each(|txid| -> Result<(), Error> {
    +                batch.del_tx(txid, false)?;
    +                del_txs += 1;
                     Ok(())
                 })?;
     
    -        // update txs
    -        self.updated_txs
    -            .iter()
    -            .inspect(|&txid| debug!("updating tx: {}", txid))
    -            .try_for_each(|txid| batch.set_tx(self.txs.get(txid).unwrap()))?;
    +        // update txs
    +        self.updated_txs
    +            .iter()
    +            .inspect(|&txid| debug!("updating tx: {}", txid))
    +            .try_for_each(|txid| batch.set_tx(self.txs.get(txid).unwrap()))?;
     
    -        // update utxos
    -        self.updated_utxos
    -            .iter()
    -            .inspect(|&utxo| debug!("updating utxo: {}", utxo.outpoint))
    -            .try_for_each(|utxo| batch.set_utxo(utxo))?;
    +        // update utxos
    +        self.updated_utxos
    +            .iter()
    +            .inspect(|&utxo| debug!("updating utxo: {}", utxo.outpoint))
    +            .try_for_each(|utxo| batch.set_utxo(utxo))?;
     
    -        // update last indexes
    -        self.last_indexes
    -            .iter()
    -            .try_for_each(|(&keychain, &index)| batch.set_last_index(keychain, index))?;
    +        // update last indexes
    +        self.last_indexes
    +            .iter()
    +            .try_for_each(|(&keychain, &index)| batch.set_last_index(keychain, index))?;
     
             info!(
                 "db batch updates: del_txs={}, update_txs={}, update_utxos={}",
    -            del_txs,
    -            self.updated_txs.len(),
    -            self.updated_utxos.len()
    +            del_txs,
    +            self.updated_txs.len(),
    +            self.updated_utxos.len()
             );
     
    -        Ok(batch)
    +        Ok(batch)
         }
     }
     
    -fn import_descriptors<'a, S>(
    -    client: &Client,
    -    start_epoch: u64,
    -    scripts_iter: S,
    -) -> Result<(), Error>
    -where
    -    S: Iterator<Item = &'a Script>,
    +fn import_descriptors<'a, S>(
    +    client: &Client,
    +    start_epoch: u64,
    +    scripts_iter: S,
    +) -> Result<(), Error>
    +where
    +    S: Iterator<Item = &'a Script>,
     {
    -    let requests = Value::Array(
    -        scripts_iter
    -            .map(|script| {
    -                let desc = descriptor_from_script_pubkey(script);
    -                json!({ "timestamp": start_epoch, "desc": desc })
    +    let requests = Value::Array(
    +        scripts_iter
    +            .map(|script| {
    +                let desc = descriptor_from_script_pubkey(script);
    +                json!({ "timestamp": start_epoch, "desc": desc })
                 })
    -            .collect(),
    +            .collect(),
         );
    -    for v in client.call::<Vec<Value>>("importdescriptors", &[requests])? {
    -        match v["success"].as_bool() {
    +    for v in client.call::<Vec<Value>>("importdescriptors", &[requests])? {
    +        match v["success"].as_bool() {
                 Some(true) => continue,
                 Some(false) => {
    -                return Err(Error::Generic(
    -                    v["error"]["message"]
    -                        .as_str()
    -                        .map_or("unknown error".into(), ToString::to_string),
    +                return Err(Error::Generic(
    +                    v["error"]["message"]
    +                        .as_str()
    +                        .map_or("unknown error".into(), ToString::to_string),
                     ))
                 }
    -            _ => return Err(Error::Generic("Unexpected response form Core".to_string())),
    +            _ => return Err(Error::Generic("Unexpected response form Core".to_string())),
             }
         }
         Ok(())
     }
     
    -fn import_multi<'a, S>(client: &Client, start_epoch: u64, scripts_iter: S) -> Result<(), Error>
    -where
    -    S: Iterator<Item = &'a Script>,
    +fn import_multi<'a, S>(client: &Client, start_epoch: u64, scripts_iter: S) -> Result<(), Error>
    +where
    +    S: Iterator<Item = &'a Script>,
     {
    -    let requests = scripts_iter
    -        .map(|script| ImportMultiRequest {
    -            timestamp: ImportMultiRescanSince::Timestamp(start_epoch),
    -            script_pubkey: Some(ImportMultiRequestScriptPubkey::Script(script)),
    -            watchonly: Some(true),
    -            ..Default::default()
    +    let requests = scripts_iter
    +        .map(|script| ImportMultiRequest {
    +            timestamp: ImportMultiRescanSince::Timestamp(start_epoch),
    +            script_pubkey: Some(ImportMultiRequestScriptPubkey::Script(script)),
    +            watchonly: Some(true),
    +            ..Default::default()
             })
    -        .collect::<Vec<_>>();
    -    let options = ImportMultiOptions { rescan: Some(true) };
    -    for v in client.import_multi(&requests, Some(&options))? {
    -        if let Some(err) = v.error {
    -            return Err(Error::Generic(format!(
    +        .collect::<Vec<_>>();
    +    let options = ImportMultiOptions { rescan: Some(true) };
    +    for v in client.import_multi(&requests, Some(&options))? {
    +        if let Some(err) = v.error {
    +            return Err(Error::Generic(format!(
                     "{} (code: {})",
    -                err.message, err.code
    +                err.message, err.code
                 )));
             }
         }
         Ok(())
     }
     
    -/// Calls the `listtransactions` RPC method in `page_size`s and returns iterator of the tx results
    -/// in chronological order.
    -///
    -/// `page_size` cannot be less than 1 and cannot be greater than 1000.
    -fn list_transactions(
    -    client: &Client,
    -    page_size: usize,
    -) -> Result<impl Iterator<Item = ListTransactionResult>, Error> {
    -    if !(1..=1000).contains(&page_size) {
    -        return Err(Error::Generic(format!(
    +/// Calls the `listtransactions` RPC method in `page_size`s and returns iterator of the tx results
    +/// in chronological order.
    +///
    +/// `page_size` cannot be less than 1 and cannot be greater than 1000.
    +fn list_transactions(
    +    client: &Client,
    +    page_size: usize,
    +) -> Result<impl Iterator<Item = ListTransactionResult>, Error> {
    +    if !(1..=1000).contains(&page_size) {
    +        return Err(Error::Generic(format!(
                 "Core RPC method `listtransactions` must have `page_size` in range [1 to 1000]: got {}",
    -            page_size
    +            page_size
             )));
         }
     
    -    // `.take_while` helper to obtain the first error (TODO: remove when we can use `.map_while`)
    -    let mut got_err = false;
    +    // `.take_while` helper to obtain the first error (TODO: remove when we can use `.map_while`)
    +    let mut got_err = false;
     
    -    // obtain results in batches (of `page_size`)
    -    let nested_list = (0_usize..)
    -        .map(|page_index| {
    -            client.list_transactions(
    +    // obtain results in batches (of `page_size`)
    +    let nested_list = (0_usize..)
    +        .map(|page_index| {
    +            client.list_transactions(
                     None,
    -                Some(page_size),
    -                Some(page_size * page_index),
    +                Some(page_size),
    +                Some(page_size * page_index),
                     Some(true),
                 )
             })
    -        // take until returned rpc call is empty or until error
    -        // TODO: replace with the following when MSRV is 1.57.0:
    -        // `.map_while(|res| res.map(|l| if l.is_empty() { None } else { Some(l) }).transpose())`
    -        .take_while(|res| {
    -            if got_err || matches!(res, Ok(list) if list.is_empty()) {
    -                // break if last iteration was an error, or if the current result is empty
    -                false
    -            } else {
    -                // record whether result is error or not
    -                got_err = res.is_err();
    -                // continue on non-empty result or first error
    -                true
    -            }
    +        // take until returned rpc call is empty or until error
    +        // TODO: replace with the following when MSRV is 1.57.0:
    +        // `.map_while(|res| res.map(|l| if l.is_empty() { None } else { Some(l) }).transpose())`
    +        .take_while(|res| {
    +            if got_err || matches!(res, Ok(list) if list.is_empty()) {
    +                // break if last iteration was an error, or if the current result is empty
    +                false
    +            } else {
    +                // record whether result is error or not
    +                got_err = res.is_err();
    +                // continue on non-empty result or first error
    +                true
    +            }
             })
    -        .collect::<Result<Vec<_>, _>>()
    -        .map_err(Error::Rpc)?;
    +        .collect::<Result<Vec<_>, _>>()
    +        .map_err(Error::Rpc)?;
     
    -    // reverse here to have txs in chronological order
    -    Ok(nested_list.into_iter().rev().flatten())
    +    // reverse here to have txs in chronological order
    +    Ok(nested_list.into_iter().rev().flatten())
     }
     
    -fn await_wallet_scan(client: &Client, rate_sec: u64, progress: &dyn Progress) -> Result<(), Error> {
    -    #[derive(Deserialize)]
    -    struct CallResult {
    -        scanning: ScanningDetails,
    +fn await_wallet_scan(client: &Client, rate_sec: u64, progress: &dyn Progress) -> Result<(), Error> {
    +    #[derive(Deserialize)]
    +    struct CallResult {
    +        scanning: ScanningDetails,
         }
     
    -    let dur = Duration::from_secs(rate_sec);
    -    loop {
    -        match client.call::<CallResult>("getwalletinfo", &[])?.scanning {
    -            ScanningDetails::Scanning {
    -                duration,
    -                progress: pc,
    +    let dur = Duration::from_secs(rate_sec);
    +    loop {
    +        match client.call::<CallResult>("getwalletinfo", &[])?.scanning {
    +            ScanningDetails::Scanning {
    +                duration,
    +                progress: pc,
                 } => {
    -                debug!("scanning: duration={}, progress={}", duration, pc);
    -                progress.update(pc, Some(format!("elapsed for {} seconds", duration)))?;
    -                thread::sleep(dur);
    +                debug!("scanning: duration={}, progress={}", duration, pc);
    +                progress.update(pc, Some(format!("elapsed for {} seconds", duration)))?;
    +                thread::sleep(dur);
                 }
    -            ScanningDetails::NotScanning(_) => {
    -                progress.update(1.0, None)?;
    +            ScanningDetails::NotScanning(_) => {
    +                progress.update(1.0, None)?;
                     info!("scanning: done!");
    -                return Ok(());
    +                return Ok(());
                 }
             };
         }
     }
     
    -/// Returns whether a wallet is legacy or descriptors by calling `getwalletinfo`.
    -///
    -/// This API is mapped by bitcoincore_rpc, but it doesn't have the fields we need (either
    -/// "descriptors" or "format") so we have to call the RPC manually
    -fn is_wallet_descriptor(client: &Client) -> Result<bool, Error> {
    -    #[derive(Deserialize)]
    -    struct CallResult {
    -        descriptors: Option<bool>,
    +/// Returns whether a wallet is legacy or descriptors by calling `getwalletinfo`.
    +///
    +/// This API is mapped by bitcoincore_rpc, but it doesn't have the fields we need (either
    +/// "descriptors" or "format") so we have to call the RPC manually
    +fn is_wallet_descriptor(client: &Client) -> Result<bool, Error> {
    +    #[derive(Deserialize)]
    +    struct CallResult {
    +        descriptors: Option<bool>,
         }
     
    -    let result: CallResult = client.call("getwalletinfo", &[])?;
    -    Ok(result.descriptors.unwrap_or(false))
    +    let result: CallResult = client.call("getwalletinfo", &[])?;
    +    Ok(result.descriptors.unwrap_or(false))
     }
     
    -fn descriptor_from_script_pubkey(script: &Script) -> String {
    -    let desc = format!("raw({})", script.to_hex());
    -    format!("{}#{}", desc, calc_checksum(&desc).unwrap())
    +fn descriptor_from_script_pubkey(script: &Script) -> String {
    +    let desc = format!("raw({})", script.to_hex());
    +    format!("{}#{}", desc, calc_checksum(&desc).unwrap())
     }
     
    -/// Factory of [`RpcBlockchain`] instances, implements [`BlockchainFactory`]
    -///
    -/// Internally caches the node url and authentication params and allows getting many different [`RpcBlockchain`]
    -/// objects for different wallet names and with different rescan heights.
    -///
    -/// ## Example
    -///
    -/// ```no_run
    -/// # use bdk::bitcoin::Network;
    -/// # use bdk::blockchain::BlockchainFactory;
    -/// # use bdk::blockchain::rpc::{Auth, RpcBlockchainFactory};
    -/// # fn main() -> Result<(), Box<dyn std::error::Error>> {
    -/// let factory = RpcBlockchainFactory {
    -///     url: "http://127.0.0.1:18332".to_string(),
    -///     auth: Auth::Cookie {
    -///         file: "/home/user/.bitcoin/.cookie".into(),
    -///     },
    -///     network: Network::Testnet,
    -///     wallet_name_prefix: Some("prefix-".to_string()),
    -///     default_skip_blocks: 100_000,
    -///     sync_params: None,
    -/// };
    -/// let main_wallet_blockchain = factory.build("main_wallet", Some(200_000))?;
    -/// # Ok(())
    -/// # }
    -/// ```
    -#[derive(Debug, Clone)]
    -pub struct RpcBlockchainFactory {
    -    /// The bitcoin node url
    -    pub url: String,
    -    /// The bitcoin node authentication mechanism
    -    pub auth: Auth,
    -    /// The network we are using (it will be checked the bitcoin node network matches this)
    -    pub network: Network,
    -    /// The optional prefix used to build the full wallet name for blockchains
    -    pub wallet_name_prefix: Option<String>,
    -    /// Default number of blocks to skip which will be inherited by blockchain unless overridden
    -    pub default_skip_blocks: u32,
    -    /// Sync parameters
    -    pub sync_params: Option<RpcSyncParams>,
    +/// Factory of [`RpcBlockchain`] instances, implements [`BlockchainFactory`]
    +///
    +/// Internally caches the node url and authentication params and allows getting many different [`RpcBlockchain`]
    +/// objects for different wallet names and with different rescan heights.
    +///
    +/// ## Example
    +///
    +/// ```no_run
    +/// # use bdk::bitcoin::Network;
    +/// # use bdk::blockchain::BlockchainFactory;
    +/// # use bdk::blockchain::rpc::{Auth, RpcBlockchainFactory};
    +/// # fn main() -> Result<(), Box<dyn std::error::Error>> {
    +/// let factory = RpcBlockchainFactory {
    +///     url: "http://127.0.0.1:18332".to_string(),
    +///     auth: Auth::Cookie {
    +///         file: "/home/user/.bitcoin/.cookie".into(),
    +///     },
    +///     network: Network::Testnet,
    +///     wallet_name_prefix: Some("prefix-".to_string()),
    +///     default_skip_blocks: 100_000,
    +///     sync_params: None,
    +/// };
    +/// let main_wallet_blockchain = factory.build("main_wallet", Some(200_000))?;
    +/// # Ok(())
    +/// # }
    +/// ```
    +#[derive(Debug, Clone)]
    +pub struct RpcBlockchainFactory {
    +    /// The bitcoin node url
    +    pub url: String,
    +    /// The bitcoin node authentication mechanism
    +    pub auth: Auth,
    +    /// The network we are using (it will be checked the bitcoin node network matches this)
    +    pub network: Network,
    +    /// The optional prefix used to build the full wallet name for blockchains
    +    pub wallet_name_prefix: Option<String>,
    +    /// Default number of blocks to skip which will be inherited by blockchain unless overridden
    +    pub default_skip_blocks: u32,
    +    /// Sync parameters
    +    pub sync_params: Option<RpcSyncParams>,
     }
     
    -impl BlockchainFactory for RpcBlockchainFactory {
    -    type Inner = RpcBlockchain;
    +impl BlockchainFactory for RpcBlockchainFactory {
    +    type Inner = RpcBlockchain;
     
    -    fn build(
    +    fn build(
             &self,
    -        checksum: &str,
    -        _override_skip_blocks: Option<u32>,
    -    ) -> Result<Self::Inner, Error> {
    -        RpcBlockchain::from_config(&RpcConfig {
    -            url: self.url.clone(),
    -            auth: self.auth.clone(),
    -            network: self.network,
    -            wallet_name: format!(
    +        checksum: &str,
    +        _override_skip_blocks: Option<u32>,
    +    ) -> Result<Self::Inner, Error> {
    +        RpcBlockchain::from_config(&RpcConfig {
    +            url: self.url.clone(),
    +            auth: self.auth.clone(),
    +            network: self.network,
    +            wallet_name: format!(
                     "{}{}",
    -                self.wallet_name_prefix.as_ref().unwrap_or(&String::new()),
    -                checksum
    +                self.wallet_name_prefix.as_ref().unwrap_or(&String::new()),
    +                checksum
                 ),
    -            sync_params: self.sync_params.clone(),
    +            sync_params: self.sync_params.clone(),
             })
         }
     }
     
    -#[cfg(test)]
    -#[cfg(any(feature = "test-rpc", feature = "test-rpc-legacy"))]
    -mod test {
    -    use super::*;
    -    use crate::{
    -        descriptor::into_wallet_descriptor_checked, testutils::blockchain_tests::TestClient,
    -        wallet::utils::SecpCtx,
    +#[cfg(test)]
    +#[cfg(any(feature = "test-rpc", feature = "test-rpc-legacy"))]
    +mod test {
    +    use super::*;
    +    use crate::{
    +        descriptor::into_wallet_descriptor_checked, testutils::blockchain_tests::TestClient,
    +        wallet::utils::SecpCtx,
         };
     
    -    use bitcoin::{Address, Network};
    -    use bitcoincore_rpc::RpcApi;
    -    use log::LevelFilter;
    -
    -    crate::bdk_blockchain_tests! {
    -        fn test_instance(test_client: &TestClient) -> RpcBlockchain {
    -            let config = RpcConfig {
    -                url: test_client.bitcoind.rpc_url(),
    -                auth: Auth::Cookie { file: test_client.bitcoind.params.cookie_file.clone() },
    -                network: Network::Regtest,
    -                wallet_name: format!("client-wallet-test-{}", std::time::SystemTime::now().duration_since(std::time::UNIX_EPOCH).unwrap().as_nanos() ),
    -                sync_params: None,
    +    use bitcoin::{Address, Network};
    +    use bitcoincore_rpc::RpcApi;
    +    use log::LevelFilter;
    +
    +    crate::bdk_blockchain_tests! {
    +        fn test_instance(test_client: &TestClient) -> RpcBlockchain {
    +            let config = RpcConfig {
    +                url: test_client.bitcoind.rpc_url(),
    +                auth: Auth::Cookie { file: test_client.bitcoind.params.cookie_file.clone() },
    +                network: Network::Regtest,
    +                wallet_name: format!("client-wallet-test-{}", std::time::SystemTime::now().duration_since(std::time::UNIX_EPOCH).unwrap().as_nanos() ),
    +                sync_params: None,
                 };
    -            RpcBlockchain::from_config(&config).unwrap()
    +            RpcBlockchain::from_config(&config).unwrap()
             }
         }
     
    -    fn get_factory() -> (TestClient, RpcBlockchainFactory) {
    -        let test_client = TestClient::default();
    +    fn get_factory() -> (TestClient, RpcBlockchainFactory) {
    +        let test_client = TestClient::default();
     
    -        let factory = RpcBlockchainFactory {
    -            url: test_client.bitcoind.rpc_url(),
    -            auth: Auth::Cookie {
    -                file: test_client.bitcoind.params.cookie_file.clone(),
    +        let factory = RpcBlockchainFactory {
    +            url: test_client.bitcoind.rpc_url(),
    +            auth: Auth::Cookie {
    +                file: test_client.bitcoind.params.cookie_file.clone(),
                 },
    -            network: Network::Regtest,
    -            wallet_name_prefix: Some("prefix-".into()),
    -            default_skip_blocks: 0,
    -            sync_params: None,
    +            network: Network::Regtest,
    +            wallet_name_prefix: Some("prefix-".into()),
    +            default_skip_blocks: 0,
    +            sync_params: None,
             };
     
    -        (test_client, factory)
    +        (test_client, factory)
         }
     
    -    #[test]
    -    fn test_rpc_blockchain_factory() {
    -        let (_test_client, factory) = get_factory();
    +    #[test]
    +    fn test_rpc_blockchain_factory() {
    +        let (_test_client, factory) = get_factory();
     
    -        let a = factory.build("aaaaaa", None).unwrap();
    +        let a = factory.build("aaaaaa", None).unwrap();
             assert_eq!(
    -            a.client
    -                .get_wallet_info()
    -                .expect("Node connection isn't working")
    -                .wallet_name,
    -            "prefix-aaaaaa"
    -        );
    -
    -        let b = factory.build("bbbbbb", Some(100)).unwrap();
    +            a.client
    +                .get_wallet_info()
    +                .expect("Node connection isn't working")
    +                .wallet_name,
    +            "prefix-aaaaaa"
    +        );
    +
    +        let b = factory.build("bbbbbb", Some(100)).unwrap();
             assert_eq!(
    -            b.client
    -                .get_wallet_info()
    -                .expect("Node connection isn't working")
    -                .wallet_name,
    -            "prefix-bbbbbb"
    -        );
    +            b.client
    +                .get_wallet_info()
    +                .expect("Node connection isn't working")
    +                .wallet_name,
    +            "prefix-bbbbbb"
    +        );
         }
     
    -    /// This test ensures that [list_transactions] always iterates through transactions in
    -    /// chronological order, independent of the `page_size`.
    -    #[test]
    -    fn test_list_transactions() {
    -        let _ = env_logger::builder()
    -            .filter_level(LevelFilter::Info)
    -            .default_format()
    -            .try_init();
    -
    -        const DESC: &'static str = "wpkh(tpubD9zMNV59kgbWgKK55SHJugmKKSt6wQXczxpucGYqNKwGmJp1x7Ar2nrLUXYHDdCctXmyDoSCn2JVMzMUDfib3FaDhwxCEMUELoq19xLSx66/*)";
    -        const AMOUNT_PER_TX: u64 = 10_000;
    -        const TX_COUNT: u32 = 50;
    -
    -        let secp = SecpCtx::default();
    -        let network = Network::Regtest;
    -        let (desc, ..) = into_wallet_descriptor_checked(DESC, &secp, network).unwrap();
    -
    -        let (mut test_client, factory) = get_factory();
    -        let bc = factory.build("itertest", None).unwrap();
    -
    -        // generate scripts (1 tx per script)
    -        let scripts = (0..TX_COUNT)
    -            .map(|index| desc.at_derivation_index(index).script_pubkey())
    -            .collect::<Vec<_>>();
    -
    -        // import scripts and wait
    -        if bc.is_descriptors {
    -            import_descriptors(&bc.client, 0, scripts.iter()).unwrap();
    -        } else {
    -            import_multi(&bc.client, 0, scripts.iter()).unwrap();
    +    /// This test ensures that [list_transactions] always iterates through transactions in
    +    /// chronological order, independent of the `page_size`.
    +    #[test]
    +    fn test_list_transactions() {
    +        let _ = env_logger::builder()
    +            .filter_level(LevelFilter::Info)
    +            .default_format()
    +            .try_init();
    +
    +        const DESC: &'static str = "wpkh(tpubD9zMNV59kgbWgKK55SHJugmKKSt6wQXczxpucGYqNKwGmJp1x7Ar2nrLUXYHDdCctXmyDoSCn2JVMzMUDfib3FaDhwxCEMUELoq19xLSx66/*)";
    +        const AMOUNT_PER_TX: u64 = 10_000;
    +        const TX_COUNT: u32 = 50;
    +
    +        let secp = SecpCtx::default();
    +        let network = Network::Regtest;
    +        let (desc, ..) = into_wallet_descriptor_checked(DESC, &secp, network).unwrap();
    +
    +        let (mut test_client, factory) = get_factory();
    +        let bc = factory.build("itertest", None).unwrap();
    +
    +        // generate scripts (1 tx per script)
    +        let scripts = (0..TX_COUNT)
    +            .map(|index| desc.at_derivation_index(index).script_pubkey())
    +            .collect::<Vec<_>>();
    +
    +        // import scripts and wait
    +        if bc.is_descriptors {
    +            import_descriptors(&bc.client, 0, scripts.iter()).unwrap();
    +        } else {
    +            import_multi(&bc.client, 0, scripts.iter()).unwrap();
             }
    -        await_wallet_scan(&bc.client, 2, &NoopProgress).unwrap();
    -
    -        // create and broadcast txs
    -        let expected_txids = scripts
    -            .iter()
    -            .map(|script| {
    -                let addr = Address::from_script(script, network).unwrap();
    -                let txid =
    -                    test_client.receive(testutils! { @tx ( (@addr addr) => AMOUNT_PER_TX ) });
    -                test_client.generate(1, None);
    -                txid
    +        await_wallet_scan(&bc.client, 2, &NoopProgress).unwrap();
    +
    +        // create and broadcast txs
    +        let expected_txids = scripts
    +            .iter()
    +            .map(|script| {
    +                let addr = Address::from_script(script, network).unwrap();
    +                let txid =
    +                    test_client.receive(testutils! { @tx ( (@addr addr) => AMOUNT_PER_TX ) });
    +                test_client.generate(1, None);
    +                txid
                 })
    -            .collect::<Vec<_>>();
    +            .collect::<Vec<_>>();
     
    -        // iterate through different page sizes - should always return txs in chronological order
    -        [1000, 1, 2, 6, 25, 49, 50].iter().for_each(|page_size| {
    -            println!("trying with page_size: {}", page_size);
    +        // iterate through different page sizes - should always return txs in chronological order
    +        [1000, 1, 2, 6, 25, 49, 50].iter().for_each(|page_size| {
    +            println!("trying with page_size: {}", page_size);
     
    -            let txids = list_transactions(&bc.client, *page_size)
    -                .unwrap()
    -                .map(|res| res.info.txid)
    -                .collect::<Vec<_>>();
    +            let txids = list_transactions(&bc.client, *page_size)
    +                .unwrap()
    +                .map(|res| res.info.txid)
    +                .collect::<Vec<_>>();
     
    -            assert_eq!(txids.len(), expected_txids.len());
    -            assert_eq!(txids, expected_txids);
    +            assert_eq!(txids.len(), expected_txids.len());
    +            assert_eq!(txids, expected_txids);
             });
         }
     }
     
    -
    - \ No newline at end of file +
    \ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/src/bdk/blockchain/script_sync.rs.html b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/src/bdk/blockchain/script_sync.rs.html index 0dbea8bb2c..8469092fbb 100644 --- a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/src/bdk/blockchain/script_sync.rs.html +++ b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/src/bdk/blockchain/script_sync.rs.html @@ -1,944 +1,937 @@ -script_sync.rs - source - -
      1
    -  2
    -  3
    -  4
    -  5
    -  6
    -  7
    -  8
    -  9
    - 10
    - 11
    - 12
    - 13
    - 14
    - 15
    - 16
    - 17
    - 18
    - 19
    - 20
    - 21
    - 22
    - 23
    - 24
    - 25
    - 26
    - 27
    - 28
    - 29
    - 30
    - 31
    - 32
    - 33
    - 34
    - 35
    - 36
    - 37
    - 38
    - 39
    - 40
    - 41
    - 42
    - 43
    - 44
    - 45
    - 46
    - 47
    - 48
    - 49
    - 50
    - 51
    - 52
    - 53
    - 54
    - 55
    - 56
    - 57
    - 58
    - 59
    - 60
    - 61
    - 62
    - 63
    - 64
    - 65
    - 66
    - 67
    - 68
    - 69
    - 70
    - 71
    - 72
    - 73
    - 74
    - 75
    - 76
    - 77
    - 78
    - 79
    - 80
    - 81
    - 82
    - 83
    - 84
    - 85
    - 86
    - 87
    - 88
    - 89
    - 90
    - 91
    - 92
    - 93
    - 94
    - 95
    - 96
    - 97
    - 98
    - 99
    -100
    -101
    -102
    -103
    -104
    -105
    -106
    -107
    -108
    -109
    -110
    -111
    -112
    -113
    -114
    -115
    -116
    -117
    -118
    -119
    -120
    -121
    -122
    -123
    -124
    -125
    -126
    -127
    -128
    -129
    -130
    -131
    -132
    -133
    -134
    -135
    -136
    -137
    -138
    -139
    -140
    -141
    -142
    -143
    -144
    -145
    -146
    -147
    -148
    -149
    -150
    -151
    -152
    -153
    -154
    -155
    -156
    -157
    -158
    -159
    -160
    -161
    -162
    -163
    -164
    -165
    -166
    -167
    -168
    -169
    -170
    -171
    -172
    -173
    -174
    -175
    -176
    -177
    -178
    -179
    -180
    -181
    -182
    -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
    -245
    -246
    -247
    -248
    -249
    -250
    -251
    -252
    -253
    -254
    -255
    -256
    -257
    -258
    -259
    -260
    -261
    -262
    -263
    -264
    -265
    -266
    -267
    -268
    -269
    -270
    -271
    -272
    -273
    -274
    -275
    -276
    -277
    -278
    -279
    -280
    -281
    -282
    -283
    -284
    -285
    -286
    -287
    -288
    -289
    -290
    -291
    -292
    -293
    -294
    -295
    -296
    -297
    -298
    -299
    -300
    -301
    -302
    -303
    -304
    -305
    -306
    -307
    -308
    -309
    -310
    -311
    -312
    -313
    -314
    -315
    -316
    -317
    -318
    -319
    -320
    -321
    -322
    -323
    -324
    -325
    -326
    -327
    -328
    -329
    -330
    -331
    -332
    -333
    -334
    -335
    -336
    -337
    -338
    -339
    -340
    -341
    -342
    -343
    -344
    -345
    -346
    -347
    -348
    -349
    -350
    -351
    -352
    -353
    -354
    -355
    -356
    -357
    -358
    -359
    -360
    -361
    -362
    -363
    -364
    -365
    -366
    -367
    -368
    -369
    -370
    -371
    -372
    -373
    -374
    -375
    -376
    -377
    -378
    -379
    -380
    -381
    -382
    -383
    -384
    -385
    -386
    -387
    -388
    -389
    -390
    -391
    -392
    -393
    -394
    -395
    -396
    -397
    -398
    -399
    -400
    -401
    -402
    -403
    -404
    -405
    -406
    -407
    -408
    -409
    -410
    -411
    -412
    -413
    -414
    -415
    -416
    -417
    -418
    -419
    -420
    -421
    -422
    -423
    -424
    -425
    -426
    -427
    -428
    -429
    -430
    -431
    -432
    -433
    -434
    -435
    -436
    -437
    -438
    -439
    -440
    -441
    -442
    -443
    -444
    -445
    -446
    -447
    -448
    -449
    -450
    -451
    -452
    -453
    -454
    -455
    -456
    -457
    -458
    -459
    -460
    -461
    -462
    -463
    -464
    -465
    -466
    -467
    +script_sync.rs - source
    1
    +2
    +3
    +4
    +5
    +6
    +7
    +8
    +9
    +10
    +11
    +12
    +13
    +14
    +15
    +16
    +17
    +18
    +19
    +20
    +21
    +22
    +23
    +24
    +25
    +26
    +27
    +28
    +29
    +30
    +31
    +32
    +33
    +34
    +35
    +36
    +37
    +38
    +39
    +40
    +41
    +42
    +43
    +44
    +45
    +46
    +47
    +48
    +49
    +50
    +51
    +52
    +53
    +54
    +55
    +56
    +57
    +58
    +59
    +60
    +61
    +62
    +63
    +64
    +65
    +66
    +67
    +68
    +69
    +70
    +71
    +72
    +73
    +74
    +75
    +76
    +77
    +78
    +79
    +80
    +81
    +82
    +83
    +84
    +85
    +86
    +87
    +88
    +89
    +90
    +91
    +92
    +93
    +94
    +95
    +96
    +97
    +98
    +99
    +100
    +101
    +102
    +103
    +104
    +105
    +106
    +107
    +108
    +109
    +110
    +111
    +112
    +113
    +114
    +115
    +116
    +117
    +118
    +119
    +120
    +121
    +122
    +123
    +124
    +125
    +126
    +127
    +128
    +129
    +130
    +131
    +132
    +133
    +134
    +135
    +136
    +137
    +138
    +139
    +140
    +141
    +142
    +143
    +144
    +145
    +146
    +147
    +148
    +149
    +150
    +151
    +152
    +153
    +154
    +155
    +156
    +157
    +158
    +159
    +160
    +161
    +162
    +163
    +164
    +165
    +166
    +167
    +168
    +169
    +170
    +171
    +172
    +173
    +174
    +175
    +176
    +177
    +178
    +179
    +180
    +181
    +182
    +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
    +245
    +246
    +247
    +248
    +249
    +250
    +251
    +252
    +253
    +254
    +255
    +256
    +257
    +258
    +259
    +260
    +261
    +262
    +263
    +264
    +265
    +266
    +267
    +268
    +269
    +270
    +271
    +272
    +273
    +274
    +275
    +276
    +277
    +278
    +279
    +280
    +281
    +282
    +283
    +284
    +285
    +286
    +287
    +288
    +289
    +290
    +291
    +292
    +293
    +294
    +295
    +296
    +297
    +298
    +299
    +300
    +301
    +302
    +303
    +304
    +305
    +306
    +307
    +308
    +309
    +310
    +311
    +312
    +313
    +314
    +315
    +316
    +317
    +318
    +319
    +320
    +321
    +322
    +323
    +324
    +325
    +326
    +327
    +328
    +329
    +330
    +331
    +332
    +333
    +334
    +335
    +336
    +337
    +338
    +339
    +340
    +341
    +342
    +343
    +344
    +345
    +346
    +347
    +348
    +349
    +350
    +351
    +352
    +353
    +354
    +355
    +356
    +357
    +358
    +359
    +360
    +361
    +362
    +363
    +364
    +365
    +366
    +367
    +368
    +369
    +370
    +371
    +372
    +373
    +374
    +375
    +376
    +377
    +378
    +379
    +380
    +381
    +382
    +383
    +384
    +385
    +386
    +387
    +388
    +389
    +390
    +391
    +392
    +393
    +394
    +395
    +396
    +397
    +398
    +399
    +400
    +401
    +402
    +403
    +404
    +405
    +406
    +407
    +408
    +409
    +410
    +411
    +412
    +413
    +414
    +415
    +416
    +417
    +418
    +419
    +420
    +421
    +422
    +423
    +424
    +425
    +426
    +427
    +428
    +429
    +430
    +431
    +432
    +433
    +434
    +435
    +436
    +437
    +438
    +439
    +440
    +441
    +442
    +443
    +444
    +445
    +446
    +447
    +448
    +449
    +450
    +451
    +452
    +453
    +454
    +455
    +456
    +457
    +458
    +459
    +460
    +461
    +462
    +463
    +464
    +465
    +466
    +467
     
    /*!
     This models a how a sync happens where you have a server that you send your script pubkeys to and it
     returns associated transactions i.e. electrum.
    -*/
    -#![allow(dead_code)]
    -use crate::{
    -    database::{BatchDatabase, BatchOperations, DatabaseUtils},
    -    error::MissingCachedScripts,
    -    wallet::time::Instant,
    -    BlockTime, Error, KeychainKind, LocalUtxo, TransactionDetails,
    +*/
    +#![allow(dead_code)]
    +use crate::{
    +    database::{BatchDatabase, BatchOperations, DatabaseUtils},
    +    error::MissingCachedScripts,
    +    wallet::time::Instant,
    +    BlockTime, Error, KeychainKind, LocalUtxo, TransactionDetails,
     };
    -use bitcoin::{OutPoint, Script, Transaction, TxOut, Txid};
    -use log::*;
    -use std::collections::{BTreeMap, BTreeSet, HashMap, HashSet, VecDeque};
    -
    -/// A request for on-chain information
    -pub enum Request<'a, D: BatchDatabase> {
    -    /// A request for transactions related to script pubkeys.
    -    Script(ScriptReq<'a, D>),
    -    /// A request for confirmation times for some transactions.
    -    Conftime(ConftimeReq<'a, D>),
    -    /// A request for full transaction details of some transactions.
    -    Tx(TxReq<'a, D>),
    -    /// Requests are finished here's a batch database update to reflect data gathered.
    -    Finish(D::Batch),
    +use bitcoin::{OutPoint, Script, Transaction, TxOut, Txid};
    +use log::*;
    +use std::collections::{BTreeMap, BTreeSet, HashMap, HashSet, VecDeque};
    +
    +/// A request for on-chain information
    +pub enum Request<'a, D: BatchDatabase> {
    +    /// A request for transactions related to script pubkeys.
    +    Script(ScriptReq<'a, D>),
    +    /// A request for confirmation times for some transactions.
    +    Conftime(ConftimeReq<'a, D>),
    +    /// A request for full transaction details of some transactions.
    +    Tx(TxReq<'a, D>),
    +    /// Requests are finished here's a batch database update to reflect data gathered.
    +    Finish(D::Batch),
     }
     
    -/// starts a sync
    -pub fn start<D: BatchDatabase>(db: &D, stop_gap: usize) -> Result<Request<'_, D>, Error> {
    -    use rand::seq::SliceRandom;
    -    let mut keychains = vec![KeychainKind::Internal, KeychainKind::External];
    -    // shuffling improve privacy, the server doesn't know my first request is from my internal or external addresses
    -    keychains.shuffle(&mut rand::thread_rng());
    -    let keychain = keychains.pop().unwrap();
    -    let scripts_needed = db
    -        .iter_script_pubkeys(Some(keychain))?
    -        .into_iter()
    -        .collect::<VecDeque<_>>();
    -    let state = State::new(db);
    -
    -    Ok(Request::Script(ScriptReq {
    -        state,
    -        initial_scripts_needed: scripts_needed.len(),
    -        scripts_needed,
    -        script_index: 0,
    -        stop_gap,
    -        keychain,
    -        next_keychains: keychains,
    +/// starts a sync
    +pub fn start<D: BatchDatabase>(db: &D, stop_gap: usize) -> Result<Request<'_, D>, Error> {
    +    use rand::seq::SliceRandom;
    +    let mut keychains = vec![KeychainKind::Internal, KeychainKind::External];
    +    // shuffling improve privacy, the server doesn't know my first request is from my internal or external addresses
    +    keychains.shuffle(&mut rand::thread_rng());
    +    let keychain = keychains.pop().unwrap();
    +    let scripts_needed = db
    +        .iter_script_pubkeys(Some(keychain))?
    +        .into_iter()
    +        .collect::<VecDeque<_>>();
    +    let state = State::new(db);
    +
    +    Ok(Request::Script(ScriptReq {
    +        state,
    +        initial_scripts_needed: scripts_needed.len(),
    +        scripts_needed,
    +        script_index: 0,
    +        stop_gap,
    +        keychain,
    +        next_keychains: keychains,
         }))
     }
     
    -pub struct ScriptReq<'a, D: BatchDatabase> {
    -    state: State<'a, D>,
    -    script_index: usize,
    -    initial_scripts_needed: usize, // if this is 1, we assume the descriptor is not derivable
    -    scripts_needed: VecDeque<Script>,
    -    stop_gap: usize,
    -    keychain: KeychainKind,
    -    next_keychains: Vec<KeychainKind>,
    +pub struct ScriptReq<'a, D: BatchDatabase> {
    +    state: State<'a, D>,
    +    script_index: usize,
    +    initial_scripts_needed: usize, // if this is 1, we assume the descriptor is not derivable
    +    scripts_needed: VecDeque<Script>,
    +    stop_gap: usize,
    +    keychain: KeychainKind,
    +    next_keychains: Vec<KeychainKind>,
     }
     
    -/// The sync starts by returning script pubkeys we are interested in.
    -impl<'a, D: BatchDatabase> ScriptReq<'a, D> {
    -    pub fn request(&self) -> impl Iterator<Item = &Script> + Clone {
    -        self.scripts_needed.iter()
    +/// The sync starts by returning script pubkeys we are interested in.
    +impl<'a, D: BatchDatabase> ScriptReq<'a, D> {
    +    pub fn request(&self) -> impl Iterator<Item = &Script> + Clone {
    +        self.scripts_needed.iter()
         }
     
    -    pub fn satisfy(
    -        mut self,
    -        // we want to know the txids assoiciated with the script and their height
    -        txids: Vec<Vec<(Txid, Option<u32>)>>,
    -    ) -> Result<Request<'a, D>, Error> {
    -        for (txid_list, script) in txids.iter().zip(self.scripts_needed.iter()) {
    +    pub fn satisfy(
    +        mut self,
    +        // we want to know the txids assoiciated with the script and their height
    +        txids: Vec<Vec<(Txid, Option<u32>)>>,
    +    ) -> Result<Request<'a, D>, Error> {
    +        for (txid_list, script) in txids.iter().zip(self.scripts_needed.iter()) {
                 debug!(
                     "found {} transactions for script pubkey {}",
    -                txid_list.len(),
    -                script
    +                txid_list.len(),
    +                script
                 );
    -            if !txid_list.is_empty() {
    -                // the address is active
    -                self.state
    -                    .last_active_index
    -                    .insert(self.keychain, self.script_index);
    +            if !txid_list.is_empty() {
    +                // the address is active
    +                self.state
    +                    .last_active_index
    +                    .insert(self.keychain, self.script_index);
                 }
     
    -            for (txid, height) in txid_list {
    -                // have we seen this txid already?
    -                match self.state.db.get_tx(txid, true)? {
    -                    Some(mut details) => {
    -                        let old_height = details.confirmation_time.as_ref().map(|x| x.height);
    -                        match (old_height, height) {
    +            for (txid, height) in txid_list {
    +                // have we seen this txid already?
    +                match self.state.db.get_tx(txid, true)? {
    +                    Some(mut details) => {
    +                        let old_height = details.confirmation_time.as_ref().map(|x| x.height);
    +                        match (old_height, height) {
                                 (None, Some(_)) => {
    -                                // It looks like the tx has confirmed since we last saw it -- we
    -                                // need to know the confirmation time.
    -                                self.state.tx_missing_conftime.insert(*txid, details);
    +                                // It looks like the tx has confirmed since we last saw it -- we
    +                                // need to know the confirmation time.
    +                                self.state.tx_missing_conftime.insert(*txid, details);
                                 }
    -                            (Some(old_height), Some(new_height)) if old_height != *new_height => {
    -                                // The height of the tx has changed !? -- It's a reorg get the new confirmation time.
    -                                self.state.tx_missing_conftime.insert(*txid, details);
    +                            (Some(old_height), Some(new_height)) if old_height != *new_height => {
    +                                // The height of the tx has changed !? -- It's a reorg get the new confirmation time.
    +                                self.state.tx_missing_conftime.insert(*txid, details);
                                 }
                                 (Some(_), None) => {
    -                                // A re-org where the tx is not in the chain anymore.
    -                                details.confirmation_time = None;
    -                                self.state.finished_txs.push(details);
    +                                // A re-org where the tx is not in the chain anymore.
    +                                details.confirmation_time = None;
    +                                self.state.finished_txs.push(details);
                                 }
    -                            _ => self.state.finished_txs.push(details),
    +                            _ => self.state.finished_txs.push(details),
                             }
                         }
    -                    None => {
    -                        // we've never seen it let's get the whole thing
    -                        self.state.tx_needed.insert(*txid);
    +                    None => {
    +                        // we've never seen it let's get the whole thing
    +                        self.state.tx_needed.insert(*txid);
                         }
                     };
                 }
     
    -            self.script_index += 1;
    +            self.script_index += 1;
             }
     
    -        self.scripts_needed.drain(..txids.len());
    +        self.scripts_needed.drain(..txids.len());
     
    -        // last active index: 0 => No last active
    -        let last = self
    -            .state
    -            .last_active_index
    -            .get(&self.keychain)
    -            .map(|&l| l + 1)
    -            .unwrap_or(0);
    -        // remaining scripts left to check
    -        let remaining = self.scripts_needed.len();
    -        // difference between current index and last active index
    -        let current_gap = self.script_index - last;
    +        // last active index: 0 => No last active
    +        let last = self
    +            .state
    +            .last_active_index
    +            .get(&self.keychain)
    +            .map(|&l| l + 1)
    +            .unwrap_or(0);
    +        // remaining scripts left to check
    +        let remaining = self.scripts_needed.len();
    +        // difference between current index and last active index
    +        let current_gap = self.script_index - last;
     
    -        // this is a hack to check whether the scripts are coming from a derivable descriptor
    -        // we assume for non-derivable descriptors, the initial script count is always 1
    -        let is_derivable = self.initial_scripts_needed > 1;
    +        // this is a hack to check whether the scripts are coming from a derivable descriptor
    +        // we assume for non-derivable descriptors, the initial script count is always 1
    +        let is_derivable = self.initial_scripts_needed > 1;
     
             debug!(
                 "sync: last={}, remaining={}, diff={}, stop_gap={}",
    -            last, remaining, current_gap, self.stop_gap
    +            last, remaining, current_gap, self.stop_gap
             );
     
    -        if is_derivable {
    -            if remaining > 0 {
    -                // we still have scriptPubKeys to do requests for
    -                return Ok(Request::Script(self));
    +        if is_derivable {
    +            if remaining > 0 {
    +                // we still have scriptPubKeys to do requests for
    +                return Ok(Request::Script(self));
                 }
     
    -            if last > 0 && current_gap < self.stop_gap {
    -                // current gap is not large enough to stop, but we are unable to keep checking since
    -                // we have exhausted cached scriptPubKeys, so return error
    -                let err = MissingCachedScripts {
    -                    last_count: self.script_index,
    -                    missing_count: self.stop_gap - current_gap,
    +            if last > 0 && current_gap < self.stop_gap {
    +                // current gap is not large enough to stop, but we are unable to keep checking since
    +                // we have exhausted cached scriptPubKeys, so return error
    +                let err = MissingCachedScripts {
    +                    last_count: self.script_index,
    +                    missing_count: self.stop_gap - current_gap,
                     };
    -                return Err(Error::MissingCachedScripts(err));
    +                return Err(Error::MissingCachedScripts(err));
                 }
     
    -            // we have exhausted cached scriptPubKeys and found no txs, continue
    -        }
    +            // we have exhausted cached scriptPubKeys and found no txs, continue
    +        }
     
             debug!(
                 "finished scanning for txs of keychain {:?} at index {:?}",
    -            self.keychain, last
    +            self.keychain, last
             );
     
    -        if let Some(keychain) = self.next_keychains.pop() {
    -            // we still have another keychain to request txs with
    -            let scripts_needed = self
    -                .state
    -                .db
    -                .iter_script_pubkeys(Some(keychain))?
    -                .into_iter()
    -                .collect::<VecDeque<_>>();
    -
    -            self.keychain = keychain;
    -            self.script_index = 0;
    -            self.initial_scripts_needed = scripts_needed.len();
    -            self.scripts_needed = scripts_needed;
    -            return Ok(Request::Script(self));
    +        if let Some(keychain) = self.next_keychains.pop() {
    +            // we still have another keychain to request txs with
    +            let scripts_needed = self
    +                .state
    +                .db
    +                .iter_script_pubkeys(Some(keychain))?
    +                .into_iter()
    +                .collect::<VecDeque<_>>();
    +
    +            self.keychain = keychain;
    +            self.script_index = 0;
    +            self.initial_scripts_needed = scripts_needed.len();
    +            self.scripts_needed = scripts_needed;
    +            return Ok(Request::Script(self));
             }
     
    -        // We have finished requesting txids, let's get the actual txs.
    -        Ok(Request::Tx(TxReq { state: self.state }))
    +        // We have finished requesting txids, let's get the actual txs.
    +        Ok(Request::Tx(TxReq { state: self.state }))
         }
     }
     
    -/// Then we get full transactions
    -pub struct TxReq<'a, D> {
    -    state: State<'a, D>,
    +/// Then we get full transactions
    +pub struct TxReq<'a, D> {
    +    state: State<'a, D>,
     }
     
    -impl<'a, D: BatchDatabase> TxReq<'a, D> {
    -    pub fn request(&self) -> impl Iterator<Item = &Txid> + Clone {
    -        self.state.tx_needed.iter()
    +impl<'a, D: BatchDatabase> TxReq<'a, D> {
    +    pub fn request(&self) -> impl Iterator<Item = &Txid> + Clone {
    +        self.state.tx_needed.iter()
         }
     
    -    pub fn satisfy(
    -        mut self,
    -        tx_details: Vec<(Vec<Option<TxOut>>, Transaction)>,
    -    ) -> Result<Request<'a, D>, Error> {
    -        let tx_details: Vec<TransactionDetails> = tx_details
    -            .into_iter()
    -            .zip(self.state.tx_needed.iter())
    -            .map(|((vout, tx), txid)| {
    -                debug!("found tx_details for {}", txid);
    -                assert_eq!(tx.txid(), *txid);
    -                let mut sent: u64 = 0;
    -                let mut received: u64 = 0;
    -                let mut inputs_sum: u64 = 0;
    -                let mut outputs_sum: u64 = 0;
    -
    -                for (txout, (_input_index, input)) in
    -                    vout.into_iter().zip(tx.input.iter().enumerate())
    +    pub fn satisfy(
    +        mut self,
    +        tx_details: Vec<(Vec<Option<TxOut>>, Transaction)>,
    +    ) -> Result<Request<'a, D>, Error> {
    +        let tx_details: Vec<TransactionDetails> = tx_details
    +            .into_iter()
    +            .zip(self.state.tx_needed.iter())
    +            .map(|((vout, tx), txid)| {
    +                debug!("found tx_details for {}", txid);
    +                assert_eq!(tx.txid(), *txid);
    +                let mut sent: u64 = 0;
    +                let mut received: u64 = 0;
    +                let mut inputs_sum: u64 = 0;
    +                let mut outputs_sum: u64 = 0;
    +
    +                for (txout, (_input_index, input)) in
    +                    vout.into_iter().zip(tx.input.iter().enumerate())
                     {
    -                    let txout = match txout {
    -                        Some(txout) => txout,
    -                        None => {
    -                            // skip coinbase inputs
    -                            debug_assert!(
    -                                input.previous_output.is_null(),
    -                                "prevout should only be missing for coinbase"
    -                            );
    +                    let txout = match txout {
    +                        Some(txout) => txout,
    +                        None => {
    +                            // skip coinbase inputs
    +                            debug_assert!(
    +                                input.previous_output.is_null(),
    +                                "prevout should only be missing for coinbase"
    +                            );
                                 continue;
                             }
                         };
    -                    // Verify this input if requested via feature flag
    -                    #[cfg(feature = "verify")]
    -                    {
    -                        use crate::wallet::verify::VerifyError;
    -                        let serialized_tx = bitcoin::consensus::serialize(&tx);
    -                        bitcoinconsensus::verify(
    -                            txout.script_pubkey.to_bytes().as_ref(),
    -                            txout.value,
    -                            &serialized_tx,
    -                            _input_index,
    +                    // Verify this input if requested via feature flag
    +                    #[cfg(feature = "verify")]
    +                    {
    +                        use crate::wallet::verify::VerifyError;
    +                        let serialized_tx = bitcoin::consensus::serialize(&tx);
    +                        bitcoinconsensus::verify(
    +                            txout.script_pubkey.to_bytes().as_ref(),
    +                            txout.value,
    +                            &serialized_tx,
    +                            _input_index,
                             )
    -                        .map_err(VerifyError::from)?;
    +                        .map_err(VerifyError::from)?;
                         }
    -                    inputs_sum += txout.value;
    -                    if self.state.db.is_mine(&txout.script_pubkey)? {
    -                        sent += txout.value;
    +                    inputs_sum += txout.value;
    +                    if self.state.db.is_mine(&txout.script_pubkey)? {
    +                        sent += txout.value;
                         }
                     }
     
    -                for out in &tx.output {
    -                    outputs_sum += out.value;
    -                    if self.state.db.is_mine(&out.script_pubkey)? {
    -                        received += out.value;
    +                for out in &tx.output {
    +                    outputs_sum += out.value;
    +                    if self.state.db.is_mine(&out.script_pubkey)? {
    +                        received += out.value;
                         }
                     }
    -                // we need to saturating sub since we want coinbase txs to map to 0 fee and
    -                // this subtraction will be negative for coinbase txs.
    -                let fee = inputs_sum.saturating_sub(outputs_sum);
    -                Result::<_, Error>::Ok(TransactionDetails {
    -                    txid: *txid,
    -                    transaction: Some(tx),
    -                    received,
    -                    sent,
    -                    // we're going to fill this in later
    -                    confirmation_time: None,
    -                    fee: Some(fee),
    +                // we need to saturating sub since we want coinbase txs to map to 0 fee and
    +                // this subtraction will be negative for coinbase txs.
    +                let fee = inputs_sum.saturating_sub(outputs_sum);
    +                Result::<_, Error>::Ok(TransactionDetails {
    +                    txid: *txid,
    +                    transaction: Some(tx),
    +                    received,
    +                    sent,
    +                    // we're going to fill this in later
    +                    confirmation_time: None,
    +                    fee: Some(fee),
                     })
                 })
    -            .collect::<Result<Vec<_>, _>>()?;
    +            .collect::<Result<Vec<_>, _>>()?;
     
    -        for tx_detail in tx_details {
    -            self.state.tx_needed.remove(&tx_detail.txid);
    -            self.state
    -                .tx_missing_conftime
    -                .insert(tx_detail.txid, tx_detail);
    +        for tx_detail in tx_details {
    +            self.state.tx_needed.remove(&tx_detail.txid);
    +            self.state
    +                .tx_missing_conftime
    +                .insert(tx_detail.txid, tx_detail);
             }
     
    -        if !self.state.tx_needed.is_empty() {
    -            Ok(Request::Tx(self))
    -        } else {
    -            Ok(Request::Conftime(ConftimeReq { state: self.state }))
    +        if !self.state.tx_needed.is_empty() {
    +            Ok(Request::Tx(self))
    +        } else {
    +            Ok(Request::Conftime(ConftimeReq { state: self.state }))
             }
         }
     }
     
    -/// Final step is to get confirmation times
    -pub struct ConftimeReq<'a, D> {
    -    state: State<'a, D>,
    +/// Final step is to get confirmation times
    +pub struct ConftimeReq<'a, D> {
    +    state: State<'a, D>,
     }
     
    -impl<'a, D: BatchDatabase> ConftimeReq<'a, D> {
    -    pub fn request(&self) -> impl Iterator<Item = &Txid> + Clone {
    -        self.state.tx_missing_conftime.keys()
    +impl<'a, D: BatchDatabase> ConftimeReq<'a, D> {
    +    pub fn request(&self) -> impl Iterator<Item = &Txid> + Clone {
    +        self.state.tx_missing_conftime.keys()
         }
     
    -    pub fn satisfy(
    -        mut self,
    -        confirmation_times: Vec<Option<BlockTime>>,
    -    ) -> Result<Request<'a, D>, Error> {
    -        let conftime_needed = self
    -            .request()
    -            .cloned()
    -            .take(confirmation_times.len())
    -            .collect::<Vec<_>>();
    -        for (confirmation_time, txid) in confirmation_times.into_iter().zip(conftime_needed.iter())
    +    pub fn satisfy(
    +        mut self,
    +        confirmation_times: Vec<Option<BlockTime>>,
    +    ) -> Result<Request<'a, D>, Error> {
    +        let conftime_needed = self
    +            .request()
    +            .cloned()
    +            .take(confirmation_times.len())
    +            .collect::<Vec<_>>();
    +        for (confirmation_time, txid) in confirmation_times.into_iter().zip(conftime_needed.iter())
             {
    -            debug!("confirmation time for {} was {:?}", txid, confirmation_time);
    -            if let Some(mut tx_details) = self.state.tx_missing_conftime.remove(txid) {
    -                tx_details.confirmation_time = confirmation_time;
    -                self.state.finished_txs.push(tx_details);
    +            debug!("confirmation time for {} was {:?}", txid, confirmation_time);
    +            if let Some(mut tx_details) = self.state.tx_missing_conftime.remove(txid) {
    +                tx_details.confirmation_time = confirmation_time;
    +                self.state.finished_txs.push(tx_details);
                 }
             }
     
    -        if self.state.tx_missing_conftime.is_empty() {
    -            Ok(Request::Finish(self.state.into_db_update()?))
    -        } else {
    -            Ok(Request::Conftime(self))
    +        if self.state.tx_missing_conftime.is_empty() {
    +            Ok(Request::Finish(self.state.into_db_update()?))
    +        } else {
    +            Ok(Request::Conftime(self))
             }
         }
     }
     
    -struct State<'a, D> {
    -    db: &'a D,
    -    last_active_index: HashMap<KeychainKind, usize>,
    -    /// Transactions where we need to get the full details
    -    tx_needed: BTreeSet<Txid>,
    -    /// Transacitions that we know everything about
    -    finished_txs: Vec<TransactionDetails>,
    -    /// Transactions that discovered conftimes should be inserted into
    -    tx_missing_conftime: BTreeMap<Txid, TransactionDetails>,
    -    /// The start of the sync
    -    start_time: Instant,
    -    /// Missing number of scripts to cache per keychain
    -    missing_script_counts: HashMap<KeychainKind, usize>,
    +struct State<'a, D> {
    +    db: &'a D,
    +    last_active_index: HashMap<KeychainKind, usize>,
    +    /// Transactions where we need to get the full details
    +    tx_needed: BTreeSet<Txid>,
    +    /// Transacitions that we know everything about
    +    finished_txs: Vec<TransactionDetails>,
    +    /// Transactions that discovered conftimes should be inserted into
    +    tx_missing_conftime: BTreeMap<Txid, TransactionDetails>,
    +    /// The start of the sync
    +    start_time: Instant,
    +    /// Missing number of scripts to cache per keychain
    +    missing_script_counts: HashMap<KeychainKind, usize>,
     }
     
    -impl<'a, D: BatchDatabase> State<'a, D> {
    -    fn new(db: &'a D) -> Self {
    -        State {
    -            db,
    -            last_active_index: HashMap::default(),
    -            finished_txs: vec![],
    -            tx_needed: BTreeSet::default(),
    -            tx_missing_conftime: BTreeMap::default(),
    -            start_time: Instant::new(),
    -            missing_script_counts: HashMap::default(),
    +impl<'a, D: BatchDatabase> State<'a, D> {
    +    fn new(db: &'a D) -> Self {
    +        State {
    +            db,
    +            last_active_index: HashMap::default(),
    +            finished_txs: vec![],
    +            tx_needed: BTreeSet::default(),
    +            tx_missing_conftime: BTreeMap::default(),
    +            start_time: Instant::new(),
    +            missing_script_counts: HashMap::default(),
             }
         }
    -    fn into_db_update(self) -> Result<D::Batch, Error> {
    -        debug_assert!(self.tx_needed.is_empty() && self.tx_missing_conftime.is_empty());
    -        let existing_txs = self.db.iter_txs(false)?;
    -        let existing_txids: HashSet<Txid> = existing_txs.iter().map(|tx| tx.txid).collect();
    -        let finished_txs = make_txs_consistent(&self.finished_txs);
    -        let observed_txids: HashSet<Txid> = finished_txs.iter().map(|tx| tx.txid).collect();
    -        let txids_to_delete = existing_txids.difference(&observed_txids);
    -
    -        // Ensure `last_active_index` does not decrement database's current state.
    -        let index_updates = self
    -            .last_active_index
    -            .iter()
    -            .map(|(keychain, sync_index)| {
    -                let sync_index = *sync_index as u32;
    -                let index_res = match self.db.get_last_index(*keychain) {
    -                    Ok(Some(db_index)) => Ok(std::cmp::max(db_index, sync_index)),
    -                    Ok(None) => Ok(sync_index),
    -                    Err(err) => Err(err),
    +    fn into_db_update(self) -> Result<D::Batch, Error> {
    +        debug_assert!(self.tx_needed.is_empty() && self.tx_missing_conftime.is_empty());
    +        let existing_txs = self.db.iter_txs(false)?;
    +        let existing_txids: HashSet<Txid> = existing_txs.iter().map(|tx| tx.txid).collect();
    +        let finished_txs = make_txs_consistent(&self.finished_txs);
    +        let observed_txids: HashSet<Txid> = finished_txs.iter().map(|tx| tx.txid).collect();
    +        let txids_to_delete = existing_txids.difference(&observed_txids);
    +
    +        // Ensure `last_active_index` does not decrement database's current state.
    +        let index_updates = self
    +            .last_active_index
    +            .iter()
    +            .map(|(keychain, sync_index)| {
    +                let sync_index = *sync_index as u32;
    +                let index_res = match self.db.get_last_index(*keychain) {
    +                    Ok(Some(db_index)) => Ok(std::cmp::max(db_index, sync_index)),
    +                    Ok(None) => Ok(sync_index),
    +                    Err(err) => Err(err),
                     };
    -                index_res.map(|index| (*keychain, index))
    +                index_res.map(|index| (*keychain, index))
                 })
    -            .collect::<Result<Vec<(KeychainKind, u32)>, _>>()?;
    -
    -        let mut batch = self.db.begin_batch();
    -
    -        // Delete old txs that no longer exist
    -        for txid in txids_to_delete {
    -            if let Some(raw_tx) = self.db.get_raw_tx(txid)? {
    -                for i in 0..raw_tx.output.len() {
    -                    // Also delete any utxos from the txs that no longer exist.
    -                    let _ = batch.del_utxo(&OutPoint {
    -                        txid: *txid,
    -                        vout: i as u32,
    +            .collect::<Result<Vec<(KeychainKind, u32)>, _>>()?;
    +
    +        let mut batch = self.db.begin_batch();
    +
    +        // Delete old txs that no longer exist
    +        for txid in txids_to_delete {
    +            if let Some(raw_tx) = self.db.get_raw_tx(txid)? {
    +                for i in 0..raw_tx.output.len() {
    +                    // Also delete any utxos from the txs that no longer exist.
    +                    let _ = batch.del_utxo(&OutPoint {
    +                        txid: *txid,
    +                        vout: i as u32,
                         })?;
                     }
    -            } else {
    +            } else {
                     unreachable!("we should always have the raw tx");
                 }
    -            batch.del_tx(txid, true)?;
    +            batch.del_tx(txid, true)?;
             }
     
    -        let mut spent_utxos = HashSet::new();
    +        let mut spent_utxos = HashSet::new();
     
    -        // track all the spent utxos
    -        for finished_tx in &finished_txs {
    -            let tx = finished_tx
    -                .transaction
    -                .as_ref()
    -                .expect("transaction will always be present here");
    -            for input in &tx.input {
    -                spent_utxos.insert(&input.previous_output);
    +        // track all the spent utxos
    +        for finished_tx in &finished_txs {
    +            let tx = finished_tx
    +                .transaction
    +                .as_ref()
    +                .expect("transaction will always be present here");
    +            for input in &tx.input {
    +                spent_utxos.insert(&input.previous_output);
                 }
             }
     
    -        // set every utxo we observed, unless it's already spent
    -        // we don't do this in the loop above as we want to know all the spent outputs before
    -        // adding the non-spent to the batch in case there are new tranasactions
    -        // that spend form each other.
    -        for finished_tx in &finished_txs {
    -            let tx = finished_tx
    -                .transaction
    -                .as_ref()
    -                .expect("transaction will always be present here");
    -            for (i, output) in tx.output.iter().enumerate() {
    -                if let Some((keychain, _)) =
    -                    self.db.get_path_from_script_pubkey(&output.script_pubkey)?
    -                {
    -                    // add utxos we own from the new transactions we've seen.
    -                    let outpoint = OutPoint {
    -                        txid: finished_tx.txid,
    -                        vout: i as u32,
    +        // set every utxo we observed, unless it's already spent
    +        // we don't do this in the loop above as we want to know all the spent outputs before
    +        // adding the non-spent to the batch in case there are new tranasactions
    +        // that spend form each other.
    +        for finished_tx in &finished_txs {
    +            let tx = finished_tx
    +                .transaction
    +                .as_ref()
    +                .expect("transaction will always be present here");
    +            for (i, output) in tx.output.iter().enumerate() {
    +                if let Some((keychain, _)) =
    +                    self.db.get_path_from_script_pubkey(&output.script_pubkey)?
    +                {
    +                    // add utxos we own from the new transactions we've seen.
    +                    let outpoint = OutPoint {
    +                        txid: finished_tx.txid,
    +                        vout: i as u32,
                         };
     
    -                    batch.set_utxo(&LocalUtxo {
    -                        outpoint,
    -                        txout: output.clone(),
    -                        keychain,
    -                        // Is this UTXO in the spent_utxos set?
    -                        is_spent: spent_utxos.get(&outpoint).is_some(),
    +                    batch.set_utxo(&LocalUtxo {
    +                        outpoint,
    +                        txout: output.clone(),
    +                        keychain,
    +                        // Is this UTXO in the spent_utxos set?
    +                        is_spent: spent_utxos.get(&outpoint).is_some(),
                         })?;
                     }
                 }
     
    -            batch.set_tx(finished_tx)?;
    +            batch.set_tx(finished_tx)?;
             }
     
    -        // apply index updates
    -        for (keychain, new_index) in index_updates {
    -            debug!("updating index ({}, {})", keychain.as_byte(), new_index);
    -            batch.set_last_index(keychain, new_index)?;
    +        // apply index updates
    +        for (keychain, new_index) in index_updates {
    +            debug!("updating index ({}, {})", keychain.as_byte(), new_index);
    +            batch.set_last_index(keychain, new_index)?;
             }
     
             info!(
                 "finished setup, elapsed {:?}ms",
    -            self.start_time.elapsed().as_millis()
    +            self.start_time.elapsed().as_millis()
             );
    -        Ok(batch)
    +        Ok(batch)
         }
     }
     
    -/// Remove conflicting transactions -- tie breaking them by fee.
    -fn make_txs_consistent(txs: &[TransactionDetails]) -> Vec<&TransactionDetails> {
    -    let mut utxo_index: HashMap<OutPoint, &TransactionDetails> = HashMap::default();
    -    for tx in txs {
    -        for input in &tx.transaction.as_ref().unwrap().input {
    -            utxo_index
    -                .entry(input.previous_output)
    -                .and_modify(|existing| match (tx.fee, existing.fee) {
    -                    (Some(fee), Some(existing_fee)) if fee > existing_fee => *existing = tx,
    -                    (Some(_), None) => *existing = tx,
    -                    _ => { /* leave it the same */ }
    +/// Remove conflicting transactions -- tie breaking them by fee.
    +fn make_txs_consistent(txs: &[TransactionDetails]) -> Vec<&TransactionDetails> {
    +    let mut utxo_index: HashMap<OutPoint, &TransactionDetails> = HashMap::default();
    +    for tx in txs {
    +        for input in &tx.transaction.as_ref().unwrap().input {
    +            utxo_index
    +                .entry(input.previous_output)
    +                .and_modify(|existing| match (tx.fee, existing.fee) {
    +                    (Some(fee), Some(existing_fee)) if fee > existing_fee => *existing = tx,
    +                    (Some(_), None) => *existing = tx,
    +                    _ => { /* leave it the same */ }
                     })
    -                .or_insert(tx);
    +                .or_insert(tx);
             }
         }
     
    -    utxo_index
    -        .into_iter()
    -        .map(|(_, tx)| (tx.txid, tx))
    -        .collect::<HashMap<_, _>>()
    -        .into_iter()
    -        .map(|(_, tx)| tx)
    -        .collect()
    +    utxo_index
    +        .into_iter()
    +        .map(|(_, tx)| (tx.txid, tx))
    +        .collect::<HashMap<_, _>>()
    +        .into_iter()
    +        .map(|(_, tx)| tx)
    +        .collect()
     }
     
    -
    - \ No newline at end of file +
    \ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/src/bdk/database/any.rs.html b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/src/bdk/database/any.rs.html index e4cbe3ecb6..233a66debb 100644 --- a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/src/bdk/database/any.rs.html +++ b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/src/bdk/database/any.rs.html @@ -1,864 +1,857 @@ -any.rs - source - -
      1
    -  2
    -  3
    -  4
    -  5
    -  6
    -  7
    -  8
    -  9
    - 10
    - 11
    - 12
    - 13
    - 14
    - 15
    - 16
    - 17
    - 18
    - 19
    - 20
    - 21
    - 22
    - 23
    - 24
    - 25
    - 26
    - 27
    - 28
    - 29
    - 30
    - 31
    - 32
    - 33
    - 34
    - 35
    - 36
    - 37
    - 38
    - 39
    - 40
    - 41
    - 42
    - 43
    - 44
    - 45
    - 46
    - 47
    - 48
    - 49
    - 50
    - 51
    - 52
    - 53
    - 54
    - 55
    - 56
    - 57
    - 58
    - 59
    - 60
    - 61
    - 62
    - 63
    - 64
    - 65
    - 66
    - 67
    - 68
    - 69
    - 70
    - 71
    - 72
    - 73
    - 74
    - 75
    - 76
    - 77
    - 78
    - 79
    - 80
    - 81
    - 82
    - 83
    - 84
    - 85
    - 86
    - 87
    - 88
    - 89
    - 90
    - 91
    - 92
    - 93
    - 94
    - 95
    - 96
    - 97
    - 98
    - 99
    -100
    -101
    -102
    -103
    -104
    -105
    -106
    -107
    -108
    -109
    -110
    -111
    -112
    -113
    -114
    -115
    -116
    -117
    -118
    -119
    -120
    -121
    -122
    -123
    -124
    -125
    -126
    -127
    -128
    -129
    -130
    -131
    -132
    -133
    -134
    -135
    -136
    -137
    -138
    -139
    -140
    -141
    -142
    -143
    -144
    -145
    -146
    -147
    -148
    -149
    -150
    -151
    -152
    -153
    -154
    -155
    -156
    -157
    -158
    -159
    -160
    -161
    -162
    -163
    -164
    -165
    -166
    -167
    -168
    -169
    -170
    -171
    -172
    -173
    -174
    -175
    -176
    -177
    -178
    -179
    -180
    -181
    -182
    -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
    -245
    -246
    -247
    -248
    -249
    -250
    -251
    -252
    -253
    -254
    -255
    -256
    -257
    -258
    -259
    -260
    -261
    -262
    -263
    -264
    -265
    -266
    -267
    -268
    -269
    -270
    -271
    -272
    -273
    -274
    -275
    -276
    -277
    -278
    -279
    -280
    -281
    -282
    -283
    -284
    -285
    -286
    -287
    -288
    -289
    -290
    -291
    -292
    -293
    -294
    -295
    -296
    -297
    -298
    -299
    -300
    -301
    -302
    -303
    -304
    -305
    -306
    -307
    -308
    -309
    -310
    -311
    -312
    -313
    -314
    -315
    -316
    -317
    -318
    -319
    -320
    -321
    -322
    -323
    -324
    -325
    -326
    -327
    -328
    -329
    -330
    -331
    -332
    -333
    -334
    -335
    -336
    -337
    -338
    -339
    -340
    -341
    -342
    -343
    -344
    -345
    -346
    -347
    -348
    -349
    -350
    -351
    -352
    -353
    -354
    -355
    -356
    -357
    -358
    -359
    -360
    -361
    -362
    -363
    -364
    -365
    -366
    -367
    -368
    -369
    -370
    -371
    -372
    -373
    -374
    -375
    -376
    -377
    -378
    -379
    -380
    -381
    -382
    -383
    -384
    -385
    -386
    -387
    -388
    -389
    -390
    -391
    -392
    -393
    -394
    -395
    -396
    -397
    -398
    -399
    -400
    -401
    -402
    -403
    -404
    -405
    -406
    -407
    -408
    -409
    -410
    -411
    -412
    -413
    -414
    -415
    -416
    -417
    -418
    -419
    -420
    -421
    -422
    -423
    -424
    -425
    -426
    -427
    -
    // Bitcoin Dev Kit
    -// Written in 2020 by Alekos Filini <alekos.filini@gmail.com>
    -//
    -// Copyright (c) 2020-2021 Bitcoin Dev Kit Developers
    -//
    -// This file is licensed under the Apache License, Version 2.0 <LICENSE-APACHE
    -// or http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
    -// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your option.
    -// You may not use this file except in accordance with one or both of these
    -// licenses.
    +any.rs - source
    1
    +2
    +3
    +4
    +5
    +6
    +7
    +8
    +9
    +10
    +11
    +12
    +13
    +14
    +15
    +16
    +17
    +18
    +19
    +20
    +21
    +22
    +23
    +24
    +25
    +26
    +27
    +28
    +29
    +30
    +31
    +32
    +33
    +34
    +35
    +36
    +37
    +38
    +39
    +40
    +41
    +42
    +43
    +44
    +45
    +46
    +47
    +48
    +49
    +50
    +51
    +52
    +53
    +54
    +55
    +56
    +57
    +58
    +59
    +60
    +61
    +62
    +63
    +64
    +65
    +66
    +67
    +68
    +69
    +70
    +71
    +72
    +73
    +74
    +75
    +76
    +77
    +78
    +79
    +80
    +81
    +82
    +83
    +84
    +85
    +86
    +87
    +88
    +89
    +90
    +91
    +92
    +93
    +94
    +95
    +96
    +97
    +98
    +99
    +100
    +101
    +102
    +103
    +104
    +105
    +106
    +107
    +108
    +109
    +110
    +111
    +112
    +113
    +114
    +115
    +116
    +117
    +118
    +119
    +120
    +121
    +122
    +123
    +124
    +125
    +126
    +127
    +128
    +129
    +130
    +131
    +132
    +133
    +134
    +135
    +136
    +137
    +138
    +139
    +140
    +141
    +142
    +143
    +144
    +145
    +146
    +147
    +148
    +149
    +150
    +151
    +152
    +153
    +154
    +155
    +156
    +157
    +158
    +159
    +160
    +161
    +162
    +163
    +164
    +165
    +166
    +167
    +168
    +169
    +170
    +171
    +172
    +173
    +174
    +175
    +176
    +177
    +178
    +179
    +180
    +181
    +182
    +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
    +245
    +246
    +247
    +248
    +249
    +250
    +251
    +252
    +253
    +254
    +255
    +256
    +257
    +258
    +259
    +260
    +261
    +262
    +263
    +264
    +265
    +266
    +267
    +268
    +269
    +270
    +271
    +272
    +273
    +274
    +275
    +276
    +277
    +278
    +279
    +280
    +281
    +282
    +283
    +284
    +285
    +286
    +287
    +288
    +289
    +290
    +291
    +292
    +293
    +294
    +295
    +296
    +297
    +298
    +299
    +300
    +301
    +302
    +303
    +304
    +305
    +306
    +307
    +308
    +309
    +310
    +311
    +312
    +313
    +314
    +315
    +316
    +317
    +318
    +319
    +320
    +321
    +322
    +323
    +324
    +325
    +326
    +327
    +328
    +329
    +330
    +331
    +332
    +333
    +334
    +335
    +336
    +337
    +338
    +339
    +340
    +341
    +342
    +343
    +344
    +345
    +346
    +347
    +348
    +349
    +350
    +351
    +352
    +353
    +354
    +355
    +356
    +357
    +358
    +359
    +360
    +361
    +362
    +363
    +364
    +365
    +366
    +367
    +368
    +369
    +370
    +371
    +372
    +373
    +374
    +375
    +376
    +377
    +378
    +379
    +380
    +381
    +382
    +383
    +384
    +385
    +386
    +387
    +388
    +389
    +390
    +391
    +392
    +393
    +394
    +395
    +396
    +397
    +398
    +399
    +400
    +401
    +402
    +403
    +404
    +405
    +406
    +407
    +408
    +409
    +410
    +411
    +412
    +413
    +414
    +415
    +416
    +417
    +418
    +419
    +420
    +421
    +422
    +423
    +424
    +425
    +426
    +427
    +
    // Bitcoin Dev Kit
    +// Written in 2020 by Alekos Filini <alekos.filini@gmail.com>
    +//
    +// Copyright (c) 2020-2021 Bitcoin Dev Kit Developers
    +//
    +// This file is licensed under the Apache License, Version 2.0 <LICENSE-APACHE
    +// or http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
    +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your option.
    +// You may not use this file except in accordance with one or both of these
    +// licenses.
     
    -//! Runtime-checked database types
    -//!
    -//! This module provides the implementation of [`AnyDatabase`] which allows switching the
    -//! inner [`Database`] type at runtime.
    -//!
    -//! ## Example
    -//!
    -//! In this example, `wallet_memory` and `wallet_sled` have the same type of `Wallet<(), AnyDatabase>`.
    -//!
    -//! ```no_run
    -//! # use bitcoin::Network;
    -//! # use bdk::database::{AnyDatabase, MemoryDatabase};
    -//! # use bdk::{Wallet};
    -//! let memory = MemoryDatabase::default();
    -//! let wallet_memory = Wallet::new("...", None, Network::Testnet, memory)?;
    -//!
    -//! # #[cfg(feature = "key-value-db")]
    -//! # {
    -//! let sled = sled::open("my-database")?.open_tree("default_tree")?;
    -//! let wallet_sled = Wallet::new("...", None, Network::Testnet, sled)?;
    -//! # }
    -//! # Ok::<(), bdk::Error>(())
    -//! ```
    -//!
    -//! When paired with the use of [`ConfigurableDatabase`], it allows creating wallets with any
    -//! database supported using a single line of code:
    -//!
    -//! ```no_run
    -//! # use bitcoin::Network;
    -//! # use bdk::database::*;
    -//! # use bdk::{Wallet};
    -//! let config = serde_json::from_str("...")?;
    -//! let database = AnyDatabase::from_config(&config)?;
    -//! let wallet = Wallet::new("...", None, Network::Testnet, database)?;
    -//! # Ok::<(), bdk::Error>(())
    -//! ```
    +//! Runtime-checked database types
    +//!
    +//! This module provides the implementation of [`AnyDatabase`] which allows switching the
    +//! inner [`Database`] type at runtime.
    +//!
    +//! ## Example
    +//!
    +//! In this example, `wallet_memory` and `wallet_sled` have the same type of `Wallet<(), AnyDatabase>`.
    +//!
    +//! ```no_run
    +//! # use bitcoin::Network;
    +//! # use bdk::database::{AnyDatabase, MemoryDatabase};
    +//! # use bdk::{Wallet};
    +//! let memory = MemoryDatabase::default();
    +//! let wallet_memory = Wallet::new("...", None, Network::Testnet, memory)?;
    +//!
    +//! # #[cfg(feature = "key-value-db")]
    +//! # {
    +//! let sled = sled::open("my-database")?.open_tree("default_tree")?;
    +//! let wallet_sled = Wallet::new("...", None, Network::Testnet, sled)?;
    +//! # }
    +//! # Ok::<(), bdk::Error>(())
    +//! ```
    +//!
    +//! When paired with the use of [`ConfigurableDatabase`], it allows creating wallets with any
    +//! database supported using a single line of code:
    +//!
    +//! ```no_run
    +//! # use bitcoin::Network;
    +//! # use bdk::database::*;
    +//! # use bdk::{Wallet};
    +//! let config = serde_json::from_str("...")?;
    +//! let database = AnyDatabase::from_config(&config)?;
    +//! let wallet = Wallet::new("...", None, Network::Testnet, database)?;
    +//! # Ok::<(), bdk::Error>(())
    +//! ```
     
    -use super::*;
    +use super::*;
     
    -macro_rules! impl_from {
    -    ( $from:ty, $to:ty, $variant:ident, $( $cfg:tt )* ) => {
    -        $( $cfg )*
    -        impl From<$from> for $to {
    -            fn from(inner: $from) -> Self {
    -                <$to>::$variant(inner)
    +macro_rules! impl_from {
    +    ( $from:ty, $to:ty, $variant:ident, $( $cfg:tt )* ) => {
    +        $( $cfg )*
    +        impl From<$from> for $to {
    +            fn from(inner: $from) -> Self {
    +                <$to>::$variant(inner)
                 }
             }
         };
     }
     
    -macro_rules! impl_inner_method {
    -    ( $enum_name:ident, $self:expr, $name:ident $(, $args:expr)* ) => {
    -        #[allow(deprecated)]
    -        match $self {
    -            $enum_name::Memory(inner) => inner.$name( $($args, )* ),
    -            #[cfg(feature = "key-value-db")]
    -            $enum_name::Sled(inner) => inner.$name( $($args, )* ),
    -            #[cfg(feature = "sqlite")]
    -            $enum_name::Sqlite(inner) => inner.$name( $($args, )* ),
    +macro_rules! impl_inner_method {
    +    ( $enum_name:ident, $self:expr, $name:ident $(, $args:expr)* ) => {
    +        #[allow(deprecated)]
    +        match $self {
    +            $enum_name::Memory(inner) => inner.$name( $($args, )* ),
    +            #[cfg(feature = "key-value-db")]
    +            $enum_name::Sled(inner) => inner.$name( $($args, )* ),
    +            #[cfg(feature = "sqlite")]
    +            $enum_name::Sqlite(inner) => inner.$name( $($args, )* ),
             }
         }
     }
     
    -/// Type that can contain any of the [`Database`] types defined by the library
    -///
    -/// It allows switching database type at runtime.
    -///
    -/// See [this module](crate::database::any)'s documentation for a usage example.
    -#[derive(Debug)]
    -pub enum AnyDatabase {
    -    /// In-memory ephemeral database
    -    Memory(memory::MemoryDatabase),
    -    #[cfg(feature = "key-value-db")]
    -    #[cfg_attr(docsrs, doc(cfg(feature = "key-value-db")))]
    -    /// Simple key-value embedded database based on [`sled`]
    -    Sled(sled::Tree),
    -    #[cfg(feature = "sqlite")]
    -    #[cfg_attr(docsrs, doc(cfg(feature = "sqlite")))]
    -    /// Sqlite embedded database using [`rusqlite`]
    -    Sqlite(sqlite::SqliteDatabase),
    +/// Type that can contain any of the [`Database`] types defined by the library
    +///
    +/// It allows switching database type at runtime.
    +///
    +/// See [this module](crate::database::any)'s documentation for a usage example.
    +#[derive(Debug)]
    +pub enum AnyDatabase {
    +    /// In-memory ephemeral database
    +    Memory(memory::MemoryDatabase),
    +    #[cfg(feature = "key-value-db")]
    +    #[cfg_attr(docsrs, doc(cfg(feature = "key-value-db")))]
    +    /// Simple key-value embedded database based on [`sled`]
    +    Sled(sled::Tree),
    +    #[cfg(feature = "sqlite")]
    +    #[cfg_attr(docsrs, doc(cfg(feature = "sqlite")))]
    +    /// Sqlite embedded database using [`rusqlite`]
    +    Sqlite(sqlite::SqliteDatabase),
     }
     
    -impl_from!(memory::MemoryDatabase, AnyDatabase, Memory,);
    -impl_from!(sled::Tree, AnyDatabase, Sled, #[cfg(feature = "key-value-db")]);
    -impl_from!(sqlite::SqliteDatabase, AnyDatabase, Sqlite, #[cfg(feature = "sqlite")]);
    +impl_from!(memory::MemoryDatabase, AnyDatabase, Memory,);
    +impl_from!(sled::Tree, AnyDatabase, Sled, #[cfg(feature = "key-value-db")]);
    +impl_from!(sqlite::SqliteDatabase, AnyDatabase, Sqlite, #[cfg(feature = "sqlite")]);
     
    -/// Type that contains any of the [`BatchDatabase::Batch`] types defined by the library
    -pub enum AnyBatch {
    -    /// In-memory ephemeral database
    -    Memory(<memory::MemoryDatabase as BatchDatabase>::Batch),
    -    #[cfg(feature = "key-value-db")]
    -    #[cfg_attr(docsrs, doc(cfg(feature = "key-value-db")))]
    -    /// Simple key-value embedded database based on [`sled`]
    -    Sled(<sled::Tree as BatchDatabase>::Batch),
    -    #[cfg(feature = "sqlite")]
    -    #[cfg_attr(docsrs, doc(cfg(feature = "sqlite")))]
    -    /// Sqlite embedded database using [`rusqlite`]
    -    Sqlite(<sqlite::SqliteDatabase as BatchDatabase>::Batch),
    +/// Type that contains any of the [`BatchDatabase::Batch`] types defined by the library
    +pub enum AnyBatch {
    +    /// In-memory ephemeral database
    +    Memory(<memory::MemoryDatabase as BatchDatabase>::Batch),
    +    #[cfg(feature = "key-value-db")]
    +    #[cfg_attr(docsrs, doc(cfg(feature = "key-value-db")))]
    +    /// Simple key-value embedded database based on [`sled`]
    +    Sled(<sled::Tree as BatchDatabase>::Batch),
    +    #[cfg(feature = "sqlite")]
    +    #[cfg_attr(docsrs, doc(cfg(feature = "sqlite")))]
    +    /// Sqlite embedded database using [`rusqlite`]
    +    Sqlite(<sqlite::SqliteDatabase as BatchDatabase>::Batch),
     }
     
     impl_from!(
    -    <memory::MemoryDatabase as BatchDatabase>::Batch,
    -    AnyBatch,
    -    Memory,
    +    <memory::MemoryDatabase as BatchDatabase>::Batch,
    +    AnyBatch,
    +    Memory,
     );
    -impl_from!(<sled::Tree as BatchDatabase>::Batch, AnyBatch, Sled, #[cfg(feature = "key-value-db")]);
    -impl_from!(<sqlite::SqliteDatabase as BatchDatabase>::Batch, AnyBatch, Sqlite, #[cfg(feature = "sqlite")]);
    +impl_from!(<sled::Tree as BatchDatabase>::Batch, AnyBatch, Sled, #[cfg(feature = "key-value-db")]);
    +impl_from!(<sqlite::SqliteDatabase as BatchDatabase>::Batch, AnyBatch, Sqlite, #[cfg(feature = "sqlite")]);
     
    -impl BatchOperations for AnyDatabase {
    -    fn set_script_pubkey(
    -        &mut self,
    -        script: &Script,
    -        keychain: KeychainKind,
    -        child: u32,
    -    ) -> Result<(), Error> {
    +impl BatchOperations for AnyDatabase {
    +    fn set_script_pubkey(
    +        &mut self,
    +        script: &Script,
    +        keychain: KeychainKind,
    +        child: u32,
    +    ) -> Result<(), Error> {
             impl_inner_method!(
    -            AnyDatabase,
    +            AnyDatabase,
                 self,
    -            set_script_pubkey,
    -            script,
    -            keychain,
    -            child
    +            set_script_pubkey,
    +            script,
    +            keychain,
    +            child
             )
         }
    -    fn set_utxo(&mut self, utxo: &LocalUtxo) -> Result<(), Error> {
    -        impl_inner_method!(AnyDatabase, self, set_utxo, utxo)
    +    fn set_utxo(&mut self, utxo: &LocalUtxo) -> Result<(), Error> {
    +        impl_inner_method!(AnyDatabase, self, set_utxo, utxo)
         }
    -    fn set_raw_tx(&mut self, transaction: &Transaction) -> Result<(), Error> {
    -        impl_inner_method!(AnyDatabase, self, set_raw_tx, transaction)
    +    fn set_raw_tx(&mut self, transaction: &Transaction) -> Result<(), Error> {
    +        impl_inner_method!(AnyDatabase, self, set_raw_tx, transaction)
         }
    -    fn set_tx(&mut self, transaction: &TransactionDetails) -> Result<(), Error> {
    -        impl_inner_method!(AnyDatabase, self, set_tx, transaction)
    +    fn set_tx(&mut self, transaction: &TransactionDetails) -> Result<(), Error> {
    +        impl_inner_method!(AnyDatabase, self, set_tx, transaction)
         }
    -    fn set_last_index(&mut self, keychain: KeychainKind, value: u32) -> Result<(), Error> {
    -        impl_inner_method!(AnyDatabase, self, set_last_index, keychain, value)
    +    fn set_last_index(&mut self, keychain: KeychainKind, value: u32) -> Result<(), Error> {
    +        impl_inner_method!(AnyDatabase, self, set_last_index, keychain, value)
         }
    -    fn set_sync_time(&mut self, sync_time: SyncTime) -> Result<(), Error> {
    -        impl_inner_method!(AnyDatabase, self, set_sync_time, sync_time)
    +    fn set_sync_time(&mut self, sync_time: SyncTime) -> Result<(), Error> {
    +        impl_inner_method!(AnyDatabase, self, set_sync_time, sync_time)
         }
     
    -    fn del_script_pubkey_from_path(
    -        &mut self,
    -        keychain: KeychainKind,
    -        child: u32,
    -    ) -> Result<Option<Script>, Error> {
    +    fn del_script_pubkey_from_path(
    +        &mut self,
    +        keychain: KeychainKind,
    +        child: u32,
    +    ) -> Result<Option<Script>, Error> {
             impl_inner_method!(
    -            AnyDatabase,
    +            AnyDatabase,
                 self,
    -            del_script_pubkey_from_path,
    -            keychain,
    -            child
    +            del_script_pubkey_from_path,
    +            keychain,
    +            child
             )
         }
    -    fn del_path_from_script_pubkey(
    -        &mut self,
    -        script: &Script,
    -    ) -> Result<Option<(KeychainKind, u32)>, Error> {
    -        impl_inner_method!(AnyDatabase, self, del_path_from_script_pubkey, script)
    +    fn del_path_from_script_pubkey(
    +        &mut self,
    +        script: &Script,
    +    ) -> Result<Option<(KeychainKind, u32)>, Error> {
    +        impl_inner_method!(AnyDatabase, self, del_path_from_script_pubkey, script)
         }
    -    fn del_utxo(&mut self, outpoint: &OutPoint) -> Result<Option<LocalUtxo>, Error> {
    -        impl_inner_method!(AnyDatabase, self, del_utxo, outpoint)
    +    fn del_utxo(&mut self, outpoint: &OutPoint) -> Result<Option<LocalUtxo>, Error> {
    +        impl_inner_method!(AnyDatabase, self, del_utxo, outpoint)
         }
    -    fn del_raw_tx(&mut self, txid: &Txid) -> Result<Option<Transaction>, Error> {
    -        impl_inner_method!(AnyDatabase, self, del_raw_tx, txid)
    +    fn del_raw_tx(&mut self, txid: &Txid) -> Result<Option<Transaction>, Error> {
    +        impl_inner_method!(AnyDatabase, self, del_raw_tx, txid)
         }
    -    fn del_tx(
    -        &mut self,
    -        txid: &Txid,
    -        include_raw: bool,
    -    ) -> Result<Option<TransactionDetails>, Error> {
    -        impl_inner_method!(AnyDatabase, self, del_tx, txid, include_raw)
    +    fn del_tx(
    +        &mut self,
    +        txid: &Txid,
    +        include_raw: bool,
    +    ) -> Result<Option<TransactionDetails>, Error> {
    +        impl_inner_method!(AnyDatabase, self, del_tx, txid, include_raw)
         }
    -    fn del_last_index(&mut self, keychain: KeychainKind) -> Result<Option<u32>, Error> {
    -        impl_inner_method!(AnyDatabase, self, del_last_index, keychain)
    +    fn del_last_index(&mut self, keychain: KeychainKind) -> Result<Option<u32>, Error> {
    +        impl_inner_method!(AnyDatabase, self, del_last_index, keychain)
         }
    -    fn del_sync_time(&mut self) -> Result<Option<SyncTime>, Error> {
    -        impl_inner_method!(AnyDatabase, self, del_sync_time)
    +    fn del_sync_time(&mut self) -> Result<Option<SyncTime>, Error> {
    +        impl_inner_method!(AnyDatabase, self, del_sync_time)
         }
     }
     
    -impl Database for AnyDatabase {
    -    fn check_descriptor_checksum<B: AsRef<[u8]>>(
    -        &mut self,
    -        keychain: KeychainKind,
    -        bytes: B,
    -    ) -> Result<(), Error> {
    +impl Database for AnyDatabase {
    +    fn check_descriptor_checksum<B: AsRef<[u8]>>(
    +        &mut self,
    +        keychain: KeychainKind,
    +        bytes: B,
    +    ) -> Result<(), Error> {
             impl_inner_method!(
    -            AnyDatabase,
    +            AnyDatabase,
                 self,
    -            check_descriptor_checksum,
    -            keychain,
    -            bytes
    +            check_descriptor_checksum,
    +            keychain,
    +            bytes
             )
         }
     
    -    fn iter_script_pubkeys(&self, keychain: Option<KeychainKind>) -> Result<Vec<Script>, Error> {
    -        impl_inner_method!(AnyDatabase, self, iter_script_pubkeys, keychain)
    +    fn iter_script_pubkeys(&self, keychain: Option<KeychainKind>) -> Result<Vec<Script>, Error> {
    +        impl_inner_method!(AnyDatabase, self, iter_script_pubkeys, keychain)
         }
    -    fn iter_utxos(&self) -> Result<Vec<LocalUtxo>, Error> {
    -        impl_inner_method!(AnyDatabase, self, iter_utxos)
    +    fn iter_utxos(&self) -> Result<Vec<LocalUtxo>, Error> {
    +        impl_inner_method!(AnyDatabase, self, iter_utxos)
         }
    -    fn iter_raw_txs(&self) -> Result<Vec<Transaction>, Error> {
    -        impl_inner_method!(AnyDatabase, self, iter_raw_txs)
    +    fn iter_raw_txs(&self) -> Result<Vec<Transaction>, Error> {
    +        impl_inner_method!(AnyDatabase, self, iter_raw_txs)
         }
    -    fn iter_txs(&self, include_raw: bool) -> Result<Vec<TransactionDetails>, Error> {
    -        impl_inner_method!(AnyDatabase, self, iter_txs, include_raw)
    +    fn iter_txs(&self, include_raw: bool) -> Result<Vec<TransactionDetails>, Error> {
    +        impl_inner_method!(AnyDatabase, self, iter_txs, include_raw)
         }
     
    -    fn get_script_pubkey_from_path(
    +    fn get_script_pubkey_from_path(
             &self,
    -        keychain: KeychainKind,
    -        child: u32,
    -    ) -> Result<Option<Script>, Error> {
    +        keychain: KeychainKind,
    +        child: u32,
    +    ) -> Result<Option<Script>, Error> {
             impl_inner_method!(
    -            AnyDatabase,
    +            AnyDatabase,
                 self,
    -            get_script_pubkey_from_path,
    -            keychain,
    -            child
    +            get_script_pubkey_from_path,
    +            keychain,
    +            child
             )
         }
    -    fn get_path_from_script_pubkey(
    +    fn get_path_from_script_pubkey(
             &self,
    -        script: &Script,
    -    ) -> Result<Option<(KeychainKind, u32)>, Error> {
    -        impl_inner_method!(AnyDatabase, self, get_path_from_script_pubkey, script)
    +        script: &Script,
    +    ) -> Result<Option<(KeychainKind, u32)>, Error> {
    +        impl_inner_method!(AnyDatabase, self, get_path_from_script_pubkey, script)
         }
    -    fn get_utxo(&self, outpoint: &OutPoint) -> Result<Option<LocalUtxo>, Error> {
    -        impl_inner_method!(AnyDatabase, self, get_utxo, outpoint)
    +    fn get_utxo(&self, outpoint: &OutPoint) -> Result<Option<LocalUtxo>, Error> {
    +        impl_inner_method!(AnyDatabase, self, get_utxo, outpoint)
         }
    -    fn get_raw_tx(&self, txid: &Txid) -> Result<Option<Transaction>, Error> {
    -        impl_inner_method!(AnyDatabase, self, get_raw_tx, txid)
    +    fn get_raw_tx(&self, txid: &Txid) -> Result<Option<Transaction>, Error> {
    +        impl_inner_method!(AnyDatabase, self, get_raw_tx, txid)
         }
    -    fn get_tx(&self, txid: &Txid, include_raw: bool) -> Result<Option<TransactionDetails>, Error> {
    -        impl_inner_method!(AnyDatabase, self, get_tx, txid, include_raw)
    +    fn get_tx(&self, txid: &Txid, include_raw: bool) -> Result<Option<TransactionDetails>, Error> {
    +        impl_inner_method!(AnyDatabase, self, get_tx, txid, include_raw)
         }
    -    fn get_last_index(&self, keychain: KeychainKind) -> Result<Option<u32>, Error> {
    -        impl_inner_method!(AnyDatabase, self, get_last_index, keychain)
    +    fn get_last_index(&self, keychain: KeychainKind) -> Result<Option<u32>, Error> {
    +        impl_inner_method!(AnyDatabase, self, get_last_index, keychain)
         }
    -    fn get_sync_time(&self) -> Result<Option<SyncTime>, Error> {
    -        impl_inner_method!(AnyDatabase, self, get_sync_time)
    +    fn get_sync_time(&self) -> Result<Option<SyncTime>, Error> {
    +        impl_inner_method!(AnyDatabase, self, get_sync_time)
         }
     
    -    fn increment_last_index(&mut self, keychain: KeychainKind) -> Result<u32, Error> {
    -        impl_inner_method!(AnyDatabase, self, increment_last_index, keychain)
    +    fn increment_last_index(&mut self, keychain: KeychainKind) -> Result<u32, Error> {
    +        impl_inner_method!(AnyDatabase, self, increment_last_index, keychain)
         }
     }
     
    -impl BatchOperations for AnyBatch {
    -    fn set_script_pubkey(
    -        &mut self,
    -        script: &Script,
    -        keychain: KeychainKind,
    -        child: u32,
    -    ) -> Result<(), Error> {
    -        impl_inner_method!(AnyBatch, self, set_script_pubkey, script, keychain, child)
    +impl BatchOperations for AnyBatch {
    +    fn set_script_pubkey(
    +        &mut self,
    +        script: &Script,
    +        keychain: KeychainKind,
    +        child: u32,
    +    ) -> Result<(), Error> {
    +        impl_inner_method!(AnyBatch, self, set_script_pubkey, script, keychain, child)
         }
    -    fn set_utxo(&mut self, utxo: &LocalUtxo) -> Result<(), Error> {
    -        impl_inner_method!(AnyBatch, self, set_utxo, utxo)
    +    fn set_utxo(&mut self, utxo: &LocalUtxo) -> Result<(), Error> {
    +        impl_inner_method!(AnyBatch, self, set_utxo, utxo)
         }
    -    fn set_raw_tx(&mut self, transaction: &Transaction) -> Result<(), Error> {
    -        impl_inner_method!(AnyBatch, self, set_raw_tx, transaction)
    +    fn set_raw_tx(&mut self, transaction: &Transaction) -> Result<(), Error> {
    +        impl_inner_method!(AnyBatch, self, set_raw_tx, transaction)
         }
    -    fn set_tx(&mut self, transaction: &TransactionDetails) -> Result<(), Error> {
    -        impl_inner_method!(AnyBatch, self, set_tx, transaction)
    +    fn set_tx(&mut self, transaction: &TransactionDetails) -> Result<(), Error> {
    +        impl_inner_method!(AnyBatch, self, set_tx, transaction)
         }
    -    fn set_last_index(&mut self, keychain: KeychainKind, value: u32) -> Result<(), Error> {
    -        impl_inner_method!(AnyBatch, self, set_last_index, keychain, value)
    +    fn set_last_index(&mut self, keychain: KeychainKind, value: u32) -> Result<(), Error> {
    +        impl_inner_method!(AnyBatch, self, set_last_index, keychain, value)
         }
    -    fn set_sync_time(&mut self, sync_time: SyncTime) -> Result<(), Error> {
    -        impl_inner_method!(AnyBatch, self, set_sync_time, sync_time)
    +    fn set_sync_time(&mut self, sync_time: SyncTime) -> Result<(), Error> {
    +        impl_inner_method!(AnyBatch, self, set_sync_time, sync_time)
         }
     
    -    fn del_script_pubkey_from_path(
    -        &mut self,
    -        keychain: KeychainKind,
    -        child: u32,
    -    ) -> Result<Option<Script>, Error> {
    -        impl_inner_method!(AnyBatch, self, del_script_pubkey_from_path, keychain, child)
    -    }
    -    fn del_path_from_script_pubkey(
    -        &mut self,
    -        script: &Script,
    -    ) -> Result<Option<(KeychainKind, u32)>, Error> {
    -        impl_inner_method!(AnyBatch, self, del_path_from_script_pubkey, script)
    -    }
    -    fn del_utxo(&mut self, outpoint: &OutPoint) -> Result<Option<LocalUtxo>, Error> {
    -        impl_inner_method!(AnyBatch, self, del_utxo, outpoint)
    -    }
    -    fn del_raw_tx(&mut self, txid: &Txid) -> Result<Option<Transaction>, Error> {
    -        impl_inner_method!(AnyBatch, self, del_raw_tx, txid)
    -    }
    -    fn del_tx(
    -        &mut self,
    -        txid: &Txid,
    -        include_raw: bool,
    -    ) -> Result<Option<TransactionDetails>, Error> {
    -        impl_inner_method!(AnyBatch, self, del_tx, txid, include_raw)
    -    }
    -    fn del_last_index(&mut self, keychain: KeychainKind) -> Result<Option<u32>, Error> {
    -        impl_inner_method!(AnyBatch, self, del_last_index, keychain)
    -    }
    -    fn del_sync_time(&mut self) -> Result<Option<SyncTime>, Error> {
    -        impl_inner_method!(AnyBatch, self, del_sync_time)
    +    fn del_script_pubkey_from_path(
    +        &mut self,
    +        keychain: KeychainKind,
    +        child: u32,
    +    ) -> Result<Option<Script>, Error> {
    +        impl_inner_method!(AnyBatch, self, del_script_pubkey_from_path, keychain, child)
    +    }
    +    fn del_path_from_script_pubkey(
    +        &mut self,
    +        script: &Script,
    +    ) -> Result<Option<(KeychainKind, u32)>, Error> {
    +        impl_inner_method!(AnyBatch, self, del_path_from_script_pubkey, script)
    +    }
    +    fn del_utxo(&mut self, outpoint: &OutPoint) -> Result<Option<LocalUtxo>, Error> {
    +        impl_inner_method!(AnyBatch, self, del_utxo, outpoint)
    +    }
    +    fn del_raw_tx(&mut self, txid: &Txid) -> Result<Option<Transaction>, Error> {
    +        impl_inner_method!(AnyBatch, self, del_raw_tx, txid)
    +    }
    +    fn del_tx(
    +        &mut self,
    +        txid: &Txid,
    +        include_raw: bool,
    +    ) -> Result<Option<TransactionDetails>, Error> {
    +        impl_inner_method!(AnyBatch, self, del_tx, txid, include_raw)
    +    }
    +    fn del_last_index(&mut self, keychain: KeychainKind) -> Result<Option<u32>, Error> {
    +        impl_inner_method!(AnyBatch, self, del_last_index, keychain)
    +    }
    +    fn del_sync_time(&mut self) -> Result<Option<SyncTime>, Error> {
    +        impl_inner_method!(AnyBatch, self, del_sync_time)
         }
     }
     
    -impl BatchDatabase for AnyDatabase {
    -    type Batch = AnyBatch;
    +impl BatchDatabase for AnyDatabase {
    +    type Batch = AnyBatch;
     
    -    fn begin_batch(&self) -> Self::Batch {
    -        match self {
    -            AnyDatabase::Memory(inner) => inner.begin_batch().into(),
    -            #[cfg(feature = "key-value-db")]
    -            AnyDatabase::Sled(inner) => inner.begin_batch().into(),
    -            #[cfg(feature = "sqlite")]
    -            AnyDatabase::Sqlite(inner) => inner.begin_batch().into(),
    +    fn begin_batch(&self) -> Self::Batch {
    +        match self {
    +            AnyDatabase::Memory(inner) => inner.begin_batch().into(),
    +            #[cfg(feature = "key-value-db")]
    +            AnyDatabase::Sled(inner) => inner.begin_batch().into(),
    +            #[cfg(feature = "sqlite")]
    +            AnyDatabase::Sqlite(inner) => inner.begin_batch().into(),
             }
         }
    -    fn commit_batch(&mut self, batch: Self::Batch) -> Result<(), Error> {
    -        match self {
    -            AnyDatabase::Memory(db) => match batch {
    -                AnyBatch::Memory(batch) => db.commit_batch(batch),
    -                #[cfg(any(feature = "key-value-db", feature = "sqlite"))]
    -                _ => unimplemented!("Other batch shouldn't be used with Memory db."),
    +    fn commit_batch(&mut self, batch: Self::Batch) -> Result<(), Error> {
    +        match self {
    +            AnyDatabase::Memory(db) => match batch {
    +                AnyBatch::Memory(batch) => db.commit_batch(batch),
    +                #[cfg(any(feature = "key-value-db", feature = "sqlite"))]
    +                _ => unimplemented!("Other batch shouldn't be used with Memory db."),
                 },
    -            #[cfg(feature = "key-value-db")]
    -            AnyDatabase::Sled(db) => match batch {
    -                AnyBatch::Sled(batch) => db.commit_batch(batch),
    -                _ => unimplemented!("Other batch shouldn't be used with Sled db."),
    +            #[cfg(feature = "key-value-db")]
    +            AnyDatabase::Sled(db) => match batch {
    +                AnyBatch::Sled(batch) => db.commit_batch(batch),
    +                _ => unimplemented!("Other batch shouldn't be used with Sled db."),
                 },
    -            #[cfg(feature = "sqlite")]
    -            AnyDatabase::Sqlite(db) => match batch {
    -                AnyBatch::Sqlite(batch) => db.commit_batch(batch),
    -                _ => unimplemented!("Other batch shouldn't be used with Sqlite db."),
    +            #[cfg(feature = "sqlite")]
    +            AnyDatabase::Sqlite(db) => match batch {
    +                AnyBatch::Sqlite(batch) => db.commit_batch(batch),
    +                _ => unimplemented!("Other batch shouldn't be used with Sqlite db."),
                 },
             }
         }
     }
     
    -/// Configuration type for a [`sled::Tree`] database
    -#[cfg(feature = "key-value-db")]
    -#[derive(Debug, serde::Serialize, serde::Deserialize)]
    -pub struct SledDbConfiguration {
    -    /// Main directory of the db
    -    pub path: String,
    -    /// Name of the database tree, a separated namespace for the data
    -    pub tree_name: String,
    +/// Configuration type for a [`sled::Tree`] database
    +#[cfg(feature = "key-value-db")]
    +#[derive(Debug, serde::Serialize, serde::Deserialize)]
    +pub struct SledDbConfiguration {
    +    /// Main directory of the db
    +    pub path: String,
    +    /// Name of the database tree, a separated namespace for the data
    +    pub tree_name: String,
     }
     
    -#[cfg(feature = "key-value-db")]
    -impl ConfigurableDatabase for sled::Tree {
    -    type Config = SledDbConfiguration;
    +#[cfg(feature = "key-value-db")]
    +impl ConfigurableDatabase for sled::Tree {
    +    type Config = SledDbConfiguration;
     
    -    fn from_config(config: &Self::Config) -> Result<Self, Error> {
    -        Ok(sled::open(&config.path)?.open_tree(&config.tree_name)?)
    +    fn from_config(config: &Self::Config) -> Result<Self, Error> {
    +        Ok(sled::open(&config.path)?.open_tree(&config.tree_name)?)
         }
     }
     
    -/// Configuration type for a [`sqlite::SqliteDatabase`] database
    -#[cfg(feature = "sqlite")]
    -#[derive(Debug, serde::Serialize, serde::Deserialize)]
    -pub struct SqliteDbConfiguration {
    -    /// Main directory of the db
    -    pub path: String,
    +/// Configuration type for a [`sqlite::SqliteDatabase`] database
    +#[cfg(feature = "sqlite")]
    +#[derive(Debug, serde::Serialize, serde::Deserialize)]
    +pub struct SqliteDbConfiguration {
    +    /// Main directory of the db
    +    pub path: String,
     }
     
    -#[cfg(feature = "sqlite")]
    -impl ConfigurableDatabase for sqlite::SqliteDatabase {
    -    type Config = SqliteDbConfiguration;
    +#[cfg(feature = "sqlite")]
    +impl ConfigurableDatabase for sqlite::SqliteDatabase {
    +    type Config = SqliteDbConfiguration;
     
    -    fn from_config(config: &Self::Config) -> Result<Self, Error> {
    -        Ok(sqlite::SqliteDatabase::new(config.path.clone()))
    +    fn from_config(config: &Self::Config) -> Result<Self, Error> {
    +        Ok(sqlite::SqliteDatabase::new(config.path.clone()))
         }
     }
     
    -/// Type that can contain any of the database configurations defined by the library
    -///
    -/// This allows storing a single configuration that can be loaded into an [`AnyDatabase`]
    -/// instance. Wallets that plan to offer users the ability to switch blockchain backend at runtime
    -/// will find this particularly useful.
    -#[derive(Debug, serde::Serialize, serde::Deserialize)]
    -pub enum AnyDatabaseConfig {
    -    /// Memory database has no config
    -    Memory(()),
    -    #[cfg(feature = "key-value-db")]
    -    #[cfg_attr(docsrs, doc(cfg(feature = "key-value-db")))]
    -    /// Simple key-value embedded database based on [`sled`]
    -    Sled(SledDbConfiguration),
    -    #[cfg(feature = "sqlite")]
    -    #[cfg_attr(docsrs, doc(cfg(feature = "sqlite")))]
    -    /// Sqlite embedded database using [`rusqlite`]
    -    Sqlite(SqliteDbConfiguration),
    +/// Type that can contain any of the database configurations defined by the library
    +///
    +/// This allows storing a single configuration that can be loaded into an [`AnyDatabase`]
    +/// instance. Wallets that plan to offer users the ability to switch blockchain backend at runtime
    +/// will find this particularly useful.
    +#[derive(Debug, serde::Serialize, serde::Deserialize)]
    +pub enum AnyDatabaseConfig {
    +    /// Memory database has no config
    +    Memory(()),
    +    #[cfg(feature = "key-value-db")]
    +    #[cfg_attr(docsrs, doc(cfg(feature = "key-value-db")))]
    +    /// Simple key-value embedded database based on [`sled`]
    +    Sled(SledDbConfiguration),
    +    #[cfg(feature = "sqlite")]
    +    #[cfg_attr(docsrs, doc(cfg(feature = "sqlite")))]
    +    /// Sqlite embedded database using [`rusqlite`]
    +    Sqlite(SqliteDbConfiguration),
     }
     
    -impl ConfigurableDatabase for AnyDatabase {
    -    type Config = AnyDatabaseConfig;
    +impl ConfigurableDatabase for AnyDatabase {
    +    type Config = AnyDatabaseConfig;
     
    -    fn from_config(config: &Self::Config) -> Result<Self, Error> {
    -        Ok(match config {
    -            AnyDatabaseConfig::Memory(inner) => {
    -                AnyDatabase::Memory(memory::MemoryDatabase::from_config(inner)?)
    +    fn from_config(config: &Self::Config) -> Result<Self, Error> {
    +        Ok(match config {
    +            AnyDatabaseConfig::Memory(inner) => {
    +                AnyDatabase::Memory(memory::MemoryDatabase::from_config(inner)?)
                 }
    -            #[cfg(feature = "key-value-db")]
    -            AnyDatabaseConfig::Sled(inner) => AnyDatabase::Sled(sled::Tree::from_config(inner)?),
    -            #[cfg(feature = "sqlite")]
    -            AnyDatabaseConfig::Sqlite(inner) => {
    -                AnyDatabase::Sqlite(sqlite::SqliteDatabase::from_config(inner)?)
    +            #[cfg(feature = "key-value-db")]
    +            AnyDatabaseConfig::Sled(inner) => AnyDatabase::Sled(sled::Tree::from_config(inner)?),
    +            #[cfg(feature = "sqlite")]
    +            AnyDatabaseConfig::Sqlite(inner) => {
    +                AnyDatabase::Sqlite(sqlite::SqliteDatabase::from_config(inner)?)
                 }
             })
         }
     }
     
    -impl_from!((), AnyDatabaseConfig, Memory,);
    -impl_from!(SledDbConfiguration, AnyDatabaseConfig, Sled, #[cfg(feature = "key-value-db")]);
    -impl_from!(SqliteDbConfiguration, AnyDatabaseConfig, Sqlite, #[cfg(feature = "sqlite")]);
    +impl_from!((), AnyDatabaseConfig, Memory,);
    +impl_from!(SledDbConfiguration, AnyDatabaseConfig, Sled, #[cfg(feature = "key-value-db")]);
    +impl_from!(SqliteDbConfiguration, AnyDatabaseConfig, Sqlite, #[cfg(feature = "sqlite")]);
     
    -
    - \ No newline at end of file +
    \ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/src/bdk/database/keyvalue.rs.html b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/src/bdk/database/keyvalue.rs.html index 534e5b4a39..28ba9772bf 100644 --- a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/src/bdk/database/keyvalue.rs.html +++ b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/src/bdk/database/keyvalue.rs.html @@ -1,1080 +1,1073 @@ -keyvalue.rs - source - -
      1
    -  2
    -  3
    -  4
    -  5
    -  6
    -  7
    -  8
    -  9
    - 10
    - 11
    - 12
    - 13
    - 14
    - 15
    - 16
    - 17
    - 18
    - 19
    - 20
    - 21
    - 22
    - 23
    - 24
    - 25
    - 26
    - 27
    - 28
    - 29
    - 30
    - 31
    - 32
    - 33
    - 34
    - 35
    - 36
    - 37
    - 38
    - 39
    - 40
    - 41
    - 42
    - 43
    - 44
    - 45
    - 46
    - 47
    - 48
    - 49
    - 50
    - 51
    - 52
    - 53
    - 54
    - 55
    - 56
    - 57
    - 58
    - 59
    - 60
    - 61
    - 62
    - 63
    - 64
    - 65
    - 66
    - 67
    - 68
    - 69
    - 70
    - 71
    - 72
    - 73
    - 74
    - 75
    - 76
    - 77
    - 78
    - 79
    - 80
    - 81
    - 82
    - 83
    - 84
    - 85
    - 86
    - 87
    - 88
    - 89
    - 90
    - 91
    - 92
    - 93
    - 94
    - 95
    - 96
    - 97
    - 98
    - 99
    -100
    -101
    -102
    -103
    -104
    -105
    -106
    -107
    -108
    -109
    -110
    -111
    -112
    -113
    -114
    -115
    -116
    -117
    -118
    -119
    -120
    -121
    -122
    -123
    -124
    -125
    -126
    -127
    -128
    -129
    -130
    -131
    -132
    -133
    -134
    -135
    -136
    -137
    -138
    -139
    -140
    -141
    -142
    -143
    -144
    -145
    -146
    -147
    -148
    -149
    -150
    -151
    -152
    -153
    -154
    -155
    -156
    -157
    -158
    -159
    -160
    -161
    -162
    -163
    -164
    -165
    -166
    -167
    -168
    -169
    -170
    -171
    -172
    -173
    -174
    -175
    -176
    -177
    -178
    -179
    -180
    -181
    -182
    -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
    -245
    -246
    -247
    -248
    -249
    -250
    -251
    -252
    -253
    -254
    -255
    -256
    -257
    -258
    -259
    -260
    -261
    -262
    -263
    -264
    -265
    -266
    -267
    -268
    -269
    -270
    -271
    -272
    -273
    -274
    -275
    -276
    -277
    -278
    -279
    -280
    -281
    -282
    -283
    -284
    -285
    -286
    -287
    -288
    -289
    -290
    -291
    -292
    -293
    -294
    -295
    -296
    -297
    -298
    -299
    -300
    -301
    -302
    -303
    -304
    -305
    -306
    -307
    -308
    -309
    -310
    -311
    -312
    -313
    -314
    -315
    -316
    -317
    -318
    -319
    -320
    -321
    -322
    -323
    -324
    -325
    -326
    -327
    -328
    -329
    -330
    -331
    -332
    -333
    -334
    -335
    -336
    -337
    -338
    -339
    -340
    -341
    -342
    -343
    -344
    -345
    -346
    -347
    -348
    -349
    -350
    -351
    -352
    -353
    -354
    -355
    -356
    -357
    -358
    -359
    -360
    -361
    -362
    -363
    -364
    -365
    -366
    -367
    -368
    -369
    -370
    -371
    -372
    -373
    -374
    -375
    -376
    -377
    -378
    -379
    -380
    -381
    -382
    -383
    -384
    -385
    -386
    -387
    -388
    -389
    -390
    -391
    -392
    -393
    -394
    -395
    -396
    -397
    -398
    -399
    -400
    -401
    -402
    -403
    -404
    -405
    -406
    -407
    -408
    -409
    -410
    -411
    -412
    -413
    -414
    -415
    -416
    -417
    -418
    -419
    -420
    -421
    -422
    -423
    -424
    -425
    -426
    -427
    -428
    -429
    -430
    -431
    -432
    -433
    -434
    -435
    -436
    -437
    -438
    -439
    -440
    -441
    -442
    -443
    -444
    -445
    -446
    -447
    -448
    -449
    -450
    -451
    -452
    -453
    -454
    -455
    -456
    -457
    -458
    -459
    -460
    -461
    -462
    -463
    -464
    -465
    -466
    -467
    -468
    -469
    -470
    -471
    -472
    -473
    -474
    -475
    -476
    -477
    -478
    -479
    -480
    -481
    -482
    -483
    -484
    -485
    -486
    -487
    -488
    -489
    -490
    -491
    -492
    -493
    -494
    -495
    -496
    -497
    -498
    -499
    -500
    -501
    -502
    -503
    -504
    -505
    -506
    -507
    -508
    -509
    -510
    -511
    -512
    -513
    -514
    -515
    -516
    -517
    -518
    -519
    -520
    -521
    -522
    -523
    -524
    -525
    -526
    -527
    -528
    -529
    -530
    -531
    -532
    -533
    -534
    -535
    -
    // Bitcoin Dev Kit
    -// Written in 2020 by Alekos Filini <alekos.filini@gmail.com>
    -//
    -// Copyright (c) 2020-2021 Bitcoin Dev Kit Developers
    -//
    -// This file is licensed under the Apache License, Version 2.0 <LICENSE-APACHE
    -// or http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
    -// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your option.
    -// You may not use this file except in accordance with one or both of these
    -// licenses.
    -
    -use std::convert::TryInto;
    -
    -use sled::{Batch, Tree};
    -
    -use bitcoin::consensus::encode::{deserialize, serialize};
    -use bitcoin::hash_types::Txid;
    -use bitcoin::{OutPoint, Script, Transaction};
    -
    -use crate::database::memory::MapKey;
    -use crate::database::{BatchDatabase, BatchOperations, Database, SyncTime};
    -use crate::error::Error;
    -use crate::types::*;
    -
    -macro_rules! impl_batch_operations {
    -    ( { $($after_insert:tt)* }, $process_delete:ident ) => {
    -        fn set_script_pubkey(&mut self, script: &Script, keychain: KeychainKind, path: u32) -> Result<(), Error> {
    -            let key = MapKey::Path((Some(keychain), Some(path))).as_map_key();
    -            self.insert(key, serialize(script))$($after_insert)*;
    -
    -            let key = MapKey::Script(Some(script)).as_map_key();
    -            let value = json!({
    -                "t": keychain,
    -                "p": path,
    +keyvalue.rs - source
    1
    +2
    +3
    +4
    +5
    +6
    +7
    +8
    +9
    +10
    +11
    +12
    +13
    +14
    +15
    +16
    +17
    +18
    +19
    +20
    +21
    +22
    +23
    +24
    +25
    +26
    +27
    +28
    +29
    +30
    +31
    +32
    +33
    +34
    +35
    +36
    +37
    +38
    +39
    +40
    +41
    +42
    +43
    +44
    +45
    +46
    +47
    +48
    +49
    +50
    +51
    +52
    +53
    +54
    +55
    +56
    +57
    +58
    +59
    +60
    +61
    +62
    +63
    +64
    +65
    +66
    +67
    +68
    +69
    +70
    +71
    +72
    +73
    +74
    +75
    +76
    +77
    +78
    +79
    +80
    +81
    +82
    +83
    +84
    +85
    +86
    +87
    +88
    +89
    +90
    +91
    +92
    +93
    +94
    +95
    +96
    +97
    +98
    +99
    +100
    +101
    +102
    +103
    +104
    +105
    +106
    +107
    +108
    +109
    +110
    +111
    +112
    +113
    +114
    +115
    +116
    +117
    +118
    +119
    +120
    +121
    +122
    +123
    +124
    +125
    +126
    +127
    +128
    +129
    +130
    +131
    +132
    +133
    +134
    +135
    +136
    +137
    +138
    +139
    +140
    +141
    +142
    +143
    +144
    +145
    +146
    +147
    +148
    +149
    +150
    +151
    +152
    +153
    +154
    +155
    +156
    +157
    +158
    +159
    +160
    +161
    +162
    +163
    +164
    +165
    +166
    +167
    +168
    +169
    +170
    +171
    +172
    +173
    +174
    +175
    +176
    +177
    +178
    +179
    +180
    +181
    +182
    +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
    +245
    +246
    +247
    +248
    +249
    +250
    +251
    +252
    +253
    +254
    +255
    +256
    +257
    +258
    +259
    +260
    +261
    +262
    +263
    +264
    +265
    +266
    +267
    +268
    +269
    +270
    +271
    +272
    +273
    +274
    +275
    +276
    +277
    +278
    +279
    +280
    +281
    +282
    +283
    +284
    +285
    +286
    +287
    +288
    +289
    +290
    +291
    +292
    +293
    +294
    +295
    +296
    +297
    +298
    +299
    +300
    +301
    +302
    +303
    +304
    +305
    +306
    +307
    +308
    +309
    +310
    +311
    +312
    +313
    +314
    +315
    +316
    +317
    +318
    +319
    +320
    +321
    +322
    +323
    +324
    +325
    +326
    +327
    +328
    +329
    +330
    +331
    +332
    +333
    +334
    +335
    +336
    +337
    +338
    +339
    +340
    +341
    +342
    +343
    +344
    +345
    +346
    +347
    +348
    +349
    +350
    +351
    +352
    +353
    +354
    +355
    +356
    +357
    +358
    +359
    +360
    +361
    +362
    +363
    +364
    +365
    +366
    +367
    +368
    +369
    +370
    +371
    +372
    +373
    +374
    +375
    +376
    +377
    +378
    +379
    +380
    +381
    +382
    +383
    +384
    +385
    +386
    +387
    +388
    +389
    +390
    +391
    +392
    +393
    +394
    +395
    +396
    +397
    +398
    +399
    +400
    +401
    +402
    +403
    +404
    +405
    +406
    +407
    +408
    +409
    +410
    +411
    +412
    +413
    +414
    +415
    +416
    +417
    +418
    +419
    +420
    +421
    +422
    +423
    +424
    +425
    +426
    +427
    +428
    +429
    +430
    +431
    +432
    +433
    +434
    +435
    +436
    +437
    +438
    +439
    +440
    +441
    +442
    +443
    +444
    +445
    +446
    +447
    +448
    +449
    +450
    +451
    +452
    +453
    +454
    +455
    +456
    +457
    +458
    +459
    +460
    +461
    +462
    +463
    +464
    +465
    +466
    +467
    +468
    +469
    +470
    +471
    +472
    +473
    +474
    +475
    +476
    +477
    +478
    +479
    +480
    +481
    +482
    +483
    +484
    +485
    +486
    +487
    +488
    +489
    +490
    +491
    +492
    +493
    +494
    +495
    +496
    +497
    +498
    +499
    +500
    +501
    +502
    +503
    +504
    +505
    +506
    +507
    +508
    +509
    +510
    +511
    +512
    +513
    +514
    +515
    +516
    +517
    +518
    +519
    +520
    +521
    +522
    +523
    +524
    +525
    +526
    +527
    +528
    +529
    +530
    +531
    +532
    +533
    +534
    +535
    +
    // Bitcoin Dev Kit
    +// Written in 2020 by Alekos Filini <alekos.filini@gmail.com>
    +//
    +// Copyright (c) 2020-2021 Bitcoin Dev Kit Developers
    +//
    +// This file is licensed under the Apache License, Version 2.0 <LICENSE-APACHE
    +// or http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
    +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your option.
    +// You may not use this file except in accordance with one or both of these
    +// licenses.
    +
    +use std::convert::TryInto;
    +
    +use sled::{Batch, Tree};
    +
    +use bitcoin::consensus::encode::{deserialize, serialize};
    +use bitcoin::hash_types::Txid;
    +use bitcoin::{OutPoint, Script, Transaction};
    +
    +use crate::database::memory::MapKey;
    +use crate::database::{BatchDatabase, BatchOperations, Database, SyncTime};
    +use crate::error::Error;
    +use crate::types::*;
    +
    +macro_rules! impl_batch_operations {
    +    ( { $($after_insert:tt)* }, $process_delete:ident ) => {
    +        fn set_script_pubkey(&mut self, script: &Script, keychain: KeychainKind, path: u32) -> Result<(), Error> {
    +            let key = MapKey::Path((Some(keychain), Some(path))).as_map_key();
    +            self.insert(key, serialize(script))$($after_insert)*;
    +
    +            let key = MapKey::Script(Some(script)).as_map_key();
    +            let value = json!({
    +                "t": keychain,
    +                "p": path,
                 });
    -            self.insert(key, serde_json::to_vec(&value)?)$($after_insert)*;
    +            self.insert(key, serde_json::to_vec(&value)?)$($after_insert)*;
     
                 Ok(())
             }
     
    -        fn set_utxo(&mut self, utxo: &LocalUtxo) -> Result<(), Error> {
    -            let key = MapKey::Utxo(Some(&utxo.outpoint)).as_map_key();
    -            let value = json!({
    -                "t": utxo.txout,
    -                "i": utxo.keychain,
    -                "s": utxo.is_spent,
    +        fn set_utxo(&mut self, utxo: &LocalUtxo) -> Result<(), Error> {
    +            let key = MapKey::Utxo(Some(&utxo.outpoint)).as_map_key();
    +            let value = json!({
    +                "t": utxo.txout,
    +                "i": utxo.keychain,
    +                "s": utxo.is_spent,
                 });
    -            self.insert(key, serde_json::to_vec(&value)?)$($after_insert)*;
    +            self.insert(key, serde_json::to_vec(&value)?)$($after_insert)*;
     
                 Ok(())
             }
     
    -        fn set_raw_tx(&mut self, transaction: &Transaction) -> Result<(), Error> {
    -            let key = MapKey::RawTx(Some(&transaction.txid())).as_map_key();
    -            let value = serialize(transaction);
    -            self.insert(key, value)$($after_insert)*;
    +        fn set_raw_tx(&mut self, transaction: &Transaction) -> Result<(), Error> {
    +            let key = MapKey::RawTx(Some(&transaction.txid())).as_map_key();
    +            let value = serialize(transaction);
    +            self.insert(key, value)$($after_insert)*;
     
                 Ok(())
             }
     
    -        fn set_tx(&mut self, transaction: &TransactionDetails) -> Result<(), Error> {
    -            let key = MapKey::Transaction(Some(&transaction.txid)).as_map_key();
    +        fn set_tx(&mut self, transaction: &TransactionDetails) -> Result<(), Error> {
    +            let key = MapKey::Transaction(Some(&transaction.txid)).as_map_key();
     
    -            // remove the raw tx from the serialized version
    -            let mut value = serde_json::to_value(transaction)?;
    -            value["transaction"] = serde_json::Value::Null;
    -            let value = serde_json::to_vec(&value)?;
    +            // remove the raw tx from the serialized version
    +            let mut value = serde_json::to_value(transaction)?;
    +            value["transaction"] = serde_json::Value::Null;
    +            let value = serde_json::to_vec(&value)?;
     
    -            self.insert(key, value)$($after_insert)*;
    +            self.insert(key, value)$($after_insert)*;
     
    -            // insert the raw_tx if present
    -            if let Some(ref tx) = transaction.transaction {
    -                self.set_raw_tx(tx)?;
    +            // insert the raw_tx if present
    +            if let Some(ref tx) = transaction.transaction {
    +                self.set_raw_tx(tx)?;
                 }
     
                 Ok(())
             }
     
    -        fn set_last_index(&mut self, keychain: KeychainKind, value: u32) -> Result<(), Error> {
    -            let key = MapKey::LastIndex(keychain).as_map_key();
    -            self.insert(key, &value.to_be_bytes())$($after_insert)*;
    +        fn set_last_index(&mut self, keychain: KeychainKind, value: u32) -> Result<(), Error> {
    +            let key = MapKey::LastIndex(keychain).as_map_key();
    +            self.insert(key, &value.to_be_bytes())$($after_insert)*;
     
                 Ok(())
             }
     
    -        fn set_sync_time(&mut self, data: SyncTime) -> Result<(), Error> {
    -            let key = MapKey::SyncTime.as_map_key();
    -            self.insert(key, serde_json::to_vec(&data)?)$($after_insert)*;
    +        fn set_sync_time(&mut self, data: SyncTime) -> Result<(), Error> {
    +            let key = MapKey::SyncTime.as_map_key();
    +            self.insert(key, serde_json::to_vec(&data)?)$($after_insert)*;
     
                 Ok(())
             }
     
    -        fn del_script_pubkey_from_path(&mut self, keychain: KeychainKind, path: u32) -> Result<Option<Script>, Error> {
    -            let key = MapKey::Path((Some(keychain), Some(path))).as_map_key();
    -            let res = self.remove(key);
    -            let res = $process_delete!(res);
    +        fn del_script_pubkey_from_path(&mut self, keychain: KeychainKind, path: u32) -> Result<Option<Script>, Error> {
    +            let key = MapKey::Path((Some(keychain), Some(path))).as_map_key();
    +            let res = self.remove(key);
    +            let res = $process_delete!(res);
     
    -            Ok(res.map_or(Ok(None), |x| Some(deserialize(&x)).transpose())?)
    +            Ok(res.map_or(Ok(None), |x| Some(deserialize(&x)).transpose())?)
             }
     
    -        fn del_path_from_script_pubkey(&mut self, script: &Script) -> Result<Option<(KeychainKind, u32)>, Error> {
    -            let key = MapKey::Script(Some(script)).as_map_key();
    -            let res = self.remove(key);
    -            let res = $process_delete!(res);
    +        fn del_path_from_script_pubkey(&mut self, script: &Script) -> Result<Option<(KeychainKind, u32)>, Error> {
    +            let key = MapKey::Script(Some(script)).as_map_key();
    +            let res = self.remove(key);
    +            let res = $process_delete!(res);
     
    -            match res {
    -                None => Ok(None),
    -                Some(b) => {
    -                    let mut val: serde_json::Value = serde_json::from_slice(&b)?;
    -                    let st = serde_json::from_value(val["t"].take())?;
    -                    let path = serde_json::from_value(val["p"].take())?;
    +            match res {
    +                None => Ok(None),
    +                Some(b) => {
    +                    let mut val: serde_json::Value = serde_json::from_slice(&b)?;
    +                    let st = serde_json::from_value(val["t"].take())?;
    +                    let path = serde_json::from_value(val["p"].take())?;
     
    -                    Ok(Some((st, path)))
    +                    Ok(Some((st, path)))
                     }
                 }
             }
     
    -        fn del_utxo(&mut self, outpoint: &OutPoint) -> Result<Option<LocalUtxo>, Error> {
    -            let key = MapKey::Utxo(Some(outpoint)).as_map_key();
    -            let res = self.remove(key);
    -            let res = $process_delete!(res);
    +        fn del_utxo(&mut self, outpoint: &OutPoint) -> Result<Option<LocalUtxo>, Error> {
    +            let key = MapKey::Utxo(Some(outpoint)).as_map_key();
    +            let res = self.remove(key);
    +            let res = $process_delete!(res);
     
    -            match res {
    -                None => Ok(None),
    -                Some(b) => {
    -                    let mut val: serde_json::Value = serde_json::from_slice(&b)?;
    -                    let txout = serde_json::from_value(val["t"].take())?;
    -                    let keychain = serde_json::from_value(val["i"].take())?;
    -                    let is_spent = val.get_mut("s").and_then(|s| s.take().as_bool()).unwrap_or(false);
    +            match res {
    +                None => Ok(None),
    +                Some(b) => {
    +                    let mut val: serde_json::Value = serde_json::from_slice(&b)?;
    +                    let txout = serde_json::from_value(val["t"].take())?;
    +                    let keychain = serde_json::from_value(val["i"].take())?;
    +                    let is_spent = val.get_mut("s").and_then(|s| s.take().as_bool()).unwrap_or(false);
     
    -                    Ok(Some(LocalUtxo { outpoint: outpoint.clone(), txout, keychain, is_spent, }))
    +                    Ok(Some(LocalUtxo { outpoint: outpoint.clone(), txout, keychain, is_spent, }))
                     }
                 }
             }
     
    -        fn del_raw_tx(&mut self, txid: &Txid) -> Result<Option<Transaction>, Error> {
    -            let key = MapKey::RawTx(Some(txid)).as_map_key();
    -            let res = self.remove(key);
    -            let res = $process_delete!(res);
    +        fn del_raw_tx(&mut self, txid: &Txid) -> Result<Option<Transaction>, Error> {
    +            let key = MapKey::RawTx(Some(txid)).as_map_key();
    +            let res = self.remove(key);
    +            let res = $process_delete!(res);
     
    -            Ok(res.map_or(Ok(None), |x| Some(deserialize(&x)).transpose())?)
    +            Ok(res.map_or(Ok(None), |x| Some(deserialize(&x)).transpose())?)
             }
     
    -        fn del_tx(&mut self, txid: &Txid, include_raw: bool) -> Result<Option<TransactionDetails>, Error> {
    -            let raw_tx = if include_raw {
    -                self.del_raw_tx(txid)?
    -            } else {
    -                None
    -            };
    +        fn del_tx(&mut self, txid: &Txid, include_raw: bool) -> Result<Option<TransactionDetails>, Error> {
    +            let raw_tx = if include_raw {
    +                self.del_raw_tx(txid)?
    +            } else {
    +                None
    +            };
     
    -            let key = MapKey::Transaction(Some(txid)).as_map_key();
    -            let res = self.remove(key);
    -            let res = $process_delete!(res);
    +            let key = MapKey::Transaction(Some(txid)).as_map_key();
    +            let res = self.remove(key);
    +            let res = $process_delete!(res);
     
    -            match res {
    -                None => Ok(None),
    -                Some(b) => {
    -                    let mut val: TransactionDetails = serde_json::from_slice(&b)?;
    -                    val.transaction = raw_tx;
    +            match res {
    +                None => Ok(None),
    +                Some(b) => {
    +                    let mut val: TransactionDetails = serde_json::from_slice(&b)?;
    +                    val.transaction = raw_tx;
     
    -                    Ok(Some(val))
    +                    Ok(Some(val))
                     }
                 }
             }
     
    -        fn del_last_index(&mut self, keychain: KeychainKind) -> Result<Option<u32>, Error> {
    -            let key = MapKey::LastIndex(keychain).as_map_key();
    -            let res = self.remove(key);
    +        fn del_last_index(&mut self, keychain: KeychainKind) -> Result<Option<u32>, Error> {
    +            let key = MapKey::LastIndex(keychain).as_map_key();
    +            let res = self.remove(key);
                 $process_delete!(res)
    -            .map(ivec_to_u32)
    -            .transpose()
    +            .map(ivec_to_u32)
    +            .transpose()
             }
     
    -        fn del_sync_time(&mut self) -> Result<Option<SyncTime>, Error> {
    -            let key = MapKey::SyncTime.as_map_key();
    -            let res = self.remove(key);
    -            let res = $process_delete!(res);
    +        fn del_sync_time(&mut self) -> Result<Option<SyncTime>, Error> {
    +            let key = MapKey::SyncTime.as_map_key();
    +            let res = self.remove(key);
    +            let res = $process_delete!(res);
     
    -            Ok(res.map(|b| serde_json::from_slice(&b)).transpose()?)
    +            Ok(res.map(|b| serde_json::from_slice(&b)).transpose()?)
             }
         }
     }
     
    -macro_rules! process_delete_tree {
    -    ($res:expr) => {
    -        $res?
    -    };
    +macro_rules! process_delete_tree {
    +    ($res:expr) => {
    +        $res?
    +    };
     }
    -impl BatchOperations for Tree {
    -    impl_batch_operations!({?}, process_delete_tree);
    +impl BatchOperations for Tree {
    +    impl_batch_operations!({?}, process_delete_tree);
     }
     
    -macro_rules! process_delete_batch {
    -    ($res:expr) => {
    -        None as Option<sled::IVec>
    +macro_rules! process_delete_batch {
    +    ($res:expr) => {
    +        None as Option<sled::IVec>
         };
     }
    -#[allow(unused_variables)]
    -impl BatchOperations for Batch {
    -    impl_batch_operations!({}, process_delete_batch);
    +#[allow(unused_variables)]
    +impl BatchOperations for Batch {
    +    impl_batch_operations!({}, process_delete_batch);
     }
     
    -impl Database for Tree {
    -    fn check_descriptor_checksum<B: AsRef<[u8]>>(
    -        &mut self,
    -        keychain: KeychainKind,
    -        bytes: B,
    -    ) -> Result<(), Error> {
    -        let key = MapKey::DescriptorChecksum(keychain).as_map_key();
    -
    -        let prev = self.get(&key)?.map(|x| x.to_vec());
    -        if let Some(val) = prev {
    -            if val == bytes.as_ref() {
    +impl Database for Tree {
    +    fn check_descriptor_checksum<B: AsRef<[u8]>>(
    +        &mut self,
    +        keychain: KeychainKind,
    +        bytes: B,
    +    ) -> Result<(), Error> {
    +        let key = MapKey::DescriptorChecksum(keychain).as_map_key();
    +
    +        let prev = self.get(&key)?.map(|x| x.to_vec());
    +        if let Some(val) = prev {
    +            if val == bytes.as_ref() {
                     Ok(())
    -            } else {
    -                Err(Error::ChecksumMismatch)
    +            } else {
    +                Err(Error::ChecksumMismatch)
                 }
    -        } else {
    -            self.insert(&key, bytes.as_ref())?;
    +        } else {
    +            self.insert(&key, bytes.as_ref())?;
                 Ok(())
             }
         }
     
    -    fn iter_script_pubkeys(&self, keychain: Option<KeychainKind>) -> Result<Vec<Script>, Error> {
    -        let key = MapKey::Path((keychain, None)).as_map_key();
    -        self.scan_prefix(key)
    -            .map(|x| -> Result<_, Error> {
    -                let (_, v) = x?;
    -                Ok(deserialize(&v)?)
    +    fn iter_script_pubkeys(&self, keychain: Option<KeychainKind>) -> Result<Vec<Script>, Error> {
    +        let key = MapKey::Path((keychain, None)).as_map_key();
    +        self.scan_prefix(key)
    +            .map(|x| -> Result<_, Error> {
    +                let (_, v) = x?;
    +                Ok(deserialize(&v)?)
                 })
    -            .collect()
    +            .collect()
         }
     
    -    fn iter_utxos(&self) -> Result<Vec<LocalUtxo>, Error> {
    -        let key = MapKey::Utxo(None).as_map_key();
    -        self.scan_prefix(key)
    -            .map(|x| -> Result<_, Error> {
    -                let (k, v) = x?;
    -                let outpoint = deserialize(&k[1..])?;
    -
    -                let mut val: serde_json::Value = serde_json::from_slice(&v)?;
    -                let txout = serde_json::from_value(val["t"].take())?;
    -                let keychain = serde_json::from_value(val["i"].take())?;
    -                let is_spent = val
    -                    .get_mut("s")
    -                    .and_then(|s| s.take().as_bool())
    -                    .unwrap_or(false);
    -
    -                Ok(LocalUtxo {
    -                    outpoint,
    -                    txout,
    -                    keychain,
    -                    is_spent,
    +    fn iter_utxos(&self) -> Result<Vec<LocalUtxo>, Error> {
    +        let key = MapKey::Utxo(None).as_map_key();
    +        self.scan_prefix(key)
    +            .map(|x| -> Result<_, Error> {
    +                let (k, v) = x?;
    +                let outpoint = deserialize(&k[1..])?;
    +
    +                let mut val: serde_json::Value = serde_json::from_slice(&v)?;
    +                let txout = serde_json::from_value(val["t"].take())?;
    +                let keychain = serde_json::from_value(val["i"].take())?;
    +                let is_spent = val
    +                    .get_mut("s")
    +                    .and_then(|s| s.take().as_bool())
    +                    .unwrap_or(false);
    +
    +                Ok(LocalUtxo {
    +                    outpoint,
    +                    txout,
    +                    keychain,
    +                    is_spent,
                     })
                 })
    -            .collect()
    +            .collect()
         }
     
    -    fn iter_raw_txs(&self) -> Result<Vec<Transaction>, Error> {
    -        let key = MapKey::RawTx(None).as_map_key();
    -        self.scan_prefix(key)
    -            .map(|x| -> Result<_, Error> {
    -                let (_, v) = x?;
    -                Ok(deserialize(&v)?)
    +    fn iter_raw_txs(&self) -> Result<Vec<Transaction>, Error> {
    +        let key = MapKey::RawTx(None).as_map_key();
    +        self.scan_prefix(key)
    +            .map(|x| -> Result<_, Error> {
    +                let (_, v) = x?;
    +                Ok(deserialize(&v)?)
                 })
    -            .collect()
    +            .collect()
         }
     
    -    fn iter_txs(&self, include_raw: bool) -> Result<Vec<TransactionDetails>, Error> {
    -        let key = MapKey::Transaction(None).as_map_key();
    -        self.scan_prefix(key)
    -            .map(|x| -> Result<_, Error> {
    -                let (k, v) = x?;
    -                let mut txdetails: TransactionDetails = serde_json::from_slice(&v)?;
    -                if include_raw {
    -                    let txid = deserialize(&k[1..])?;
    -                    txdetails.transaction = self.get_raw_tx(&txid)?;
    +    fn iter_txs(&self, include_raw: bool) -> Result<Vec<TransactionDetails>, Error> {
    +        let key = MapKey::Transaction(None).as_map_key();
    +        self.scan_prefix(key)
    +            .map(|x| -> Result<_, Error> {
    +                let (k, v) = x?;
    +                let mut txdetails: TransactionDetails = serde_json::from_slice(&v)?;
    +                if include_raw {
    +                    let txid = deserialize(&k[1..])?;
    +                    txdetails.transaction = self.get_raw_tx(&txid)?;
                     }
     
    -                Ok(txdetails)
    +                Ok(txdetails)
                 })
    -            .collect()
    +            .collect()
         }
     
    -    fn get_script_pubkey_from_path(
    +    fn get_script_pubkey_from_path(
             &self,
    -        keychain: KeychainKind,
    -        path: u32,
    -    ) -> Result<Option<Script>, Error> {
    -        let key = MapKey::Path((Some(keychain), Some(path))).as_map_key();
    -        Ok(self.get(key)?.map(|b| deserialize(&b)).transpose()?)
    +        keychain: KeychainKind,
    +        path: u32,
    +    ) -> Result<Option<Script>, Error> {
    +        let key = MapKey::Path((Some(keychain), Some(path))).as_map_key();
    +        Ok(self.get(key)?.map(|b| deserialize(&b)).transpose()?)
         }
     
    -    fn get_path_from_script_pubkey(
    +    fn get_path_from_script_pubkey(
             &self,
    -        script: &Script,
    -    ) -> Result<Option<(KeychainKind, u32)>, Error> {
    -        let key = MapKey::Script(Some(script)).as_map_key();
    -        self.get(key)?
    -            .map(|b| -> Result<_, Error> {
    -                let mut val: serde_json::Value = serde_json::from_slice(&b)?;
    -                let st = serde_json::from_value(val["t"].take())?;
    -                let path = serde_json::from_value(val["p"].take())?;
    -
    -                Ok((st, path))
    +        script: &Script,
    +    ) -> Result<Option<(KeychainKind, u32)>, Error> {
    +        let key = MapKey::Script(Some(script)).as_map_key();
    +        self.get(key)?
    +            .map(|b| -> Result<_, Error> {
    +                let mut val: serde_json::Value = serde_json::from_slice(&b)?;
    +                let st = serde_json::from_value(val["t"].take())?;
    +                let path = serde_json::from_value(val["p"].take())?;
    +
    +                Ok((st, path))
                 })
    -            .transpose()
    +            .transpose()
         }
     
    -    fn get_utxo(&self, outpoint: &OutPoint) -> Result<Option<LocalUtxo>, Error> {
    -        let key = MapKey::Utxo(Some(outpoint)).as_map_key();
    -        self.get(key)?
    -            .map(|b| -> Result<_, Error> {
    -                let mut val: serde_json::Value = serde_json::from_slice(&b)?;
    -                let txout = serde_json::from_value(val["t"].take())?;
    -                let keychain = serde_json::from_value(val["i"].take())?;
    -                let is_spent = val
    -                    .get_mut("s")
    -                    .and_then(|s| s.take().as_bool())
    -                    .unwrap_or(false);
    -
    -                Ok(LocalUtxo {
    -                    outpoint: *outpoint,
    -                    txout,
    -                    keychain,
    -                    is_spent,
    +    fn get_utxo(&self, outpoint: &OutPoint) -> Result<Option<LocalUtxo>, Error> {
    +        let key = MapKey::Utxo(Some(outpoint)).as_map_key();
    +        self.get(key)?
    +            .map(|b| -> Result<_, Error> {
    +                let mut val: serde_json::Value = serde_json::from_slice(&b)?;
    +                let txout = serde_json::from_value(val["t"].take())?;
    +                let keychain = serde_json::from_value(val["i"].take())?;
    +                let is_spent = val
    +                    .get_mut("s")
    +                    .and_then(|s| s.take().as_bool())
    +                    .unwrap_or(false);
    +
    +                Ok(LocalUtxo {
    +                    outpoint: *outpoint,
    +                    txout,
    +                    keychain,
    +                    is_spent,
                     })
                 })
    -            .transpose()
    +            .transpose()
         }
     
    -    fn get_raw_tx(&self, txid: &Txid) -> Result<Option<Transaction>, Error> {
    -        let key = MapKey::RawTx(Some(txid)).as_map_key();
    -        Ok(self.get(key)?.map(|b| deserialize(&b)).transpose()?)
    +    fn get_raw_tx(&self, txid: &Txid) -> Result<Option<Transaction>, Error> {
    +        let key = MapKey::RawTx(Some(txid)).as_map_key();
    +        Ok(self.get(key)?.map(|b| deserialize(&b)).transpose()?)
         }
     
    -    fn get_tx(&self, txid: &Txid, include_raw: bool) -> Result<Option<TransactionDetails>, Error> {
    -        let key = MapKey::Transaction(Some(txid)).as_map_key();
    -        self.get(key)?
    -            .map(|b| -> Result<_, Error> {
    -                let mut txdetails: TransactionDetails = serde_json::from_slice(&b)?;
    -                if include_raw {
    -                    txdetails.transaction = self.get_raw_tx(txid)?;
    +    fn get_tx(&self, txid: &Txid, include_raw: bool) -> Result<Option<TransactionDetails>, Error> {
    +        let key = MapKey::Transaction(Some(txid)).as_map_key();
    +        self.get(key)?
    +            .map(|b| -> Result<_, Error> {
    +                let mut txdetails: TransactionDetails = serde_json::from_slice(&b)?;
    +                if include_raw {
    +                    txdetails.transaction = self.get_raw_tx(txid)?;
                     }
     
    -                Ok(txdetails)
    +                Ok(txdetails)
                 })
    -            .transpose()
    +            .transpose()
         }
     
    -    fn get_last_index(&self, keychain: KeychainKind) -> Result<Option<u32>, Error> {
    -        let key = MapKey::LastIndex(keychain).as_map_key();
    -        self.get(key)?.map(ivec_to_u32).transpose()
    +    fn get_last_index(&self, keychain: KeychainKind) -> Result<Option<u32>, Error> {
    +        let key = MapKey::LastIndex(keychain).as_map_key();
    +        self.get(key)?.map(ivec_to_u32).transpose()
         }
     
    -    fn get_sync_time(&self) -> Result<Option<SyncTime>, Error> {
    -        let key = MapKey::SyncTime.as_map_key();
    -        Ok(self
    -            .get(key)?
    -            .map(|b| serde_json::from_slice(&b))
    -            .transpose()?)
    +    fn get_sync_time(&self) -> Result<Option<SyncTime>, Error> {
    +        let key = MapKey::SyncTime.as_map_key();
    +        Ok(self
    +            .get(key)?
    +            .map(|b| serde_json::from_slice(&b))
    +            .transpose()?)
         }
     
    -    // inserts 0 if not present
    -    fn increment_last_index(&mut self, keychain: KeychainKind) -> Result<u32, Error> {
    -        let key = MapKey::LastIndex(keychain).as_map_key();
    -        self.update_and_fetch(key, |prev| {
    -            let new = match prev {
    -                Some(b) => {
    -                    let array: [u8; 4] = b.try_into().unwrap_or([0; 4]);
    -                    let val = u32::from_be_bytes(array);
    -
    -                    val + 1
    -                }
    -                None => 0,
    +    // inserts 0 if not present
    +    fn increment_last_index(&mut self, keychain: KeychainKind) -> Result<u32, Error> {
    +        let key = MapKey::LastIndex(keychain).as_map_key();
    +        self.update_and_fetch(key, |prev| {
    +            let new = match prev {
    +                Some(b) => {
    +                    let array: [u8; 4] = b.try_into().unwrap_or([0; 4]);
    +                    let val = u32::from_be_bytes(array);
    +
    +                    val + 1
    +                }
    +                None => 0,
                 };
     
    -            Some(new.to_be_bytes().to_vec())
    -        })?
    -        .map_or(Ok(0), ivec_to_u32)
    +            Some(new.to_be_bytes().to_vec())
    +        })?
    +        .map_or(Ok(0), ivec_to_u32)
         }
     }
     
    -fn ivec_to_u32(b: sled::IVec) -> Result<u32, Error> {
    -    let array: [u8; 4] = b
    -        .as_ref()
    -        .try_into()
    -        .map_err(|_| Error::InvalidU32Bytes(b.to_vec()))?;
    -    let val = u32::from_be_bytes(array);
    -    Ok(val)
    +fn ivec_to_u32(b: sled::IVec) -> Result<u32, Error> {
    +    let array: [u8; 4] = b
    +        .as_ref()
    +        .try_into()
    +        .map_err(|_| Error::InvalidU32Bytes(b.to_vec()))?;
    +    let val = u32::from_be_bytes(array);
    +    Ok(val)
     }
     
    -impl BatchDatabase for Tree {
    -    type Batch = sled::Batch;
    +impl BatchDatabase for Tree {
    +    type Batch = sled::Batch;
     
    -    fn begin_batch(&self) -> Self::Batch {
    -        sled::Batch::default()
    +    fn begin_batch(&self) -> Self::Batch {
    +        sled::Batch::default()
         }
     
    -    fn commit_batch(&mut self, batch: Self::Batch) -> Result<(), Error> {
    -        Ok(self.apply_batch(batch)?)
    +    fn commit_batch(&mut self, batch: Self::Batch) -> Result<(), Error> {
    +        Ok(self.apply_batch(batch)?)
         }
     }
     
    -#[cfg(test)]
    -mod test {
    -    use lazy_static::lazy_static;
    -    use std::sync::{Arc, Condvar, Mutex, Once};
    -    use std::time::{SystemTime, UNIX_EPOCH};
    +#[cfg(test)]
    +mod test {
    +    use lazy_static::lazy_static;
    +    use std::sync::{Arc, Condvar, Mutex, Once};
    +    use std::time::{SystemTime, UNIX_EPOCH};
     
    -    use sled::{Db, Tree};
    +    use sled::{Db, Tree};
     
    -    static mut COUNT: usize = 0;
    +    static mut COUNT: usize = 0;
     
    -    lazy_static! {
    -        static ref DB: Arc<(Mutex<Option<Db>>, Condvar)> =
    -            Arc::new((Mutex::new(None), Condvar::new()));
    -        static ref INIT: Once = Once::new();
    +    lazy_static! {
    +        static ref DB: Arc<(Mutex<Option<Db>>, Condvar)> =
    +            Arc::new((Mutex::new(None), Condvar::new()));
    +        static ref INIT: Once = Once::new();
         }
     
    -    fn get_tree() -> Tree {
    -        unsafe {
    -            let cloned = DB.clone();
    -            let (mutex, cvar) = &*cloned;
    +    fn get_tree() -> Tree {
    +        unsafe {
    +            let cloned = DB.clone();
    +            let (mutex, cvar) = &*cloned;
     
    -            INIT.call_once(|| {
    -                let mut db = mutex.lock().unwrap();
    +            INIT.call_once(|| {
    +                let mut db = mutex.lock().unwrap();
     
    -                let time = SystemTime::now().duration_since(UNIX_EPOCH).unwrap();
    -                let mut dir = std::env::temp_dir();
    -                dir.push(format!("mbw_{}", time.as_nanos()));
    +                let time = SystemTime::now().duration_since(UNIX_EPOCH).unwrap();
    +                let mut dir = std::env::temp_dir();
    +                dir.push(format!("mbw_{}", time.as_nanos()));
     
    -                *db = Some(sled::open(dir).unwrap());
    -                cvar.notify_all();
    +                *db = Some(sled::open(dir).unwrap());
    +                cvar.notify_all();
                 });
     
    -            let mut db = mutex.lock().unwrap();
    -            while !db.is_some() {
    -                db = cvar.wait(db).unwrap();
    +            let mut db = mutex.lock().unwrap();
    +            while !db.is_some() {
    +                db = cvar.wait(db).unwrap();
                 }
     
    -            COUNT += 1;
    +            COUNT += 1;
     
    -            db.as_ref()
    -                .unwrap()
    -                .open_tree(format!("tree_{}", COUNT))
    -                .unwrap()
    +            db.as_ref()
    +                .unwrap()
    +                .open_tree(format!("tree_{}", COUNT))
    +                .unwrap()
             }
         }
     
    -    #[test]
    -    fn test_script_pubkey() {
    -        crate::database::test::test_script_pubkey(get_tree());
    +    #[test]
    +    fn test_script_pubkey() {
    +        crate::database::test::test_script_pubkey(get_tree());
         }
     
    -    #[test]
    -    fn test_batch_script_pubkey() {
    -        crate::database::test::test_batch_script_pubkey(get_tree());
    +    #[test]
    +    fn test_batch_script_pubkey() {
    +        crate::database::test::test_batch_script_pubkey(get_tree());
         }
     
    -    #[test]
    -    fn test_iter_script_pubkey() {
    -        crate::database::test::test_iter_script_pubkey(get_tree());
    +    #[test]
    +    fn test_iter_script_pubkey() {
    +        crate::database::test::test_iter_script_pubkey(get_tree());
         }
     
    -    #[test]
    -    fn test_del_script_pubkey() {
    -        crate::database::test::test_del_script_pubkey(get_tree());
    +    #[test]
    +    fn test_del_script_pubkey() {
    +        crate::database::test::test_del_script_pubkey(get_tree());
         }
     
    -    #[test]
    -    fn test_utxo() {
    -        crate::database::test::test_utxo(get_tree());
    +    #[test]
    +    fn test_utxo() {
    +        crate::database::test::test_utxo(get_tree());
         }
     
    -    #[test]
    -    fn test_raw_tx() {
    -        crate::database::test::test_raw_tx(get_tree());
    +    #[test]
    +    fn test_raw_tx() {
    +        crate::database::test::test_raw_tx(get_tree());
         }
     
    -    #[test]
    -    fn test_tx() {
    -        crate::database::test::test_tx(get_tree());
    +    #[test]
    +    fn test_tx() {
    +        crate::database::test::test_tx(get_tree());
         }
     
    -    #[test]
    -    fn test_last_index() {
    -        crate::database::test::test_last_index(get_tree());
    +    #[test]
    +    fn test_last_index() {
    +        crate::database::test::test_last_index(get_tree());
         }
     
    -    #[test]
    -    fn test_sync_time() {
    -        crate::database::test::test_sync_time(get_tree());
    +    #[test]
    +    fn test_sync_time() {
    +        crate::database::test::test_sync_time(get_tree());
         }
     
    -    #[test]
    -    fn test_iter_raw_txs() {
    -        crate::database::test::test_iter_raw_txs(get_tree());
    +    #[test]
    +    fn test_iter_raw_txs() {
    +        crate::database::test::test_iter_raw_txs(get_tree());
         }
     
    -    #[test]
    -    fn test_del_path_from_script_pubkey() {
    -        crate::database::test::test_del_path_from_script_pubkey(get_tree());
    +    #[test]
    +    fn test_del_path_from_script_pubkey() {
    +        crate::database::test::test_del_path_from_script_pubkey(get_tree());
         }
     
    -    #[test]
    -    fn test_iter_script_pubkeys() {
    -        crate::database::test::test_iter_script_pubkeys(get_tree());
    +    #[test]
    +    fn test_iter_script_pubkeys() {
    +        crate::database::test::test_iter_script_pubkeys(get_tree());
         }
     
    -    #[test]
    -    fn test_del_utxo() {
    -        crate::database::test::test_del_utxo(get_tree());
    +    #[test]
    +    fn test_del_utxo() {
    +        crate::database::test::test_del_utxo(get_tree());
         }
     
    -    #[test]
    -    fn test_del_raw_tx() {
    -        crate::database::test::test_del_raw_tx(get_tree());
    +    #[test]
    +    fn test_del_raw_tx() {
    +        crate::database::test::test_del_raw_tx(get_tree());
         }
     
    -    #[test]
    -    fn test_del_tx() {
    -        crate::database::test::test_del_tx(get_tree());
    +    #[test]
    +    fn test_del_tx() {
    +        crate::database::test::test_del_tx(get_tree());
         }
     
    -    #[test]
    -    fn test_del_last_index() {
    -        crate::database::test::test_del_last_index(get_tree());
    +    #[test]
    +    fn test_del_last_index() {
    +        crate::database::test::test_del_last_index(get_tree());
         }
     
    -    #[test]
    -    fn test_check_descriptor_checksum() {
    -        crate::database::test::test_check_descriptor_checksum(get_tree());
    +    #[test]
    +    fn test_check_descriptor_checksum() {
    +        crate::database::test::test_check_descriptor_checksum(get_tree());
         }
     }
     
    -
    - \ No newline at end of file +
    \ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/src/bdk/database/memory.rs.html b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/src/bdk/database/memory.rs.html index d6b4fd8027..7ddcf45124 100644 --- a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/src/bdk/database/memory.rs.html +++ b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/src/bdk/database/memory.rs.html @@ -1,1390 +1,1383 @@ -memory.rs - source - -
      1
    -  2
    -  3
    -  4
    -  5
    -  6
    -  7
    -  8
    -  9
    - 10
    - 11
    - 12
    - 13
    - 14
    - 15
    - 16
    - 17
    - 18
    - 19
    - 20
    - 21
    - 22
    - 23
    - 24
    - 25
    - 26
    - 27
    - 28
    - 29
    - 30
    - 31
    - 32
    - 33
    - 34
    - 35
    - 36
    - 37
    - 38
    - 39
    - 40
    - 41
    - 42
    - 43
    - 44
    - 45
    - 46
    - 47
    - 48
    - 49
    - 50
    - 51
    - 52
    - 53
    - 54
    - 55
    - 56
    - 57
    - 58
    - 59
    - 60
    - 61
    - 62
    - 63
    - 64
    - 65
    - 66
    - 67
    - 68
    - 69
    - 70
    - 71
    - 72
    - 73
    - 74
    - 75
    - 76
    - 77
    - 78
    - 79
    - 80
    - 81
    - 82
    - 83
    - 84
    - 85
    - 86
    - 87
    - 88
    - 89
    - 90
    - 91
    - 92
    - 93
    - 94
    - 95
    - 96
    - 97
    - 98
    - 99
    -100
    -101
    -102
    -103
    -104
    -105
    -106
    -107
    -108
    -109
    -110
    -111
    -112
    -113
    -114
    -115
    -116
    -117
    -118
    -119
    -120
    -121
    -122
    -123
    -124
    -125
    -126
    -127
    -128
    -129
    -130
    -131
    -132
    -133
    -134
    -135
    -136
    -137
    -138
    -139
    -140
    -141
    -142
    -143
    -144
    -145
    -146
    -147
    -148
    -149
    -150
    -151
    -152
    -153
    -154
    -155
    -156
    -157
    -158
    -159
    -160
    -161
    -162
    -163
    -164
    -165
    -166
    -167
    -168
    -169
    -170
    -171
    -172
    -173
    -174
    -175
    -176
    -177
    -178
    -179
    -180
    -181
    -182
    -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
    -245
    -246
    -247
    -248
    -249
    -250
    -251
    -252
    -253
    -254
    -255
    -256
    -257
    -258
    -259
    -260
    -261
    -262
    -263
    -264
    -265
    -266
    -267
    -268
    -269
    -270
    -271
    -272
    -273
    -274
    -275
    -276
    -277
    -278
    -279
    -280
    -281
    -282
    -283
    -284
    -285
    -286
    -287
    -288
    -289
    -290
    -291
    -292
    -293
    -294
    -295
    -296
    -297
    -298
    -299
    -300
    -301
    -302
    -303
    -304
    -305
    -306
    -307
    -308
    -309
    -310
    -311
    -312
    -313
    -314
    -315
    -316
    -317
    -318
    -319
    -320
    -321
    -322
    -323
    -324
    -325
    -326
    -327
    -328
    -329
    -330
    -331
    -332
    -333
    -334
    -335
    -336
    -337
    -338
    -339
    -340
    -341
    -342
    -343
    -344
    -345
    -346
    -347
    -348
    -349
    -350
    -351
    -352
    -353
    -354
    -355
    -356
    -357
    -358
    -359
    -360
    -361
    -362
    -363
    -364
    -365
    -366
    -367
    -368
    -369
    -370
    -371
    -372
    -373
    -374
    -375
    -376
    -377
    -378
    -379
    -380
    -381
    -382
    -383
    -384
    -385
    -386
    -387
    -388
    -389
    -390
    -391
    -392
    -393
    -394
    -395
    -396
    -397
    -398
    -399
    -400
    -401
    -402
    -403
    -404
    -405
    -406
    -407
    -408
    -409
    -410
    -411
    -412
    -413
    -414
    -415
    -416
    -417
    -418
    -419
    -420
    -421
    -422
    -423
    -424
    -425
    -426
    -427
    -428
    -429
    -430
    -431
    -432
    -433
    -434
    -435
    -436
    -437
    -438
    -439
    -440
    -441
    -442
    -443
    -444
    -445
    -446
    -447
    -448
    -449
    -450
    -451
    -452
    -453
    -454
    -455
    -456
    -457
    -458
    -459
    -460
    -461
    -462
    -463
    -464
    -465
    -466
    -467
    -468
    -469
    -470
    -471
    -472
    -473
    -474
    -475
    -476
    -477
    -478
    -479
    -480
    -481
    -482
    -483
    -484
    -485
    -486
    -487
    -488
    -489
    -490
    -491
    -492
    -493
    -494
    -495
    -496
    -497
    -498
    -499
    -500
    -501
    -502
    -503
    -504
    -505
    -506
    -507
    -508
    -509
    -510
    -511
    -512
    -513
    -514
    -515
    -516
    -517
    -518
    -519
    -520
    -521
    -522
    -523
    -524
    -525
    -526
    -527
    -528
    -529
    -530
    -531
    -532
    -533
    -534
    -535
    -536
    -537
    -538
    -539
    -540
    -541
    -542
    -543
    -544
    -545
    -546
    -547
    -548
    -549
    -550
    -551
    -552
    -553
    -554
    -555
    -556
    -557
    -558
    -559
    -560
    -561
    -562
    -563
    -564
    -565
    -566
    -567
    -568
    -569
    -570
    -571
    -572
    -573
    -574
    -575
    -576
    -577
    -578
    -579
    -580
    -581
    -582
    -583
    -584
    -585
    -586
    -587
    -588
    -589
    -590
    -591
    -592
    -593
    -594
    -595
    -596
    -597
    -598
    -599
    -600
    -601
    -602
    -603
    -604
    -605
    -606
    -607
    -608
    -609
    -610
    -611
    -612
    -613
    -614
    -615
    -616
    -617
    -618
    -619
    -620
    -621
    -622
    -623
    -624
    -625
    -626
    -627
    -628
    -629
    -630
    -631
    -632
    -633
    -634
    -635
    -636
    -637
    -638
    -639
    -640
    -641
    -642
    -643
    -644
    -645
    -646
    -647
    -648
    -649
    -650
    -651
    -652
    -653
    -654
    -655
    -656
    -657
    -658
    -659
    -660
    -661
    -662
    -663
    -664
    -665
    -666
    -667
    -668
    -669
    -670
    -671
    -672
    -673
    -674
    -675
    -676
    -677
    -678
    -679
    -680
    -681
    -682
    -683
    -684
    -685
    -686
    -687
    -688
    -689
    -690
    -
    // Bitcoin Dev Kit
    -// Written in 2020 by Alekos Filini <alekos.filini@gmail.com>
    -//
    -// Copyright (c) 2020-2021 Bitcoin Dev Kit Developers
    -//
    -// This file is licensed under the Apache License, Version 2.0 <LICENSE-APACHE
    -// or http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
    -// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your option.
    -// You may not use this file except in accordance with one or both of these
    -// licenses.
    -
    -//! In-memory ephemeral database
    -//!
    -//! This module defines an in-memory database type called [`MemoryDatabase`] that is based on a
    -//! [`BTreeMap`].
    -
    -use std::any::Any;
    -use std::collections::BTreeMap;
    -use std::ops::Bound::{Excluded, Included};
    -
    -use bitcoin::consensus::encode::{deserialize, serialize};
    -use bitcoin::hash_types::Txid;
    -use bitcoin::{OutPoint, Script, Transaction};
    -
    -use crate::database::{BatchDatabase, BatchOperations, ConfigurableDatabase, Database, SyncTime};
    -use crate::error::Error;
    -use crate::types::*;
    -
    -// path -> script       p{i,e}<path> -> script
    -// script -> path       s<script> -> {i,e}<path>
    -// outpoint             u<outpoint> -> txout
    -// rawtx                r<txid> -> tx
    -// transactions         t<txid> -> tx details
    -// deriv indexes        c{i,e} -> u32
    -// descriptor checksum  d{i,e} -> vec<u8>
    -// last sync time       l -> { height, timestamp }
    -
    -pub(crate) enum MapKey<'a> {
    -    Path((Option<KeychainKind>, Option<u32>)),
    -    Script(Option<&'a Script>),
    -    Utxo(Option<&'a OutPoint>),
    -    RawTx(Option<&'a Txid>),
    -    Transaction(Option<&'a Txid>),
    -    LastIndex(KeychainKind),
    -    SyncTime,
    -    DescriptorChecksum(KeychainKind),
    +memory.rs - source
    1
    +2
    +3
    +4
    +5
    +6
    +7
    +8
    +9
    +10
    +11
    +12
    +13
    +14
    +15
    +16
    +17
    +18
    +19
    +20
    +21
    +22
    +23
    +24
    +25
    +26
    +27
    +28
    +29
    +30
    +31
    +32
    +33
    +34
    +35
    +36
    +37
    +38
    +39
    +40
    +41
    +42
    +43
    +44
    +45
    +46
    +47
    +48
    +49
    +50
    +51
    +52
    +53
    +54
    +55
    +56
    +57
    +58
    +59
    +60
    +61
    +62
    +63
    +64
    +65
    +66
    +67
    +68
    +69
    +70
    +71
    +72
    +73
    +74
    +75
    +76
    +77
    +78
    +79
    +80
    +81
    +82
    +83
    +84
    +85
    +86
    +87
    +88
    +89
    +90
    +91
    +92
    +93
    +94
    +95
    +96
    +97
    +98
    +99
    +100
    +101
    +102
    +103
    +104
    +105
    +106
    +107
    +108
    +109
    +110
    +111
    +112
    +113
    +114
    +115
    +116
    +117
    +118
    +119
    +120
    +121
    +122
    +123
    +124
    +125
    +126
    +127
    +128
    +129
    +130
    +131
    +132
    +133
    +134
    +135
    +136
    +137
    +138
    +139
    +140
    +141
    +142
    +143
    +144
    +145
    +146
    +147
    +148
    +149
    +150
    +151
    +152
    +153
    +154
    +155
    +156
    +157
    +158
    +159
    +160
    +161
    +162
    +163
    +164
    +165
    +166
    +167
    +168
    +169
    +170
    +171
    +172
    +173
    +174
    +175
    +176
    +177
    +178
    +179
    +180
    +181
    +182
    +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
    +245
    +246
    +247
    +248
    +249
    +250
    +251
    +252
    +253
    +254
    +255
    +256
    +257
    +258
    +259
    +260
    +261
    +262
    +263
    +264
    +265
    +266
    +267
    +268
    +269
    +270
    +271
    +272
    +273
    +274
    +275
    +276
    +277
    +278
    +279
    +280
    +281
    +282
    +283
    +284
    +285
    +286
    +287
    +288
    +289
    +290
    +291
    +292
    +293
    +294
    +295
    +296
    +297
    +298
    +299
    +300
    +301
    +302
    +303
    +304
    +305
    +306
    +307
    +308
    +309
    +310
    +311
    +312
    +313
    +314
    +315
    +316
    +317
    +318
    +319
    +320
    +321
    +322
    +323
    +324
    +325
    +326
    +327
    +328
    +329
    +330
    +331
    +332
    +333
    +334
    +335
    +336
    +337
    +338
    +339
    +340
    +341
    +342
    +343
    +344
    +345
    +346
    +347
    +348
    +349
    +350
    +351
    +352
    +353
    +354
    +355
    +356
    +357
    +358
    +359
    +360
    +361
    +362
    +363
    +364
    +365
    +366
    +367
    +368
    +369
    +370
    +371
    +372
    +373
    +374
    +375
    +376
    +377
    +378
    +379
    +380
    +381
    +382
    +383
    +384
    +385
    +386
    +387
    +388
    +389
    +390
    +391
    +392
    +393
    +394
    +395
    +396
    +397
    +398
    +399
    +400
    +401
    +402
    +403
    +404
    +405
    +406
    +407
    +408
    +409
    +410
    +411
    +412
    +413
    +414
    +415
    +416
    +417
    +418
    +419
    +420
    +421
    +422
    +423
    +424
    +425
    +426
    +427
    +428
    +429
    +430
    +431
    +432
    +433
    +434
    +435
    +436
    +437
    +438
    +439
    +440
    +441
    +442
    +443
    +444
    +445
    +446
    +447
    +448
    +449
    +450
    +451
    +452
    +453
    +454
    +455
    +456
    +457
    +458
    +459
    +460
    +461
    +462
    +463
    +464
    +465
    +466
    +467
    +468
    +469
    +470
    +471
    +472
    +473
    +474
    +475
    +476
    +477
    +478
    +479
    +480
    +481
    +482
    +483
    +484
    +485
    +486
    +487
    +488
    +489
    +490
    +491
    +492
    +493
    +494
    +495
    +496
    +497
    +498
    +499
    +500
    +501
    +502
    +503
    +504
    +505
    +506
    +507
    +508
    +509
    +510
    +511
    +512
    +513
    +514
    +515
    +516
    +517
    +518
    +519
    +520
    +521
    +522
    +523
    +524
    +525
    +526
    +527
    +528
    +529
    +530
    +531
    +532
    +533
    +534
    +535
    +536
    +537
    +538
    +539
    +540
    +541
    +542
    +543
    +544
    +545
    +546
    +547
    +548
    +549
    +550
    +551
    +552
    +553
    +554
    +555
    +556
    +557
    +558
    +559
    +560
    +561
    +562
    +563
    +564
    +565
    +566
    +567
    +568
    +569
    +570
    +571
    +572
    +573
    +574
    +575
    +576
    +577
    +578
    +579
    +580
    +581
    +582
    +583
    +584
    +585
    +586
    +587
    +588
    +589
    +590
    +591
    +592
    +593
    +594
    +595
    +596
    +597
    +598
    +599
    +600
    +601
    +602
    +603
    +604
    +605
    +606
    +607
    +608
    +609
    +610
    +611
    +612
    +613
    +614
    +615
    +616
    +617
    +618
    +619
    +620
    +621
    +622
    +623
    +624
    +625
    +626
    +627
    +628
    +629
    +630
    +631
    +632
    +633
    +634
    +635
    +636
    +637
    +638
    +639
    +640
    +641
    +642
    +643
    +644
    +645
    +646
    +647
    +648
    +649
    +650
    +651
    +652
    +653
    +654
    +655
    +656
    +657
    +658
    +659
    +660
    +661
    +662
    +663
    +664
    +665
    +666
    +667
    +668
    +669
    +670
    +671
    +672
    +673
    +674
    +675
    +676
    +677
    +678
    +679
    +680
    +681
    +682
    +683
    +684
    +685
    +686
    +687
    +688
    +689
    +690
    +
    // Bitcoin Dev Kit
    +// Written in 2020 by Alekos Filini <alekos.filini@gmail.com>
    +//
    +// Copyright (c) 2020-2021 Bitcoin Dev Kit Developers
    +//
    +// This file is licensed under the Apache License, Version 2.0 <LICENSE-APACHE
    +// or http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
    +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your option.
    +// You may not use this file except in accordance with one or both of these
    +// licenses.
    +
    +//! In-memory ephemeral database
    +//!
    +//! This module defines an in-memory database type called [`MemoryDatabase`] that is based on a
    +//! [`BTreeMap`].
    +
    +use std::any::Any;
    +use std::collections::BTreeMap;
    +use std::ops::Bound::{Excluded, Included};
    +
    +use bitcoin::consensus::encode::{deserialize, serialize};
    +use bitcoin::hash_types::Txid;
    +use bitcoin::{OutPoint, Script, Transaction};
    +
    +use crate::database::{BatchDatabase, BatchOperations, ConfigurableDatabase, Database, SyncTime};
    +use crate::error::Error;
    +use crate::types::*;
    +
    +// path -> script       p{i,e}<path> -> script
    +// script -> path       s<script> -> {i,e}<path>
    +// outpoint             u<outpoint> -> txout
    +// rawtx                r<txid> -> tx
    +// transactions         t<txid> -> tx details
    +// deriv indexes        c{i,e} -> u32
    +// descriptor checksum  d{i,e} -> vec<u8>
    +// last sync time       l -> { height, timestamp }
    +
    +pub(crate) enum MapKey<'a> {
    +    Path((Option<KeychainKind>, Option<u32>)),
    +    Script(Option<&'a Script>),
    +    Utxo(Option<&'a OutPoint>),
    +    RawTx(Option<&'a Txid>),
    +    Transaction(Option<&'a Txid>),
    +    LastIndex(KeychainKind),
    +    SyncTime,
    +    DescriptorChecksum(KeychainKind),
     }
     
    -impl MapKey<'_> {
    -    fn as_prefix(&self) -> Vec<u8> {
    -        match self {
    -            MapKey::Path((st, _)) => {
    -                let mut v = b"p".to_vec();
    -                if let Some(st) = st {
    -                    v.push(st.as_byte());
    +impl MapKey<'_> {
    +    fn as_prefix(&self) -> Vec<u8> {
    +        match self {
    +            MapKey::Path((st, _)) => {
    +                let mut v = b"p".to_vec();
    +                if let Some(st) = st {
    +                    v.push(st.as_byte());
                     }
    -                v
    +                v
                 }
    -            MapKey::Script(_) => b"s".to_vec(),
    -            MapKey::Utxo(_) => b"u".to_vec(),
    -            MapKey::RawTx(_) => b"r".to_vec(),
    -            MapKey::Transaction(_) => b"t".to_vec(),
    -            MapKey::LastIndex(st) => [b"c", st.as_ref()].concat(),
    -            MapKey::SyncTime => b"l".to_vec(),
    -            MapKey::DescriptorChecksum(st) => [b"d", st.as_ref()].concat(),
    +            MapKey::Script(_) => b"s".to_vec(),
    +            MapKey::Utxo(_) => b"u".to_vec(),
    +            MapKey::RawTx(_) => b"r".to_vec(),
    +            MapKey::Transaction(_) => b"t".to_vec(),
    +            MapKey::LastIndex(st) => [b"c", st.as_ref()].concat(),
    +            MapKey::SyncTime => b"l".to_vec(),
    +            MapKey::DescriptorChecksum(st) => [b"d", st.as_ref()].concat(),
             }
         }
     
    -    fn serialize_content(&self) -> Vec<u8> {
    -        match self {
    -            MapKey::Path((_, Some(child))) => child.to_be_bytes().to_vec(),
    -            MapKey::Script(Some(s)) => serialize(*s),
    -            MapKey::Utxo(Some(s)) => serialize(*s),
    -            MapKey::RawTx(Some(s)) => serialize(*s),
    -            MapKey::Transaction(Some(s)) => serialize(*s),
    -            _ => vec![],
    +    fn serialize_content(&self) -> Vec<u8> {
    +        match self {
    +            MapKey::Path((_, Some(child))) => child.to_be_bytes().to_vec(),
    +            MapKey::Script(Some(s)) => serialize(*s),
    +            MapKey::Utxo(Some(s)) => serialize(*s),
    +            MapKey::RawTx(Some(s)) => serialize(*s),
    +            MapKey::Transaction(Some(s)) => serialize(*s),
    +            _ => vec![],
             }
         }
     
    -    pub fn as_map_key(&self) -> Vec<u8> {
    -        let mut v = self.as_prefix();
    -        v.extend_from_slice(&self.serialize_content());
    +    pub fn as_map_key(&self) -> Vec<u8> {
    +        let mut v = self.as_prefix();
    +        v.extend_from_slice(&self.serialize_content());
     
    -        v
    +        v
         }
     }
     
    -fn after(key: &[u8]) -> Vec<u8> {
    -    let mut key = key.to_owned();
    -    let mut idx = key.len();
    -    while idx > 0 {
    -        if key[idx - 1] == 0xFF {
    -            idx -= 1;
    +fn after(key: &[u8]) -> Vec<u8> {
    +    let mut key = key.to_owned();
    +    let mut idx = key.len();
    +    while idx > 0 {
    +        if key[idx - 1] == 0xFF {
    +            idx -= 1;
                 continue;
    -        } else {
    -            key[idx - 1] += 1;
    +        } else {
    +            key[idx - 1] += 1;
                 break;
             }
         }
     
    -    key
    +    key
     }
     
    -/// In-memory ephemeral database
    -///
    -/// This database can be used as a temporary storage for wallets that are not kept permanently on
    -/// a device, or on platforms that don't provide a filesystem, like `wasm32`.
    -///
    -/// Once it's dropped its content will be lost.
    -///
    -/// If you are looking for a permanent storage solution, you can try with the default key-value
    -/// database called [`sled`]. See the [`database`] module documentation for more details.
    -///
    -/// [`database`]: crate::database
    -#[derive(Debug, Default)]
    -pub struct MemoryDatabase {
    -    map: BTreeMap<Vec<u8>, Box<dyn Any + Send + Sync>>,
    -    deleted_keys: Vec<Vec<u8>>,
    +/// In-memory ephemeral database
    +///
    +/// This database can be used as a temporary storage for wallets that are not kept permanently on
    +/// a device, or on platforms that don't provide a filesystem, like `wasm32`.
    +///
    +/// Once it's dropped its content will be lost.
    +///
    +/// If you are looking for a permanent storage solution, you can try with the default key-value
    +/// database called [`sled`]. See the [`database`] module documentation for more details.
    +///
    +/// [`database`]: crate::database
    +#[derive(Debug, Default)]
    +pub struct MemoryDatabase {
    +    map: BTreeMap<Vec<u8>, Box<dyn Any + Send + Sync>>,
    +    deleted_keys: Vec<Vec<u8>>,
     }
     
    -impl MemoryDatabase {
    -    /// Create a new empty database
    -    pub fn new() -> Self {
    -        MemoryDatabase {
    -            map: BTreeMap::new(),
    -            deleted_keys: Vec::new(),
    +impl MemoryDatabase {
    +    /// Create a new empty database
    +    pub fn new() -> Self {
    +        MemoryDatabase {
    +            map: BTreeMap::new(),
    +            deleted_keys: Vec::new(),
             }
         }
     }
     
    -impl BatchOperations for MemoryDatabase {
    -    fn set_script_pubkey(
    -        &mut self,
    -        script: &Script,
    -        keychain: KeychainKind,
    -        path: u32,
    -    ) -> Result<(), Error> {
    -        let key = MapKey::Path((Some(keychain), Some(path))).as_map_key();
    -        self.map.insert(key, Box::new(script.clone()));
    -
    -        let key = MapKey::Script(Some(script)).as_map_key();
    -        let value = json!({
    -            "t": keychain,
    -            "p": path,
    +impl BatchOperations for MemoryDatabase {
    +    fn set_script_pubkey(
    +        &mut self,
    +        script: &Script,
    +        keychain: KeychainKind,
    +        path: u32,
    +    ) -> Result<(), Error> {
    +        let key = MapKey::Path((Some(keychain), Some(path))).as_map_key();
    +        self.map.insert(key, Box::new(script.clone()));
    +
    +        let key = MapKey::Script(Some(script)).as_map_key();
    +        let value = json!({
    +            "t": keychain,
    +            "p": path,
             });
    -        self.map.insert(key, Box::new(value));
    +        self.map.insert(key, Box::new(value));
     
             Ok(())
         }
     
    -    fn set_utxo(&mut self, utxo: &LocalUtxo) -> Result<(), Error> {
    -        let key = MapKey::Utxo(Some(&utxo.outpoint)).as_map_key();
    -        self.map.insert(
    -            key,
    -            Box::new((utxo.txout.clone(), utxo.keychain, utxo.is_spent)),
    +    fn set_utxo(&mut self, utxo: &LocalUtxo) -> Result<(), Error> {
    +        let key = MapKey::Utxo(Some(&utxo.outpoint)).as_map_key();
    +        self.map.insert(
    +            key,
    +            Box::new((utxo.txout.clone(), utxo.keychain, utxo.is_spent)),
             );
     
             Ok(())
         }
    -    fn set_raw_tx(&mut self, transaction: &Transaction) -> Result<(), Error> {
    -        let key = MapKey::RawTx(Some(&transaction.txid())).as_map_key();
    -        self.map.insert(key, Box::new(transaction.clone()));
    +    fn set_raw_tx(&mut self, transaction: &Transaction) -> Result<(), Error> {
    +        let key = MapKey::RawTx(Some(&transaction.txid())).as_map_key();
    +        self.map.insert(key, Box::new(transaction.clone()));
     
             Ok(())
         }
    -    fn set_tx(&mut self, transaction: &TransactionDetails) -> Result<(), Error> {
    -        let key = MapKey::Transaction(Some(&transaction.txid)).as_map_key();
    +    fn set_tx(&mut self, transaction: &TransactionDetails) -> Result<(), Error> {
    +        let key = MapKey::Transaction(Some(&transaction.txid)).as_map_key();
     
    -        // insert the raw_tx if present
    -        if let Some(ref tx) = transaction.transaction {
    -            self.set_raw_tx(tx)?;
    +        // insert the raw_tx if present
    +        if let Some(ref tx) = transaction.transaction {
    +            self.set_raw_tx(tx)?;
             }
     
    -        // remove the raw tx from the serialized version
    -        let mut transaction = transaction.clone();
    -        transaction.transaction = None;
    +        // remove the raw tx from the serialized version
    +        let mut transaction = transaction.clone();
    +        transaction.transaction = None;
     
    -        self.map.insert(key, Box::new(transaction));
    +        self.map.insert(key, Box::new(transaction));
     
             Ok(())
         }
    -    fn set_last_index(&mut self, keychain: KeychainKind, value: u32) -> Result<(), Error> {
    -        let key = MapKey::LastIndex(keychain).as_map_key();
    -        self.map.insert(key, Box::new(value));
    +    fn set_last_index(&mut self, keychain: KeychainKind, value: u32) -> Result<(), Error> {
    +        let key = MapKey::LastIndex(keychain).as_map_key();
    +        self.map.insert(key, Box::new(value));
     
             Ok(())
         }
    -    fn set_sync_time(&mut self, data: SyncTime) -> Result<(), Error> {
    -        let key = MapKey::SyncTime.as_map_key();
    -        self.map.insert(key, Box::new(data));
    +    fn set_sync_time(&mut self, data: SyncTime) -> Result<(), Error> {
    +        let key = MapKey::SyncTime.as_map_key();
    +        self.map.insert(key, Box::new(data));
     
             Ok(())
         }
     
    -    fn del_script_pubkey_from_path(
    -        &mut self,
    -        keychain: KeychainKind,
    -        path: u32,
    -    ) -> Result<Option<Script>, Error> {
    -        let key = MapKey::Path((Some(keychain), Some(path))).as_map_key();
    -        let res = self.map.remove(&key);
    -        self.deleted_keys.push(key);
    +    fn del_script_pubkey_from_path(
    +        &mut self,
    +        keychain: KeychainKind,
    +        path: u32,
    +    ) -> Result<Option<Script>, Error> {
    +        let key = MapKey::Path((Some(keychain), Some(path))).as_map_key();
    +        let res = self.map.remove(&key);
    +        self.deleted_keys.push(key);
     
    -        Ok(res.map(|x| x.downcast_ref().cloned().unwrap()))
    +        Ok(res.map(|x| x.downcast_ref().cloned().unwrap()))
         }
    -    fn del_path_from_script_pubkey(
    -        &mut self,
    -        script: &Script,
    -    ) -> Result<Option<(KeychainKind, u32)>, Error> {
    -        let key = MapKey::Script(Some(script)).as_map_key();
    -        let res = self.map.remove(&key);
    -        self.deleted_keys.push(key);
    -
    -        match res {
    -            None => Ok(None),
    -            Some(b) => {
    -                let mut val: serde_json::Value = b.downcast_ref().cloned().unwrap();
    -                let st = serde_json::from_value(val["t"].take())?;
    -                let path = serde_json::from_value(val["p"].take())?;
    -
    -                Ok(Some((st, path)))
    +    fn del_path_from_script_pubkey(
    +        &mut self,
    +        script: &Script,
    +    ) -> Result<Option<(KeychainKind, u32)>, Error> {
    +        let key = MapKey::Script(Some(script)).as_map_key();
    +        let res = self.map.remove(&key);
    +        self.deleted_keys.push(key);
    +
    +        match res {
    +            None => Ok(None),
    +            Some(b) => {
    +                let mut val: serde_json::Value = b.downcast_ref().cloned().unwrap();
    +                let st = serde_json::from_value(val["t"].take())?;
    +                let path = serde_json::from_value(val["p"].take())?;
    +
    +                Ok(Some((st, path)))
                 }
             }
         }
    -    fn del_utxo(&mut self, outpoint: &OutPoint) -> Result<Option<LocalUtxo>, Error> {
    -        let key = MapKey::Utxo(Some(outpoint)).as_map_key();
    -        let res = self.map.remove(&key);
    -        self.deleted_keys.push(key);
    -
    -        match res {
    -            None => Ok(None),
    -            Some(b) => {
    -                let (txout, keychain, is_spent) = b.downcast_ref().cloned().unwrap();
    -                Ok(Some(LocalUtxo {
    -                    outpoint: *outpoint,
    -                    txout,
    -                    keychain,
    -                    is_spent,
    +    fn del_utxo(&mut self, outpoint: &OutPoint) -> Result<Option<LocalUtxo>, Error> {
    +        let key = MapKey::Utxo(Some(outpoint)).as_map_key();
    +        let res = self.map.remove(&key);
    +        self.deleted_keys.push(key);
    +
    +        match res {
    +            None => Ok(None),
    +            Some(b) => {
    +                let (txout, keychain, is_spent) = b.downcast_ref().cloned().unwrap();
    +                Ok(Some(LocalUtxo {
    +                    outpoint: *outpoint,
    +                    txout,
    +                    keychain,
    +                    is_spent,
                     }))
                 }
             }
         }
    -    fn del_raw_tx(&mut self, txid: &Txid) -> Result<Option<Transaction>, Error> {
    -        let key = MapKey::RawTx(Some(txid)).as_map_key();
    -        let res = self.map.remove(&key);
    -        self.deleted_keys.push(key);
    +    fn del_raw_tx(&mut self, txid: &Txid) -> Result<Option<Transaction>, Error> {
    +        let key = MapKey::RawTx(Some(txid)).as_map_key();
    +        let res = self.map.remove(&key);
    +        self.deleted_keys.push(key);
     
    -        Ok(res.map(|x| x.downcast_ref().cloned().unwrap()))
    +        Ok(res.map(|x| x.downcast_ref().cloned().unwrap()))
         }
    -    fn del_tx(
    -        &mut self,
    -        txid: &Txid,
    -        include_raw: bool,
    -    ) -> Result<Option<TransactionDetails>, Error> {
    -        let raw_tx = if include_raw {
    -            self.del_raw_tx(txid)?
    -        } else {
    -            None
    -        };
    -
    -        let key = MapKey::Transaction(Some(txid)).as_map_key();
    -        let res = self.map.remove(&key);
    -        self.deleted_keys.push(key);
    -
    -        match res {
    -            None => Ok(None),
    -            Some(b) => {
    -                let mut val: TransactionDetails = b.downcast_ref().cloned().unwrap();
    -                val.transaction = raw_tx;
    -
    -                Ok(Some(val))
    +    fn del_tx(
    +        &mut self,
    +        txid: &Txid,
    +        include_raw: bool,
    +    ) -> Result<Option<TransactionDetails>, Error> {
    +        let raw_tx = if include_raw {
    +            self.del_raw_tx(txid)?
    +        } else {
    +            None
    +        };
    +
    +        let key = MapKey::Transaction(Some(txid)).as_map_key();
    +        let res = self.map.remove(&key);
    +        self.deleted_keys.push(key);
    +
    +        match res {
    +            None => Ok(None),
    +            Some(b) => {
    +                let mut val: TransactionDetails = b.downcast_ref().cloned().unwrap();
    +                val.transaction = raw_tx;
    +
    +                Ok(Some(val))
                 }
             }
         }
    -    fn del_last_index(&mut self, keychain: KeychainKind) -> Result<Option<u32>, Error> {
    -        let key = MapKey::LastIndex(keychain).as_map_key();
    -        let res = self.map.remove(&key);
    -        self.deleted_keys.push(key);
    -
    -        match res {
    -            None => Ok(None),
    -            Some(b) => Ok(Some(*b.downcast_ref().unwrap())),
    +    fn del_last_index(&mut self, keychain: KeychainKind) -> Result<Option<u32>, Error> {
    +        let key = MapKey::LastIndex(keychain).as_map_key();
    +        let res = self.map.remove(&key);
    +        self.deleted_keys.push(key);
    +
    +        match res {
    +            None => Ok(None),
    +            Some(b) => Ok(Some(*b.downcast_ref().unwrap())),
             }
         }
    -    fn del_sync_time(&mut self) -> Result<Option<SyncTime>, Error> {
    -        let key = MapKey::SyncTime.as_map_key();
    -        let res = self.map.remove(&key);
    -        self.deleted_keys.push(key);
    +    fn del_sync_time(&mut self) -> Result<Option<SyncTime>, Error> {
    +        let key = MapKey::SyncTime.as_map_key();
    +        let res = self.map.remove(&key);
    +        self.deleted_keys.push(key);
     
    -        Ok(res.map(|b| b.downcast_ref().cloned().unwrap()))
    +        Ok(res.map(|b| b.downcast_ref().cloned().unwrap()))
         }
     }
     
    -impl Database for MemoryDatabase {
    -    fn check_descriptor_checksum<B: AsRef<[u8]>>(
    -        &mut self,
    -        keychain: KeychainKind,
    -        bytes: B,
    -    ) -> Result<(), Error> {
    -        let key = MapKey::DescriptorChecksum(keychain).as_map_key();
    -
    -        let prev = self
    -            .map
    -            .get(&key)
    -            .map(|x| x.downcast_ref::<Vec<u8>>().unwrap());
    -        if let Some(val) = prev {
    -            if val == &bytes.as_ref().to_vec() {
    +impl Database for MemoryDatabase {
    +    fn check_descriptor_checksum<B: AsRef<[u8]>>(
    +        &mut self,
    +        keychain: KeychainKind,
    +        bytes: B,
    +    ) -> Result<(), Error> {
    +        let key = MapKey::DescriptorChecksum(keychain).as_map_key();
    +
    +        let prev = self
    +            .map
    +            .get(&key)
    +            .map(|x| x.downcast_ref::<Vec<u8>>().unwrap());
    +        if let Some(val) = prev {
    +            if val == &bytes.as_ref().to_vec() {
                     Ok(())
    -            } else {
    -                Err(Error::ChecksumMismatch)
    +            } else {
    +                Err(Error::ChecksumMismatch)
                 }
    -        } else {
    -            self.map.insert(key, Box::new(bytes.as_ref().to_vec()));
    +        } else {
    +            self.map.insert(key, Box::new(bytes.as_ref().to_vec()));
                 Ok(())
             }
         }
     
    -    fn iter_script_pubkeys(&self, keychain: Option<KeychainKind>) -> Result<Vec<Script>, Error> {
    -        let key = MapKey::Path((keychain, None)).as_map_key();
    -        self.map
    -            .range::<Vec<u8>, _>((Included(&key), Excluded(&after(&key))))
    -            .map(|(_, v)| Ok(v.downcast_ref().cloned().unwrap()))
    -            .collect()
    +    fn iter_script_pubkeys(&self, keychain: Option<KeychainKind>) -> Result<Vec<Script>, Error> {
    +        let key = MapKey::Path((keychain, None)).as_map_key();
    +        self.map
    +            .range::<Vec<u8>, _>((Included(&key), Excluded(&after(&key))))
    +            .map(|(_, v)| Ok(v.downcast_ref().cloned().unwrap()))
    +            .collect()
         }
     
    -    fn iter_utxos(&self) -> Result<Vec<LocalUtxo>, Error> {
    -        let key = MapKey::Utxo(None).as_map_key();
    -        self.map
    -            .range::<Vec<u8>, _>((Included(&key), Excluded(&after(&key))))
    -            .map(|(k, v)| {
    -                let outpoint = deserialize(&k[1..]).unwrap();
    -                let (txout, keychain, is_spent) = v.downcast_ref().cloned().unwrap();
    -                Ok(LocalUtxo {
    -                    outpoint,
    -                    txout,
    -                    keychain,
    -                    is_spent,
    +    fn iter_utxos(&self) -> Result<Vec<LocalUtxo>, Error> {
    +        let key = MapKey::Utxo(None).as_map_key();
    +        self.map
    +            .range::<Vec<u8>, _>((Included(&key), Excluded(&after(&key))))
    +            .map(|(k, v)| {
    +                let outpoint = deserialize(&k[1..]).unwrap();
    +                let (txout, keychain, is_spent) = v.downcast_ref().cloned().unwrap();
    +                Ok(LocalUtxo {
    +                    outpoint,
    +                    txout,
    +                    keychain,
    +                    is_spent,
                     })
                 })
    -            .collect()
    +            .collect()
         }
     
    -    fn iter_raw_txs(&self) -> Result<Vec<Transaction>, Error> {
    -        let key = MapKey::RawTx(None).as_map_key();
    -        self.map
    -            .range::<Vec<u8>, _>((Included(&key), Excluded(&after(&key))))
    -            .map(|(_, v)| Ok(v.downcast_ref().cloned().unwrap()))
    -            .collect()
    +    fn iter_raw_txs(&self) -> Result<Vec<Transaction>, Error> {
    +        let key = MapKey::RawTx(None).as_map_key();
    +        self.map
    +            .range::<Vec<u8>, _>((Included(&key), Excluded(&after(&key))))
    +            .map(|(_, v)| Ok(v.downcast_ref().cloned().unwrap()))
    +            .collect()
         }
     
    -    fn iter_txs(&self, include_raw: bool) -> Result<Vec<TransactionDetails>, Error> {
    -        let key = MapKey::Transaction(None).as_map_key();
    -        self.map
    -            .range::<Vec<u8>, _>((Included(&key), Excluded(&after(&key))))
    -            .map(|(k, v)| {
    -                let mut txdetails: TransactionDetails = v.downcast_ref().cloned().unwrap();
    -                if include_raw {
    -                    let txid = deserialize(&k[1..])?;
    -                    txdetails.transaction = self.get_raw_tx(&txid)?;
    +    fn iter_txs(&self, include_raw: bool) -> Result<Vec<TransactionDetails>, Error> {
    +        let key = MapKey::Transaction(None).as_map_key();
    +        self.map
    +            .range::<Vec<u8>, _>((Included(&key), Excluded(&after(&key))))
    +            .map(|(k, v)| {
    +                let mut txdetails: TransactionDetails = v.downcast_ref().cloned().unwrap();
    +                if include_raw {
    +                    let txid = deserialize(&k[1..])?;
    +                    txdetails.transaction = self.get_raw_tx(&txid)?;
                     }
     
    -                Ok(txdetails)
    +                Ok(txdetails)
                 })
    -            .collect()
    +            .collect()
         }
     
    -    fn get_script_pubkey_from_path(
    +    fn get_script_pubkey_from_path(
             &self,
    -        keychain: KeychainKind,
    -        path: u32,
    -    ) -> Result<Option<Script>, Error> {
    -        let key = MapKey::Path((Some(keychain), Some(path))).as_map_key();
    -        Ok(self
    -            .map
    -            .get(&key)
    -            .map(|b| b.downcast_ref().cloned().unwrap()))
    +        keychain: KeychainKind,
    +        path: u32,
    +    ) -> Result<Option<Script>, Error> {
    +        let key = MapKey::Path((Some(keychain), Some(path))).as_map_key();
    +        Ok(self
    +            .map
    +            .get(&key)
    +            .map(|b| b.downcast_ref().cloned().unwrap()))
         }
     
    -    fn get_path_from_script_pubkey(
    +    fn get_path_from_script_pubkey(
             &self,
    -        script: &Script,
    -    ) -> Result<Option<(KeychainKind, u32)>, Error> {
    -        let key = MapKey::Script(Some(script)).as_map_key();
    -        Ok(self.map.get(&key).map(|b| {
    -            let mut val: serde_json::Value = b.downcast_ref().cloned().unwrap();
    -            let st = serde_json::from_value(val["t"].take()).unwrap();
    -            let path = serde_json::from_value(val["p"].take()).unwrap();
    -
    -            (st, path)
    +        script: &Script,
    +    ) -> Result<Option<(KeychainKind, u32)>, Error> {
    +        let key = MapKey::Script(Some(script)).as_map_key();
    +        Ok(self.map.get(&key).map(|b| {
    +            let mut val: serde_json::Value = b.downcast_ref().cloned().unwrap();
    +            let st = serde_json::from_value(val["t"].take()).unwrap();
    +            let path = serde_json::from_value(val["p"].take()).unwrap();
    +
    +            (st, path)
             }))
         }
     
    -    fn get_utxo(&self, outpoint: &OutPoint) -> Result<Option<LocalUtxo>, Error> {
    -        let key = MapKey::Utxo(Some(outpoint)).as_map_key();
    -        Ok(self.map.get(&key).map(|b| {
    -            let (txout, keychain, is_spent) = b.downcast_ref().cloned().unwrap();
    -            LocalUtxo {
    -                outpoint: *outpoint,
    -                txout,
    -                keychain,
    -                is_spent,
    +    fn get_utxo(&self, outpoint: &OutPoint) -> Result<Option<LocalUtxo>, Error> {
    +        let key = MapKey::Utxo(Some(outpoint)).as_map_key();
    +        Ok(self.map.get(&key).map(|b| {
    +            let (txout, keychain, is_spent) = b.downcast_ref().cloned().unwrap();
    +            LocalUtxo {
    +                outpoint: *outpoint,
    +                txout,
    +                keychain,
    +                is_spent,
                 }
             }))
         }
     
    -    fn get_raw_tx(&self, txid: &Txid) -> Result<Option<Transaction>, Error> {
    -        let key = MapKey::RawTx(Some(txid)).as_map_key();
    -        Ok(self
    -            .map
    -            .get(&key)
    -            .map(|b| b.downcast_ref().cloned().unwrap()))
    +    fn get_raw_tx(&self, txid: &Txid) -> Result<Option<Transaction>, Error> {
    +        let key = MapKey::RawTx(Some(txid)).as_map_key();
    +        Ok(self
    +            .map
    +            .get(&key)
    +            .map(|b| b.downcast_ref().cloned().unwrap()))
         }
     
    -    fn get_tx(&self, txid: &Txid, include_raw: bool) -> Result<Option<TransactionDetails>, Error> {
    -        let key = MapKey::Transaction(Some(txid)).as_map_key();
    -        Ok(self.map.get(&key).map(|b| {
    -            let mut txdetails: TransactionDetails = b.downcast_ref().cloned().unwrap();
    -            if include_raw {
    -                txdetails.transaction = self.get_raw_tx(txid).unwrap();
    +    fn get_tx(&self, txid: &Txid, include_raw: bool) -> Result<Option<TransactionDetails>, Error> {
    +        let key = MapKey::Transaction(Some(txid)).as_map_key();
    +        Ok(self.map.get(&key).map(|b| {
    +            let mut txdetails: TransactionDetails = b.downcast_ref().cloned().unwrap();
    +            if include_raw {
    +                txdetails.transaction = self.get_raw_tx(txid).unwrap();
                 }
     
    -            txdetails
    +            txdetails
             }))
         }
     
    -    fn get_last_index(&self, keychain: KeychainKind) -> Result<Option<u32>, Error> {
    -        let key = MapKey::LastIndex(keychain).as_map_key();
    -        Ok(self.map.get(&key).map(|b| *b.downcast_ref().unwrap()))
    +    fn get_last_index(&self, keychain: KeychainKind) -> Result<Option<u32>, Error> {
    +        let key = MapKey::LastIndex(keychain).as_map_key();
    +        Ok(self.map.get(&key).map(|b| *b.downcast_ref().unwrap()))
         }
     
    -    fn get_sync_time(&self) -> Result<Option<SyncTime>, Error> {
    -        let key = MapKey::SyncTime.as_map_key();
    -        Ok(self
    -            .map
    -            .get(&key)
    -            .map(|b| b.downcast_ref().cloned().unwrap()))
    +    fn get_sync_time(&self) -> Result<Option<SyncTime>, Error> {
    +        let key = MapKey::SyncTime.as_map_key();
    +        Ok(self
    +            .map
    +            .get(&key)
    +            .map(|b| b.downcast_ref().cloned().unwrap()))
         }
     
    -    // inserts 0 if not present
    -    fn increment_last_index(&mut self, keychain: KeychainKind) -> Result<u32, Error> {
    -        let key = MapKey::LastIndex(keychain).as_map_key();
    -        let value = self
    -            .map
    -            .entry(key)
    -            .and_modify(|x| *x.downcast_mut::<u32>().unwrap() += 1)
    -            .or_insert_with(|| Box::<u32>::new(0))
    -            .downcast_mut()
    -            .unwrap();
    -
    -        Ok(*value)
    +    // inserts 0 if not present
    +    fn increment_last_index(&mut self, keychain: KeychainKind) -> Result<u32, Error> {
    +        let key = MapKey::LastIndex(keychain).as_map_key();
    +        let value = self
    +            .map
    +            .entry(key)
    +            .and_modify(|x| *x.downcast_mut::<u32>().unwrap() += 1)
    +            .or_insert_with(|| Box::<u32>::new(0))
    +            .downcast_mut()
    +            .unwrap();
    +
    +        Ok(*value)
         }
     }
     
    -impl BatchDatabase for MemoryDatabase {
    -    type Batch = Self;
    +impl BatchDatabase for MemoryDatabase {
    +    type Batch = Self;
     
    -    fn begin_batch(&self) -> Self::Batch {
    -        MemoryDatabase::new()
    +    fn begin_batch(&self) -> Self::Batch {
    +        MemoryDatabase::new()
         }
     
    -    fn commit_batch(&mut self, mut batch: Self::Batch) -> Result<(), Error> {
    -        for key in batch.deleted_keys.iter() {
    -            self.map.remove(key);
    +    fn commit_batch(&mut self, mut batch: Self::Batch) -> Result<(), Error> {
    +        for key in batch.deleted_keys.iter() {
    +            self.map.remove(key);
             }
    -        self.map.append(&mut batch.map);
    +        self.map.append(&mut batch.map);
             Ok(())
         }
     }
     
    -impl ConfigurableDatabase for MemoryDatabase {
    -    type Config = ();
    +impl ConfigurableDatabase for MemoryDatabase {
    +    type Config = ();
     
    -    fn from_config(_config: &Self::Config) -> Result<Self, Error> {
    -        Ok(MemoryDatabase::default())
    +    fn from_config(_config: &Self::Config) -> Result<Self, Error> {
    +        Ok(MemoryDatabase::default())
         }
     }
     
    -#[macro_export]
    -#[doc(hidden)]
    -/// Artificially insert a tx in the database, as if we had found it with a `sync`. This is a hidden
    -/// macro and not a `[cfg(test)]` function so it can be called within the context of doctests which
    -/// don't have `test` set.
    -macro_rules! populate_test_db {
    -    ($db:expr, $tx_meta:expr, $current_height:expr$(,)?) => {{
    -        $crate::populate_test_db!($db, $tx_meta, $current_height, (@coinbase false))
    +#[macro_export]
    +#[doc(hidden)]
    +/// Artificially insert a tx in the database, as if we had found it with a `sync`. This is a hidden
    +/// macro and not a `[cfg(test)]` function so it can be called within the context of doctests which
    +/// don't have `test` set.
    +macro_rules! populate_test_db {
    +    ($db:expr, $tx_meta:expr, $current_height:expr$(,)?) => {{
    +        $crate::populate_test_db!($db, $tx_meta, $current_height, (@coinbase false))
         }};
    -    ($db:expr, $tx_meta:expr, $current_height:expr, (@coinbase $is_coinbase:expr)$(,)?) => {{
    -        use std::str::FromStr;
    -        use $crate::database::SyncTime;
    -        use $crate::database::{BatchOperations, Database};
    -        let mut db = $db;
    -        let tx_meta = $tx_meta;
    -        let current_height: Option<u32> = $current_height;
    -        let mut input = vec![$crate::bitcoin::TxIn::default()];
    -        if !$is_coinbase {
    -            input[0].previous_output.vout = 0;
    +    ($db:expr, $tx_meta:expr, $current_height:expr, (@coinbase $is_coinbase:expr)$(,)?) => {{
    +        use std::str::FromStr;
    +        use $crate::database::SyncTime;
    +        use $crate::database::{BatchOperations, Database};
    +        let mut db = $db;
    +        let tx_meta = $tx_meta;
    +        let current_height: Option<u32> = $current_height;
    +        let mut input = vec![$crate::bitcoin::TxIn::default()];
    +        if !$is_coinbase {
    +            input[0].previous_output.vout = 0;
             }
    -        let tx = $crate::bitcoin::Transaction {
    -            version: 1,
    -            lock_time: bitcoin::PackedLockTime(0),
    -            input,
    -            output: tx_meta
    -                .output
    -                .iter()
    -                .map(|out_meta| $crate::bitcoin::TxOut {
    -                    value: out_meta.value,
    -                    script_pubkey: $crate::bitcoin::Address::from_str(&out_meta.to_address)
    -                        .unwrap()
    -                        .script_pubkey(),
    +        let tx = $crate::bitcoin::Transaction {
    +            version: 1,
    +            lock_time: bitcoin::PackedLockTime(0),
    +            input,
    +            output: tx_meta
    +                .output
    +                .iter()
    +                .map(|out_meta| $crate::bitcoin::TxOut {
    +                    value: out_meta.value,
    +                    script_pubkey: $crate::bitcoin::Address::from_str(&out_meta.to_address)
    +                        .unwrap()
    +                        .script_pubkey(),
                     })
    -                .collect(),
    +                .collect(),
             };
     
    -        let txid = tx.txid();
    -        // Set Confirmation time only if current height is provided.
    -        // panics if `tx_meta.min_confirmation` is Some, and current_height is None.
    -        let confirmation_time = tx_meta
    -            .min_confirmations
    -            .and_then(|v| if v == 0 { None } else { Some(v) })
    -            .map(|conf| $crate::BlockTime {
    -                height: current_height.expect("Current height is needed for testing transaction with min-confirmation values").checked_sub(conf as u32).unwrap() + 1,
    -                timestamp: 0,
    +        let txid = tx.txid();
    +        // Set Confirmation time only if current height is provided.
    +        // panics if `tx_meta.min_confirmation` is Some, and current_height is None.
    +        let confirmation_time = tx_meta
    +            .min_confirmations
    +            .and_then(|v| if v == 0 { None } else { Some(v) })
    +            .map(|conf| $crate::BlockTime {
    +                height: current_height.expect("Current height is needed for testing transaction with min-confirmation values").checked_sub(conf as u32).unwrap() + 1,
    +                timestamp: 0,
                 });
     
    -        // Set the database sync_time.
    -        // Check if the current_height is less than already known sync height, apply the max
    -        // If any of them is None, the other will be applied instead.
    -        // If both are None, this will not be set.
    -        if let Some(height) = db.get_sync_time().unwrap()
    -                                .map(|sync_time| sync_time.block_time.height)
    -                                .max(current_height) {
    -            let sync_time = SyncTime {
    -                block_time: BlockTime {
    -                    height,
    -                    timestamp: 0
    -                }
    +        // Set the database sync_time.
    +        // Check if the current_height is less than already known sync height, apply the max
    +        // If any of them is None, the other will be applied instead.
    +        // If both are None, this will not be set.
    +        if let Some(height) = db.get_sync_time().unwrap()
    +                                .map(|sync_time| sync_time.block_time.height)
    +                                .max(current_height) {
    +            let sync_time = SyncTime {
    +                block_time: BlockTime {
    +                    height,
    +                    timestamp: 0
    +                }
                 };
    -            db.set_sync_time(sync_time).unwrap();
    +            db.set_sync_time(sync_time).unwrap();
             }
     
    -        let tx_details = $crate::TransactionDetails {
    -            transaction: Some(tx.clone()),
    -            txid,
    -            fee: Some(0),
    -            received: 0,
    -            sent: 0,
    -            confirmation_time,
    +        let tx_details = $crate::TransactionDetails {
    +            transaction: Some(tx.clone()),
    +            txid,
    +            fee: Some(0),
    +            received: 0,
    +            sent: 0,
    +            confirmation_time,
             };
     
    -        db.set_tx(&tx_details).unwrap();
    -        for (vout, out) in tx.output.iter().enumerate() {
    -            db.set_utxo(&$crate::LocalUtxo {
    -                txout: out.clone(),
    -                outpoint: $crate::bitcoin::OutPoint {
    -                    txid,
    -                    vout: vout as u32,
    +        db.set_tx(&tx_details).unwrap();
    +        for (vout, out) in tx.output.iter().enumerate() {
    +            db.set_utxo(&$crate::LocalUtxo {
    +                txout: out.clone(),
    +                outpoint: $crate::bitcoin::OutPoint {
    +                    txid,
    +                    vout: vout as u32,
                     },
    -                keychain: $crate::KeychainKind::External,
    -                is_spent: false,
    +                keychain: $crate::KeychainKind::External,
    +                is_spent: false,
                 })
    -            .unwrap();
    +            .unwrap();
             }
     
    -        txid
    +        txid
         }};
     }
     
    -#[macro_export]
    -#[doc(hidden)]
    -/// Macro for getting a wallet for use in a doctest
    -macro_rules! doctest_wallet {
    +#[macro_export]
    +#[doc(hidden)]
    +/// Macro for getting a wallet for use in a doctest
    +macro_rules! doctest_wallet {
         () => {{
    -        use $crate::bitcoin::Network;
    -        use $crate::database::MemoryDatabase;
    -        use $crate::testutils;
    -        let descriptor = "wpkh(cVpPVruEDdmutPzisEsYvtST1usBR3ntr8pXSyt6D2YYqXRyPcFW)";
    -        let descriptors = testutils!(@descriptors (descriptor) (descriptor));
    -
    -        let mut db = MemoryDatabase::new();
    -        let txid = populate_test_db!(
    -            &mut db,
    -            testutils! {
    -                @tx ( (@external descriptors, 0) => 500_000 ) (@confirmations 1)
    +        use $crate::bitcoin::Network;
    +        use $crate::database::MemoryDatabase;
    +        use $crate::testutils;
    +        let descriptor = "wpkh(cVpPVruEDdmutPzisEsYvtST1usBR3ntr8pXSyt6D2YYqXRyPcFW)";
    +        let descriptors = testutils!(@descriptors (descriptor) (descriptor));
    +
    +        let mut db = MemoryDatabase::new();
    +        let txid = populate_test_db!(
    +            &mut db,
    +            testutils! {
    +                @tx ( (@external descriptors, 0) => 500_000 ) (@confirmations 1)
                 },
                 Some(100),
             );
     
    -        $crate::Wallet::new(
    -            &descriptors.0,
    -            descriptors.1.as_ref(),
    -            Network::Regtest,
    -            db
    +        $crate::Wallet::new(
    +            &descriptors.0,
    +            descriptors.1.as_ref(),
    +            Network::Regtest,
    +            db
             )
    -        .unwrap()
    +        .unwrap()
         }}
     }
     
    -#[cfg(test)]
    -mod test {
    -    use super::MemoryDatabase;
    +#[cfg(test)]
    +mod test {
    +    use super::MemoryDatabase;
     
    -    fn get_tree() -> MemoryDatabase {
    -        MemoryDatabase::new()
    +    fn get_tree() -> MemoryDatabase {
    +        MemoryDatabase::new()
         }
     
    -    #[test]
    -    fn test_script_pubkey() {
    -        crate::database::test::test_script_pubkey(get_tree());
    +    #[test]
    +    fn test_script_pubkey() {
    +        crate::database::test::test_script_pubkey(get_tree());
         }
     
    -    #[test]
    -    fn test_batch_script_pubkey() {
    -        crate::database::test::test_batch_script_pubkey(get_tree());
    +    #[test]
    +    fn test_batch_script_pubkey() {
    +        crate::database::test::test_batch_script_pubkey(get_tree());
         }
     
    -    #[test]
    -    fn test_iter_script_pubkey() {
    -        crate::database::test::test_iter_script_pubkey(get_tree());
    +    #[test]
    +    fn test_iter_script_pubkey() {
    +        crate::database::test::test_iter_script_pubkey(get_tree());
         }
     
    -    #[test]
    -    fn test_del_script_pubkey() {
    -        crate::database::test::test_del_script_pubkey(get_tree());
    +    #[test]
    +    fn test_del_script_pubkey() {
    +        crate::database::test::test_del_script_pubkey(get_tree());
         }
     
    -    #[test]
    -    fn test_utxo() {
    -        crate::database::test::test_utxo(get_tree());
    +    #[test]
    +    fn test_utxo() {
    +        crate::database::test::test_utxo(get_tree());
         }
     
    -    #[test]
    -    fn test_raw_tx() {
    -        crate::database::test::test_raw_tx(get_tree());
    +    #[test]
    +    fn test_raw_tx() {
    +        crate::database::test::test_raw_tx(get_tree());
         }
     
    -    #[test]
    -    fn test_tx() {
    -        crate::database::test::test_tx(get_tree());
    +    #[test]
    +    fn test_tx() {
    +        crate::database::test::test_tx(get_tree());
         }
     
    -    #[test]
    -    fn test_last_index() {
    -        crate::database::test::test_last_index(get_tree());
    +    #[test]
    +    fn test_last_index() {
    +        crate::database::test::test_last_index(get_tree());
         }
     
    -    #[test]
    -    fn test_sync_time() {
    -        crate::database::test::test_sync_time(get_tree());
    +    #[test]
    +    fn test_sync_time() {
    +        crate::database::test::test_sync_time(get_tree());
         }
     
    -    #[test]
    -    fn test_iter_raw_txs() {
    -        crate::database::test::test_iter_raw_txs(get_tree());
    +    #[test]
    +    fn test_iter_raw_txs() {
    +        crate::database::test::test_iter_raw_txs(get_tree());
         }
     
    -    #[test]
    -    fn test_del_path_from_script_pubkey() {
    -        crate::database::test::test_del_path_from_script_pubkey(get_tree());
    +    #[test]
    +    fn test_del_path_from_script_pubkey() {
    +        crate::database::test::test_del_path_from_script_pubkey(get_tree());
         }
     
    -    #[test]
    -    fn test_iter_script_pubkeys() {
    -        crate::database::test::test_iter_script_pubkeys(get_tree());
    +    #[test]
    +    fn test_iter_script_pubkeys() {
    +        crate::database::test::test_iter_script_pubkeys(get_tree());
         }
     
    -    #[test]
    -    fn test_del_utxo() {
    -        crate::database::test::test_del_utxo(get_tree());
    +    #[test]
    +    fn test_del_utxo() {
    +        crate::database::test::test_del_utxo(get_tree());
         }
     
    -    #[test]
    -    fn test_del_raw_tx() {
    -        crate::database::test::test_del_raw_tx(get_tree());
    +    #[test]
    +    fn test_del_raw_tx() {
    +        crate::database::test::test_del_raw_tx(get_tree());
         }
     
    -    #[test]
    -    fn test_del_tx() {
    -        crate::database::test::test_del_tx(get_tree());
    +    #[test]
    +    fn test_del_tx() {
    +        crate::database::test::test_del_tx(get_tree());
         }
     
    -    #[test]
    -    fn test_del_last_index() {
    -        crate::database::test::test_del_last_index(get_tree());
    +    #[test]
    +    fn test_del_last_index() {
    +        crate::database::test::test_del_last_index(get_tree());
         }
     
    -    #[test]
    -    fn test_check_descriptor_checksum() {
    -        crate::database::test::test_check_descriptor_checksum(get_tree());
    +    #[test]
    +    fn test_check_descriptor_checksum() {
    +        crate::database::test::test_check_descriptor_checksum(get_tree());
         }
     }
     
    -
    - \ No newline at end of file +
    \ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/src/bdk/database/mod.rs.html b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/src/bdk/database/mod.rs.html index a25b4b8f80..d66b547b5a 100644 --- a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/src/bdk/database/mod.rs.html +++ b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/src/bdk/database/mod.rs.html @@ -1,1324 +1,1317 @@ -mod.rs - source - -
      1
    -  2
    -  3
    -  4
    -  5
    -  6
    -  7
    -  8
    -  9
    - 10
    - 11
    - 12
    - 13
    - 14
    - 15
    - 16
    - 17
    - 18
    - 19
    - 20
    - 21
    - 22
    - 23
    - 24
    - 25
    - 26
    - 27
    - 28
    - 29
    - 30
    - 31
    - 32
    - 33
    - 34
    - 35
    - 36
    - 37
    - 38
    - 39
    - 40
    - 41
    - 42
    - 43
    - 44
    - 45
    - 46
    - 47
    - 48
    - 49
    - 50
    - 51
    - 52
    - 53
    - 54
    - 55
    - 56
    - 57
    - 58
    - 59
    - 60
    - 61
    - 62
    - 63
    - 64
    - 65
    - 66
    - 67
    - 68
    - 69
    - 70
    - 71
    - 72
    - 73
    - 74
    - 75
    - 76
    - 77
    - 78
    - 79
    - 80
    - 81
    - 82
    - 83
    - 84
    - 85
    - 86
    - 87
    - 88
    - 89
    - 90
    - 91
    - 92
    - 93
    - 94
    - 95
    - 96
    - 97
    - 98
    - 99
    -100
    -101
    -102
    -103
    -104
    -105
    -106
    -107
    -108
    -109
    -110
    -111
    -112
    -113
    -114
    -115
    -116
    -117
    -118
    -119
    -120
    -121
    -122
    -123
    -124
    -125
    -126
    -127
    -128
    -129
    -130
    -131
    -132
    -133
    -134
    -135
    -136
    -137
    -138
    -139
    -140
    -141
    -142
    -143
    -144
    -145
    -146
    -147
    -148
    -149
    -150
    -151
    -152
    -153
    -154
    -155
    -156
    -157
    -158
    -159
    -160
    -161
    -162
    -163
    -164
    -165
    -166
    -167
    -168
    -169
    -170
    -171
    -172
    -173
    -174
    -175
    -176
    -177
    -178
    -179
    -180
    -181
    -182
    -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
    -245
    -246
    -247
    -248
    -249
    -250
    -251
    -252
    -253
    -254
    -255
    -256
    -257
    -258
    -259
    -260
    -261
    -262
    -263
    -264
    -265
    -266
    -267
    -268
    -269
    -270
    -271
    -272
    -273
    -274
    -275
    -276
    -277
    -278
    -279
    -280
    -281
    -282
    -283
    -284
    -285
    -286
    -287
    -288
    -289
    -290
    -291
    -292
    -293
    -294
    -295
    -296
    -297
    -298
    -299
    -300
    -301
    -302
    -303
    -304
    -305
    -306
    -307
    -308
    -309
    -310
    -311
    -312
    -313
    -314
    -315
    -316
    -317
    -318
    -319
    -320
    -321
    -322
    -323
    -324
    -325
    -326
    -327
    -328
    -329
    -330
    -331
    -332
    -333
    -334
    -335
    -336
    -337
    -338
    -339
    -340
    -341
    -342
    -343
    -344
    -345
    -346
    -347
    -348
    -349
    -350
    -351
    -352
    -353
    -354
    -355
    -356
    -357
    -358
    -359
    -360
    -361
    -362
    -363
    -364
    -365
    -366
    -367
    -368
    -369
    -370
    -371
    -372
    -373
    -374
    -375
    -376
    -377
    -378
    -379
    -380
    -381
    -382
    -383
    -384
    -385
    -386
    -387
    -388
    -389
    -390
    -391
    -392
    -393
    -394
    -395
    -396
    -397
    -398
    -399
    -400
    -401
    -402
    -403
    -404
    -405
    -406
    -407
    -408
    -409
    -410
    -411
    -412
    -413
    -414
    -415
    -416
    -417
    -418
    -419
    -420
    -421
    -422
    -423
    -424
    -425
    -426
    -427
    -428
    -429
    -430
    -431
    -432
    -433
    -434
    -435
    -436
    -437
    -438
    -439
    -440
    -441
    -442
    -443
    -444
    -445
    -446
    -447
    -448
    -449
    -450
    -451
    -452
    -453
    -454
    -455
    -456
    -457
    -458
    -459
    -460
    -461
    -462
    -463
    -464
    -465
    -466
    -467
    -468
    -469
    -470
    -471
    -472
    -473
    -474
    -475
    -476
    -477
    -478
    -479
    -480
    -481
    -482
    -483
    -484
    -485
    -486
    -487
    -488
    -489
    -490
    -491
    -492
    -493
    -494
    -495
    -496
    -497
    -498
    -499
    -500
    -501
    -502
    -503
    -504
    -505
    -506
    -507
    -508
    -509
    -510
    -511
    -512
    -513
    -514
    -515
    -516
    -517
    -518
    -519
    -520
    -521
    -522
    -523
    -524
    -525
    -526
    -527
    -528
    -529
    -530
    -531
    -532
    -533
    -534
    -535
    -536
    -537
    -538
    -539
    -540
    -541
    -542
    -543
    -544
    -545
    -546
    -547
    -548
    -549
    -550
    -551
    -552
    -553
    -554
    -555
    -556
    -557
    -558
    -559
    -560
    -561
    -562
    -563
    -564
    -565
    -566
    -567
    -568
    -569
    -570
    -571
    -572
    -573
    -574
    -575
    -576
    -577
    -578
    -579
    -580
    -581
    -582
    -583
    -584
    -585
    -586
    -587
    -588
    -589
    -590
    -591
    -592
    -593
    -594
    -595
    -596
    -597
    -598
    -599
    -600
    -601
    -602
    -603
    -604
    -605
    -606
    -607
    -608
    -609
    -610
    -611
    -612
    -613
    -614
    -615
    -616
    -617
    -618
    -619
    -620
    -621
    -622
    -623
    -624
    -625
    -626
    -627
    -628
    -629
    -630
    -631
    -632
    -633
    -634
    -635
    -636
    -637
    -638
    -639
    -640
    -641
    -642
    -643
    -644
    -645
    -646
    -647
    -648
    -649
    -650
    -651
    -652
    -653
    -654
    -655
    -656
    -657
    -
    // Bitcoin Dev Kit
    -// Written in 2020 by Alekos Filini <alekos.filini@gmail.com>
    -//
    -// Copyright (c) 2020-2021 Bitcoin Dev Kit Developers
    -//
    -// This file is licensed under the Apache License, Version 2.0 <LICENSE-APACHE
    -// or http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
    -// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your option.
    -// You may not use this file except in accordance with one or both of these
    -// licenses.
    -
    -//! Database types
    -//!
    -//! This module provides the implementation of some defaults database types, along with traits that
    -//! can be implemented externally to let [`Wallet`]s use customized databases.
    -//!
    -//! It's important to note that the databases defined here only contains "blockchain-related" data.
    -//! They can be seen more as a cache than a critical piece of storage that contains secrets and
    -//! keys.
    -//!
    -//! The currently recommended database is [`sled`], which is a pretty simple key-value embedded
    -//! database written in Rust. If the `key-value-db` feature is enabled (which by default is),
    -//! this library automatically implements all the required traits for [`sled::Tree`].
    -//!
    -//! [`Wallet`]: crate::wallet::Wallet
    -
    -use serde::{Deserialize, Serialize};
    -
    -use bitcoin::hash_types::Txid;
    -use bitcoin::{OutPoint, Script, Transaction, TxOut};
    -
    -use crate::error::Error;
    -use crate::types::*;
    -
    -pub mod any;
    -pub use any::{AnyDatabase, AnyDatabaseConfig};
    -
    -#[cfg(feature = "key-value-db")]
    -pub(crate) mod keyvalue;
    -
    -#[cfg(feature = "sqlite")]
    -pub(crate) mod sqlite;
    -#[cfg(feature = "sqlite")]
    -pub use sqlite::SqliteDatabase;
    -
    -pub mod memory;
    -pub use memory::MemoryDatabase;
    -
    -/// Blockchain state at the time of syncing
    -///
    -/// Contains only the block time and height at the moment
    -#[derive(Clone, Debug, Serialize, Deserialize)]
    -pub struct SyncTime {
    -    /// Block timestamp and height at the time of sync
    -    pub block_time: BlockTime,
    +mod.rs - source
    1
    +2
    +3
    +4
    +5
    +6
    +7
    +8
    +9
    +10
    +11
    +12
    +13
    +14
    +15
    +16
    +17
    +18
    +19
    +20
    +21
    +22
    +23
    +24
    +25
    +26
    +27
    +28
    +29
    +30
    +31
    +32
    +33
    +34
    +35
    +36
    +37
    +38
    +39
    +40
    +41
    +42
    +43
    +44
    +45
    +46
    +47
    +48
    +49
    +50
    +51
    +52
    +53
    +54
    +55
    +56
    +57
    +58
    +59
    +60
    +61
    +62
    +63
    +64
    +65
    +66
    +67
    +68
    +69
    +70
    +71
    +72
    +73
    +74
    +75
    +76
    +77
    +78
    +79
    +80
    +81
    +82
    +83
    +84
    +85
    +86
    +87
    +88
    +89
    +90
    +91
    +92
    +93
    +94
    +95
    +96
    +97
    +98
    +99
    +100
    +101
    +102
    +103
    +104
    +105
    +106
    +107
    +108
    +109
    +110
    +111
    +112
    +113
    +114
    +115
    +116
    +117
    +118
    +119
    +120
    +121
    +122
    +123
    +124
    +125
    +126
    +127
    +128
    +129
    +130
    +131
    +132
    +133
    +134
    +135
    +136
    +137
    +138
    +139
    +140
    +141
    +142
    +143
    +144
    +145
    +146
    +147
    +148
    +149
    +150
    +151
    +152
    +153
    +154
    +155
    +156
    +157
    +158
    +159
    +160
    +161
    +162
    +163
    +164
    +165
    +166
    +167
    +168
    +169
    +170
    +171
    +172
    +173
    +174
    +175
    +176
    +177
    +178
    +179
    +180
    +181
    +182
    +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
    +245
    +246
    +247
    +248
    +249
    +250
    +251
    +252
    +253
    +254
    +255
    +256
    +257
    +258
    +259
    +260
    +261
    +262
    +263
    +264
    +265
    +266
    +267
    +268
    +269
    +270
    +271
    +272
    +273
    +274
    +275
    +276
    +277
    +278
    +279
    +280
    +281
    +282
    +283
    +284
    +285
    +286
    +287
    +288
    +289
    +290
    +291
    +292
    +293
    +294
    +295
    +296
    +297
    +298
    +299
    +300
    +301
    +302
    +303
    +304
    +305
    +306
    +307
    +308
    +309
    +310
    +311
    +312
    +313
    +314
    +315
    +316
    +317
    +318
    +319
    +320
    +321
    +322
    +323
    +324
    +325
    +326
    +327
    +328
    +329
    +330
    +331
    +332
    +333
    +334
    +335
    +336
    +337
    +338
    +339
    +340
    +341
    +342
    +343
    +344
    +345
    +346
    +347
    +348
    +349
    +350
    +351
    +352
    +353
    +354
    +355
    +356
    +357
    +358
    +359
    +360
    +361
    +362
    +363
    +364
    +365
    +366
    +367
    +368
    +369
    +370
    +371
    +372
    +373
    +374
    +375
    +376
    +377
    +378
    +379
    +380
    +381
    +382
    +383
    +384
    +385
    +386
    +387
    +388
    +389
    +390
    +391
    +392
    +393
    +394
    +395
    +396
    +397
    +398
    +399
    +400
    +401
    +402
    +403
    +404
    +405
    +406
    +407
    +408
    +409
    +410
    +411
    +412
    +413
    +414
    +415
    +416
    +417
    +418
    +419
    +420
    +421
    +422
    +423
    +424
    +425
    +426
    +427
    +428
    +429
    +430
    +431
    +432
    +433
    +434
    +435
    +436
    +437
    +438
    +439
    +440
    +441
    +442
    +443
    +444
    +445
    +446
    +447
    +448
    +449
    +450
    +451
    +452
    +453
    +454
    +455
    +456
    +457
    +458
    +459
    +460
    +461
    +462
    +463
    +464
    +465
    +466
    +467
    +468
    +469
    +470
    +471
    +472
    +473
    +474
    +475
    +476
    +477
    +478
    +479
    +480
    +481
    +482
    +483
    +484
    +485
    +486
    +487
    +488
    +489
    +490
    +491
    +492
    +493
    +494
    +495
    +496
    +497
    +498
    +499
    +500
    +501
    +502
    +503
    +504
    +505
    +506
    +507
    +508
    +509
    +510
    +511
    +512
    +513
    +514
    +515
    +516
    +517
    +518
    +519
    +520
    +521
    +522
    +523
    +524
    +525
    +526
    +527
    +528
    +529
    +530
    +531
    +532
    +533
    +534
    +535
    +536
    +537
    +538
    +539
    +540
    +541
    +542
    +543
    +544
    +545
    +546
    +547
    +548
    +549
    +550
    +551
    +552
    +553
    +554
    +555
    +556
    +557
    +558
    +559
    +560
    +561
    +562
    +563
    +564
    +565
    +566
    +567
    +568
    +569
    +570
    +571
    +572
    +573
    +574
    +575
    +576
    +577
    +578
    +579
    +580
    +581
    +582
    +583
    +584
    +585
    +586
    +587
    +588
    +589
    +590
    +591
    +592
    +593
    +594
    +595
    +596
    +597
    +598
    +599
    +600
    +601
    +602
    +603
    +604
    +605
    +606
    +607
    +608
    +609
    +610
    +611
    +612
    +613
    +614
    +615
    +616
    +617
    +618
    +619
    +620
    +621
    +622
    +623
    +624
    +625
    +626
    +627
    +628
    +629
    +630
    +631
    +632
    +633
    +634
    +635
    +636
    +637
    +638
    +639
    +640
    +641
    +642
    +643
    +644
    +645
    +646
    +647
    +648
    +649
    +650
    +651
    +652
    +653
    +654
    +655
    +656
    +657
    +
    // Bitcoin Dev Kit
    +// Written in 2020 by Alekos Filini <alekos.filini@gmail.com>
    +//
    +// Copyright (c) 2020-2021 Bitcoin Dev Kit Developers
    +//
    +// This file is licensed under the Apache License, Version 2.0 <LICENSE-APACHE
    +// or http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
    +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your option.
    +// You may not use this file except in accordance with one or both of these
    +// licenses.
    +
    +//! Database types
    +//!
    +//! This module provides the implementation of some defaults database types, along with traits that
    +//! can be implemented externally to let [`Wallet`]s use customized databases.
    +//!
    +//! It's important to note that the databases defined here only contains "blockchain-related" data.
    +//! They can be seen more as a cache than a critical piece of storage that contains secrets and
    +//! keys.
    +//!
    +//! The currently recommended database is [`sled`], which is a pretty simple key-value embedded
    +//! database written in Rust. If the `key-value-db` feature is enabled (which by default is),
    +//! this library automatically implements all the required traits for [`sled::Tree`].
    +//!
    +//! [`Wallet`]: crate::wallet::Wallet
    +
    +use serde::{Deserialize, Serialize};
    +
    +use bitcoin::hash_types::Txid;
    +use bitcoin::{OutPoint, Script, Transaction, TxOut};
    +
    +use crate::error::Error;
    +use crate::types::*;
    +
    +pub mod any;
    +pub use any::{AnyDatabase, AnyDatabaseConfig};
    +
    +#[cfg(feature = "key-value-db")]
    +pub(crate) mod keyvalue;
    +
    +#[cfg(feature = "sqlite")]
    +pub(crate) mod sqlite;
    +#[cfg(feature = "sqlite")]
    +pub use sqlite::SqliteDatabase;
    +
    +pub mod memory;
    +pub use memory::MemoryDatabase;
    +
    +/// Blockchain state at the time of syncing
    +///
    +/// Contains only the block time and height at the moment
    +#[derive(Clone, Debug, Serialize, Deserialize)]
    +pub struct SyncTime {
    +    /// Block timestamp and height at the time of sync
    +    pub block_time: BlockTime,
     }
     
    -/// Trait for operations that can be batched
    -///
    -/// This trait defines the list of operations that must be implemented on the [`Database`] type and
    -/// the [`BatchDatabase::Batch`] type.
    -pub trait BatchOperations {
    -    /// Store a script_pubkey along with its keychain and child number.
    -    fn set_script_pubkey(
    -        &mut self,
    -        script: &Script,
    -        keychain: KeychainKind,
    -        child: u32,
    -    ) -> Result<(), Error>;
    -    /// Store a [`LocalUtxo`]
    -    fn set_utxo(&mut self, utxo: &LocalUtxo) -> Result<(), Error>;
    -    /// Store a raw transaction
    -    fn set_raw_tx(&mut self, transaction: &Transaction) -> Result<(), Error>;
    -    /// Store the metadata of a transaction
    -    fn set_tx(&mut self, transaction: &TransactionDetails) -> Result<(), Error>;
    -    /// Store the last derivation index for a given keychain.
    -    fn set_last_index(&mut self, keychain: KeychainKind, value: u32) -> Result<(), Error>;
    -    /// Store the sync time
    -    fn set_sync_time(&mut self, sync_time: SyncTime) -> Result<(), Error>;
    -
    -    /// Delete a script_pubkey given the keychain and its child number.
    -    fn del_script_pubkey_from_path(
    -        &mut self,
    -        keychain: KeychainKind,
    -        child: u32,
    -    ) -> Result<Option<Script>, Error>;
    -    /// Delete the data related to a specific script_pubkey, meaning the keychain and the child
    -    /// number.
    -    fn del_path_from_script_pubkey(
    -        &mut self,
    -        script: &Script,
    -    ) -> Result<Option<(KeychainKind, u32)>, Error>;
    -    /// Delete a [`LocalUtxo`] given its [`OutPoint`]
    -    fn del_utxo(&mut self, outpoint: &OutPoint) -> Result<Option<LocalUtxo>, Error>;
    -    /// Delete a raw transaction given its [`Txid`]
    -    fn del_raw_tx(&mut self, txid: &Txid) -> Result<Option<Transaction>, Error>;
    -    /// Delete the metadata of a transaction and optionally the raw transaction itself
    -    fn del_tx(
    -        &mut self,
    -        txid: &Txid,
    -        include_raw: bool,
    -    ) -> Result<Option<TransactionDetails>, Error>;
    -    /// Delete the last derivation index for a keychain.
    -    fn del_last_index(&mut self, keychain: KeychainKind) -> Result<Option<u32>, Error>;
    -    /// Reset the sync time to `None`
    -    ///
    -    /// Returns the removed value
    -    fn del_sync_time(&mut self) -> Result<Option<SyncTime>, Error>;
    +/// Trait for operations that can be batched
    +///
    +/// This trait defines the list of operations that must be implemented on the [`Database`] type and
    +/// the [`BatchDatabase::Batch`] type.
    +pub trait BatchOperations {
    +    /// Store a script_pubkey along with its keychain and child number.
    +    fn set_script_pubkey(
    +        &mut self,
    +        script: &Script,
    +        keychain: KeychainKind,
    +        child: u32,
    +    ) -> Result<(), Error>;
    +    /// Store a [`LocalUtxo`]
    +    fn set_utxo(&mut self, utxo: &LocalUtxo) -> Result<(), Error>;
    +    /// Store a raw transaction
    +    fn set_raw_tx(&mut self, transaction: &Transaction) -> Result<(), Error>;
    +    /// Store the metadata of a transaction
    +    fn set_tx(&mut self, transaction: &TransactionDetails) -> Result<(), Error>;
    +    /// Store the last derivation index for a given keychain.
    +    fn set_last_index(&mut self, keychain: KeychainKind, value: u32) -> Result<(), Error>;
    +    /// Store the sync time
    +    fn set_sync_time(&mut self, sync_time: SyncTime) -> Result<(), Error>;
    +
    +    /// Delete a script_pubkey given the keychain and its child number.
    +    fn del_script_pubkey_from_path(
    +        &mut self,
    +        keychain: KeychainKind,
    +        child: u32,
    +    ) -> Result<Option<Script>, Error>;
    +    /// Delete the data related to a specific script_pubkey, meaning the keychain and the child
    +    /// number.
    +    fn del_path_from_script_pubkey(
    +        &mut self,
    +        script: &Script,
    +    ) -> Result<Option<(KeychainKind, u32)>, Error>;
    +    /// Delete a [`LocalUtxo`] given its [`OutPoint`]
    +    fn del_utxo(&mut self, outpoint: &OutPoint) -> Result<Option<LocalUtxo>, Error>;
    +    /// Delete a raw transaction given its [`Txid`]
    +    fn del_raw_tx(&mut self, txid: &Txid) -> Result<Option<Transaction>, Error>;
    +    /// Delete the metadata of a transaction and optionally the raw transaction itself
    +    fn del_tx(
    +        &mut self,
    +        txid: &Txid,
    +        include_raw: bool,
    +    ) -> Result<Option<TransactionDetails>, Error>;
    +    /// Delete the last derivation index for a keychain.
    +    fn del_last_index(&mut self, keychain: KeychainKind) -> Result<Option<u32>, Error>;
    +    /// Reset the sync time to `None`
    +    ///
    +    /// Returns the removed value
    +    fn del_sync_time(&mut self) -> Result<Option<SyncTime>, Error>;
     }
     
    -/// Trait for reading data from a database
    -///
    -/// This traits defines the operations that can be used to read data out of a database
    -pub trait Database: BatchOperations {
    -    /// Read and checks the descriptor checksum for a given keychain.
    -    ///
    -    /// Should return [`Error::ChecksumMismatch`](crate::error::Error::ChecksumMismatch) if the
    -    /// checksum doesn't match. If there's no checksum in the database, simply store it for the
    -    /// next time.
    -    fn check_descriptor_checksum<B: AsRef<[u8]>>(
    -        &mut self,
    -        keychain: KeychainKind,
    -        bytes: B,
    -    ) -> Result<(), Error>;
    -
    -    /// Return the list of script_pubkeys
    -    fn iter_script_pubkeys(&self, keychain: Option<KeychainKind>) -> Result<Vec<Script>, Error>;
    -    /// Return the list of [`LocalUtxo`]s
    -    fn iter_utxos(&self) -> Result<Vec<LocalUtxo>, Error>;
    -    /// Return the list of raw transactions
    -    fn iter_raw_txs(&self) -> Result<Vec<Transaction>, Error>;
    -    /// Return the list of transactions metadata
    -    fn iter_txs(&self, include_raw: bool) -> Result<Vec<TransactionDetails>, Error>;
    -
    -    /// Fetch a script_pubkey given the child number of a keychain.
    -    fn get_script_pubkey_from_path(
    +/// Trait for reading data from a database
    +///
    +/// This traits defines the operations that can be used to read data out of a database
    +pub trait Database: BatchOperations {
    +    /// Read and checks the descriptor checksum for a given keychain.
    +    ///
    +    /// Should return [`Error::ChecksumMismatch`](crate::error::Error::ChecksumMismatch) if the
    +    /// checksum doesn't match. If there's no checksum in the database, simply store it for the
    +    /// next time.
    +    fn check_descriptor_checksum<B: AsRef<[u8]>>(
    +        &mut self,
    +        keychain: KeychainKind,
    +        bytes: B,
    +    ) -> Result<(), Error>;
    +
    +    /// Return the list of script_pubkeys
    +    fn iter_script_pubkeys(&self, keychain: Option<KeychainKind>) -> Result<Vec<Script>, Error>;
    +    /// Return the list of [`LocalUtxo`]s
    +    fn iter_utxos(&self) -> Result<Vec<LocalUtxo>, Error>;
    +    /// Return the list of raw transactions
    +    fn iter_raw_txs(&self) -> Result<Vec<Transaction>, Error>;
    +    /// Return the list of transactions metadata
    +    fn iter_txs(&self, include_raw: bool) -> Result<Vec<TransactionDetails>, Error>;
    +
    +    /// Fetch a script_pubkey given the child number of a keychain.
    +    fn get_script_pubkey_from_path(
             &self,
    -        keychain: KeychainKind,
    -        child: u32,
    -    ) -> Result<Option<Script>, Error>;
    -    /// Fetch the keychain and child number of a given script_pubkey
    -    fn get_path_from_script_pubkey(
    +        keychain: KeychainKind,
    +        child: u32,
    +    ) -> Result<Option<Script>, Error>;
    +    /// Fetch the keychain and child number of a given script_pubkey
    +    fn get_path_from_script_pubkey(
             &self,
    -        script: &Script,
    -    ) -> Result<Option<(KeychainKind, u32)>, Error>;
    -    /// Fetch a [`LocalUtxo`] given its [`OutPoint`]
    -    fn get_utxo(&self, outpoint: &OutPoint) -> Result<Option<LocalUtxo>, Error>;
    -    /// Fetch a raw transaction given its [`Txid`]
    -    fn get_raw_tx(&self, txid: &Txid) -> Result<Option<Transaction>, Error>;
    -    /// Fetch the transaction metadata and optionally also the raw transaction
    -    fn get_tx(&self, txid: &Txid, include_raw: bool) -> Result<Option<TransactionDetails>, Error>;
    -    /// Return the last derivation index for a keychain.
    -    fn get_last_index(&self, keychain: KeychainKind) -> Result<Option<u32>, Error>;
    -    /// Return the sync time, if present
    -    fn get_sync_time(&self) -> Result<Option<SyncTime>, Error>;
    -
    -    /// Increment the last derivation index for a keychain and return it
    -    ///
    -    /// It should insert and return `0` if not present in the database
    -    fn increment_last_index(&mut self, keychain: KeychainKind) -> Result<u32, Error>;
    +        script: &Script,
    +    ) -> Result<Option<(KeychainKind, u32)>, Error>;
    +    /// Fetch a [`LocalUtxo`] given its [`OutPoint`]
    +    fn get_utxo(&self, outpoint: &OutPoint) -> Result<Option<LocalUtxo>, Error>;
    +    /// Fetch a raw transaction given its [`Txid`]
    +    fn get_raw_tx(&self, txid: &Txid) -> Result<Option<Transaction>, Error>;
    +    /// Fetch the transaction metadata and optionally also the raw transaction
    +    fn get_tx(&self, txid: &Txid, include_raw: bool) -> Result<Option<TransactionDetails>, Error>;
    +    /// Return the last derivation index for a keychain.
    +    fn get_last_index(&self, keychain: KeychainKind) -> Result<Option<u32>, Error>;
    +    /// Return the sync time, if present
    +    fn get_sync_time(&self) -> Result<Option<SyncTime>, Error>;
    +
    +    /// Increment the last derivation index for a keychain and return it
    +    ///
    +    /// It should insert and return `0` if not present in the database
    +    fn increment_last_index(&mut self, keychain: KeychainKind) -> Result<u32, Error>;
     }
     
    -/// Trait for a database that supports batch operations
    -///
    -/// This trait defines the methods to start and apply a batch of operations.
    -pub trait BatchDatabase: Database {
    -    /// Container for the operations
    -    type Batch: BatchOperations;
    -
    -    /// Create a new batch container
    -    fn begin_batch(&self) -> Self::Batch;
    -    /// Consume and apply a batch of operations
    -    fn commit_batch(&mut self, batch: Self::Batch) -> Result<(), Error>;
    +/// Trait for a database that supports batch operations
    +///
    +/// This trait defines the methods to start and apply a batch of operations.
    +pub trait BatchDatabase: Database {
    +    /// Container for the operations
    +    type Batch: BatchOperations;
    +
    +    /// Create a new batch container
    +    fn begin_batch(&self) -> Self::Batch;
    +    /// Consume and apply a batch of operations
    +    fn commit_batch(&mut self, batch: Self::Batch) -> Result<(), Error>;
     }
     
    -/// Trait for [`Database`] types that can be created given a configuration
    -pub trait ConfigurableDatabase: Database + Sized {
    -    /// Type that contains the configuration
    -    type Config: std::fmt::Debug;
    +/// Trait for [`Database`] types that can be created given a configuration
    +pub trait ConfigurableDatabase: Database + Sized {
    +    /// Type that contains the configuration
    +    type Config: std::fmt::Debug;
     
    -    /// Create a new instance given a configuration
    -    fn from_config(config: &Self::Config) -> Result<Self, Error>;
    +    /// Create a new instance given a configuration
    +    fn from_config(config: &Self::Config) -> Result<Self, Error>;
     }
     
    -pub(crate) trait DatabaseUtils: Database {
    -    fn is_mine(&self, script: &Script) -> Result<bool, Error> {
    -        self.get_path_from_script_pubkey(script)
    -            .map(|o| o.is_some())
    +pub(crate) trait DatabaseUtils: Database {
    +    fn is_mine(&self, script: &Script) -> Result<bool, Error> {
    +        self.get_path_from_script_pubkey(script)
    +            .map(|o| o.is_some())
         }
     
    -    fn get_raw_tx_or<D>(&self, txid: &Txid, default: D) -> Result<Option<Transaction>, Error>
    -    where
    -        D: FnOnce() -> Result<Option<Transaction>, Error>,
    +    fn get_raw_tx_or<D>(&self, txid: &Txid, default: D) -> Result<Option<Transaction>, Error>
    +    where
    +        D: FnOnce() -> Result<Option<Transaction>, Error>,
         {
    -        self.get_tx(txid, true)?
    -            .and_then(|t| t.transaction)
    -            .map_or_else(default, |t| Ok(Some(t)))
    +        self.get_tx(txid, true)?
    +            .and_then(|t| t.transaction)
    +            .map_or_else(default, |t| Ok(Some(t)))
         }
     
    -    fn get_previous_output(&self, outpoint: &OutPoint) -> Result<Option<TxOut>, Error> {
    -        self.get_raw_tx(&outpoint.txid)?
    -            .map(|previous_tx| {
    -                if outpoint.vout as usize >= previous_tx.output.len() {
    -                    Err(Error::InvalidOutpoint(*outpoint))
    -                } else {
    -                    Ok(previous_tx.output[outpoint.vout as usize].clone())
    +    fn get_previous_output(&self, outpoint: &OutPoint) -> Result<Option<TxOut>, Error> {
    +        self.get_raw_tx(&outpoint.txid)?
    +            .map(|previous_tx| {
    +                if outpoint.vout as usize >= previous_tx.output.len() {
    +                    Err(Error::InvalidOutpoint(*outpoint))
    +                } else {
    +                    Ok(previous_tx.output[outpoint.vout as usize].clone())
                     }
                 })
    -            .transpose()
    +            .transpose()
         }
     }
     
    -impl<T: Database> DatabaseUtils for T {}
    +impl<T: Database> DatabaseUtils for T {}
     
    -#[cfg(test)]
    -pub mod test {
    -    use std::str::FromStr;
    +#[cfg(test)]
    +pub mod test {
    +    use std::str::FromStr;
     
    -    use bitcoin::consensus::encode::deserialize;
    -    use bitcoin::consensus::serialize;
    -    use bitcoin::hashes::hex::*;
    -    use bitcoin::*;
    +    use bitcoin::consensus::encode::deserialize;
    +    use bitcoin::consensus::serialize;
    +    use bitcoin::hashes::hex::*;
    +    use bitcoin::*;
     
    -    use super::*;
    +    use super::*;
     
    -    pub fn test_script_pubkey<D: Database>(mut db: D) {
    -        let script = Script::from(
    -            Vec::<u8>::from_hex("76a91402306a7c23f3e8010de41e9e591348bb83f11daa88ac").unwrap(),
    +    pub fn test_script_pubkey<D: Database>(mut db: D) {
    +        let script = Script::from(
    +            Vec::<u8>::from_hex("76a91402306a7c23f3e8010de41e9e591348bb83f11daa88ac").unwrap(),
             );
    -        let path = 42;
    -        let keychain = KeychainKind::External;
    +        let path = 42;
    +        let keychain = KeychainKind::External;
     
    -        db.set_script_pubkey(&script, keychain, path).unwrap();
    +        db.set_script_pubkey(&script, keychain, path).unwrap();
     
             assert_eq!(
    -            db.get_script_pubkey_from_path(keychain, path).unwrap(),
    -            Some(script.clone())
    +            db.get_script_pubkey_from_path(keychain, path).unwrap(),
    +            Some(script.clone())
             );
             assert_eq!(
    -            db.get_path_from_script_pubkey(&script).unwrap(),
    -            Some((keychain, path))
    +            db.get_path_from_script_pubkey(&script).unwrap(),
    +            Some((keychain, path))
             );
         }
     
    -    pub fn test_batch_script_pubkey<D: BatchDatabase>(mut db: D) {
    -        let mut batch = db.begin_batch();
    +    pub fn test_batch_script_pubkey<D: BatchDatabase>(mut db: D) {
    +        let mut batch = db.begin_batch();
     
    -        let script = Script::from(
    -            Vec::<u8>::from_hex("76a91402306a7c23f3e8010de41e9e591348bb83f11daa88ac").unwrap(),
    +        let script = Script::from(
    +            Vec::<u8>::from_hex("76a91402306a7c23f3e8010de41e9e591348bb83f11daa88ac").unwrap(),
             );
    -        let path = 42;
    -        let keychain = KeychainKind::External;
    +        let path = 42;
    +        let keychain = KeychainKind::External;
     
    -        batch.set_script_pubkey(&script, keychain, path).unwrap();
    +        batch.set_script_pubkey(&script, keychain, path).unwrap();
     
             assert_eq!(
    -            db.get_script_pubkey_from_path(keychain, path).unwrap(),
    -            None
    -        );
    -        assert_eq!(db.get_path_from_script_pubkey(&script).unwrap(), None);
    +            db.get_script_pubkey_from_path(keychain, path).unwrap(),
    +            None
    +        );
    +        assert_eq!(db.get_path_from_script_pubkey(&script).unwrap(), None);
     
    -        db.commit_batch(batch).unwrap();
    +        db.commit_batch(batch).unwrap();
     
             assert_eq!(
    -            db.get_script_pubkey_from_path(keychain, path).unwrap(),
    -            Some(script.clone())
    +            db.get_script_pubkey_from_path(keychain, path).unwrap(),
    +            Some(script.clone())
             );
             assert_eq!(
    -            db.get_path_from_script_pubkey(&script).unwrap(),
    -            Some((keychain, path))
    +            db.get_path_from_script_pubkey(&script).unwrap(),
    +            Some((keychain, path))
             );
         }
     
    -    pub fn test_iter_script_pubkey<D: Database>(mut db: D) {
    -        let script = Script::from(
    -            Vec::<u8>::from_hex("76a91402306a7c23f3e8010de41e9e591348bb83f11daa88ac").unwrap(),
    +    pub fn test_iter_script_pubkey<D: Database>(mut db: D) {
    +        let script = Script::from(
    +            Vec::<u8>::from_hex("76a91402306a7c23f3e8010de41e9e591348bb83f11daa88ac").unwrap(),
             );
    -        let path = 42;
    -        let keychain = KeychainKind::External;
    +        let path = 42;
    +        let keychain = KeychainKind::External;
     
    -        db.set_script_pubkey(&script, keychain, path).unwrap();
    +        db.set_script_pubkey(&script, keychain, path).unwrap();
     
    -        assert_eq!(db.iter_script_pubkeys(None).unwrap().len(), 1);
    +        assert_eq!(db.iter_script_pubkeys(None).unwrap().len(), 1);
         }
     
    -    pub fn test_del_script_pubkey<D: Database>(mut db: D) {
    -        let script = Script::from(
    -            Vec::<u8>::from_hex("76a91402306a7c23f3e8010de41e9e591348bb83f11daa88ac").unwrap(),
    +    pub fn test_del_script_pubkey<D: Database>(mut db: D) {
    +        let script = Script::from(
    +            Vec::<u8>::from_hex("76a91402306a7c23f3e8010de41e9e591348bb83f11daa88ac").unwrap(),
             );
    -        let path = 42;
    -        let keychain = KeychainKind::External;
    +        let path = 42;
    +        let keychain = KeychainKind::External;
     
    -        db.set_script_pubkey(&script, keychain, path).unwrap();
    -        assert_eq!(db.iter_script_pubkeys(None).unwrap().len(), 1);
    +        db.set_script_pubkey(&script, keychain, path).unwrap();
    +        assert_eq!(db.iter_script_pubkeys(None).unwrap().len(), 1);
     
    -        db.del_script_pubkey_from_path(keychain, path).unwrap();
    -        assert_eq!(db.iter_script_pubkeys(None).unwrap().len(), 0);
    +        db.del_script_pubkey_from_path(keychain, path).unwrap();
    +        assert_eq!(db.iter_script_pubkeys(None).unwrap().len(), 0);
         }
     
    -    pub fn test_utxo<D: Database>(mut db: D) {
    -        let outpoint = OutPoint::from_str(
    +    pub fn test_utxo<D: Database>(mut db: D) {
    +        let outpoint = OutPoint::from_str(
                 "5df6e0e2761359d30a8275058e299fcc0381534545f55cf43e41983f5d4c9456:0",
             )
    -        .unwrap();
    -        let script = Script::from(
    -            Vec::<u8>::from_hex("76a91402306a7c23f3e8010de41e9e591348bb83f11daa88ac").unwrap(),
    +        .unwrap();
    +        let script = Script::from(
    +            Vec::<u8>::from_hex("76a91402306a7c23f3e8010de41e9e591348bb83f11daa88ac").unwrap(),
             );
    -        let txout = TxOut {
    -            value: 133742,
    -            script_pubkey: script,
    +        let txout = TxOut {
    +            value: 133742,
    +            script_pubkey: script,
             };
    -        let utxo = LocalUtxo {
    -            txout,
    -            outpoint,
    -            keychain: KeychainKind::External,
    -            is_spent: true,
    +        let utxo = LocalUtxo {
    +            txout,
    +            outpoint,
    +            keychain: KeychainKind::External,
    +            is_spent: true,
             };
     
    -        db.set_utxo(&utxo).unwrap();
    -        db.set_utxo(&utxo).unwrap();
    -        assert_eq!(db.iter_utxos().unwrap().len(), 1);
    -        assert_eq!(db.get_utxo(&outpoint).unwrap(), Some(utxo));
    +        db.set_utxo(&utxo).unwrap();
    +        db.set_utxo(&utxo).unwrap();
    +        assert_eq!(db.iter_utxos().unwrap().len(), 1);
    +        assert_eq!(db.get_utxo(&outpoint).unwrap(), Some(utxo));
         }
     
    -    pub fn test_raw_tx<D: Database>(mut db: D) {
    -        let hex_tx = Vec::<u8>::from_hex("02000000000101f58c18a90d7a76b30c7e47d4e817adfdd79a6a589a615ef36e360f913adce2cd0000000000feffffff0210270000000000001600145c9a1816d38db5cbdd4b067b689dc19eb7d930e2cf70aa2b080000001600140f48b63160043047f4f60f7f8f551f80458f693f024730440220413f42b7bc979945489a38f5221e5527d4b8e3aa63eae2099e01945896ad6c10022024ceec492d685c31d8adb64e935a06933877c5ae0e21f32efe029850914c5bad012102361caae96f0e9f3a453d354bb37a5c3244422fb22819bf0166c0647a38de39f21fca2300").unwrap();
    -        let mut tx: Transaction = deserialize(&hex_tx).unwrap();
    +    pub fn test_raw_tx<D: Database>(mut db: D) {
    +        let hex_tx = Vec::<u8>::from_hex("02000000000101f58c18a90d7a76b30c7e47d4e817adfdd79a6a589a615ef36e360f913adce2cd0000000000feffffff0210270000000000001600145c9a1816d38db5cbdd4b067b689dc19eb7d930e2cf70aa2b080000001600140f48b63160043047f4f60f7f8f551f80458f693f024730440220413f42b7bc979945489a38f5221e5527d4b8e3aa63eae2099e01945896ad6c10022024ceec492d685c31d8adb64e935a06933877c5ae0e21f32efe029850914c5bad012102361caae96f0e9f3a453d354bb37a5c3244422fb22819bf0166c0647a38de39f21fca2300").unwrap();
    +        let mut tx: Transaction = deserialize(&hex_tx).unwrap();
     
    -        db.set_raw_tx(&tx).unwrap();
    +        db.set_raw_tx(&tx).unwrap();
     
    -        let txid = tx.txid();
    +        let txid = tx.txid();
     
    -        assert_eq!(db.get_raw_tx(&txid).unwrap(), Some(tx.clone()));
    +        assert_eq!(db.get_raw_tx(&txid).unwrap(), Some(tx.clone()));
     
    -        // mutate transaction's witnesses
    -        for tx_in in tx.input.iter_mut() {
    -            tx_in.witness = Witness::new();
    +        // mutate transaction's witnesses
    +        for tx_in in tx.input.iter_mut() {
    +            tx_in.witness = Witness::new();
             }
     
    -        let updated_hex_tx = serialize(&tx);
    +        let updated_hex_tx = serialize(&tx);
     
    -        // verify that mutation was successful
    -        assert_ne!(hex_tx, updated_hex_tx);
    +        // verify that mutation was successful
    +        assert_ne!(hex_tx, updated_hex_tx);
     
    -        db.set_raw_tx(&tx).unwrap();
    +        db.set_raw_tx(&tx).unwrap();
     
    -        let txid = tx.txid();
    +        let txid = tx.txid();
     
    -        assert_eq!(db.get_raw_tx(&txid).unwrap(), Some(tx));
    +        assert_eq!(db.get_raw_tx(&txid).unwrap(), Some(tx));
         }
     
    -    pub fn test_tx<D: Database>(mut db: D) {
    -        let hex_tx = Vec::<u8>::from_hex("0100000001a15d57094aa7a21a28cb20b59aab8fc7d1149a3bdbcddba9c622e4f5f6a99ece010000006c493046022100f93bb0e7d8db7bd46e40132d1f8242026e045f03a0efe71bbb8e3f475e970d790221009337cd7f1f929f00cc6ff01f03729b069a7c21b59b1736ddfee5db5946c5da8c0121033b9b137ee87d5a812d6f506efdd37f0affa7ffc310711c06c7f3e097c9447c52ffffffff0100e1f505000000001976a9140389035a9225b3839e2bbf32d826a1e222031fd888ac00000000").unwrap();
    -        let tx: Transaction = deserialize(&hex_tx).unwrap();
    -        let txid = tx.txid();
    -        let mut tx_details = TransactionDetails {
    -            transaction: Some(tx),
    -            txid,
    -            received: 1337,
    -            sent: 420420,
    -            fee: Some(140),
    -            confirmation_time: Some(BlockTime {
    -                timestamp: 123456,
    -                height: 1000,
    +    pub fn test_tx<D: Database>(mut db: D) {
    +        let hex_tx = Vec::<u8>::from_hex("0100000001a15d57094aa7a21a28cb20b59aab8fc7d1149a3bdbcddba9c622e4f5f6a99ece010000006c493046022100f93bb0e7d8db7bd46e40132d1f8242026e045f03a0efe71bbb8e3f475e970d790221009337cd7f1f929f00cc6ff01f03729b069a7c21b59b1736ddfee5db5946c5da8c0121033b9b137ee87d5a812d6f506efdd37f0affa7ffc310711c06c7f3e097c9447c52ffffffff0100e1f505000000001976a9140389035a9225b3839e2bbf32d826a1e222031fd888ac00000000").unwrap();
    +        let tx: Transaction = deserialize(&hex_tx).unwrap();
    +        let txid = tx.txid();
    +        let mut tx_details = TransactionDetails {
    +            transaction: Some(tx),
    +            txid,
    +            received: 1337,
    +            sent: 420420,
    +            fee: Some(140),
    +            confirmation_time: Some(BlockTime {
    +                timestamp: 123456,
    +                height: 1000,
                 }),
             };
     
    -        db.set_tx(&tx_details).unwrap();
    +        db.set_tx(&tx_details).unwrap();
     
    -        // get with raw tx too
    -        assert_eq!(
    -            db.get_tx(&tx_details.txid, true).unwrap(),
    -            Some(tx_details.clone())
    +        // get with raw tx too
    +        assert_eq!(
    +            db.get_tx(&tx_details.txid, true).unwrap(),
    +            Some(tx_details.clone())
             );
    -        // get only raw_tx
    -        assert_eq!(
    -            db.get_raw_tx(&tx_details.txid).unwrap(),
    -            tx_details.transaction
    +        // get only raw_tx
    +        assert_eq!(
    +            db.get_raw_tx(&tx_details.txid).unwrap(),
    +            tx_details.transaction
             );
     
    -        // now get without raw_tx
    -        tx_details.transaction = None;
    +        // now get without raw_tx
    +        tx_details.transaction = None;
             assert_eq!(
    -            db.get_tx(&tx_details.txid, false).unwrap(),
    -            Some(tx_details)
    +            db.get_tx(&tx_details.txid, false).unwrap(),
    +            Some(tx_details)
             );
         }
     
    -    pub fn test_list_transaction<D: Database>(mut db: D) {
    -        let hex_tx = Vec::<u8>::from_hex("0100000001a15d57094aa7a21a28cb20b59aab8fc7d1149a3bdbcddba9c622e4f5f6a99ece010000006c493046022100f93bb0e7d8db7bd46e40132d1f8242026e045f03a0efe71bbb8e3f475e970d790221009337cd7f1f929f00cc6ff01f03729b069a7c21b59b1736ddfee5db5946c5da8c0121033b9b137ee87d5a812d6f506efdd37f0affa7ffc310711c06c7f3e097c9447c52ffffffff0100e1f505000000001976a9140389035a9225b3839e2bbf32d826a1e222031fd888ac00000000").unwrap();
    -        let tx: Transaction = deserialize(&hex_tx).unwrap();
    -        let txid = tx.txid();
    -        let mut tx_details = TransactionDetails {
    -            transaction: Some(tx),
    -            txid,
    -            received: 1337,
    -            sent: 420420,
    -            fee: Some(140),
    -            confirmation_time: Some(BlockTime {
    -                timestamp: 123456,
    -                height: 1000,
    +    pub fn test_list_transaction<D: Database>(mut db: D) {
    +        let hex_tx = Vec::<u8>::from_hex("0100000001a15d57094aa7a21a28cb20b59aab8fc7d1149a3bdbcddba9c622e4f5f6a99ece010000006c493046022100f93bb0e7d8db7bd46e40132d1f8242026e045f03a0efe71bbb8e3f475e970d790221009337cd7f1f929f00cc6ff01f03729b069a7c21b59b1736ddfee5db5946c5da8c0121033b9b137ee87d5a812d6f506efdd37f0affa7ffc310711c06c7f3e097c9447c52ffffffff0100e1f505000000001976a9140389035a9225b3839e2bbf32d826a1e222031fd888ac00000000").unwrap();
    +        let tx: Transaction = deserialize(&hex_tx).unwrap();
    +        let txid = tx.txid();
    +        let mut tx_details = TransactionDetails {
    +            transaction: Some(tx),
    +            txid,
    +            received: 1337,
    +            sent: 420420,
    +            fee: Some(140),
    +            confirmation_time: Some(BlockTime {
    +                timestamp: 123456,
    +                height: 1000,
                 }),
             };
     
    -        db.set_tx(&tx_details).unwrap();
    +        db.set_tx(&tx_details).unwrap();
     
    -        // get raw tx
    -        assert_eq!(db.iter_txs(true).unwrap(), vec![tx_details.clone()]);
    +        // get raw tx
    +        assert_eq!(db.iter_txs(true).unwrap(), vec![tx_details.clone()]);
     
    -        // now get without raw tx
    -        tx_details.transaction = None;
    +        // now get without raw tx
    +        tx_details.transaction = None;
     
    -        // get not raw tx
    -        assert_eq!(db.iter_txs(false).unwrap(), vec![tx_details.clone()]);
    +        // get not raw tx
    +        assert_eq!(db.iter_txs(false).unwrap(), vec![tx_details.clone()]);
         }
     
    -    pub fn test_last_index<D: Database>(mut db: D) {
    -        db.set_last_index(KeychainKind::External, 1337).unwrap();
    +    pub fn test_last_index<D: Database>(mut db: D) {
    +        db.set_last_index(KeychainKind::External, 1337).unwrap();
     
             assert_eq!(
    -            db.get_last_index(KeychainKind::External).unwrap(),
    +            db.get_last_index(KeychainKind::External).unwrap(),
                 Some(1337)
             );
    -        assert_eq!(db.get_last_index(KeychainKind::Internal).unwrap(), None);
    +        assert_eq!(db.get_last_index(KeychainKind::Internal).unwrap(), None);
     
    -        let res = db.increment_last_index(KeychainKind::External).unwrap();
    -        assert_eq!(res, 1338);
    -        let res = db.increment_last_index(KeychainKind::Internal).unwrap();
    -        assert_eq!(res, 0);
    +        let res = db.increment_last_index(KeychainKind::External).unwrap();
    +        assert_eq!(res, 1338);
    +        let res = db.increment_last_index(KeychainKind::Internal).unwrap();
    +        assert_eq!(res, 0);
     
             assert_eq!(
    -            db.get_last_index(KeychainKind::External).unwrap(),
    +            db.get_last_index(KeychainKind::External).unwrap(),
                 Some(1338)
             );
    -        assert_eq!(db.get_last_index(KeychainKind::Internal).unwrap(), Some(0));
    +        assert_eq!(db.get_last_index(KeychainKind::Internal).unwrap(), Some(0));
         }
     
    -    pub fn test_sync_time<D: Database>(mut db: D) {
    -        assert!(db.get_sync_time().unwrap().is_none());
    +    pub fn test_sync_time<D: Database>(mut db: D) {
    +        assert!(db.get_sync_time().unwrap().is_none());
     
    -        db.set_sync_time(SyncTime {
    -            block_time: BlockTime {
    -                height: 100,
    -                timestamp: 1000,
    +        db.set_sync_time(SyncTime {
    +            block_time: BlockTime {
    +                height: 100,
    +                timestamp: 1000,
                 },
             })
    -        .unwrap();
    +        .unwrap();
     
    -        let extracted = db.get_sync_time().unwrap();
    -        assert!(extracted.is_some());
    -        assert_eq!(extracted.as_ref().unwrap().block_time.height, 100);
    -        assert_eq!(extracted.as_ref().unwrap().block_time.timestamp, 1000);
    +        let extracted = db.get_sync_time().unwrap();
    +        assert!(extracted.is_some());
    +        assert_eq!(extracted.as_ref().unwrap().block_time.height, 100);
    +        assert_eq!(extracted.as_ref().unwrap().block_time.timestamp, 1000);
     
    -        db.del_sync_time().unwrap();
    -        assert!(db.get_sync_time().unwrap().is_none());
    +        db.del_sync_time().unwrap();
    +        assert!(db.get_sync_time().unwrap().is_none());
         }
     
    -    pub fn test_iter_raw_txs<D: Database>(mut db: D) {
    -        let txs = db.iter_raw_txs().unwrap();
    -        assert!(txs.is_empty());
    +    pub fn test_iter_raw_txs<D: Database>(mut db: D) {
    +        let txs = db.iter_raw_txs().unwrap();
    +        assert!(txs.is_empty());
     
    -        let hex_tx = Vec::<u8>::from_hex("0100000001a15d57094aa7a21a28cb20b59aab8fc7d1149a3bdbcddba9c622e4f5f6a99ece010000006c493046022100f93bb0e7d8db7bd46e40132d1f8242026e045f03a0efe71bbb8e3f475e970d790221009337cd7f1f929f00cc6ff01f03729b069a7c21b59b1736ddfee5db5946c5da8c0121033b9b137ee87d5a812d6f506efdd37f0affa7ffc310711c06c7f3e097c9447c52ffffffff0100e1f505000000001976a9140389035a9225b3839e2bbf32d826a1e222031fd888ac00000000").unwrap();
    -        let first_tx: Transaction = deserialize(&hex_tx).unwrap();
    +        let hex_tx = Vec::<u8>::from_hex("0100000001a15d57094aa7a21a28cb20b59aab8fc7d1149a3bdbcddba9c622e4f5f6a99ece010000006c493046022100f93bb0e7d8db7bd46e40132d1f8242026e045f03a0efe71bbb8e3f475e970d790221009337cd7f1f929f00cc6ff01f03729b069a7c21b59b1736ddfee5db5946c5da8c0121033b9b137ee87d5a812d6f506efdd37f0affa7ffc310711c06c7f3e097c9447c52ffffffff0100e1f505000000001976a9140389035a9225b3839e2bbf32d826a1e222031fd888ac00000000").unwrap();
    +        let first_tx: Transaction = deserialize(&hex_tx).unwrap();
     
    -        let hex_tx = Vec::<u8>::from_hex("02000000000101f58c18a90d7a76b30c7e47d4e817adfdd79a6a589a615ef36e360f913adce2cd0000000000feffffff0210270000000000001600145c9a1816d38db5cbdd4b067b689dc19eb7d930e2cf70aa2b080000001600140f48b63160043047f4f60f7f8f551f80458f693f024730440220413f42b7bc979945489a38f5221e5527d4b8e3aa63eae2099e01945896ad6c10022024ceec492d685c31d8adb64e935a06933877c5ae0e21f32efe029850914c5bad012102361caae96f0e9f3a453d354bb37a5c3244422fb22819bf0166c0647a38de39f21fca2300").unwrap();
    -        let second_tx: Transaction = deserialize(&hex_tx).unwrap();
    +        let hex_tx = Vec::<u8>::from_hex("02000000000101f58c18a90d7a76b30c7e47d4e817adfdd79a6a589a615ef36e360f913adce2cd0000000000feffffff0210270000000000001600145c9a1816d38db5cbdd4b067b689dc19eb7d930e2cf70aa2b080000001600140f48b63160043047f4f60f7f8f551f80458f693f024730440220413f42b7bc979945489a38f5221e5527d4b8e3aa63eae2099e01945896ad6c10022024ceec492d685c31d8adb64e935a06933877c5ae0e21f32efe029850914c5bad012102361caae96f0e9f3a453d354bb37a5c3244422fb22819bf0166c0647a38de39f21fca2300").unwrap();
    +        let second_tx: Transaction = deserialize(&hex_tx).unwrap();
     
    -        db.set_raw_tx(&first_tx).unwrap();
    -        db.set_raw_tx(&second_tx).unwrap();
    +        db.set_raw_tx(&first_tx).unwrap();
    +        db.set_raw_tx(&second_tx).unwrap();
     
    -        let txs = db.iter_raw_txs().unwrap();
    +        let txs = db.iter_raw_txs().unwrap();
     
    -        assert!(txs.contains(&first_tx));
    -        assert!(txs.contains(&second_tx));
    -        assert_eq!(txs.len(), 2);
    +        assert!(txs.contains(&first_tx));
    +        assert!(txs.contains(&second_tx));
    +        assert_eq!(txs.len(), 2);
         }
     
    -    pub fn test_del_path_from_script_pubkey<D: Database>(mut db: D) {
    -        let keychain = KeychainKind::External;
    +    pub fn test_del_path_from_script_pubkey<D: Database>(mut db: D) {
    +        let keychain = KeychainKind::External;
     
    -        let script = Script::from(
    -            Vec::<u8>::from_hex("76a91402306a7c23f3e8010de41e9e591348bb83f11daa88ac").unwrap(),
    +        let script = Script::from(
    +            Vec::<u8>::from_hex("76a91402306a7c23f3e8010de41e9e591348bb83f11daa88ac").unwrap(),
             );
    -        let path = 42;
    +        let path = 42;
     
    -        let res = db.del_path_from_script_pubkey(&script).unwrap();
    +        let res = db.del_path_from_script_pubkey(&script).unwrap();
     
    -        assert!(res.is_none());
    +        assert!(res.is_none());
     
    -        let _res = db.set_script_pubkey(&script, keychain, path);
    -        let (chain, child) = db.del_path_from_script_pubkey(&script).unwrap().unwrap();
    +        let _res = db.set_script_pubkey(&script, keychain, path);
    +        let (chain, child) = db.del_path_from_script_pubkey(&script).unwrap().unwrap();
     
    -        assert_eq!(chain, keychain);
    -        assert_eq!(child, path);
    +        assert_eq!(chain, keychain);
    +        assert_eq!(child, path);
     
    -        let res = db.get_path_from_script_pubkey(&script).unwrap();
    -        assert!(res.is_none());
    +        let res = db.get_path_from_script_pubkey(&script).unwrap();
    +        assert!(res.is_none());
         }
     
    -    pub fn test_iter_script_pubkeys<D: Database>(mut db: D) {
    -        let keychain = KeychainKind::External;
    -        let scripts = db.iter_script_pubkeys(Some(keychain)).unwrap();
    -        assert!(scripts.is_empty());
    +    pub fn test_iter_script_pubkeys<D: Database>(mut db: D) {
    +        let keychain = KeychainKind::External;
    +        let scripts = db.iter_script_pubkeys(Some(keychain)).unwrap();
    +        assert!(scripts.is_empty());
     
    -        let first_script = Script::from(
    -            Vec::<u8>::from_hex("76a91402306a7c23f3e8010de41e9e591348bb83f11daa88ac").unwrap(),
    +        let first_script = Script::from(
    +            Vec::<u8>::from_hex("76a91402306a7c23f3e8010de41e9e591348bb83f11daa88ac").unwrap(),
             );
    -        let path = 42;
    +        let path = 42;
     
    -        db.set_script_pubkey(&first_script, keychain, path).unwrap();
    +        db.set_script_pubkey(&first_script, keychain, path).unwrap();
     
    -        let second_script = Script::from(
    -            Vec::<u8>::from_hex("00145c9a1816d38db5cbdd4b067b689dc19eb7d930e2").unwrap(),
    +        let second_script = Script::from(
    +            Vec::<u8>::from_hex("00145c9a1816d38db5cbdd4b067b689dc19eb7d930e2").unwrap(),
             );
    -        let path = 57;
    +        let path = 57;
     
    -        db.set_script_pubkey(&second_script, keychain, path)
    -            .unwrap();
    -        let scripts = db.iter_script_pubkeys(Some(keychain)).unwrap();
    +        db.set_script_pubkey(&second_script, keychain, path)
    +            .unwrap();
    +        let scripts = db.iter_script_pubkeys(Some(keychain)).unwrap();
     
    -        assert!(scripts.contains(&first_script));
    -        assert!(scripts.contains(&second_script));
    -        assert_eq!(scripts.len(), 2);
    +        assert!(scripts.contains(&first_script));
    +        assert!(scripts.contains(&second_script));
    +        assert_eq!(scripts.len(), 2);
         }
     
    -    pub fn test_del_utxo<D: Database>(mut db: D) {
    -        let outpoint = OutPoint::from_str(
    +    pub fn test_del_utxo<D: Database>(mut db: D) {
    +        let outpoint = OutPoint::from_str(
                 "5df6e0e2761359d30a8275058e299fcc0381534545f55cf43e41983f5d4c9456:0",
             )
    -        .unwrap();
    -        let script = Script::from(
    -            Vec::<u8>::from_hex("76a91402306a7c23f3e8010de41e9e591348bb83f11daa88ac").unwrap(),
    +        .unwrap();
    +        let script = Script::from(
    +            Vec::<u8>::from_hex("76a91402306a7c23f3e8010de41e9e591348bb83f11daa88ac").unwrap(),
             );
    -        let txout = TxOut {
    -            value: 133742,
    -            script_pubkey: script,
    +        let txout = TxOut {
    +            value: 133742,
    +            script_pubkey: script,
             };
    -        let utxo = LocalUtxo {
    -            txout,
    -            outpoint,
    -            keychain: KeychainKind::External,
    -            is_spent: true,
    +        let utxo = LocalUtxo {
    +            txout,
    +            outpoint,
    +            keychain: KeychainKind::External,
    +            is_spent: true,
             };
     
    -        let res = db.del_utxo(&outpoint).unwrap();
    -        assert!(res.is_none());
    +        let res = db.del_utxo(&outpoint).unwrap();
    +        assert!(res.is_none());
     
    -        db.set_utxo(&utxo).unwrap();
    +        db.set_utxo(&utxo).unwrap();
     
    -        let res = db.del_utxo(&outpoint).unwrap();
    +        let res = db.del_utxo(&outpoint).unwrap();
     
    -        assert_eq!(res.unwrap(), utxo);
    +        assert_eq!(res.unwrap(), utxo);
     
    -        let res = db.get_utxo(&outpoint).unwrap();
    -        assert!(res.is_none());
    +        let res = db.get_utxo(&outpoint).unwrap();
    +        assert!(res.is_none());
         }
     
    -    pub fn test_del_raw_tx<D: Database>(mut db: D) {
    -        let hex_tx = Vec::<u8>::from_hex("02000000000101f58c18a90d7a76b30c7e47d4e817adfdd79a6a589a615ef36e360f913adce2cd0000000000feffffff0210270000000000001600145c9a1816d38db5cbdd4b067b689dc19eb7d930e2cf70aa2b080000001600140f48b63160043047f4f60f7f8f551f80458f693f024730440220413f42b7bc979945489a38f5221e5527d4b8e3aa63eae2099e01945896ad6c10022024ceec492d685c31d8adb64e935a06933877c5ae0e21f32efe029850914c5bad012102361caae96f0e9f3a453d354bb37a5c3244422fb22819bf0166c0647a38de39f21fca2300").unwrap();
    -        let tx: Transaction = deserialize(&hex_tx).unwrap();
    +    pub fn test_del_raw_tx<D: Database>(mut db: D) {
    +        let hex_tx = Vec::<u8>::from_hex("02000000000101f58c18a90d7a76b30c7e47d4e817adfdd79a6a589a615ef36e360f913adce2cd0000000000feffffff0210270000000000001600145c9a1816d38db5cbdd4b067b689dc19eb7d930e2cf70aa2b080000001600140f48b63160043047f4f60f7f8f551f80458f693f024730440220413f42b7bc979945489a38f5221e5527d4b8e3aa63eae2099e01945896ad6c10022024ceec492d685c31d8adb64e935a06933877c5ae0e21f32efe029850914c5bad012102361caae96f0e9f3a453d354bb37a5c3244422fb22819bf0166c0647a38de39f21fca2300").unwrap();
    +        let tx: Transaction = deserialize(&hex_tx).unwrap();
     
    -        let res = db.del_raw_tx(&tx.txid()).unwrap();
    +        let res = db.del_raw_tx(&tx.txid()).unwrap();
     
    -        assert!(res.is_none());
    +        assert!(res.is_none());
     
    -        db.set_raw_tx(&tx).unwrap();
    +        db.set_raw_tx(&tx).unwrap();
     
    -        let res = db.del_raw_tx(&tx.txid()).unwrap();
    +        let res = db.del_raw_tx(&tx.txid()).unwrap();
     
    -        assert_eq!(res.unwrap(), tx);
    +        assert_eq!(res.unwrap(), tx);
     
    -        let res = db.get_raw_tx(&tx.txid()).unwrap();
    -        assert!(res.is_none());
    +        let res = db.get_raw_tx(&tx.txid()).unwrap();
    +        assert!(res.is_none());
         }
     
    -    pub fn test_del_tx<D: Database>(mut db: D) {
    -        let hex_tx = Vec::<u8>::from_hex("0100000001a15d57094aa7a21a28cb20b59aab8fc7d1149a3bdbcddba9c622e4f5f6a99ece010000006c493046022100f93bb0e7d8db7bd46e40132d1f8242026e045f03a0efe71bbb8e3f475e970d790221009337cd7f1f929f00cc6ff01f03729b069a7c21b59b1736ddfee5db5946c5da8c0121033b9b137ee87d5a812d6f506efdd37f0affa7ffc310711c06c7f3e097c9447c52ffffffff0100e1f505000000001976a9140389035a9225b3839e2bbf32d826a1e222031fd888ac00000000").unwrap();
    -        let tx: Transaction = deserialize(&hex_tx).unwrap();
    -        let txid = tx.txid();
    -        let mut tx_details = TransactionDetails {
    -            transaction: Some(tx.clone()),
    -            txid,
    -            received: 1337,
    -            sent: 420420,
    -            fee: Some(140),
    -            confirmation_time: Some(BlockTime {
    -                timestamp: 123456,
    -                height: 1000,
    +    pub fn test_del_tx<D: Database>(mut db: D) {
    +        let hex_tx = Vec::<u8>::from_hex("0100000001a15d57094aa7a21a28cb20b59aab8fc7d1149a3bdbcddba9c622e4f5f6a99ece010000006c493046022100f93bb0e7d8db7bd46e40132d1f8242026e045f03a0efe71bbb8e3f475e970d790221009337cd7f1f929f00cc6ff01f03729b069a7c21b59b1736ddfee5db5946c5da8c0121033b9b137ee87d5a812d6f506efdd37f0affa7ffc310711c06c7f3e097c9447c52ffffffff0100e1f505000000001976a9140389035a9225b3839e2bbf32d826a1e222031fd888ac00000000").unwrap();
    +        let tx: Transaction = deserialize(&hex_tx).unwrap();
    +        let txid = tx.txid();
    +        let mut tx_details = TransactionDetails {
    +            transaction: Some(tx.clone()),
    +            txid,
    +            received: 1337,
    +            sent: 420420,
    +            fee: Some(140),
    +            confirmation_time: Some(BlockTime {
    +                timestamp: 123456,
    +                height: 1000,
                 }),
             };
     
    -        let res = db.del_tx(&tx.txid(), true).unwrap();
    +        let res = db.del_tx(&tx.txid(), true).unwrap();
     
    -        assert!(res.is_none());
    +        assert!(res.is_none());
     
    -        db.set_tx(&tx_details).unwrap();
    +        db.set_tx(&tx_details).unwrap();
     
    -        let res = db.del_tx(&tx.txid(), false).unwrap();
    -        tx_details.transaction = None;
    -        assert_eq!(res.unwrap(), tx_details);
    +        let res = db.del_tx(&tx.txid(), false).unwrap();
    +        tx_details.transaction = None;
    +        assert_eq!(res.unwrap(), tx_details);
     
    -        let res = db.get_tx(&tx.txid(), true).unwrap();
    -        assert!(res.is_none());
    +        let res = db.get_tx(&tx.txid(), true).unwrap();
    +        assert!(res.is_none());
     
    -        let res = db.get_raw_tx(&tx.txid()).unwrap();
    -        assert_eq!(res.unwrap(), tx);
    +        let res = db.get_raw_tx(&tx.txid()).unwrap();
    +        assert_eq!(res.unwrap(), tx);
     
    -        db.set_tx(&tx_details).unwrap();
    -        let res = db.del_tx(&tx.txid(), true).unwrap();
    -        tx_details.transaction = Some(tx.clone());
    -        assert_eq!(res.unwrap(), tx_details);
    +        db.set_tx(&tx_details).unwrap();
    +        let res = db.del_tx(&tx.txid(), true).unwrap();
    +        tx_details.transaction = Some(tx.clone());
    +        assert_eq!(res.unwrap(), tx_details);
     
    -        let res = db.get_tx(&tx.txid(), true).unwrap();
    -        assert!(res.is_none());
    +        let res = db.get_tx(&tx.txid(), true).unwrap();
    +        assert!(res.is_none());
     
    -        let res = db.get_raw_tx(&tx.txid()).unwrap();
    -        assert!(res.is_none());
    +        let res = db.get_raw_tx(&tx.txid()).unwrap();
    +        assert!(res.is_none());
         }
     
    -    pub fn test_del_last_index<D: Database>(mut db: D) {
    -        let keychain = KeychainKind::External;
    +    pub fn test_del_last_index<D: Database>(mut db: D) {
    +        let keychain = KeychainKind::External;
     
    -        let _res = db.increment_last_index(keychain);
    +        let _res = db.increment_last_index(keychain);
     
    -        let res = db.get_last_index(keychain).unwrap().unwrap();
    +        let res = db.get_last_index(keychain).unwrap().unwrap();
     
    -        assert_eq!(res, 0);
    +        assert_eq!(res, 0);
     
    -        let _res = db.increment_last_index(keychain);
    +        let _res = db.increment_last_index(keychain);
     
    -        let res = db.del_last_index(keychain).unwrap().unwrap();
    +        let res = db.del_last_index(keychain).unwrap().unwrap();
     
    -        assert_eq!(res, 1);
    +        assert_eq!(res, 1);
     
    -        let res = db.get_last_index(keychain).unwrap();
    -        assert!(res.is_none());
    +        let res = db.get_last_index(keychain).unwrap();
    +        assert!(res.is_none());
         }
     
    -    pub fn test_check_descriptor_checksum<D: Database>(mut db: D) {
    -        // insert checksum associated to keychain
    -        let checksum = "1cead456".as_bytes();
    -        let keychain = KeychainKind::External;
    -        let _res = db.check_descriptor_checksum(keychain, checksum);
    -
    -        // check if `check_descriptor_checksum` throws
    -        // `Error::ChecksumMismatch` error if the
    -        // function is passed a checksum that does
    -        // not match the one initially inserted
    -        let checksum = "1cead454".as_bytes();
    -        let keychain = KeychainKind::External;
    -        let res = db.check_descriptor_checksum(keychain, checksum);
    -
    -        assert!(res.is_err());
    +    pub fn test_check_descriptor_checksum<D: Database>(mut db: D) {
    +        // insert checksum associated to keychain
    +        let checksum = "1cead456".as_bytes();
    +        let keychain = KeychainKind::External;
    +        let _res = db.check_descriptor_checksum(keychain, checksum);
    +
    +        // check if `check_descriptor_checksum` throws
    +        // `Error::ChecksumMismatch` error if the
    +        // function is passed a checksum that does
    +        // not match the one initially inserted
    +        let checksum = "1cead454".as_bytes();
    +        let keychain = KeychainKind::External;
    +        let res = db.check_descriptor_checksum(keychain, checksum);
    +
    +        assert!(res.is_err());
         }
     
    -    // TODO: more tests...
    -}
    +    // TODO: more tests...
    +}
     
    -
    - \ No newline at end of file +
    \ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/src/bdk/database/sqlite.rs.html b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/src/bdk/database/sqlite.rs.html index 528c87d8d8..89ada38c57 100644 --- a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/src/bdk/database/sqlite.rs.html +++ b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/src/bdk/database/sqlite.rs.html @@ -1,1183 +1,1177 @@ -sqlite.rs - source - -
       1
    -   2
    -   3
    -   4
    -   5
    -   6
    -   7
    -   8
    -   9
    -  10
    -  11
    -  12
    -  13
    -  14
    -  15
    -  16
    -  17
    -  18
    -  19
    -  20
    -  21
    -  22
    -  23
    -  24
    -  25
    -  26
    -  27
    -  28
    -  29
    -  30
    -  31
    -  32
    -  33
    -  34
    -  35
    -  36
    -  37
    -  38
    -  39
    -  40
    -  41
    -  42
    -  43
    -  44
    -  45
    -  46
    -  47
    -  48
    -  49
    -  50
    -  51
    -  52
    -  53
    -  54
    -  55
    -  56
    -  57
    -  58
    -  59
    -  60
    -  61
    -  62
    -  63
    -  64
    -  65
    -  66
    -  67
    -  68
    -  69
    -  70
    -  71
    -  72
    -  73
    -  74
    -  75
    -  76
    -  77
    -  78
    -  79
    -  80
    -  81
    -  82
    -  83
    -  84
    -  85
    -  86
    -  87
    -  88
    -  89
    -  90
    -  91
    -  92
    -  93
    -  94
    -  95
    -  96
    -  97
    -  98
    -  99
    - 100
    - 101
    - 102
    - 103
    - 104
    - 105
    - 106
    - 107
    - 108
    - 109
    - 110
    - 111
    - 112
    - 113
    - 114
    - 115
    - 116
    - 117
    - 118
    - 119
    - 120
    - 121
    - 122
    - 123
    - 124
    - 125
    - 126
    - 127
    - 128
    - 129
    - 130
    - 131
    - 132
    - 133
    - 134
    - 135
    - 136
    - 137
    - 138
    - 139
    - 140
    - 141
    - 142
    - 143
    - 144
    - 145
    - 146
    - 147
    - 148
    - 149
    - 150
    - 151
    - 152
    - 153
    - 154
    - 155
    - 156
    - 157
    - 158
    - 159
    - 160
    - 161
    - 162
    - 163
    - 164
    - 165
    - 166
    - 167
    - 168
    - 169
    - 170
    - 171
    - 172
    - 173
    - 174
    - 175
    - 176
    - 177
    - 178
    - 179
    - 180
    - 181
    - 182
    - 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
    - 245
    - 246
    - 247
    - 248
    - 249
    - 250
    - 251
    - 252
    - 253
    - 254
    - 255
    - 256
    - 257
    - 258
    - 259
    - 260
    - 261
    - 262
    - 263
    - 264
    - 265
    - 266
    - 267
    - 268
    - 269
    - 270
    - 271
    - 272
    - 273
    - 274
    - 275
    - 276
    - 277
    - 278
    - 279
    - 280
    - 281
    - 282
    - 283
    - 284
    - 285
    - 286
    - 287
    - 288
    - 289
    - 290
    - 291
    - 292
    - 293
    - 294
    - 295
    - 296
    - 297
    - 298
    - 299
    - 300
    - 301
    - 302
    - 303
    - 304
    - 305
    - 306
    - 307
    - 308
    - 309
    - 310
    - 311
    - 312
    - 313
    - 314
    - 315
    - 316
    - 317
    - 318
    - 319
    - 320
    - 321
    - 322
    - 323
    - 324
    - 325
    - 326
    - 327
    - 328
    - 329
    - 330
    - 331
    - 332
    - 333
    - 334
    - 335
    - 336
    - 337
    - 338
    - 339
    - 340
    - 341
    - 342
    - 343
    - 344
    - 345
    - 346
    - 347
    - 348
    - 349
    - 350
    - 351
    - 352
    - 353
    - 354
    - 355
    - 356
    - 357
    - 358
    - 359
    - 360
    - 361
    - 362
    - 363
    - 364
    - 365
    - 366
    - 367
    - 368
    - 369
    - 370
    - 371
    - 372
    - 373
    - 374
    - 375
    - 376
    - 377
    - 378
    - 379
    - 380
    - 381
    - 382
    - 383
    - 384
    - 385
    - 386
    - 387
    - 388
    - 389
    - 390
    - 391
    - 392
    - 393
    - 394
    - 395
    - 396
    - 397
    - 398
    - 399
    - 400
    - 401
    - 402
    - 403
    - 404
    - 405
    - 406
    - 407
    - 408
    - 409
    - 410
    - 411
    - 412
    - 413
    - 414
    - 415
    - 416
    - 417
    - 418
    - 419
    - 420
    - 421
    - 422
    - 423
    - 424
    - 425
    - 426
    - 427
    - 428
    - 429
    - 430
    - 431
    - 432
    - 433
    - 434
    - 435
    - 436
    - 437
    - 438
    - 439
    - 440
    - 441
    - 442
    - 443
    - 444
    - 445
    - 446
    - 447
    - 448
    - 449
    - 450
    - 451
    - 452
    - 453
    - 454
    - 455
    - 456
    - 457
    - 458
    - 459
    - 460
    - 461
    - 462
    - 463
    - 464
    - 465
    - 466
    - 467
    - 468
    - 469
    - 470
    - 471
    - 472
    - 473
    - 474
    - 475
    - 476
    - 477
    - 478
    - 479
    - 480
    - 481
    - 482
    - 483
    - 484
    - 485
    - 486
    - 487
    - 488
    - 489
    - 490
    - 491
    - 492
    - 493
    - 494
    - 495
    - 496
    - 497
    - 498
    - 499
    - 500
    - 501
    - 502
    - 503
    - 504
    - 505
    - 506
    - 507
    - 508
    - 509
    - 510
    - 511
    - 512
    - 513
    - 514
    - 515
    - 516
    - 517
    - 518
    - 519
    - 520
    - 521
    - 522
    - 523
    - 524
    - 525
    - 526
    - 527
    - 528
    - 529
    - 530
    - 531
    - 532
    - 533
    - 534
    - 535
    - 536
    - 537
    - 538
    - 539
    - 540
    - 541
    - 542
    - 543
    - 544
    - 545
    - 546
    - 547
    - 548
    - 549
    - 550
    - 551
    - 552
    - 553
    - 554
    - 555
    - 556
    - 557
    - 558
    - 559
    - 560
    - 561
    - 562
    - 563
    - 564
    - 565
    - 566
    - 567
    - 568
    - 569
    - 570
    - 571
    - 572
    - 573
    - 574
    - 575
    - 576
    - 577
    - 578
    - 579
    - 580
    - 581
    - 582
    - 583
    - 584
    - 585
    - 586
    - 587
    - 588
    - 589
    - 590
    - 591
    - 592
    - 593
    - 594
    - 595
    - 596
    - 597
    - 598
    - 599
    - 600
    - 601
    - 602
    - 603
    - 604
    - 605
    - 606
    - 607
    - 608
    - 609
    - 610
    - 611
    - 612
    - 613
    - 614
    - 615
    - 616
    - 617
    - 618
    - 619
    - 620
    - 621
    - 622
    - 623
    - 624
    - 625
    - 626
    - 627
    - 628
    - 629
    - 630
    - 631
    - 632
    - 633
    - 634
    - 635
    - 636
    - 637
    - 638
    - 639
    - 640
    - 641
    - 642
    - 643
    - 644
    - 645
    - 646
    - 647
    - 648
    - 649
    - 650
    - 651
    - 652
    - 653
    - 654
    - 655
    - 656
    - 657
    - 658
    - 659
    - 660
    - 661
    - 662
    - 663
    - 664
    - 665
    - 666
    - 667
    - 668
    - 669
    - 670
    - 671
    - 672
    - 673
    - 674
    - 675
    - 676
    - 677
    - 678
    - 679
    - 680
    - 681
    - 682
    - 683
    - 684
    - 685
    - 686
    - 687
    - 688
    - 689
    - 690
    - 691
    - 692
    - 693
    - 694
    - 695
    - 696
    - 697
    - 698
    - 699
    - 700
    - 701
    - 702
    - 703
    - 704
    - 705
    - 706
    - 707
    - 708
    - 709
    - 710
    - 711
    - 712
    - 713
    - 714
    - 715
    - 716
    - 717
    - 718
    - 719
    - 720
    - 721
    - 722
    - 723
    - 724
    - 725
    - 726
    - 727
    - 728
    - 729
    - 730
    - 731
    - 732
    - 733
    - 734
    - 735
    - 736
    - 737
    - 738
    - 739
    - 740
    - 741
    - 742
    - 743
    - 744
    - 745
    - 746
    - 747
    - 748
    - 749
    - 750
    - 751
    - 752
    - 753
    - 754
    - 755
    - 756
    - 757
    - 758
    - 759
    - 760
    - 761
    - 762
    - 763
    - 764
    - 765
    - 766
    - 767
    - 768
    - 769
    - 770
    - 771
    - 772
    - 773
    - 774
    - 775
    - 776
    - 777
    - 778
    - 779
    - 780
    - 781
    - 782
    - 783
    - 784
    - 785
    - 786
    - 787
    - 788
    - 789
    - 790
    - 791
    - 792
    - 793
    - 794
    - 795
    - 796
    - 797
    - 798
    - 799
    - 800
    - 801
    - 802
    - 803
    - 804
    - 805
    - 806
    - 807
    - 808
    - 809
    - 810
    - 811
    - 812
    - 813
    - 814
    - 815
    - 816
    - 817
    - 818
    - 819
    - 820
    - 821
    - 822
    - 823
    - 824
    - 825
    - 826
    - 827
    - 828
    - 829
    - 830
    - 831
    - 832
    - 833
    - 834
    - 835
    - 836
    - 837
    - 838
    - 839
    - 840
    - 841
    - 842
    - 843
    - 844
    - 845
    - 846
    - 847
    - 848
    - 849
    - 850
    - 851
    - 852
    - 853
    - 854
    - 855
    - 856
    - 857
    - 858
    - 859
    - 860
    - 861
    - 862
    - 863
    - 864
    - 865
    - 866
    - 867
    - 868
    - 869
    - 870
    - 871
    - 872
    - 873
    - 874
    - 875
    - 876
    - 877
    - 878
    - 879
    - 880
    - 881
    - 882
    - 883
    - 884
    - 885
    - 886
    - 887
    - 888
    - 889
    - 890
    - 891
    - 892
    - 893
    - 894
    - 895
    - 896
    - 897
    - 898
    - 899
    - 900
    - 901
    - 902
    - 903
    - 904
    - 905
    - 906
    - 907
    - 908
    - 909
    - 910
    - 911
    - 912
    - 913
    - 914
    - 915
    - 916
    - 917
    - 918
    - 919
    - 920
    - 921
    - 922
    - 923
    - 924
    - 925
    - 926
    - 927
    - 928
    - 929
    - 930
    - 931
    - 932
    - 933
    - 934
    - 935
    - 936
    - 937
    - 938
    - 939
    - 940
    - 941
    - 942
    - 943
    - 944
    - 945
    - 946
    - 947
    - 948
    - 949
    - 950
    - 951
    - 952
    - 953
    - 954
    - 955
    - 956
    - 957
    - 958
    - 959
    - 960
    - 961
    - 962
    - 963
    - 964
    - 965
    - 966
    - 967
    - 968
    - 969
    - 970
    - 971
    - 972
    - 973
    - 974
    - 975
    - 976
    - 977
    - 978
    - 979
    - 980
    - 981
    - 982
    - 983
    - 984
    - 985
    - 986
    - 987
    - 988
    - 989
    - 990
    - 991
    - 992
    - 993
    - 994
    - 995
    - 996
    - 997
    - 998
    - 999
    -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
    -1028
    -1029
    -1030
    -1031
    -1032
    -1033
    -1034
    -1035
    -1036
    -1037
    -1038
    -1039
    -1040
    -1041
    -1042
    -1043
    -1044
    -1045
    -1046
    -1047
    -1048
    -1049
    -1050
    -1051
    -1052
    -1053
    -1054
    -1055
    -1056
    -1057
    -1058
    -1059
    -1060
    -1061
    -1062
    -1063
    -1064
    -1065
    -1066
    -1067
    -1068
    -1069
    -1070
    -1071
    -1072
    -1073
    -1074
    -1075
    -1076
    -1077
    -1078
    -1079
    -1080
    -1081
    -1082
    -1083
    -1084
    -1085
    -1086
    -1087
    -1088
    -1089
    -1090
    -1091
    -1092
    -1093
    -1094
    -1095
    -1096
    -1097
    -1098
    -1099
    -1100
    -1101
    -1102
    -1103
    -1104
    -1105
    -1106
    -1107
    -1108
    -1109
    -1110
    -1111
    -1112
    -1113
    -1114
    -1115
    -1116
    -1117
    -1118
    -1119
    -1120
    -1121
    -1122
    -1123
    -1124
    -1125
    -1126
    -1127
    -1128
    -1129
    -1130
    -1131
    -1132
    -1133
    -1134
    -1135
    -1136
    -1137
    -1138
    -1139
    -1140
    -1141
    -1142
    -1143
    -1144
    -1145
    -1146
    -1147
    -1148
    -1149
    -
    // Bitcoin Dev Kit
    -// Written in 2020 by Alekos Filini <alekos.filini@gmail.com>
    -//
    -// Copyright (c) 2020-2021 Bitcoin Dev Kit Developers
    -//
    -// This file is licensed under the Apache License, Version 2.0 <LICENSE-APACHE
    -// or http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
    -// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your option.
    -// You may not use this file except in accordance with one or both of these
    -// licenses.
    -use std::path::Path;
    -use std::path::PathBuf;
    -
    -use bitcoin::consensus::encode::{deserialize, serialize};
    -use bitcoin::hash_types::Txid;
    -use bitcoin::{OutPoint, Script, Transaction, TxOut};
    -
    -use crate::database::{BatchDatabase, BatchOperations, Database, SyncTime};
    -use crate::error::Error;
    -use crate::types::*;
    -
    -use rusqlite::{named_params, Connection};
    -
    -static MIGRATIONS: &[&str] = &[
    +sqlite.rs - source
    1
    +2
    +3
    +4
    +5
    +6
    +7
    +8
    +9
    +10
    +11
    +12
    +13
    +14
    +15
    +16
    +17
    +18
    +19
    +20
    +21
    +22
    +23
    +24
    +25
    +26
    +27
    +28
    +29
    +30
    +31
    +32
    +33
    +34
    +35
    +36
    +37
    +38
    +39
    +40
    +41
    +42
    +43
    +44
    +45
    +46
    +47
    +48
    +49
    +50
    +51
    +52
    +53
    +54
    +55
    +56
    +57
    +58
    +59
    +60
    +61
    +62
    +63
    +64
    +65
    +66
    +67
    +68
    +69
    +70
    +71
    +72
    +73
    +74
    +75
    +76
    +77
    +78
    +79
    +80
    +81
    +82
    +83
    +84
    +85
    +86
    +87
    +88
    +89
    +90
    +91
    +92
    +93
    +94
    +95
    +96
    +97
    +98
    +99
    +100
    +101
    +102
    +103
    +104
    +105
    +106
    +107
    +108
    +109
    +110
    +111
    +112
    +113
    +114
    +115
    +116
    +117
    +118
    +119
    +120
    +121
    +122
    +123
    +124
    +125
    +126
    +127
    +128
    +129
    +130
    +131
    +132
    +133
    +134
    +135
    +136
    +137
    +138
    +139
    +140
    +141
    +142
    +143
    +144
    +145
    +146
    +147
    +148
    +149
    +150
    +151
    +152
    +153
    +154
    +155
    +156
    +157
    +158
    +159
    +160
    +161
    +162
    +163
    +164
    +165
    +166
    +167
    +168
    +169
    +170
    +171
    +172
    +173
    +174
    +175
    +176
    +177
    +178
    +179
    +180
    +181
    +182
    +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
    +245
    +246
    +247
    +248
    +249
    +250
    +251
    +252
    +253
    +254
    +255
    +256
    +257
    +258
    +259
    +260
    +261
    +262
    +263
    +264
    +265
    +266
    +267
    +268
    +269
    +270
    +271
    +272
    +273
    +274
    +275
    +276
    +277
    +278
    +279
    +280
    +281
    +282
    +283
    +284
    +285
    +286
    +287
    +288
    +289
    +290
    +291
    +292
    +293
    +294
    +295
    +296
    +297
    +298
    +299
    +300
    +301
    +302
    +303
    +304
    +305
    +306
    +307
    +308
    +309
    +310
    +311
    +312
    +313
    +314
    +315
    +316
    +317
    +318
    +319
    +320
    +321
    +322
    +323
    +324
    +325
    +326
    +327
    +328
    +329
    +330
    +331
    +332
    +333
    +334
    +335
    +336
    +337
    +338
    +339
    +340
    +341
    +342
    +343
    +344
    +345
    +346
    +347
    +348
    +349
    +350
    +351
    +352
    +353
    +354
    +355
    +356
    +357
    +358
    +359
    +360
    +361
    +362
    +363
    +364
    +365
    +366
    +367
    +368
    +369
    +370
    +371
    +372
    +373
    +374
    +375
    +376
    +377
    +378
    +379
    +380
    +381
    +382
    +383
    +384
    +385
    +386
    +387
    +388
    +389
    +390
    +391
    +392
    +393
    +394
    +395
    +396
    +397
    +398
    +399
    +400
    +401
    +402
    +403
    +404
    +405
    +406
    +407
    +408
    +409
    +410
    +411
    +412
    +413
    +414
    +415
    +416
    +417
    +418
    +419
    +420
    +421
    +422
    +423
    +424
    +425
    +426
    +427
    +428
    +429
    +430
    +431
    +432
    +433
    +434
    +435
    +436
    +437
    +438
    +439
    +440
    +441
    +442
    +443
    +444
    +445
    +446
    +447
    +448
    +449
    +450
    +451
    +452
    +453
    +454
    +455
    +456
    +457
    +458
    +459
    +460
    +461
    +462
    +463
    +464
    +465
    +466
    +467
    +468
    +469
    +470
    +471
    +472
    +473
    +474
    +475
    +476
    +477
    +478
    +479
    +480
    +481
    +482
    +483
    +484
    +485
    +486
    +487
    +488
    +489
    +490
    +491
    +492
    +493
    +494
    +495
    +496
    +497
    +498
    +499
    +500
    +501
    +502
    +503
    +504
    +505
    +506
    +507
    +508
    +509
    +510
    +511
    +512
    +513
    +514
    +515
    +516
    +517
    +518
    +519
    +520
    +521
    +522
    +523
    +524
    +525
    +526
    +527
    +528
    +529
    +530
    +531
    +532
    +533
    +534
    +535
    +536
    +537
    +538
    +539
    +540
    +541
    +542
    +543
    +544
    +545
    +546
    +547
    +548
    +549
    +550
    +551
    +552
    +553
    +554
    +555
    +556
    +557
    +558
    +559
    +560
    +561
    +562
    +563
    +564
    +565
    +566
    +567
    +568
    +569
    +570
    +571
    +572
    +573
    +574
    +575
    +576
    +577
    +578
    +579
    +580
    +581
    +582
    +583
    +584
    +585
    +586
    +587
    +588
    +589
    +590
    +591
    +592
    +593
    +594
    +595
    +596
    +597
    +598
    +599
    +600
    +601
    +602
    +603
    +604
    +605
    +606
    +607
    +608
    +609
    +610
    +611
    +612
    +613
    +614
    +615
    +616
    +617
    +618
    +619
    +620
    +621
    +622
    +623
    +624
    +625
    +626
    +627
    +628
    +629
    +630
    +631
    +632
    +633
    +634
    +635
    +636
    +637
    +638
    +639
    +640
    +641
    +642
    +643
    +644
    +645
    +646
    +647
    +648
    +649
    +650
    +651
    +652
    +653
    +654
    +655
    +656
    +657
    +658
    +659
    +660
    +661
    +662
    +663
    +664
    +665
    +666
    +667
    +668
    +669
    +670
    +671
    +672
    +673
    +674
    +675
    +676
    +677
    +678
    +679
    +680
    +681
    +682
    +683
    +684
    +685
    +686
    +687
    +688
    +689
    +690
    +691
    +692
    +693
    +694
    +695
    +696
    +697
    +698
    +699
    +700
    +701
    +702
    +703
    +704
    +705
    +706
    +707
    +708
    +709
    +710
    +711
    +712
    +713
    +714
    +715
    +716
    +717
    +718
    +719
    +720
    +721
    +722
    +723
    +724
    +725
    +726
    +727
    +728
    +729
    +730
    +731
    +732
    +733
    +734
    +735
    +736
    +737
    +738
    +739
    +740
    +741
    +742
    +743
    +744
    +745
    +746
    +747
    +748
    +749
    +750
    +751
    +752
    +753
    +754
    +755
    +756
    +757
    +758
    +759
    +760
    +761
    +762
    +763
    +764
    +765
    +766
    +767
    +768
    +769
    +770
    +771
    +772
    +773
    +774
    +775
    +776
    +777
    +778
    +779
    +780
    +781
    +782
    +783
    +784
    +785
    +786
    +787
    +788
    +789
    +790
    +791
    +792
    +793
    +794
    +795
    +796
    +797
    +798
    +799
    +800
    +801
    +802
    +803
    +804
    +805
    +806
    +807
    +808
    +809
    +810
    +811
    +812
    +813
    +814
    +815
    +816
    +817
    +818
    +819
    +820
    +821
    +822
    +823
    +824
    +825
    +826
    +827
    +828
    +829
    +830
    +831
    +832
    +833
    +834
    +835
    +836
    +837
    +838
    +839
    +840
    +841
    +842
    +843
    +844
    +845
    +846
    +847
    +848
    +849
    +850
    +851
    +852
    +853
    +854
    +855
    +856
    +857
    +858
    +859
    +860
    +861
    +862
    +863
    +864
    +865
    +866
    +867
    +868
    +869
    +870
    +871
    +872
    +873
    +874
    +875
    +876
    +877
    +878
    +879
    +880
    +881
    +882
    +883
    +884
    +885
    +886
    +887
    +888
    +889
    +890
    +891
    +892
    +893
    +894
    +895
    +896
    +897
    +898
    +899
    +900
    +901
    +902
    +903
    +904
    +905
    +906
    +907
    +908
    +909
    +910
    +911
    +912
    +913
    +914
    +915
    +916
    +917
    +918
    +919
    +920
    +921
    +922
    +923
    +924
    +925
    +926
    +927
    +928
    +929
    +930
    +931
    +932
    +933
    +934
    +935
    +936
    +937
    +938
    +939
    +940
    +941
    +942
    +943
    +944
    +945
    +946
    +947
    +948
    +949
    +950
    +951
    +952
    +953
    +954
    +955
    +956
    +957
    +958
    +959
    +960
    +961
    +962
    +963
    +964
    +965
    +966
    +967
    +968
    +969
    +970
    +971
    +972
    +973
    +974
    +975
    +976
    +977
    +978
    +979
    +980
    +981
    +982
    +983
    +984
    +985
    +986
    +987
    +988
    +989
    +990
    +991
    +992
    +993
    +994
    +995
    +996
    +997
    +998
    +999
    +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
    +1028
    +1029
    +1030
    +1031
    +1032
    +1033
    +1034
    +1035
    +1036
    +1037
    +1038
    +1039
    +1040
    +1041
    +1042
    +1043
    +1044
    +1045
    +1046
    +1047
    +1048
    +1049
    +1050
    +1051
    +1052
    +1053
    +1054
    +1055
    +1056
    +1057
    +1058
    +1059
    +1060
    +1061
    +1062
    +1063
    +1064
    +1065
    +1066
    +1067
    +1068
    +1069
    +1070
    +1071
    +1072
    +1073
    +1074
    +1075
    +1076
    +1077
    +1078
    +1079
    +1080
    +1081
    +1082
    +1083
    +1084
    +1085
    +1086
    +1087
    +1088
    +1089
    +1090
    +1091
    +1092
    +1093
    +1094
    +1095
    +1096
    +1097
    +1098
    +1099
    +1100
    +1101
    +1102
    +1103
    +1104
    +1105
    +1106
    +1107
    +1108
    +1109
    +1110
    +1111
    +1112
    +1113
    +1114
    +1115
    +1116
    +1117
    +1118
    +1119
    +1120
    +1121
    +1122
    +1123
    +1124
    +1125
    +1126
    +1127
    +1128
    +1129
    +1130
    +1131
    +1132
    +1133
    +1134
    +1135
    +1136
    +1137
    +1138
    +1139
    +1140
    +1141
    +1142
    +1143
    +1144
    +1145
    +1146
    +1147
    +1148
    +1149
    +
    // Bitcoin Dev Kit
    +// Written in 2020 by Alekos Filini <alekos.filini@gmail.com>
    +//
    +// Copyright (c) 2020-2021 Bitcoin Dev Kit Developers
    +//
    +// This file is licensed under the Apache License, Version 2.0 <LICENSE-APACHE
    +// or http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
    +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your option.
    +// You may not use this file except in accordance with one or both of these
    +// licenses.
    +use std::path::Path;
    +use std::path::PathBuf;
    +
    +use bitcoin::consensus::encode::{deserialize, serialize};
    +use bitcoin::hash_types::Txid;
    +use bitcoin::{OutPoint, Script, Transaction, TxOut};
    +
    +use crate::database::{BatchDatabase, BatchOperations, Database, SyncTime};
    +use crate::error::Error;
    +use crate::types::*;
    +
    +use rusqlite::{named_params, Connection};
    +
    +static MIGRATIONS: &[&str] = &[
         "CREATE TABLE version (version INTEGER)",
         "INSERT INTO version VALUES (1)",
         "CREATE TABLE script_pubkeys (keychain TEXT, child INTEGER, script BLOB);",
    @@ -1199,8 +1193,8 @@
         "INSERT INTO transaction_details SELECT txid, timestamp, received, sent, fee, height FROM transaction_details_old;",
         "DROP TABLE transaction_details_old;",
         "ALTER TABLE utxos ADD COLUMN is_spent;",
    -    // drop all data due to possible inconsistencies with duplicate utxos, re-sync required
    -    "DELETE FROM checksums;",
    +    // drop all data due to possible inconsistencies with duplicate utxos, re-sync required
    +    "DELETE FROM checksums;",
         "DELETE FROM last_derivation_indices;",
         "DELETE FROM script_pubkeys;",
         "DELETE FROM sync_time;",
    @@ -1214,8 +1208,8 @@
         "INSERT INTO utxos SELECT value, keychain, vout, txid, script, is_spent FROM utxos_old;",
         "DROP TABLE utxos_old;",
         "CREATE UNIQUE INDEX idx_utxos_txid_vout ON utxos(txid, vout);",
    -    // Fix issue https://github.com/bitcoindevkit/bdk/issues/801: drop duplicated script_pubkeys
    -    "ALTER TABLE script_pubkeys RENAME TO script_pubkeys_old;",
    +    // Fix issue https://github.com/bitcoindevkit/bdk/issues/801: drop duplicated script_pubkeys
    +    "ALTER TABLE script_pubkeys RENAME TO script_pubkeys_old;",
         "DROP INDEX idx_keychain_child;",
         "DROP INDEX idx_script;",
         "CREATE TABLE script_pubkeys (keychain TEXT, child INTEGER, script BLOB);",
    @@ -1223,1086 +1217,1085 @@
         "CREATE INDEX idx_script ON script_pubkeys(script);",
         "CREATE UNIQUE INDEX idx_script_pks_unique ON script_pubkeys(keychain, child);",
         "INSERT OR REPLACE INTO script_pubkeys SELECT keychain, child, script FROM script_pubkeys_old;",
    -    "DROP TABLE script_pubkeys_old;"
    -];
    -
    -/// Sqlite database stored on filesystem
    -///
    -/// This is a permanent storage solution for devices and platforms that provide a filesystem.
    -/// [`crate::database`]
    -#[derive(Debug)]
    -pub struct SqliteDatabase {
    -    /// Path on the local filesystem to store the sqlite file
    -    pub path: PathBuf,
    -    /// A rusqlite connection object to the sqlite database
    -    pub connection: Connection,
    +    "DROP TABLE script_pubkeys_old;"
    +];
    +
    +/// Sqlite database stored on filesystem
    +///
    +/// This is a permanent storage solution for devices and platforms that provide a filesystem.
    +/// [`crate::database`]
    +#[derive(Debug)]
    +pub struct SqliteDatabase {
    +    /// Path on the local filesystem to store the sqlite file
    +    pub path: PathBuf,
    +    /// A rusqlite connection object to the sqlite database
    +    pub connection: Connection,
     }
     
    -impl SqliteDatabase {
    -    /// Instantiate a new SqliteDatabase instance by creating a connection
    -    /// to the database stored at path
    -    pub fn new<T: AsRef<Path>>(path: T) -> Self {
    -        let connection = get_connection(&path).unwrap();
    -        SqliteDatabase {
    -            path: PathBuf::from(path.as_ref()),
    -            connection,
    +impl SqliteDatabase {
    +    /// Instantiate a new SqliteDatabase instance by creating a connection
    +    /// to the database stored at path
    +    pub fn new<T: AsRef<Path>>(path: T) -> Self {
    +        let connection = get_connection(&path).unwrap();
    +        SqliteDatabase {
    +            path: PathBuf::from(path.as_ref()),
    +            connection,
             }
         }
    -    fn insert_script_pubkey(
    +    fn insert_script_pubkey(
             &self,
    -        keychain: String,
    -        child: u32,
    -        script: &[u8],
    -    ) -> Result<i64, Error> {
    -        let mut statement = self.connection.prepare_cached("INSERT OR REPLACE INTO script_pubkeys (keychain, child, script) VALUES (:keychain, :child, :script)")?;
    -        statement.execute(named_params! {
    -            ":keychain": keychain,
    -            ":child": child,
    -            ":script": script
    +        keychain: String,
    +        child: u32,
    +        script: &[u8],
    +    ) -> Result<i64, Error> {
    +        let mut statement = self.connection.prepare_cached("INSERT OR REPLACE INTO script_pubkeys (keychain, child, script) VALUES (:keychain, :child, :script)")?;
    +        statement.execute(named_params! {
    +            ":keychain": keychain,
    +            ":child": child,
    +            ":script": script
             })?;
     
    -        Ok(self.connection.last_insert_rowid())
    +        Ok(self.connection.last_insert_rowid())
         }
    -    fn insert_utxo(
    +    fn insert_utxo(
             &self,
    -        value: u64,
    -        keychain: String,
    -        vout: u32,
    -        txid: &[u8],
    -        script: &[u8],
    -        is_spent: bool,
    -    ) -> Result<i64, Error> {
    -        let mut statement = self.connection.prepare_cached("INSERT INTO utxos (value, keychain, vout, txid, script, is_spent) VALUES (:value, :keychain, :vout, :txid, :script, :is_spent) ON CONFLICT(txid, vout) DO UPDATE SET value=:value, keychain=:keychain, script=:script, is_spent=:is_spent")?;
    -        statement.execute(named_params! {
    -            ":value": value,
    -            ":keychain": keychain,
    -            ":vout": vout,
    -            ":txid": txid,
    -            ":script": script,
    -            ":is_spent": is_spent,
    +        value: u64,
    +        keychain: String,
    +        vout: u32,
    +        txid: &[u8],
    +        script: &[u8],
    +        is_spent: bool,
    +    ) -> Result<i64, Error> {
    +        let mut statement = self.connection.prepare_cached("INSERT INTO utxos (value, keychain, vout, txid, script, is_spent) VALUES (:value, :keychain, :vout, :txid, :script, :is_spent) ON CONFLICT(txid, vout) DO UPDATE SET value=:value, keychain=:keychain, script=:script, is_spent=:is_spent")?;
    +        statement.execute(named_params! {
    +            ":value": value,
    +            ":keychain": keychain,
    +            ":vout": vout,
    +            ":txid": txid,
    +            ":script": script,
    +            ":is_spent": is_spent,
             })?;
     
    -        Ok(self.connection.last_insert_rowid())
    +        Ok(self.connection.last_insert_rowid())
         }
    -    fn insert_transaction(&self, txid: &[u8], raw_tx: &[u8]) -> Result<i64, Error> {
    -        let mut statement = self
    -            .connection
    -            .prepare_cached("INSERT INTO transactions (txid, raw_tx) VALUES (:txid, :raw_tx)")?;
    -        statement.execute(named_params! {
    -            ":txid": txid,
    -            ":raw_tx": raw_tx,
    +    fn insert_transaction(&self, txid: &[u8], raw_tx: &[u8]) -> Result<i64, Error> {
    +        let mut statement = self
    +            .connection
    +            .prepare_cached("INSERT INTO transactions (txid, raw_tx) VALUES (:txid, :raw_tx)")?;
    +        statement.execute(named_params! {
    +            ":txid": txid,
    +            ":raw_tx": raw_tx,
             })?;
     
    -        Ok(self.connection.last_insert_rowid())
    +        Ok(self.connection.last_insert_rowid())
         }
     
    -    fn update_transaction(&self, txid: &[u8], raw_tx: &[u8]) -> Result<(), Error> {
    -        let mut statement = self
    -            .connection
    -            .prepare_cached("UPDATE transactions SET raw_tx=:raw_tx WHERE txid=:txid")?;
    +    fn update_transaction(&self, txid: &[u8], raw_tx: &[u8]) -> Result<(), Error> {
    +        let mut statement = self
    +            .connection
    +            .prepare_cached("UPDATE transactions SET raw_tx=:raw_tx WHERE txid=:txid")?;
     
    -        statement.execute(named_params! {
    -            ":txid": txid,
    -            ":raw_tx": raw_tx,
    +        statement.execute(named_params! {
    +            ":txid": txid,
    +            ":raw_tx": raw_tx,
             })?;
     
             Ok(())
         }
     
    -    fn insert_transaction_details(&self, transaction: &TransactionDetails) -> Result<i64, Error> {
    -        let (timestamp, height) = match &transaction.confirmation_time {
    -            Some(confirmation_time) => (
    -                Some(confirmation_time.timestamp),
    -                Some(confirmation_time.height),
    +    fn insert_transaction_details(&self, transaction: &TransactionDetails) -> Result<i64, Error> {
    +        let (timestamp, height) = match &transaction.confirmation_time {
    +            Some(confirmation_time) => (
    +                Some(confirmation_time.timestamp),
    +                Some(confirmation_time.height),
                 ),
    -            None => (None, None),
    +            None => (None, None),
             };
     
    -        let txid: &[u8] = &transaction.txid;
    +        let txid: &[u8] = &transaction.txid;
     
    -        let mut statement = self.connection.prepare_cached("INSERT INTO transaction_details (txid, timestamp, received, sent, fee, height) VALUES (:txid, :timestamp, :received, :sent, :fee, :height)")?;
    +        let mut statement = self.connection.prepare_cached("INSERT INTO transaction_details (txid, timestamp, received, sent, fee, height) VALUES (:txid, :timestamp, :received, :sent, :fee, :height)")?;
     
    -        statement.execute(named_params! {
    -            ":txid": txid,
    -            ":timestamp": timestamp,
    -            ":received": transaction.received,
    -            ":sent": transaction.sent,
    -            ":fee": transaction.fee,
    -            ":height": height,
    +        statement.execute(named_params! {
    +            ":txid": txid,
    +            ":timestamp": timestamp,
    +            ":received": transaction.received,
    +            ":sent": transaction.sent,
    +            ":fee": transaction.fee,
    +            ":height": height,
             })?;
     
    -        Ok(self.connection.last_insert_rowid())
    +        Ok(self.connection.last_insert_rowid())
         }
     
    -    fn update_transaction_details(&self, transaction: &TransactionDetails) -> Result<(), Error> {
    -        let (timestamp, height) = match &transaction.confirmation_time {
    -            Some(confirmation_time) => (
    -                Some(confirmation_time.timestamp),
    -                Some(confirmation_time.height),
    +    fn update_transaction_details(&self, transaction: &TransactionDetails) -> Result<(), Error> {
    +        let (timestamp, height) = match &transaction.confirmation_time {
    +            Some(confirmation_time) => (
    +                Some(confirmation_time.timestamp),
    +                Some(confirmation_time.height),
                 ),
    -            None => (None, None),
    +            None => (None, None),
             };
     
    -        let txid: &[u8] = &transaction.txid;
    +        let txid: &[u8] = &transaction.txid;
     
    -        let mut statement = self.connection.prepare_cached("UPDATE transaction_details SET timestamp=:timestamp, received=:received, sent=:sent, fee=:fee, height=:height WHERE txid=:txid")?;
    +        let mut statement = self.connection.prepare_cached("UPDATE transaction_details SET timestamp=:timestamp, received=:received, sent=:sent, fee=:fee, height=:height WHERE txid=:txid")?;
     
    -        statement.execute(named_params! {
    -            ":txid": txid,
    -            ":timestamp": timestamp,
    -            ":received": transaction.received,
    -            ":sent": transaction.sent,
    -            ":fee": transaction.fee,
    -            ":height": height,
    +        statement.execute(named_params! {
    +            ":txid": txid,
    +            ":timestamp": timestamp,
    +            ":received": transaction.received,
    +            ":sent": transaction.sent,
    +            ":fee": transaction.fee,
    +            ":height": height,
             })?;
     
             Ok(())
         }
     
    -    fn insert_last_derivation_index(&self, keychain: String, value: u32) -> Result<i64, Error> {
    -        let mut statement = self.connection.prepare_cached(
    +    fn insert_last_derivation_index(&self, keychain: String, value: u32) -> Result<i64, Error> {
    +        let mut statement = self.connection.prepare_cached(
                 "INSERT INTO last_derivation_indices (keychain, value) VALUES (:keychain, :value)",
             )?;
     
    -        statement.execute(named_params! {
    -            ":keychain": keychain,
    -            ":value": value,
    +        statement.execute(named_params! {
    +            ":keychain": keychain,
    +            ":value": value,
             })?;
     
    -        Ok(self.connection.last_insert_rowid())
    +        Ok(self.connection.last_insert_rowid())
         }
     
    -    fn insert_checksum(&self, keychain: String, checksum: &[u8]) -> Result<i64, Error> {
    -        let mut statement = self.connection.prepare_cached(
    +    fn insert_checksum(&self, keychain: String, checksum: &[u8]) -> Result<i64, Error> {
    +        let mut statement = self.connection.prepare_cached(
                 "INSERT INTO checksums (keychain, checksum) VALUES (:keychain, :checksum)",
             )?;
    -        statement.execute(named_params! {
    -            ":keychain": keychain,
    -            ":checksum": checksum,
    +        statement.execute(named_params! {
    +            ":keychain": keychain,
    +            ":checksum": checksum,
             })?;
     
    -        Ok(self.connection.last_insert_rowid())
    +        Ok(self.connection.last_insert_rowid())
         }
     
    -    fn update_last_derivation_index(&self, keychain: String, value: u32) -> Result<(), Error> {
    -        let mut statement = self.connection.prepare_cached(
    +    fn update_last_derivation_index(&self, keychain: String, value: u32) -> Result<(), Error> {
    +        let mut statement = self.connection.prepare_cached(
                 "INSERT INTO last_derivation_indices (keychain, value) VALUES (:keychain, :value) ON CONFLICT(keychain) DO UPDATE SET value=:value WHERE keychain=:keychain",
             )?;
     
    -        statement.execute(named_params! {
    -            ":keychain": keychain,
    -            ":value": value,
    +        statement.execute(named_params! {
    +            ":keychain": keychain,
    +            ":value": value,
             })?;
     
             Ok(())
         }
     
    -    fn update_sync_time(&self, data: SyncTime) -> Result<i64, Error> {
    -        let mut statement = self.connection.prepare_cached(
    +    fn update_sync_time(&self, data: SyncTime) -> Result<i64, Error> {
    +        let mut statement = self.connection.prepare_cached(
                 "INSERT INTO sync_time (id, height, timestamp) VALUES (0, :height, :timestamp) ON CONFLICT(id) DO UPDATE SET height=:height, timestamp=:timestamp WHERE id = 0",
             )?;
     
    -        statement.execute(named_params! {
    -            ":height": data.block_time.height,
    -            ":timestamp": data.block_time.timestamp,
    +        statement.execute(named_params! {
    +            ":height": data.block_time.height,
    +            ":timestamp": data.block_time.timestamp,
             })?;
     
    -        Ok(self.connection.last_insert_rowid())
    +        Ok(self.connection.last_insert_rowid())
         }
     
    -    fn select_script_pubkeys(&self) -> Result<Vec<Script>, Error> {
    -        let mut statement = self
    -            .connection
    -            .prepare_cached("SELECT script FROM script_pubkeys")?;
    -        let mut scripts: Vec<Script> = vec![];
    -        let mut rows = statement.query([])?;
    -        while let Some(row) = rows.next()? {
    -            let raw_script: Vec<u8> = row.get(0)?;
    -            scripts.push(raw_script.into());
    +    fn select_script_pubkeys(&self) -> Result<Vec<Script>, Error> {
    +        let mut statement = self
    +            .connection
    +            .prepare_cached("SELECT script FROM script_pubkeys")?;
    +        let mut scripts: Vec<Script> = vec![];
    +        let mut rows = statement.query([])?;
    +        while let Some(row) = rows.next()? {
    +            let raw_script: Vec<u8> = row.get(0)?;
    +            scripts.push(raw_script.into());
             }
     
    -        Ok(scripts)
    +        Ok(scripts)
         }
     
    -    fn select_script_pubkeys_by_keychain(&self, keychain: String) -> Result<Vec<Script>, Error> {
    -        let mut statement = self
    -            .connection
    -            .prepare_cached("SELECT script FROM script_pubkeys WHERE keychain=:keychain")?;
    -        let mut scripts: Vec<Script> = vec![];
    -        let mut rows = statement.query(named_params! {":keychain": keychain})?;
    -        while let Some(row) = rows.next()? {
    -            let raw_script: Vec<u8> = row.get(0)?;
    -            scripts.push(raw_script.into());
    +    fn select_script_pubkeys_by_keychain(&self, keychain: String) -> Result<Vec<Script>, Error> {
    +        let mut statement = self
    +            .connection
    +            .prepare_cached("SELECT script FROM script_pubkeys WHERE keychain=:keychain")?;
    +        let mut scripts: Vec<Script> = vec![];
    +        let mut rows = statement.query(named_params! {":keychain": keychain})?;
    +        while let Some(row) = rows.next()? {
    +            let raw_script: Vec<u8> = row.get(0)?;
    +            scripts.push(raw_script.into());
             }
     
    -        Ok(scripts)
    +        Ok(scripts)
         }
     
    -    fn select_script_pubkey_by_path(
    +    fn select_script_pubkey_by_path(
             &self,
    -        keychain: String,
    -        child: u32,
    -    ) -> Result<Option<Script>, Error> {
    -        let mut statement = self.connection.prepare_cached(
    +        keychain: String,
    +        child: u32,
    +    ) -> Result<Option<Script>, Error> {
    +        let mut statement = self.connection.prepare_cached(
                 "SELECT script FROM script_pubkeys WHERE keychain=:keychain AND child=:child",
             )?;
    -        let mut rows = statement.query(named_params! {":keychain": keychain,":child": child})?;
    +        let mut rows = statement.query(named_params! {":keychain": keychain,":child": child})?;
     
    -        match rows.next()? {
    -            Some(row) => {
    -                let script: Vec<u8> = row.get(0)?;
    -                let script: Script = script.into();
    -                Ok(Some(script))
    +        match rows.next()? {
    +            Some(row) => {
    +                let script: Vec<u8> = row.get(0)?;
    +                let script: Script = script.into();
    +                Ok(Some(script))
                 }
    -            None => Ok(None),
    +            None => Ok(None),
             }
         }
     
    -    fn select_script_pubkey_by_script(
    +    fn select_script_pubkey_by_script(
             &self,
    -        script: &[u8],
    -    ) -> Result<Option<(KeychainKind, u32)>, Error> {
    -        let mut statement = self
    -            .connection
    -            .prepare_cached("SELECT keychain, child FROM script_pubkeys WHERE script=:script")?;
    -        let mut rows = statement.query(named_params! {":script": script})?;
    -        match rows.next()? {
    -            Some(row) => {
    -                let keychain: String = row.get(0)?;
    -                let keychain: KeychainKind = serde_json::from_str(&keychain)?;
    -                let child: u32 = row.get(1)?;
    -                Ok(Some((keychain, child)))
    +        script: &[u8],
    +    ) -> Result<Option<(KeychainKind, u32)>, Error> {
    +        let mut statement = self
    +            .connection
    +            .prepare_cached("SELECT keychain, child FROM script_pubkeys WHERE script=:script")?;
    +        let mut rows = statement.query(named_params! {":script": script})?;
    +        match rows.next()? {
    +            Some(row) => {
    +                let keychain: String = row.get(0)?;
    +                let keychain: KeychainKind = serde_json::from_str(&keychain)?;
    +                let child: u32 = row.get(1)?;
    +                Ok(Some((keychain, child)))
                 }
    -            None => Ok(None),
    +            None => Ok(None),
             }
         }
     
    -    fn select_utxos(&self) -> Result<Vec<LocalUtxo>, Error> {
    -        let mut statement = self
    -            .connection
    -            .prepare_cached("SELECT value, keychain, vout, txid, script, is_spent FROM utxos")?;
    -        let mut utxos: Vec<LocalUtxo> = vec![];
    -        let mut rows = statement.query([])?;
    -        while let Some(row) = rows.next()? {
    -            let value = row.get(0)?;
    -            let keychain: String = row.get(1)?;
    -            let vout = row.get(2)?;
    -            let txid: Vec<u8> = row.get(3)?;
    -            let script: Vec<u8> = row.get(4)?;
    -            let is_spent: bool = row.get(5)?;
    -
    -            let keychain: KeychainKind = serde_json::from_str(&keychain)?;
    -
    -            utxos.push(LocalUtxo {
    -                outpoint: OutPoint::new(deserialize(&txid)?, vout),
    -                txout: TxOut {
    -                    value,
    -                    script_pubkey: script.into(),
    +    fn select_utxos(&self) -> Result<Vec<LocalUtxo>, Error> {
    +        let mut statement = self
    +            .connection
    +            .prepare_cached("SELECT value, keychain, vout, txid, script, is_spent FROM utxos")?;
    +        let mut utxos: Vec<LocalUtxo> = vec![];
    +        let mut rows = statement.query([])?;
    +        while let Some(row) = rows.next()? {
    +            let value = row.get(0)?;
    +            let keychain: String = row.get(1)?;
    +            let vout = row.get(2)?;
    +            let txid: Vec<u8> = row.get(3)?;
    +            let script: Vec<u8> = row.get(4)?;
    +            let is_spent: bool = row.get(5)?;
    +
    +            let keychain: KeychainKind = serde_json::from_str(&keychain)?;
    +
    +            utxos.push(LocalUtxo {
    +                outpoint: OutPoint::new(deserialize(&txid)?, vout),
    +                txout: TxOut {
    +                    value,
    +                    script_pubkey: script.into(),
                     },
    -                keychain,
    -                is_spent,
    +                keychain,
    +                is_spent,
                 })
             }
     
    -        Ok(utxos)
    +        Ok(utxos)
         }
     
    -    fn select_utxo_by_outpoint(&self, txid: &[u8], vout: u32) -> Result<Option<LocalUtxo>, Error> {
    -        let mut statement = self.connection.prepare_cached(
    +    fn select_utxo_by_outpoint(&self, txid: &[u8], vout: u32) -> Result<Option<LocalUtxo>, Error> {
    +        let mut statement = self.connection.prepare_cached(
                 "SELECT value, keychain, script, is_spent FROM utxos WHERE txid=:txid AND vout=:vout",
             )?;
    -        let mut rows = statement.query(named_params! {":txid": txid,":vout": vout})?;
    -        match rows.next()? {
    -            Some(row) => {
    -                let value: u64 = row.get(0)?;
    -                let keychain: String = row.get(1)?;
    -                let keychain: KeychainKind = serde_json::from_str(&keychain)?;
    -                let script: Vec<u8> = row.get(2)?;
    -                let script_pubkey: Script = script.into();
    -                let is_spent: bool = row.get(3)?;
    -
    -                Ok(Some(LocalUtxo {
    -                    outpoint: OutPoint::new(deserialize(txid)?, vout),
    -                    txout: TxOut {
    -                        value,
    -                        script_pubkey,
    +        let mut rows = statement.query(named_params! {":txid": txid,":vout": vout})?;
    +        match rows.next()? {
    +            Some(row) => {
    +                let value: u64 = row.get(0)?;
    +                let keychain: String = row.get(1)?;
    +                let keychain: KeychainKind = serde_json::from_str(&keychain)?;
    +                let script: Vec<u8> = row.get(2)?;
    +                let script_pubkey: Script = script.into();
    +                let is_spent: bool = row.get(3)?;
    +
    +                Ok(Some(LocalUtxo {
    +                    outpoint: OutPoint::new(deserialize(txid)?, vout),
    +                    txout: TxOut {
    +                        value,
    +                        script_pubkey,
                         },
    -                    keychain,
    -                    is_spent,
    +                    keychain,
    +                    is_spent,
                     }))
                 }
    -            None => Ok(None),
    +            None => Ok(None),
             }
         }
     
    -    fn select_transactions(&self) -> Result<Vec<Transaction>, Error> {
    -        let mut statement = self
    -            .connection
    -            .prepare_cached("SELECT raw_tx FROM transactions")?;
    -        let mut txs: Vec<Transaction> = vec![];
    -        let mut rows = statement.query([])?;
    -        while let Some(row) = rows.next()? {
    -            let raw_tx: Vec<u8> = row.get(0)?;
    -            let tx: Transaction = deserialize(&raw_tx)?;
    -            txs.push(tx);
    +    fn select_transactions(&self) -> Result<Vec<Transaction>, Error> {
    +        let mut statement = self
    +            .connection
    +            .prepare_cached("SELECT raw_tx FROM transactions")?;
    +        let mut txs: Vec<Transaction> = vec![];
    +        let mut rows = statement.query([])?;
    +        while let Some(row) = rows.next()? {
    +            let raw_tx: Vec<u8> = row.get(0)?;
    +            let tx: Transaction = deserialize(&raw_tx)?;
    +            txs.push(tx);
             }
    -        Ok(txs)
    -    }
    -
    -    fn select_transaction_by_txid(&self, txid: &[u8]) -> Result<Option<Transaction>, Error> {
    -        let mut statement = self
    -            .connection
    -            .prepare_cached("SELECT raw_tx FROM transactions WHERE txid=:txid")?;
    -        let mut rows = statement.query(named_params! {":txid": txid})?;
    -        match rows.next()? {
    -            Some(row) => {
    -                let raw_tx: Vec<u8> = row.get(0)?;
    -                let tx: Transaction = deserialize(&raw_tx)?;
    -                Ok(Some(tx))
    +        Ok(txs)
    +    }
    +
    +    fn select_transaction_by_txid(&self, txid: &[u8]) -> Result<Option<Transaction>, Error> {
    +        let mut statement = self
    +            .connection
    +            .prepare_cached("SELECT raw_tx FROM transactions WHERE txid=:txid")?;
    +        let mut rows = statement.query(named_params! {":txid": txid})?;
    +        match rows.next()? {
    +            Some(row) => {
    +                let raw_tx: Vec<u8> = row.get(0)?;
    +                let tx: Transaction = deserialize(&raw_tx)?;
    +                Ok(Some(tx))
                 }
    -            None => Ok(None),
    +            None => Ok(None),
             }
         }
     
    -    fn select_transaction_details_with_raw(&self) -> Result<Vec<TransactionDetails>, Error> {
    -        let mut statement = self.connection.prepare_cached("SELECT transaction_details.txid, transaction_details.timestamp, transaction_details.received, transaction_details.sent, transaction_details.fee, transaction_details.height, transactions.raw_tx FROM transaction_details, transactions WHERE transaction_details.txid = transactions.txid")?;
    -        let mut transaction_details: Vec<TransactionDetails> = vec![];
    -        let mut rows = statement.query([])?;
    -        while let Some(row) = rows.next()? {
    -            let txid: Vec<u8> = row.get(0)?;
    -            let txid: Txid = deserialize(&txid)?;
    -            let timestamp: Option<u64> = row.get(1)?;
    -            let received: u64 = row.get(2)?;
    -            let sent: u64 = row.get(3)?;
    -            let fee: Option<u64> = row.get(4)?;
    -            let height: Option<u32> = row.get(5)?;
    -            let raw_tx: Option<Vec<u8>> = row.get(6)?;
    -            let tx: Option<Transaction> = match raw_tx {
    -                Some(raw_tx) => {
    -                    let tx: Transaction = deserialize(&raw_tx)?;
    -                    Some(tx)
    +    fn select_transaction_details_with_raw(&self) -> Result<Vec<TransactionDetails>, Error> {
    +        let mut statement = self.connection.prepare_cached("SELECT transaction_details.txid, transaction_details.timestamp, transaction_details.received, transaction_details.sent, transaction_details.fee, transaction_details.height, transactions.raw_tx FROM transaction_details, transactions WHERE transaction_details.txid = transactions.txid")?;
    +        let mut transaction_details: Vec<TransactionDetails> = vec![];
    +        let mut rows = statement.query([])?;
    +        while let Some(row) = rows.next()? {
    +            let txid: Vec<u8> = row.get(0)?;
    +            let txid: Txid = deserialize(&txid)?;
    +            let timestamp: Option<u64> = row.get(1)?;
    +            let received: u64 = row.get(2)?;
    +            let sent: u64 = row.get(3)?;
    +            let fee: Option<u64> = row.get(4)?;
    +            let height: Option<u32> = row.get(5)?;
    +            let raw_tx: Option<Vec<u8>> = row.get(6)?;
    +            let tx: Option<Transaction> = match raw_tx {
    +                Some(raw_tx) => {
    +                    let tx: Transaction = deserialize(&raw_tx)?;
    +                    Some(tx)
                     }
    -                None => None,
    +                None => None,
                 };
     
    -            let confirmation_time = match (height, timestamp) {
    -                (Some(height), Some(timestamp)) => Some(BlockTime { height, timestamp }),
    -                _ => None,
    +            let confirmation_time = match (height, timestamp) {
    +                (Some(height), Some(timestamp)) => Some(BlockTime { height, timestamp }),
    +                _ => None,
                 };
     
    -            transaction_details.push(TransactionDetails {
    -                transaction: tx,
    -                txid,
    -                received,
    -                sent,
    -                fee,
    -                confirmation_time,
    +            transaction_details.push(TransactionDetails {
    +                transaction: tx,
    +                txid,
    +                received,
    +                sent,
    +                fee,
    +                confirmation_time,
                 });
             }
    -        Ok(transaction_details)
    +        Ok(transaction_details)
         }
     
    -    fn select_transaction_details(&self) -> Result<Vec<TransactionDetails>, Error> {
    -        let mut statement = self.connection.prepare_cached(
    +    fn select_transaction_details(&self) -> Result<Vec<TransactionDetails>, Error> {
    +        let mut statement = self.connection.prepare_cached(
                 "SELECT txid, timestamp, received, sent, fee, height FROM transaction_details",
             )?;
    -        let mut transaction_details: Vec<TransactionDetails> = vec![];
    -        let mut rows = statement.query([])?;
    -        while let Some(row) = rows.next()? {
    -            let txid: Vec<u8> = row.get(0)?;
    -            let txid: Txid = deserialize(&txid)?;
    -            let timestamp: Option<u64> = row.get(1)?;
    -            let received: u64 = row.get(2)?;
    -            let sent: u64 = row.get(3)?;
    -            let fee: Option<u64> = row.get(4)?;
    -            let height: Option<u32> = row.get(5)?;
    -
    -            let confirmation_time = match (height, timestamp) {
    -                (Some(height), Some(timestamp)) => Some(BlockTime { height, timestamp }),
    -                _ => None,
    +        let mut transaction_details: Vec<TransactionDetails> = vec![];
    +        let mut rows = statement.query([])?;
    +        while let Some(row) = rows.next()? {
    +            let txid: Vec<u8> = row.get(0)?;
    +            let txid: Txid = deserialize(&txid)?;
    +            let timestamp: Option<u64> = row.get(1)?;
    +            let received: u64 = row.get(2)?;
    +            let sent: u64 = row.get(3)?;
    +            let fee: Option<u64> = row.get(4)?;
    +            let height: Option<u32> = row.get(5)?;
    +
    +            let confirmation_time = match (height, timestamp) {
    +                (Some(height), Some(timestamp)) => Some(BlockTime { height, timestamp }),
    +                _ => None,
                 };
     
    -            transaction_details.push(TransactionDetails {
    -                transaction: None,
    -                txid,
    -                received,
    -                sent,
    -                fee,
    -                confirmation_time,
    +            transaction_details.push(TransactionDetails {
    +                transaction: None,
    +                txid,
    +                received,
    +                sent,
    +                fee,
    +                confirmation_time,
                 });
             }
    -        Ok(transaction_details)
    +        Ok(transaction_details)
         }
     
    -    fn select_transaction_details_by_txid(
    +    fn select_transaction_details_by_txid(
             &self,
    -        txid: &[u8],
    -    ) -> Result<Option<TransactionDetails>, Error> {
    -        let mut statement = self.connection.prepare_cached("SELECT transaction_details.timestamp, transaction_details.received, transaction_details.sent, transaction_details.fee, transaction_details.height, transactions.raw_tx FROM transaction_details, transactions WHERE transaction_details.txid=transactions.txid AND transaction_details.txid=:txid")?;
    -        let mut rows = statement.query(named_params! { ":txid": txid })?;
    -
    -        match rows.next()? {
    -            Some(row) => {
    -                let timestamp: Option<u64> = row.get(0)?;
    -                let received: u64 = row.get(1)?;
    -                let sent: u64 = row.get(2)?;
    -                let fee: Option<u64> = row.get(3)?;
    -                let height: Option<u32> = row.get(4)?;
    -
    -                let raw_tx: Option<Vec<u8>> = row.get(5)?;
    -                let tx: Option<Transaction> = match raw_tx {
    -                    Some(raw_tx) => {
    -                        let tx: Transaction = deserialize(&raw_tx)?;
    -                        Some(tx)
    +        txid: &[u8],
    +    ) -> Result<Option<TransactionDetails>, Error> {
    +        let mut statement = self.connection.prepare_cached("SELECT transaction_details.timestamp, transaction_details.received, transaction_details.sent, transaction_details.fee, transaction_details.height, transactions.raw_tx FROM transaction_details, transactions WHERE transaction_details.txid=transactions.txid AND transaction_details.txid=:txid")?;
    +        let mut rows = statement.query(named_params! { ":txid": txid })?;
    +
    +        match rows.next()? {
    +            Some(row) => {
    +                let timestamp: Option<u64> = row.get(0)?;
    +                let received: u64 = row.get(1)?;
    +                let sent: u64 = row.get(2)?;
    +                let fee: Option<u64> = row.get(3)?;
    +                let height: Option<u32> = row.get(4)?;
    +
    +                let raw_tx: Option<Vec<u8>> = row.get(5)?;
    +                let tx: Option<Transaction> = match raw_tx {
    +                    Some(raw_tx) => {
    +                        let tx: Transaction = deserialize(&raw_tx)?;
    +                        Some(tx)
                         }
    -                    None => None,
    +                    None => None,
                     };
     
    -                let confirmation_time = match (height, timestamp) {
    -                    (Some(height), Some(timestamp)) => Some(BlockTime { height, timestamp }),
    -                    _ => None,
    +                let confirmation_time = match (height, timestamp) {
    +                    (Some(height), Some(timestamp)) => Some(BlockTime { height, timestamp }),
    +                    _ => None,
                     };
     
    -                Ok(Some(TransactionDetails {
    -                    transaction: tx,
    -                    txid: deserialize(txid)?,
    -                    received,
    -                    sent,
    -                    fee,
    -                    confirmation_time,
    +                Ok(Some(TransactionDetails {
    +                    transaction: tx,
    +                    txid: deserialize(txid)?,
    +                    received,
    +                    sent,
    +                    fee,
    +                    confirmation_time,
                     }))
                 }
    -            None => Ok(None),
    +            None => Ok(None),
             }
         }
     
    -    fn select_last_derivation_index_by_keychain(
    +    fn select_last_derivation_index_by_keychain(
             &self,
    -        keychain: String,
    -    ) -> Result<Option<u32>, Error> {
    -        let mut statement = self
    -            .connection
    -            .prepare_cached("SELECT value FROM last_derivation_indices WHERE keychain=:keychain")?;
    -        let mut rows = statement.query(named_params! {":keychain": keychain})?;
    -        match rows.next()? {
    -            Some(row) => {
    -                let value: u32 = row.get(0)?;
    -                Ok(Some(value))
    +        keychain: String,
    +    ) -> Result<Option<u32>, Error> {
    +        let mut statement = self
    +            .connection
    +            .prepare_cached("SELECT value FROM last_derivation_indices WHERE keychain=:keychain")?;
    +        let mut rows = statement.query(named_params! {":keychain": keychain})?;
    +        match rows.next()? {
    +            Some(row) => {
    +                let value: u32 = row.get(0)?;
    +                Ok(Some(value))
                 }
    -            None => Ok(None),
    +            None => Ok(None),
             }
         }
     
    -    fn select_sync_time(&self) -> Result<Option<SyncTime>, Error> {
    -        let mut statement = self
    -            .connection
    -            .prepare_cached("SELECT height, timestamp FROM sync_time WHERE id = 0")?;
    -        let mut rows = statement.query([])?;
    +    fn select_sync_time(&self) -> Result<Option<SyncTime>, Error> {
    +        let mut statement = self
    +            .connection
    +            .prepare_cached("SELECT height, timestamp FROM sync_time WHERE id = 0")?;
    +        let mut rows = statement.query([])?;
     
    -        if let Some(row) = rows.next()? {
    -            Ok(Some(SyncTime {
    -                block_time: BlockTime {
    -                    height: row.get(0)?,
    -                    timestamp: row.get(1)?,
    +        if let Some(row) = rows.next()? {
    +            Ok(Some(SyncTime {
    +                block_time: BlockTime {
    +                    height: row.get(0)?,
    +                    timestamp: row.get(1)?,
                     },
                 }))
    -        } else {
    +        } else {
                 Ok(None)
             }
         }
     
    -    fn select_checksum_by_keychain(&self, keychain: String) -> Result<Option<Vec<u8>>, Error> {
    -        let mut statement = self
    -            .connection
    -            .prepare_cached("SELECT checksum FROM checksums WHERE keychain=:keychain")?;
    -        let mut rows = statement.query(named_params! {":keychain": keychain})?;
    +    fn select_checksum_by_keychain(&self, keychain: String) -> Result<Option<Vec<u8>>, Error> {
    +        let mut statement = self
    +            .connection
    +            .prepare_cached("SELECT checksum FROM checksums WHERE keychain=:keychain")?;
    +        let mut rows = statement.query(named_params! {":keychain": keychain})?;
     
    -        match rows.next()? {
    -            Some(row) => {
    -                let checksum: Vec<u8> = row.get(0)?;
    -                Ok(Some(checksum))
    +        match rows.next()? {
    +            Some(row) => {
    +                let checksum: Vec<u8> = row.get(0)?;
    +                Ok(Some(checksum))
                 }
    -            None => Ok(None),
    +            None => Ok(None),
             }
         }
     
    -    fn delete_script_pubkey_by_path(&self, keychain: String, child: u32) -> Result<(), Error> {
    -        let mut statement = self.connection.prepare_cached(
    +    fn delete_script_pubkey_by_path(&self, keychain: String, child: u32) -> Result<(), Error> {
    +        let mut statement = self.connection.prepare_cached(
                 "DELETE FROM script_pubkeys WHERE keychain=:keychain AND child=:child",
             )?;
    -        statement.execute(named_params! {
    -            ":keychain": keychain,
    -            ":child": child
    +        statement.execute(named_params! {
    +            ":keychain": keychain,
    +            ":child": child
             })?;
     
             Ok(())
         }
     
    -    fn delete_script_pubkey_by_script(&self, script: &[u8]) -> Result<(), Error> {
    -        let mut statement = self
    -            .connection
    -            .prepare_cached("DELETE FROM script_pubkeys WHERE script=:script")?;
    -        statement.execute(named_params! {
    -            ":script": script
    +    fn delete_script_pubkey_by_script(&self, script: &[u8]) -> Result<(), Error> {
    +        let mut statement = self
    +            .connection
    +            .prepare_cached("DELETE FROM script_pubkeys WHERE script=:script")?;
    +        statement.execute(named_params! {
    +            ":script": script
             })?;
     
             Ok(())
         }
     
    -    fn delete_utxo_by_outpoint(&self, txid: &[u8], vout: u32) -> Result<(), Error> {
    -        let mut statement = self
    -            .connection
    -            .prepare_cached("DELETE FROM utxos WHERE txid=:txid AND vout=:vout")?;
    -        statement.execute(named_params! {
    -            ":txid": txid,
    -            ":vout": vout
    +    fn delete_utxo_by_outpoint(&self, txid: &[u8], vout: u32) -> Result<(), Error> {
    +        let mut statement = self
    +            .connection
    +            .prepare_cached("DELETE FROM utxos WHERE txid=:txid AND vout=:vout")?;
    +        statement.execute(named_params! {
    +            ":txid": txid,
    +            ":vout": vout
             })?;
     
             Ok(())
         }
     
    -    fn delete_transaction_by_txid(&self, txid: &[u8]) -> Result<(), Error> {
    -        let mut statement = self
    -            .connection
    -            .prepare_cached("DELETE FROM transactions WHERE txid=:txid")?;
    -        statement.execute(named_params! {":txid": txid})?;
    +    fn delete_transaction_by_txid(&self, txid: &[u8]) -> Result<(), Error> {
    +        let mut statement = self
    +            .connection
    +            .prepare_cached("DELETE FROM transactions WHERE txid=:txid")?;
    +        statement.execute(named_params! {":txid": txid})?;
             Ok(())
         }
     
    -    fn delete_transaction_details_by_txid(&self, txid: &[u8]) -> Result<(), Error> {
    -        let mut statement = self
    -            .connection
    -            .prepare_cached("DELETE FROM transaction_details WHERE txid=:txid")?;
    -        statement.execute(named_params! {":txid": txid})?;
    +    fn delete_transaction_details_by_txid(&self, txid: &[u8]) -> Result<(), Error> {
    +        let mut statement = self
    +            .connection
    +            .prepare_cached("DELETE FROM transaction_details WHERE txid=:txid")?;
    +        statement.execute(named_params! {":txid": txid})?;
             Ok(())
         }
     
    -    fn delete_last_derivation_index_by_keychain(&self, keychain: String) -> Result<(), Error> {
    -        let mut statement = self
    -            .connection
    -            .prepare_cached("DELETE FROM last_derivation_indices WHERE keychain=:keychain")?;
    -        statement.execute(named_params! {
    -            ":keychain": &keychain
    +    fn delete_last_derivation_index_by_keychain(&self, keychain: String) -> Result<(), Error> {
    +        let mut statement = self
    +            .connection
    +            .prepare_cached("DELETE FROM last_derivation_indices WHERE keychain=:keychain")?;
    +        statement.execute(named_params! {
    +            ":keychain": &keychain
             })?;
     
             Ok(())
         }
     
    -    fn delete_sync_time(&self) -> Result<(), Error> {
    -        let mut statement = self
    -            .connection
    -            .prepare_cached("DELETE FROM sync_time WHERE id = 0")?;
    -        statement.execute([])?;
    +    fn delete_sync_time(&self) -> Result<(), Error> {
    +        let mut statement = self
    +            .connection
    +            .prepare_cached("DELETE FROM sync_time WHERE id = 0")?;
    +        statement.execute([])?;
             Ok(())
         }
     }
     
    -impl BatchOperations for SqliteDatabase {
    -    fn set_script_pubkey(
    -        &mut self,
    -        script: &Script,
    -        keychain: KeychainKind,
    -        child: u32,
    -    ) -> Result<(), Error> {
    -        let keychain = serde_json::to_string(&keychain)?;
    -        self.insert_script_pubkey(keychain, child, script.as_bytes())?;
    +impl BatchOperations for SqliteDatabase {
    +    fn set_script_pubkey(
    +        &mut self,
    +        script: &Script,
    +        keychain: KeychainKind,
    +        child: u32,
    +    ) -> Result<(), Error> {
    +        let keychain = serde_json::to_string(&keychain)?;
    +        self.insert_script_pubkey(keychain, child, script.as_bytes())?;
             Ok(())
         }
     
    -    fn set_utxo(&mut self, utxo: &LocalUtxo) -> Result<(), Error> {
    -        self.insert_utxo(
    -            utxo.txout.value,
    -            serde_json::to_string(&utxo.keychain)?,
    -            utxo.outpoint.vout,
    -            &utxo.outpoint.txid,
    -            utxo.txout.script_pubkey.as_bytes(),
    -            utxo.is_spent,
    +    fn set_utxo(&mut self, utxo: &LocalUtxo) -> Result<(), Error> {
    +        self.insert_utxo(
    +            utxo.txout.value,
    +            serde_json::to_string(&utxo.keychain)?,
    +            utxo.outpoint.vout,
    +            &utxo.outpoint.txid,
    +            utxo.txout.script_pubkey.as_bytes(),
    +            utxo.is_spent,
             )?;
             Ok(())
         }
     
    -    fn set_raw_tx(&mut self, transaction: &Transaction) -> Result<(), Error> {
    -        match self.select_transaction_by_txid(&transaction.txid())? {
    +    fn set_raw_tx(&mut self, transaction: &Transaction) -> Result<(), Error> {
    +        match self.select_transaction_by_txid(&transaction.txid())? {
                 Some(_) => {
    -                self.update_transaction(&transaction.txid(), &serialize(transaction))?;
    +                self.update_transaction(&transaction.txid(), &serialize(transaction))?;
                 }
    -            None => {
    -                self.insert_transaction(&transaction.txid(), &serialize(transaction))?;
    +            None => {
    +                self.insert_transaction(&transaction.txid(), &serialize(transaction))?;
                 }
             }
             Ok(())
         }
     
    -    fn set_tx(&mut self, transaction: &TransactionDetails) -> Result<(), Error> {
    -        match self.select_transaction_details_by_txid(&transaction.txid)? {
    +    fn set_tx(&mut self, transaction: &TransactionDetails) -> Result<(), Error> {
    +        match self.select_transaction_details_by_txid(&transaction.txid)? {
                 Some(_) => {
    -                self.update_transaction_details(transaction)?;
    +                self.update_transaction_details(transaction)?;
                 }
    -            None => {
    -                self.insert_transaction_details(transaction)?;
    +            None => {
    +                self.insert_transaction_details(transaction)?;
                 }
             }
     
    -        if let Some(tx) = &transaction.transaction {
    -            self.set_raw_tx(tx)?;
    +        if let Some(tx) = &transaction.transaction {
    +            self.set_raw_tx(tx)?;
             }
     
             Ok(())
         }
     
    -    fn set_last_index(&mut self, keychain: KeychainKind, value: u32) -> Result<(), Error> {
    -        self.update_last_derivation_index(serde_json::to_string(&keychain)?, value)?;
    +    fn set_last_index(&mut self, keychain: KeychainKind, value: u32) -> Result<(), Error> {
    +        self.update_last_derivation_index(serde_json::to_string(&keychain)?, value)?;
             Ok(())
         }
     
    -    fn set_sync_time(&mut self, ct: SyncTime) -> Result<(), Error> {
    -        self.update_sync_time(ct)?;
    +    fn set_sync_time(&mut self, ct: SyncTime) -> Result<(), Error> {
    +        self.update_sync_time(ct)?;
             Ok(())
         }
     
    -    fn del_script_pubkey_from_path(
    -        &mut self,
    -        keychain: KeychainKind,
    -        child: u32,
    -    ) -> Result<Option<Script>, Error> {
    -        let keychain = serde_json::to_string(&keychain)?;
    -        let script = self.select_script_pubkey_by_path(keychain.clone(), child)?;
    -        match script {
    -            Some(script) => {
    -                self.delete_script_pubkey_by_path(keychain, child)?;
    -                Ok(Some(script))
    +    fn del_script_pubkey_from_path(
    +        &mut self,
    +        keychain: KeychainKind,
    +        child: u32,
    +    ) -> Result<Option<Script>, Error> {
    +        let keychain = serde_json::to_string(&keychain)?;
    +        let script = self.select_script_pubkey_by_path(keychain.clone(), child)?;
    +        match script {
    +            Some(script) => {
    +                self.delete_script_pubkey_by_path(keychain, child)?;
    +                Ok(Some(script))
                 }
    -            None => Ok(None),
    +            None => Ok(None),
             }
         }
     
    -    fn del_path_from_script_pubkey(
    -        &mut self,
    -        script: &Script,
    -    ) -> Result<Option<(KeychainKind, u32)>, Error> {
    -        match self.select_script_pubkey_by_script(script.as_bytes())? {
    -            Some((keychain, child)) => {
    -                self.delete_script_pubkey_by_script(script.as_bytes())?;
    -                Ok(Some((keychain, child)))
    +    fn del_path_from_script_pubkey(
    +        &mut self,
    +        script: &Script,
    +    ) -> Result<Option<(KeychainKind, u32)>, Error> {
    +        match self.select_script_pubkey_by_script(script.as_bytes())? {
    +            Some((keychain, child)) => {
    +                self.delete_script_pubkey_by_script(script.as_bytes())?;
    +                Ok(Some((keychain, child)))
                 }
    -            None => Ok(None),
    +            None => Ok(None),
             }
         }
     
    -    fn del_utxo(&mut self, outpoint: &OutPoint) -> Result<Option<LocalUtxo>, Error> {
    -        match self.select_utxo_by_outpoint(&outpoint.txid, outpoint.vout)? {
    -            Some(local_utxo) => {
    -                self.delete_utxo_by_outpoint(&outpoint.txid, outpoint.vout)?;
    -                Ok(Some(local_utxo))
    +    fn del_utxo(&mut self, outpoint: &OutPoint) -> Result<Option<LocalUtxo>, Error> {
    +        match self.select_utxo_by_outpoint(&outpoint.txid, outpoint.vout)? {
    +            Some(local_utxo) => {
    +                self.delete_utxo_by_outpoint(&outpoint.txid, outpoint.vout)?;
    +                Ok(Some(local_utxo))
                 }
    -            None => Ok(None),
    +            None => Ok(None),
             }
         }
     
    -    fn del_raw_tx(&mut self, txid: &Txid) -> Result<Option<Transaction>, Error> {
    -        match self.select_transaction_by_txid(txid)? {
    -            Some(tx) => {
    -                self.delete_transaction_by_txid(txid)?;
    -                Ok(Some(tx))
    +    fn del_raw_tx(&mut self, txid: &Txid) -> Result<Option<Transaction>, Error> {
    +        match self.select_transaction_by_txid(txid)? {
    +            Some(tx) => {
    +                self.delete_transaction_by_txid(txid)?;
    +                Ok(Some(tx))
                 }
    -            None => Ok(None),
    +            None => Ok(None),
             }
         }
     
    -    fn del_tx(
    -        &mut self,
    -        txid: &Txid,
    -        include_raw: bool,
    -    ) -> Result<Option<TransactionDetails>, Error> {
    -        match self.select_transaction_details_by_txid(txid)? {
    -            Some(mut transaction_details) => {
    -                self.delete_transaction_details_by_txid(txid)?;
    +    fn del_tx(
    +        &mut self,
    +        txid: &Txid,
    +        include_raw: bool,
    +    ) -> Result<Option<TransactionDetails>, Error> {
    +        match self.select_transaction_details_by_txid(txid)? {
    +            Some(mut transaction_details) => {
    +                self.delete_transaction_details_by_txid(txid)?;
     
    -                if include_raw {
    -                    self.delete_transaction_by_txid(txid)?;
    -                } else {
    -                    transaction_details.transaction = None;
    +                if include_raw {
    +                    self.delete_transaction_by_txid(txid)?;
    +                } else {
    +                    transaction_details.transaction = None;
                     }
    -                Ok(Some(transaction_details))
    +                Ok(Some(transaction_details))
                 }
    -            None => Ok(None),
    +            None => Ok(None),
             }
         }
     
    -    fn del_last_index(&mut self, keychain: KeychainKind) -> Result<Option<u32>, Error> {
    -        let keychain = serde_json::to_string(&keychain)?;
    -        match self.select_last_derivation_index_by_keychain(keychain.clone())? {
    -            Some(value) => {
    -                self.delete_last_derivation_index_by_keychain(keychain)?;
    +    fn del_last_index(&mut self, keychain: KeychainKind) -> Result<Option<u32>, Error> {
    +        let keychain = serde_json::to_string(&keychain)?;
    +        match self.select_last_derivation_index_by_keychain(keychain.clone())? {
    +            Some(value) => {
    +                self.delete_last_derivation_index_by_keychain(keychain)?;
     
    -                Ok(Some(value))
    +                Ok(Some(value))
                 }
    -            None => Ok(None),
    +            None => Ok(None),
             }
         }
     
    -    fn del_sync_time(&mut self) -> Result<Option<SyncTime>, Error> {
    -        match self.select_sync_time()? {
    -            Some(value) => {
    -                self.delete_sync_time()?;
    +    fn del_sync_time(&mut self) -> Result<Option<SyncTime>, Error> {
    +        match self.select_sync_time()? {
    +            Some(value) => {
    +                self.delete_sync_time()?;
     
    -                Ok(Some(value))
    +                Ok(Some(value))
                 }
    -            None => Ok(None),
    +            None => Ok(None),
             }
         }
     }
     
    -impl Database for SqliteDatabase {
    -    fn check_descriptor_checksum<B: AsRef<[u8]>>(
    -        &mut self,
    -        keychain: KeychainKind,
    -        bytes: B,
    -    ) -> Result<(), Error> {
    -        let keychain = serde_json::to_string(&keychain)?;
    -
    -        match self.select_checksum_by_keychain(keychain.clone())? {
    -            Some(checksum) => {
    -                if checksum == bytes.as_ref().to_vec() {
    +impl Database for SqliteDatabase {
    +    fn check_descriptor_checksum<B: AsRef<[u8]>>(
    +        &mut self,
    +        keychain: KeychainKind,
    +        bytes: B,
    +    ) -> Result<(), Error> {
    +        let keychain = serde_json::to_string(&keychain)?;
    +
    +        match self.select_checksum_by_keychain(keychain.clone())? {
    +            Some(checksum) => {
    +                if checksum == bytes.as_ref().to_vec() {
                         Ok(())
    -                } else {
    -                    Err(Error::ChecksumMismatch)
    +                } else {
    +                    Err(Error::ChecksumMismatch)
                     }
                 }
    -            None => {
    -                self.insert_checksum(keychain, bytes.as_ref())?;
    +            None => {
    +                self.insert_checksum(keychain, bytes.as_ref())?;
                     Ok(())
                 }
             }
         }
     
    -    fn iter_script_pubkeys(&self, keychain: Option<KeychainKind>) -> Result<Vec<Script>, Error> {
    -        match keychain {
    -            Some(keychain) => {
    -                let keychain = serde_json::to_string(&keychain)?;
    -                self.select_script_pubkeys_by_keychain(keychain)
    +    fn iter_script_pubkeys(&self, keychain: Option<KeychainKind>) -> Result<Vec<Script>, Error> {
    +        match keychain {
    +            Some(keychain) => {
    +                let keychain = serde_json::to_string(&keychain)?;
    +                self.select_script_pubkeys_by_keychain(keychain)
                 }
    -            None => self.select_script_pubkeys(),
    +            None => self.select_script_pubkeys(),
             }
         }
     
    -    fn iter_utxos(&self) -> Result<Vec<LocalUtxo>, Error> {
    -        self.select_utxos()
    +    fn iter_utxos(&self) -> Result<Vec<LocalUtxo>, Error> {
    +        self.select_utxos()
         }
     
    -    fn iter_raw_txs(&self) -> Result<Vec<Transaction>, Error> {
    -        self.select_transactions()
    +    fn iter_raw_txs(&self) -> Result<Vec<Transaction>, Error> {
    +        self.select_transactions()
         }
     
    -    fn iter_txs(&self, include_raw: bool) -> Result<Vec<TransactionDetails>, Error> {
    -        match include_raw {
    -            true => self.select_transaction_details_with_raw(),
    -            false => self.select_transaction_details(),
    +    fn iter_txs(&self, include_raw: bool) -> Result<Vec<TransactionDetails>, Error> {
    +        match include_raw {
    +            true => self.select_transaction_details_with_raw(),
    +            false => self.select_transaction_details(),
             }
         }
     
    -    fn get_script_pubkey_from_path(
    +    fn get_script_pubkey_from_path(
             &self,
    -        keychain: KeychainKind,
    -        child: u32,
    -    ) -> Result<Option<Script>, Error> {
    -        let keychain = serde_json::to_string(&keychain)?;
    -        match self.select_script_pubkey_by_path(keychain, child)? {
    -            Some(script) => Ok(Some(script)),
    -            None => Ok(None),
    +        keychain: KeychainKind,
    +        child: u32,
    +    ) -> Result<Option<Script>, Error> {
    +        let keychain = serde_json::to_string(&keychain)?;
    +        match self.select_script_pubkey_by_path(keychain, child)? {
    +            Some(script) => Ok(Some(script)),
    +            None => Ok(None),
             }
         }
     
    -    fn get_path_from_script_pubkey(
    +    fn get_path_from_script_pubkey(
             &self,
    -        script: &Script,
    -    ) -> Result<Option<(KeychainKind, u32)>, Error> {
    -        match self.select_script_pubkey_by_script(script.as_bytes())? {
    -            Some((keychain, child)) => Ok(Some((keychain, child))),
    -            None => Ok(None),
    +        script: &Script,
    +    ) -> Result<Option<(KeychainKind, u32)>, Error> {
    +        match self.select_script_pubkey_by_script(script.as_bytes())? {
    +            Some((keychain, child)) => Ok(Some((keychain, child))),
    +            None => Ok(None),
             }
         }
     
    -    fn get_utxo(&self, outpoint: &OutPoint) -> Result<Option<LocalUtxo>, Error> {
    -        self.select_utxo_by_outpoint(&outpoint.txid, outpoint.vout)
    +    fn get_utxo(&self, outpoint: &OutPoint) -> Result<Option<LocalUtxo>, Error> {
    +        self.select_utxo_by_outpoint(&outpoint.txid, outpoint.vout)
         }
     
    -    fn get_raw_tx(&self, txid: &Txid) -> Result<Option<Transaction>, Error> {
    -        match self.select_transaction_by_txid(txid)? {
    -            Some(tx) => Ok(Some(tx)),
    -            None => Ok(None),
    +    fn get_raw_tx(&self, txid: &Txid) -> Result<Option<Transaction>, Error> {
    +        match self.select_transaction_by_txid(txid)? {
    +            Some(tx) => Ok(Some(tx)),
    +            None => Ok(None),
             }
         }
     
    -    fn get_tx(&self, txid: &Txid, include_raw: bool) -> Result<Option<TransactionDetails>, Error> {
    -        match self.select_transaction_details_by_txid(txid)? {
    -            Some(mut transaction_details) => {
    -                if !include_raw {
    -                    transaction_details.transaction = None;
    +    fn get_tx(&self, txid: &Txid, include_raw: bool) -> Result<Option<TransactionDetails>, Error> {
    +        match self.select_transaction_details_by_txid(txid)? {
    +            Some(mut transaction_details) => {
    +                if !include_raw {
    +                    transaction_details.transaction = None;
                     }
    -                Ok(Some(transaction_details))
    +                Ok(Some(transaction_details))
                 }
    -            None => Ok(None),
    +            None => Ok(None),
             }
         }
     
    -    fn get_last_index(&self, keychain: KeychainKind) -> Result<Option<u32>, Error> {
    -        let keychain = serde_json::to_string(&keychain)?;
    -        let value = self.select_last_derivation_index_by_keychain(keychain)?;
    -        Ok(value)
    +    fn get_last_index(&self, keychain: KeychainKind) -> Result<Option<u32>, Error> {
    +        let keychain = serde_json::to_string(&keychain)?;
    +        let value = self.select_last_derivation_index_by_keychain(keychain)?;
    +        Ok(value)
         }
     
    -    fn get_sync_time(&self) -> Result<Option<SyncTime>, Error> {
    -        self.select_sync_time()
    +    fn get_sync_time(&self) -> Result<Option<SyncTime>, Error> {
    +        self.select_sync_time()
         }
     
    -    fn increment_last_index(&mut self, keychain: KeychainKind) -> Result<u32, Error> {
    -        let keychain_string = serde_json::to_string(&keychain)?;
    -        match self.get_last_index(keychain)? {
    -            Some(value) => {
    -                self.update_last_derivation_index(keychain_string, value + 1)?;
    -                Ok(value + 1)
    +    fn increment_last_index(&mut self, keychain: KeychainKind) -> Result<u32, Error> {
    +        let keychain_string = serde_json::to_string(&keychain)?;
    +        match self.get_last_index(keychain)? {
    +            Some(value) => {
    +                self.update_last_derivation_index(keychain_string, value + 1)?;
    +                Ok(value + 1)
                 }
    -            None => {
    -                self.insert_last_derivation_index(keychain_string, 0)?;
    +            None => {
    +                self.insert_last_derivation_index(keychain_string, 0)?;
                     Ok(0)
                 }
             }
         }
     }
     
    -impl BatchDatabase for SqliteDatabase {
    -    type Batch = SqliteDatabase;
    +impl BatchDatabase for SqliteDatabase {
    +    type Batch = SqliteDatabase;
     
    -    fn begin_batch(&self) -> Self::Batch {
    -        let db = SqliteDatabase::new(self.path.clone());
    -        db.connection.execute("BEGIN TRANSACTION", []).unwrap();
    -        db
    +    fn begin_batch(&self) -> Self::Batch {
    +        let db = SqliteDatabase::new(self.path.clone());
    +        db.connection.execute("BEGIN TRANSACTION", []).unwrap();
    +        db
         }
     
    -    fn commit_batch(&mut self, batch: Self::Batch) -> Result<(), Error> {
    -        batch.connection.execute("COMMIT TRANSACTION", [])?;
    +    fn commit_batch(&mut self, batch: Self::Batch) -> Result<(), Error> {
    +        batch.connection.execute("COMMIT TRANSACTION", [])?;
             Ok(())
         }
     }
     
    -pub fn get_connection<T: AsRef<Path>>(path: &T) -> Result<Connection, Error> {
    -    let mut connection = Connection::open(path)?;
    -    migrate(&mut connection)?;
    -    Ok(connection)
    +pub fn get_connection<T: AsRef<Path>>(path: &T) -> Result<Connection, Error> {
    +    let mut connection = Connection::open(path)?;
    +    migrate(&mut connection)?;
    +    Ok(connection)
     }
     
    -pub fn get_schema_version(conn: &Connection) -> rusqlite::Result<i32> {
    -    let statement = conn.prepare_cached("SELECT version FROM version");
    -    match statement {
    -        Err(rusqlite::Error::SqliteFailure(e, Some(msg))) => {
    -            if msg == "no such table: version" {
    +pub fn get_schema_version(conn: &Connection) -> rusqlite::Result<i32> {
    +    let statement = conn.prepare_cached("SELECT version FROM version");
    +    match statement {
    +        Err(rusqlite::Error::SqliteFailure(e, Some(msg))) => {
    +            if msg == "no such table: version" {
                     Ok(0)
    -            } else {
    -                Err(rusqlite::Error::SqliteFailure(e, Some(msg)))
    +            } else {
    +                Err(rusqlite::Error::SqliteFailure(e, Some(msg)))
                 }
             }
    -        Ok(mut stmt) => {
    -            let mut rows = stmt.query([])?;
    -            match rows.next()? {
    -                Some(row) => {
    -                    let version: i32 = row.get(0)?;
    -                    Ok(version)
    +        Ok(mut stmt) => {
    +            let mut rows = stmt.query([])?;
    +            match rows.next()? {
    +                Some(row) => {
    +                    let version: i32 = row.get(0)?;
    +                    Ok(version)
                     }
    -                None => Ok(0),
    +                None => Ok(0),
                 }
             }
    -        _ => Ok(0),
    +        _ => Ok(0),
         }
     }
     
    -pub fn set_schema_version(conn: &Connection, version: i32) -> rusqlite::Result<usize> {
    -    conn.execute(
    +pub fn set_schema_version(conn: &Connection, version: i32) -> rusqlite::Result<usize> {
    +    conn.execute(
             "UPDATE version SET version=:version",
    -        named_params! {":version": version},
    +        named_params! {":version": version},
         )
     }
     
    -pub fn migrate(conn: &mut Connection) -> Result<(), Error> {
    -    let version = get_schema_version(conn)?;
    -    let stmts = &MIGRATIONS[(version as usize)..];
    +pub fn migrate(conn: &mut Connection) -> Result<(), Error> {
    +    let version = get_schema_version(conn)?;
    +    let stmts = &MIGRATIONS[(version as usize)..];
     
    -    // begin transaction, all migration statements and new schema version commit or rollback
    -    let tx = conn.transaction()?;
    +    // begin transaction, all migration statements and new schema version commit or rollback
    +    let tx = conn.transaction()?;
     
    -    // execute every statement and return `Some` new schema version
    -    // if execution fails, return `Error::Rusqlite`
    -    // if no statements executed returns `None`
    -    let new_version = stmts
    -        .iter()
    -        .enumerate()
    -        .map(|version_stmt| {
    +    // execute every statement and return `Some` new schema version
    +    // if execution fails, return `Error::Rusqlite`
    +    // if no statements executed returns `None`
    +    let new_version = stmts
    +        .iter()
    +        .enumerate()
    +        .map(|version_stmt| {
                 log::info!(
                     "executing db migration {}: `{}`",
    -                version + version_stmt.0 as i32 + 1,
    -                version_stmt.1
    -            );
    -            tx.execute(version_stmt.1, [])
    -                // map result value to next migration version
    -                .map(|_| version_stmt.0 as i32 + version + 1)
    +                version + version_stmt.0 as i32 + 1,
    +                version_stmt.1
    +            );
    +            tx.execute(version_stmt.1, [])
    +                // map result value to next migration version
    +                .map(|_| version_stmt.0 as i32 + version + 1)
             })
    -        .last()
    -        .transpose()?;
    +        .last()
    +        .transpose()?;
     
    -    // if `Some` new statement version, set new schema version
    -    if let Some(version) = new_version {
    -        set_schema_version(&tx, version)?;
    -    } else {
    +    // if `Some` new statement version, set new schema version
    +    if let Some(version) = new_version {
    +        set_schema_version(&tx, version)?;
    +    } else {
             log::info!("db up to date, no migration needed");
         }
     
    -    // commit transaction
    -    tx.commit()?;
    +    // commit transaction
    +    tx.commit()?;
         Ok(())
     }
     
    -#[cfg(test)]
    -pub mod test {
    -    use crate::database::SqliteDatabase;
    -    use std::time::{SystemTime, UNIX_EPOCH};
    +#[cfg(test)]
    +pub mod test {
    +    use crate::database::SqliteDatabase;
    +    use std::time::{SystemTime, UNIX_EPOCH};
     
    -    fn get_database() -> SqliteDatabase {
    -        let time = SystemTime::now().duration_since(UNIX_EPOCH).unwrap();
    -        let mut dir = std::env::temp_dir();
    -        dir.push(format!("bdk_{}", time.as_nanos()));
    -        SqliteDatabase::new(String::from(dir.to_str().unwrap()))
    +    fn get_database() -> SqliteDatabase {
    +        let time = SystemTime::now().duration_since(UNIX_EPOCH).unwrap();
    +        let mut dir = std::env::temp_dir();
    +        dir.push(format!("bdk_{}", time.as_nanos()));
    +        SqliteDatabase::new(String::from(dir.to_str().unwrap()))
         }
     
    -    #[test]
    -    fn test_script_pubkey() {
    -        crate::database::test::test_script_pubkey(get_database());
    +    #[test]
    +    fn test_script_pubkey() {
    +        crate::database::test::test_script_pubkey(get_database());
         }
     
    -    #[test]
    -    fn test_batch_script_pubkey() {
    -        crate::database::test::test_batch_script_pubkey(get_database());
    +    #[test]
    +    fn test_batch_script_pubkey() {
    +        crate::database::test::test_batch_script_pubkey(get_database());
         }
     
    -    #[test]
    -    fn test_iter_script_pubkey() {
    -        crate::database::test::test_iter_script_pubkey(get_database());
    +    #[test]
    +    fn test_iter_script_pubkey() {
    +        crate::database::test::test_iter_script_pubkey(get_database());
         }
     
    -    #[test]
    -    fn test_del_script_pubkey() {
    -        crate::database::test::test_del_script_pubkey(get_database());
    +    #[test]
    +    fn test_del_script_pubkey() {
    +        crate::database::test::test_del_script_pubkey(get_database());
         }
     
    -    #[test]
    -    fn test_utxo() {
    -        crate::database::test::test_utxo(get_database());
    +    #[test]
    +    fn test_utxo() {
    +        crate::database::test::test_utxo(get_database());
         }
     
    -    #[test]
    -    fn test_raw_tx() {
    -        crate::database::test::test_raw_tx(get_database());
    +    #[test]
    +    fn test_raw_tx() {
    +        crate::database::test::test_raw_tx(get_database());
         }
     
    -    #[test]
    -    fn test_tx() {
    -        crate::database::test::test_tx(get_database());
    +    #[test]
    +    fn test_tx() {
    +        crate::database::test::test_tx(get_database());
         }
     
    -    #[test]
    -    fn test_last_index() {
    -        crate::database::test::test_last_index(get_database());
    +    #[test]
    +    fn test_last_index() {
    +        crate::database::test::test_last_index(get_database());
         }
     
    -    #[test]
    -    fn test_sync_time() {
    -        crate::database::test::test_sync_time(get_database());
    +    #[test]
    +    fn test_sync_time() {
    +        crate::database::test::test_sync_time(get_database());
         }
     
    -    #[test]
    -    fn test_txs() {
    -        crate::database::test::test_list_transaction(get_database());
    +    #[test]
    +    fn test_txs() {
    +        crate::database::test::test_list_transaction(get_database());
         }
     
    -    #[test]
    -    fn test_iter_raw_txs() {
    -        crate::database::test::test_iter_raw_txs(get_database());
    +    #[test]
    +    fn test_iter_raw_txs() {
    +        crate::database::test::test_iter_raw_txs(get_database());
         }
     
    -    #[test]
    -    fn test_del_path_from_script_pubkey() {
    -        crate::database::test::test_del_path_from_script_pubkey(get_database());
    +    #[test]
    +    fn test_del_path_from_script_pubkey() {
    +        crate::database::test::test_del_path_from_script_pubkey(get_database());
         }
     
    -    #[test]
    -    fn test_iter_script_pubkeys() {
    -        crate::database::test::test_iter_script_pubkeys(get_database());
    +    #[test]
    +    fn test_iter_script_pubkeys() {
    +        crate::database::test::test_iter_script_pubkeys(get_database());
         }
     
    -    #[test]
    -    fn test_del_utxo() {
    -        crate::database::test::test_del_utxo(get_database());
    +    #[test]
    +    fn test_del_utxo() {
    +        crate::database::test::test_del_utxo(get_database());
         }
     
    -    #[test]
    -    fn test_del_raw_tx() {
    -        crate::database::test::test_del_raw_tx(get_database());
    +    #[test]
    +    fn test_del_raw_tx() {
    +        crate::database::test::test_del_raw_tx(get_database());
         }
     
    -    #[test]
    -    fn test_del_tx() {
    -        crate::database::test::test_del_tx(get_database());
    +    #[test]
    +    fn test_del_tx() {
    +        crate::database::test::test_del_tx(get_database());
         }
     
    -    #[test]
    -    fn test_del_last_index() {
    -        crate::database::test::test_del_last_index(get_database());
    +    #[test]
    +    fn test_del_last_index() {
    +        crate::database::test::test_del_last_index(get_database());
         }
     
    -    #[test]
    -    fn test_check_descriptor_checksum() {
    -        crate::database::test::test_check_descriptor_checksum(get_database());
    +    #[test]
    +    fn test_check_descriptor_checksum() {
    +        crate::database::test::test_check_descriptor_checksum(get_database());
         }
     
    -    // Issue 801: https://github.com/bitcoindevkit/bdk/issues/801
    -    #[test]
    -    fn test_unique_spks() {
    -        use crate::bitcoin::hashes::hex::FromHex;
    -        use crate::database::*;
    +    // Issue 801: https://github.com/bitcoindevkit/bdk/issues/801
    +    #[test]
    +    fn test_unique_spks() {
    +        use crate::bitcoin::hashes::hex::FromHex;
    +        use crate::database::*;
     
    -        let mut db = get_database();
    +        let mut db = get_database();
     
    -        let script = Script::from(
    -            Vec::<u8>::from_hex("76a91402306a7c23f3e8010de41e9e591348bb83f11daa88ac").unwrap(),
    +        let script = Script::from(
    +            Vec::<u8>::from_hex("76a91402306a7c23f3e8010de41e9e591348bb83f11daa88ac").unwrap(),
             );
    -        let path = 42;
    -        let keychain = KeychainKind::External;
    +        let path = 42;
    +        let keychain = KeychainKind::External;
     
    -        for _ in 0..100 {
    -            db.set_script_pubkey(&script, keychain, path).unwrap();
    +        for _ in 0..100 {
    +            db.set_script_pubkey(&script, keychain, path).unwrap();
             }
     
    -        let mut statement = db
    -            .connection
    -            .prepare_cached(
    +        let mut statement = db
    +            .connection
    +            .prepare_cached(
                     "select keychain,child,count(child) from script_pubkeys group by keychain,child;",
                 )
    -            .unwrap();
    -        let mut rows = statement.query([]).unwrap();
    -        while let Some(row) = rows.next().unwrap() {
    -            let keychain: String = row.get(0).unwrap();
    -            let child: u32 = row.get(1).unwrap();
    -            let count: usize = row.get(2).unwrap();
    +            .unwrap();
    +        let mut rows = statement.query([]).unwrap();
    +        while let Some(row) = rows.next().unwrap() {
    +            let keychain: String = row.get(0).unwrap();
    +            let child: u32 = row.get(1).unwrap();
    +            let count: usize = row.get(2).unwrap();
     
                 assert!(
    -                count == 1,
    +                count == 1,
                     "keychain={}, child={}, count={}",
    -                keychain,
    -                child,
    -                count
    +                keychain,
    +                child,
    +                count
                 );
             }
         }
     }
     
    -
    - \ No newline at end of file +
    \ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/src/bdk/descriptor/checksum.rs.html b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/src/bdk/descriptor/checksum.rs.html index b9c9fb7bce..90e9d0a01f 100644 --- a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/src/bdk/descriptor/checksum.rs.html +++ b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/src/bdk/descriptor/checksum.rs.html @@ -1,370 +1,363 @@ -checksum.rs - source - -
      1
    -  2
    -  3
    -  4
    -  5
    -  6
    -  7
    -  8
    -  9
    - 10
    - 11
    - 12
    - 13
    - 14
    - 15
    - 16
    - 17
    - 18
    - 19
    - 20
    - 21
    - 22
    - 23
    - 24
    - 25
    - 26
    - 27
    - 28
    - 29
    - 30
    - 31
    - 32
    - 33
    - 34
    - 35
    - 36
    - 37
    - 38
    - 39
    - 40
    - 41
    - 42
    - 43
    - 44
    - 45
    - 46
    - 47
    - 48
    - 49
    - 50
    - 51
    - 52
    - 53
    - 54
    - 55
    - 56
    - 57
    - 58
    - 59
    - 60
    - 61
    - 62
    - 63
    - 64
    - 65
    - 66
    - 67
    - 68
    - 69
    - 70
    - 71
    - 72
    - 73
    - 74
    - 75
    - 76
    - 77
    - 78
    - 79
    - 80
    - 81
    - 82
    - 83
    - 84
    - 85
    - 86
    - 87
    - 88
    - 89
    - 90
    - 91
    - 92
    - 93
    - 94
    - 95
    - 96
    - 97
    - 98
    - 99
    -100
    -101
    -102
    -103
    -104
    -105
    -106
    -107
    -108
    -109
    -110
    -111
    -112
    -113
    -114
    -115
    -116
    -117
    -118
    -119
    -120
    -121
    -122
    -123
    -124
    -125
    -126
    -127
    -128
    -129
    -130
    -131
    -132
    -133
    -134
    -135
    -136
    -137
    -138
    -139
    -140
    -141
    -142
    -143
    -144
    -145
    -146
    -147
    -148
    -149
    -150
    -151
    -152
    -153
    -154
    -155
    -156
    -157
    -158
    -159
    -160
    -161
    -162
    -163
    -164
    -165
    -166
    -167
    -168
    -169
    -170
    -171
    -172
    -173
    -174
    -175
    -176
    -177
    -178
    -179
    -180
    -
    // Bitcoin Dev Kit
    -// Written in 2020 by Alekos Filini <alekos.filini@gmail.com>
    -//
    -// Copyright (c) 2020-2021 Bitcoin Dev Kit Developers
    -//
    -// This file is licensed under the Apache License, Version 2.0 <LICENSE-APACHE
    -// or http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
    -// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your option.
    -// You may not use this file except in accordance with one or both of these
    -// licenses.
    +checksum.rs - source
    1
    +2
    +3
    +4
    +5
    +6
    +7
    +8
    +9
    +10
    +11
    +12
    +13
    +14
    +15
    +16
    +17
    +18
    +19
    +20
    +21
    +22
    +23
    +24
    +25
    +26
    +27
    +28
    +29
    +30
    +31
    +32
    +33
    +34
    +35
    +36
    +37
    +38
    +39
    +40
    +41
    +42
    +43
    +44
    +45
    +46
    +47
    +48
    +49
    +50
    +51
    +52
    +53
    +54
    +55
    +56
    +57
    +58
    +59
    +60
    +61
    +62
    +63
    +64
    +65
    +66
    +67
    +68
    +69
    +70
    +71
    +72
    +73
    +74
    +75
    +76
    +77
    +78
    +79
    +80
    +81
    +82
    +83
    +84
    +85
    +86
    +87
    +88
    +89
    +90
    +91
    +92
    +93
    +94
    +95
    +96
    +97
    +98
    +99
    +100
    +101
    +102
    +103
    +104
    +105
    +106
    +107
    +108
    +109
    +110
    +111
    +112
    +113
    +114
    +115
    +116
    +117
    +118
    +119
    +120
    +121
    +122
    +123
    +124
    +125
    +126
    +127
    +128
    +129
    +130
    +131
    +132
    +133
    +134
    +135
    +136
    +137
    +138
    +139
    +140
    +141
    +142
    +143
    +144
    +145
    +146
    +147
    +148
    +149
    +150
    +151
    +152
    +153
    +154
    +155
    +156
    +157
    +158
    +159
    +160
    +161
    +162
    +163
    +164
    +165
    +166
    +167
    +168
    +169
    +170
    +171
    +172
    +173
    +174
    +175
    +176
    +177
    +178
    +179
    +180
    +
    // Bitcoin Dev Kit
    +// Written in 2020 by Alekos Filini <alekos.filini@gmail.com>
    +//
    +// Copyright (c) 2020-2021 Bitcoin Dev Kit Developers
    +//
    +// This file is licensed under the Apache License, Version 2.0 <LICENSE-APACHE
    +// or http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
    +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your option.
    +// You may not use this file except in accordance with one or both of these
    +// licenses.
     
    -//! Descriptor checksum
    -//!
    -//! This module contains a re-implementation of the function used by Bitcoin Core to calculate the
    -//! checksum of a descriptor
    +//! Descriptor checksum
    +//!
    +//! This module contains a re-implementation of the function used by Bitcoin Core to calculate the
    +//! checksum of a descriptor
     
    -use crate::descriptor::DescriptorError;
    +use crate::descriptor::DescriptorError;
     
    -const INPUT_CHARSET: &[u8] = b"0123456789()[],'/*abcdefgh@:$%{}IJKLMNOPQRSTUVWXYZ&+-.;<=>?!^_|~ijklmnopqrstuvwxyzABCDEFGH`#\"\\ ";
    -const CHECKSUM_CHARSET: &[u8] = b"qpzry9x8gf2tvdw0s3jn54khce6mua7l";
    +const INPUT_CHARSET: &[u8] = b"0123456789()[],'/*abcdefgh@:$%{}IJKLMNOPQRSTUVWXYZ&+-.;<=>?!^_|~ijklmnopqrstuvwxyzABCDEFGH`#\"\\ ";
    +const CHECKSUM_CHARSET: &[u8] = b"qpzry9x8gf2tvdw0s3jn54khce6mua7l";
     
    -fn poly_mod(mut c: u64, val: u64) -> u64 {
    -    let c0 = c >> 35;
    -    c = ((c & 0x7ffffffff) << 5) ^ val;
    -    if c0 & 1 > 0 {
    -        c ^= 0xf5dee51989
    -    };
    -    if c0 & 2 > 0 {
    -        c ^= 0xa9fdca3312
    -    };
    -    if c0 & 4 > 0 {
    -        c ^= 0x1bab10e32d
    -    };
    -    if c0 & 8 > 0 {
    -        c ^= 0x3706b1677a
    -    };
    -    if c0 & 16 > 0 {
    -        c ^= 0x644d626ffd
    -    };
    +fn poly_mod(mut c: u64, val: u64) -> u64 {
    +    let c0 = c >> 35;
    +    c = ((c & 0x7ffffffff) << 5) ^ val;
    +    if c0 & 1 > 0 {
    +        c ^= 0xf5dee51989
    +    };
    +    if c0 & 2 > 0 {
    +        c ^= 0xa9fdca3312
    +    };
    +    if c0 & 4 > 0 {
    +        c ^= 0x1bab10e32d
    +    };
    +    if c0 & 8 > 0 {
    +        c ^= 0x3706b1677a
    +    };
    +    if c0 & 16 > 0 {
    +        c ^= 0x644d626ffd
    +    };
     
    -    c
    +    c
     }
     
    -/// Computes the checksum bytes of a descriptor.
    -/// `exclude_hash = true` ignores all data after the first '#' (inclusive).
    -pub(crate) fn calc_checksum_bytes_internal(
    -    mut desc: &str,
    -    exclude_hash: bool,
    -) -> Result<[u8; 8], DescriptorError> {
    -    let mut c = 1;
    -    let mut cls = 0;
    -    let mut clscount = 0;
    +/// Computes the checksum bytes of a descriptor.
    +/// `exclude_hash = true` ignores all data after the first '#' (inclusive).
    +pub(crate) fn calc_checksum_bytes_internal(
    +    mut desc: &str,
    +    exclude_hash: bool,
    +) -> Result<[u8; 8], DescriptorError> {
    +    let mut c = 1;
    +    let mut cls = 0;
    +    let mut clscount = 0;
     
    -    let mut original_checksum = None;
    -    if exclude_hash {
    -        if let Some(split) = desc.split_once('#') {
    -            desc = split.0;
    -            original_checksum = Some(split.1);
    +    let mut original_checksum = None;
    +    if exclude_hash {
    +        if let Some(split) = desc.split_once('#') {
    +            desc = split.0;
    +            original_checksum = Some(split.1);
             }
         }
     
    -    for ch in desc.as_bytes() {
    -        let pos = INPUT_CHARSET
    -            .iter()
    -            .position(|b| b == ch)
    -            .ok_or(DescriptorError::InvalidDescriptorCharacter(*ch))? as u64;
    -        c = poly_mod(c, pos & 31);
    -        cls = cls * 3 + (pos >> 5);
    -        clscount += 1;
    -        if clscount == 3 {
    -            c = poly_mod(c, cls);
    -            cls = 0;
    -            clscount = 0;
    +    for ch in desc.as_bytes() {
    +        let pos = INPUT_CHARSET
    +            .iter()
    +            .position(|b| b == ch)
    +            .ok_or(DescriptorError::InvalidDescriptorCharacter(*ch))? as u64;
    +        c = poly_mod(c, pos & 31);
    +        cls = cls * 3 + (pos >> 5);
    +        clscount += 1;
    +        if clscount == 3 {
    +            c = poly_mod(c, cls);
    +            cls = 0;
    +            clscount = 0;
             }
         }
    -    if clscount > 0 {
    -        c = poly_mod(c, cls);
    +    if clscount > 0 {
    +        c = poly_mod(c, cls);
         }
    -    (0..8).for_each(|_| c = poly_mod(c, 0));
    -    c ^= 1;
    +    (0..8).for_each(|_| c = poly_mod(c, 0));
    +    c ^= 1;
     
    -    let mut checksum = [0_u8; 8];
    -    for j in 0..8 {
    -        checksum[j] = CHECKSUM_CHARSET[((c >> (5 * (7 - j))) & 31) as usize];
    +    let mut checksum = [0_u8; 8];
    +    for j in 0..8 {
    +        checksum[j] = CHECKSUM_CHARSET[((c >> (5 * (7 - j))) & 31) as usize];
         }
     
    -    // if input data already had a checksum, check calculated checksum against original checksum
    -    if let Some(original_checksum) = original_checksum {
    -        if original_checksum.as_bytes() != checksum {
    -            return Err(DescriptorError::InvalidDescriptorChecksum);
    +    // if input data already had a checksum, check calculated checksum against original checksum
    +    if let Some(original_checksum) = original_checksum {
    +        if original_checksum.as_bytes() != checksum {
    +            return Err(DescriptorError::InvalidDescriptorChecksum);
             }
         }
     
    -    Ok(checksum)
    +    Ok(checksum)
     }
     
    -/// Compute the checksum bytes of a descriptor, excludes any existing checksum in the descriptor string from the calculation
    -pub fn calc_checksum_bytes(desc: &str) -> Result<[u8; 8], DescriptorError> {
    -    calc_checksum_bytes_internal(desc, true)
    +/// Compute the checksum bytes of a descriptor, excludes any existing checksum in the descriptor string from the calculation
    +pub fn calc_checksum_bytes(desc: &str) -> Result<[u8; 8], DescriptorError> {
    +    calc_checksum_bytes_internal(desc, true)
     }
     
    -/// Compute the checksum of a descriptor, excludes any existing checksum in the descriptor string from the calculation
    -pub fn calc_checksum(desc: &str) -> Result<String, DescriptorError> {
    -    // unsafe is okay here as the checksum only uses bytes in `CHECKSUM_CHARSET`
    -    calc_checksum_bytes_internal(desc, true)
    -        .map(|b| unsafe { String::from_utf8_unchecked(b.to_vec()) })
    +/// Compute the checksum of a descriptor, excludes any existing checksum in the descriptor string from the calculation
    +pub fn calc_checksum(desc: &str) -> Result<String, DescriptorError> {
    +    // unsafe is okay here as the checksum only uses bytes in `CHECKSUM_CHARSET`
    +    calc_checksum_bytes_internal(desc, true)
    +        .map(|b| unsafe { String::from_utf8_unchecked(b.to_vec()) })
     }
     
    -// TODO in release 0.25.0, remove get_checksum_bytes and get_checksum
    -// TODO in release 0.25.0, consolidate calc_checksum_bytes_internal into calc_checksum_bytes
    +// TODO in release 0.25.0, remove get_checksum_bytes and get_checksum
    +// TODO in release 0.25.0, consolidate calc_checksum_bytes_internal into calc_checksum_bytes
     
    -/// Compute the checksum bytes of a descriptor
    -#[deprecated(
    -    since = "0.24.0",
    -    note = "Use new `calc_checksum_bytes` function which excludes any existing checksum in the descriptor string before calculating the checksum hash bytes. See https://github.com/bitcoindevkit/bdk/pull/765."
    -)]
    -pub fn get_checksum_bytes(desc: &str) -> Result<[u8; 8], DescriptorError> {
    -    calc_checksum_bytes_internal(desc, false)
    +/// Compute the checksum bytes of a descriptor
    +#[deprecated(
    +    since = "0.24.0",
    +    note = "Use new `calc_checksum_bytes` function which excludes any existing checksum in the descriptor string before calculating the checksum hash bytes. See https://github.com/bitcoindevkit/bdk/pull/765."
    +)]
    +pub fn get_checksum_bytes(desc: &str) -> Result<[u8; 8], DescriptorError> {
    +    calc_checksum_bytes_internal(desc, false)
     }
     
    -/// Compute the checksum of a descriptor
    -#[deprecated(
    -    since = "0.24.0",
    -    note = "Use new `calc_checksum` function which excludes any existing checksum in the descriptor string before calculating the checksum hash. See https://github.com/bitcoindevkit/bdk/pull/765."
    -)]
    -pub fn get_checksum(desc: &str) -> Result<String, DescriptorError> {
    -    // unsafe is okay here as the checksum only uses bytes in `CHECKSUM_CHARSET`
    -    calc_checksum_bytes_internal(desc, false)
    -        .map(|b| unsafe { String::from_utf8_unchecked(b.to_vec()) })
    +/// Compute the checksum of a descriptor
    +#[deprecated(
    +    since = "0.24.0",
    +    note = "Use new `calc_checksum` function which excludes any existing checksum in the descriptor string before calculating the checksum hash. See https://github.com/bitcoindevkit/bdk/pull/765."
    +)]
    +pub fn get_checksum(desc: &str) -> Result<String, DescriptorError> {
    +    // unsafe is okay here as the checksum only uses bytes in `CHECKSUM_CHARSET`
    +    calc_checksum_bytes_internal(desc, false)
    +        .map(|b| unsafe { String::from_utf8_unchecked(b.to_vec()) })
     }
     
    -#[cfg(test)]
    -mod test {
    -    use super::*;
    -    use crate::descriptor::calc_checksum;
    +#[cfg(test)]
    +mod test {
    +    use super::*;
    +    use crate::descriptor::calc_checksum;
     
    -    // test calc_checksum() function; it should return the same value as Bitcoin Core
    -    #[test]
    -    fn test_calc_checksum() {
    -        let desc = "wpkh(tprv8ZgxMBicQKsPdpkqS7Eair4YxjcuuvDPNYmKX3sCniCf16tHEVrjjiSXEkFRnUH77yXc6ZcwHHcLNfjdi5qUvw3VDfgYiH5mNsj5izuiu2N/1/2/*)";
    -        assert_eq!(calc_checksum(desc).unwrap(), "tqz0nc62");
    +    // test calc_checksum() function; it should return the same value as Bitcoin Core
    +    #[test]
    +    fn test_calc_checksum() {
    +        let desc = "wpkh(tprv8ZgxMBicQKsPdpkqS7Eair4YxjcuuvDPNYmKX3sCniCf16tHEVrjjiSXEkFRnUH77yXc6ZcwHHcLNfjdi5qUvw3VDfgYiH5mNsj5izuiu2N/1/2/*)";
    +        assert_eq!(calc_checksum(desc).unwrap(), "tqz0nc62");
     
    -        let desc = "pkh(tpubD6NzVbkrYhZ4XHndKkuB8FifXm8r5FQHwrN6oZuWCz13qb93rtgKvD4PQsqC4HP4yhV3tA2fqr2RbY5mNXfM7RxXUoeABoDtsFUq2zJq6YK/44'/1'/0'/0/*)";
    -        assert_eq!(calc_checksum(desc).unwrap(), "lasegmfs");
    +        let desc = "pkh(tpubD6NzVbkrYhZ4XHndKkuB8FifXm8r5FQHwrN6oZuWCz13qb93rtgKvD4PQsqC4HP4yhV3tA2fqr2RbY5mNXfM7RxXUoeABoDtsFUq2zJq6YK/44'/1'/0'/0/*)";
    +        assert_eq!(calc_checksum(desc).unwrap(), "lasegmfs");
         }
     
    -    // test calc_checksum() function; it should return the same value as Bitcoin Core even if the
    -    // descriptor string includes a checksum hash
    -    #[test]
    -    fn test_calc_checksum_with_checksum_hash() {
    -        let desc = "wpkh(tprv8ZgxMBicQKsPdpkqS7Eair4YxjcuuvDPNYmKX3sCniCf16tHEVrjjiSXEkFRnUH77yXc6ZcwHHcLNfjdi5qUvw3VDfgYiH5mNsj5izuiu2N/1/2/*)#tqz0nc62";
    -        assert_eq!(calc_checksum(desc).unwrap(), "tqz0nc62");
    +    // test calc_checksum() function; it should return the same value as Bitcoin Core even if the
    +    // descriptor string includes a checksum hash
    +    #[test]
    +    fn test_calc_checksum_with_checksum_hash() {
    +        let desc = "wpkh(tprv8ZgxMBicQKsPdpkqS7Eair4YxjcuuvDPNYmKX3sCniCf16tHEVrjjiSXEkFRnUH77yXc6ZcwHHcLNfjdi5qUvw3VDfgYiH5mNsj5izuiu2N/1/2/*)#tqz0nc62";
    +        assert_eq!(calc_checksum(desc).unwrap(), "tqz0nc62");
     
    -        let desc = "pkh(tpubD6NzVbkrYhZ4XHndKkuB8FifXm8r5FQHwrN6oZuWCz13qb93rtgKvD4PQsqC4HP4yhV3tA2fqr2RbY5mNXfM7RxXUoeABoDtsFUq2zJq6YK/44'/1'/0'/0/*)#lasegmfs";
    -        assert_eq!(calc_checksum(desc).unwrap(), "lasegmfs");
    +        let desc = "pkh(tpubD6NzVbkrYhZ4XHndKkuB8FifXm8r5FQHwrN6oZuWCz13qb93rtgKvD4PQsqC4HP4yhV3tA2fqr2RbY5mNXfM7RxXUoeABoDtsFUq2zJq6YK/44'/1'/0'/0/*)#lasegmfs";
    +        assert_eq!(calc_checksum(desc).unwrap(), "lasegmfs");
     
    -        let desc = "wpkh(tprv8ZgxMBicQKsPdpkqS7Eair4YxjcuuvDPNYmKX3sCniCf16tHEVrjjiSXEkFRnUH77yXc6ZcwHHcLNfjdi5qUvw3VDfgYiH5mNsj5izuiu2N/1/2/*)#tqz0nc26";
    +        let desc = "wpkh(tprv8ZgxMBicQKsPdpkqS7Eair4YxjcuuvDPNYmKX3sCniCf16tHEVrjjiSXEkFRnUH77yXc6ZcwHHcLNfjdi5qUvw3VDfgYiH5mNsj5izuiu2N/1/2/*)#tqz0nc26";
             assert!(matches!(
    -            calc_checksum(desc).err(),
    -            Some(DescriptorError::InvalidDescriptorChecksum)
    +            calc_checksum(desc).err(),
    +            Some(DescriptorError::InvalidDescriptorChecksum)
             ));
     
    -        let desc = "pkh(tpubD6NzVbkrYhZ4XHndKkuB8FifXm8r5FQHwrN6oZuWCz13qb93rtgKvD4PQsqC4HP4yhV3tA2fqr2RbY5mNXfM7RxXUoeABoDtsFUq2zJq6YK/44'/1'/0'/0/*)#lasegmsf";
    +        let desc = "pkh(tpubD6NzVbkrYhZ4XHndKkuB8FifXm8r5FQHwrN6oZuWCz13qb93rtgKvD4PQsqC4HP4yhV3tA2fqr2RbY5mNXfM7RxXUoeABoDtsFUq2zJq6YK/44'/1'/0'/0/*)#lasegmsf";
             assert!(matches!(
    -            calc_checksum(desc).err(),
    -            Some(DescriptorError::InvalidDescriptorChecksum)
    +            calc_checksum(desc).err(),
    +            Some(DescriptorError::InvalidDescriptorChecksum)
             ));
         }
     
    -    #[test]
    -    fn test_calc_checksum_invalid_character() {
    -        let sparkle_heart = unsafe { std::str::from_utf8_unchecked(&[240, 159, 146, 150]) };
    -        let invalid_desc = format!("wpkh(tprv8ZgxMBicQKsPdpkqS7Eair4YxjcuuvDPNYmKX3sCniCf16tHEVrjjiSXEkFRnUH77yXc6ZcwHHcL{}fjdi5qUvw3VDfgYiH5mNsj5izuiu2N/1/2/*)", sparkle_heart);
    +    #[test]
    +    fn test_calc_checksum_invalid_character() {
    +        let sparkle_heart = unsafe { std::str::from_utf8_unchecked(&[240, 159, 146, 150]) };
    +        let invalid_desc = format!("wpkh(tprv8ZgxMBicQKsPdpkqS7Eair4YxjcuuvDPNYmKX3sCniCf16tHEVrjjiSXEkFRnUH77yXc6ZcwHHcL{}fjdi5qUvw3VDfgYiH5mNsj5izuiu2N/1/2/*)", sparkle_heart);
     
             assert!(matches!(
    -            calc_checksum(&invalid_desc).err(),
    -            Some(DescriptorError::InvalidDescriptorCharacter(invalid_char)) if invalid_char == sparkle_heart.as_bytes()[0]
    +            calc_checksum(&invalid_desc).err(),
    +            Some(DescriptorError::InvalidDescriptorCharacter(invalid_char)) if invalid_char == sparkle_heart.as_bytes()[0]
             ));
         }
     }
     
    -
    - \ No newline at end of file +
    \ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/src/bdk/descriptor/dsl.rs.html b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/src/bdk/descriptor/dsl.rs.html index 2b4608c6d1..c8e46e4600 100644 --- a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/src/bdk/descriptor/dsl.rs.html +++ b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/src/bdk/descriptor/dsl.rs.html @@ -1,2173 +1,2167 @@ -dsl.rs - source - -
       1
    -   2
    -   3
    -   4
    -   5
    -   6
    -   7
    -   8
    -   9
    -  10
    -  11
    -  12
    -  13
    -  14
    -  15
    -  16
    -  17
    -  18
    -  19
    -  20
    -  21
    -  22
    -  23
    -  24
    -  25
    -  26
    -  27
    -  28
    -  29
    -  30
    -  31
    -  32
    -  33
    -  34
    -  35
    -  36
    -  37
    -  38
    -  39
    -  40
    -  41
    -  42
    -  43
    -  44
    -  45
    -  46
    -  47
    -  48
    -  49
    -  50
    -  51
    -  52
    -  53
    -  54
    -  55
    -  56
    -  57
    -  58
    -  59
    -  60
    -  61
    -  62
    -  63
    -  64
    -  65
    -  66
    -  67
    -  68
    -  69
    -  70
    -  71
    -  72
    -  73
    -  74
    -  75
    -  76
    -  77
    -  78
    -  79
    -  80
    -  81
    -  82
    -  83
    -  84
    -  85
    -  86
    -  87
    -  88
    -  89
    -  90
    -  91
    -  92
    -  93
    -  94
    -  95
    -  96
    -  97
    -  98
    -  99
    - 100
    - 101
    - 102
    - 103
    - 104
    - 105
    - 106
    - 107
    - 108
    - 109
    - 110
    - 111
    - 112
    - 113
    - 114
    - 115
    - 116
    - 117
    - 118
    - 119
    - 120
    - 121
    - 122
    - 123
    - 124
    - 125
    - 126
    - 127
    - 128
    - 129
    - 130
    - 131
    - 132
    - 133
    - 134
    - 135
    - 136
    - 137
    - 138
    - 139
    - 140
    - 141
    - 142
    - 143
    - 144
    - 145
    - 146
    - 147
    - 148
    - 149
    - 150
    - 151
    - 152
    - 153
    - 154
    - 155
    - 156
    - 157
    - 158
    - 159
    - 160
    - 161
    - 162
    - 163
    - 164
    - 165
    - 166
    - 167
    - 168
    - 169
    - 170
    - 171
    - 172
    - 173
    - 174
    - 175
    - 176
    - 177
    - 178
    - 179
    - 180
    - 181
    - 182
    - 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
    - 245
    - 246
    - 247
    - 248
    - 249
    - 250
    - 251
    - 252
    - 253
    - 254
    - 255
    - 256
    - 257
    - 258
    - 259
    - 260
    - 261
    - 262
    - 263
    - 264
    - 265
    - 266
    - 267
    - 268
    - 269
    - 270
    - 271
    - 272
    - 273
    - 274
    - 275
    - 276
    - 277
    - 278
    - 279
    - 280
    - 281
    - 282
    - 283
    - 284
    - 285
    - 286
    - 287
    - 288
    - 289
    - 290
    - 291
    - 292
    - 293
    - 294
    - 295
    - 296
    - 297
    - 298
    - 299
    - 300
    - 301
    - 302
    - 303
    - 304
    - 305
    - 306
    - 307
    - 308
    - 309
    - 310
    - 311
    - 312
    - 313
    - 314
    - 315
    - 316
    - 317
    - 318
    - 319
    - 320
    - 321
    - 322
    - 323
    - 324
    - 325
    - 326
    - 327
    - 328
    - 329
    - 330
    - 331
    - 332
    - 333
    - 334
    - 335
    - 336
    - 337
    - 338
    - 339
    - 340
    - 341
    - 342
    - 343
    - 344
    - 345
    - 346
    - 347
    - 348
    - 349
    - 350
    - 351
    - 352
    - 353
    - 354
    - 355
    - 356
    - 357
    - 358
    - 359
    - 360
    - 361
    - 362
    - 363
    - 364
    - 365
    - 366
    - 367
    - 368
    - 369
    - 370
    - 371
    - 372
    - 373
    - 374
    - 375
    - 376
    - 377
    - 378
    - 379
    - 380
    - 381
    - 382
    - 383
    - 384
    - 385
    - 386
    - 387
    - 388
    - 389
    - 390
    - 391
    - 392
    - 393
    - 394
    - 395
    - 396
    - 397
    - 398
    - 399
    - 400
    - 401
    - 402
    - 403
    - 404
    - 405
    - 406
    - 407
    - 408
    - 409
    - 410
    - 411
    - 412
    - 413
    - 414
    - 415
    - 416
    - 417
    - 418
    - 419
    - 420
    - 421
    - 422
    - 423
    - 424
    - 425
    - 426
    - 427
    - 428
    - 429
    - 430
    - 431
    - 432
    - 433
    - 434
    - 435
    - 436
    - 437
    - 438
    - 439
    - 440
    - 441
    - 442
    - 443
    - 444
    - 445
    - 446
    - 447
    - 448
    - 449
    - 450
    - 451
    - 452
    - 453
    - 454
    - 455
    - 456
    - 457
    - 458
    - 459
    - 460
    - 461
    - 462
    - 463
    - 464
    - 465
    - 466
    - 467
    - 468
    - 469
    - 470
    - 471
    - 472
    - 473
    - 474
    - 475
    - 476
    - 477
    - 478
    - 479
    - 480
    - 481
    - 482
    - 483
    - 484
    - 485
    - 486
    - 487
    - 488
    - 489
    - 490
    - 491
    - 492
    - 493
    - 494
    - 495
    - 496
    - 497
    - 498
    - 499
    - 500
    - 501
    - 502
    - 503
    - 504
    - 505
    - 506
    - 507
    - 508
    - 509
    - 510
    - 511
    - 512
    - 513
    - 514
    - 515
    - 516
    - 517
    - 518
    - 519
    - 520
    - 521
    - 522
    - 523
    - 524
    - 525
    - 526
    - 527
    - 528
    - 529
    - 530
    - 531
    - 532
    - 533
    - 534
    - 535
    - 536
    - 537
    - 538
    - 539
    - 540
    - 541
    - 542
    - 543
    - 544
    - 545
    - 546
    - 547
    - 548
    - 549
    - 550
    - 551
    - 552
    - 553
    - 554
    - 555
    - 556
    - 557
    - 558
    - 559
    - 560
    - 561
    - 562
    - 563
    - 564
    - 565
    - 566
    - 567
    - 568
    - 569
    - 570
    - 571
    - 572
    - 573
    - 574
    - 575
    - 576
    - 577
    - 578
    - 579
    - 580
    - 581
    - 582
    - 583
    - 584
    - 585
    - 586
    - 587
    - 588
    - 589
    - 590
    - 591
    - 592
    - 593
    - 594
    - 595
    - 596
    - 597
    - 598
    - 599
    - 600
    - 601
    - 602
    - 603
    - 604
    - 605
    - 606
    - 607
    - 608
    - 609
    - 610
    - 611
    - 612
    - 613
    - 614
    - 615
    - 616
    - 617
    - 618
    - 619
    - 620
    - 621
    - 622
    - 623
    - 624
    - 625
    - 626
    - 627
    - 628
    - 629
    - 630
    - 631
    - 632
    - 633
    - 634
    - 635
    - 636
    - 637
    - 638
    - 639
    - 640
    - 641
    - 642
    - 643
    - 644
    - 645
    - 646
    - 647
    - 648
    - 649
    - 650
    - 651
    - 652
    - 653
    - 654
    - 655
    - 656
    - 657
    - 658
    - 659
    - 660
    - 661
    - 662
    - 663
    - 664
    - 665
    - 666
    - 667
    - 668
    - 669
    - 670
    - 671
    - 672
    - 673
    - 674
    - 675
    - 676
    - 677
    - 678
    - 679
    - 680
    - 681
    - 682
    - 683
    - 684
    - 685
    - 686
    - 687
    - 688
    - 689
    - 690
    - 691
    - 692
    - 693
    - 694
    - 695
    - 696
    - 697
    - 698
    - 699
    - 700
    - 701
    - 702
    - 703
    - 704
    - 705
    - 706
    - 707
    - 708
    - 709
    - 710
    - 711
    - 712
    - 713
    - 714
    - 715
    - 716
    - 717
    - 718
    - 719
    - 720
    - 721
    - 722
    - 723
    - 724
    - 725
    - 726
    - 727
    - 728
    - 729
    - 730
    - 731
    - 732
    - 733
    - 734
    - 735
    - 736
    - 737
    - 738
    - 739
    - 740
    - 741
    - 742
    - 743
    - 744
    - 745
    - 746
    - 747
    - 748
    - 749
    - 750
    - 751
    - 752
    - 753
    - 754
    - 755
    - 756
    - 757
    - 758
    - 759
    - 760
    - 761
    - 762
    - 763
    - 764
    - 765
    - 766
    - 767
    - 768
    - 769
    - 770
    - 771
    - 772
    - 773
    - 774
    - 775
    - 776
    - 777
    - 778
    - 779
    - 780
    - 781
    - 782
    - 783
    - 784
    - 785
    - 786
    - 787
    - 788
    - 789
    - 790
    - 791
    - 792
    - 793
    - 794
    - 795
    - 796
    - 797
    - 798
    - 799
    - 800
    - 801
    - 802
    - 803
    - 804
    - 805
    - 806
    - 807
    - 808
    - 809
    - 810
    - 811
    - 812
    - 813
    - 814
    - 815
    - 816
    - 817
    - 818
    - 819
    - 820
    - 821
    - 822
    - 823
    - 824
    - 825
    - 826
    - 827
    - 828
    - 829
    - 830
    - 831
    - 832
    - 833
    - 834
    - 835
    - 836
    - 837
    - 838
    - 839
    - 840
    - 841
    - 842
    - 843
    - 844
    - 845
    - 846
    - 847
    - 848
    - 849
    - 850
    - 851
    - 852
    - 853
    - 854
    - 855
    - 856
    - 857
    - 858
    - 859
    - 860
    - 861
    - 862
    - 863
    - 864
    - 865
    - 866
    - 867
    - 868
    - 869
    - 870
    - 871
    - 872
    - 873
    - 874
    - 875
    - 876
    - 877
    - 878
    - 879
    - 880
    - 881
    - 882
    - 883
    - 884
    - 885
    - 886
    - 887
    - 888
    - 889
    - 890
    - 891
    - 892
    - 893
    - 894
    - 895
    - 896
    - 897
    - 898
    - 899
    - 900
    - 901
    - 902
    - 903
    - 904
    - 905
    - 906
    - 907
    - 908
    - 909
    - 910
    - 911
    - 912
    - 913
    - 914
    - 915
    - 916
    - 917
    - 918
    - 919
    - 920
    - 921
    - 922
    - 923
    - 924
    - 925
    - 926
    - 927
    - 928
    - 929
    - 930
    - 931
    - 932
    - 933
    - 934
    - 935
    - 936
    - 937
    - 938
    - 939
    - 940
    - 941
    - 942
    - 943
    - 944
    - 945
    - 946
    - 947
    - 948
    - 949
    - 950
    - 951
    - 952
    - 953
    - 954
    - 955
    - 956
    - 957
    - 958
    - 959
    - 960
    - 961
    - 962
    - 963
    - 964
    - 965
    - 966
    - 967
    - 968
    - 969
    - 970
    - 971
    - 972
    - 973
    - 974
    - 975
    - 976
    - 977
    - 978
    - 979
    - 980
    - 981
    - 982
    - 983
    - 984
    - 985
    - 986
    - 987
    - 988
    - 989
    - 990
    - 991
    - 992
    - 993
    - 994
    - 995
    - 996
    - 997
    - 998
    - 999
    -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
    -1028
    -1029
    -1030
    -1031
    -1032
    -1033
    -1034
    -1035
    -1036
    -1037
    -1038
    -1039
    -1040
    -1041
    -1042
    -1043
    -1044
    -1045
    -1046
    -1047
    -1048
    -1049
    -1050
    -1051
    -1052
    -1053
    -1054
    -1055
    -1056
    -1057
    -1058
    -1059
    -1060
    -1061
    -1062
    -1063
    -1064
    -1065
    -1066
    -1067
    -1068
    -1069
    -1070
    -1071
    -1072
    -1073
    -1074
    -1075
    -1076
    -1077
    -1078
    -1079
    -1080
    -1081
    -1082
    -1083
    -1084
    -1085
    -1086
    -1087
    -1088
    -1089
    -1090
    -1091
    -1092
    -1093
    -1094
    -1095
    -1096
    -1097
    -1098
    -1099
    -1100
    -1101
    -1102
    -1103
    -1104
    -1105
    -1106
    -1107
    -1108
    -1109
    -1110
    -1111
    -1112
    -1113
    -1114
    -1115
    -1116
    -1117
    -1118
    -1119
    -1120
    -1121
    -1122
    -1123
    -1124
    -1125
    -1126
    -1127
    -1128
    -1129
    -1130
    -1131
    -1132
    -1133
    -1134
    -1135
    -1136
    -1137
    -1138
    -1139
    -1140
    -1141
    -1142
    -1143
    -1144
    -1145
    -1146
    -1147
    -1148
    -1149
    -1150
    -1151
    -1152
    -1153
    -1154
    -1155
    -1156
    -1157
    -1158
    -1159
    -1160
    -1161
    -1162
    -1163
    -1164
    -1165
    -1166
    -1167
    -1168
    -1169
    -1170
    -1171
    -1172
    -1173
    -1174
    -1175
    -1176
    -1177
    -1178
    -1179
    -1180
    -1181
    -1182
    -1183
    -1184
    -1185
    -1186
    -1187
    -1188
    -1189
    -1190
    -1191
    -1192
    -1193
    -1194
    -1195
    -1196
    -1197
    -1198
    -1199
    -1200
    -1201
    -1202
    -1203
    -1204
    -1205
    -1206
    -1207
    -1208
    -1209
    -1210
    -1211
    -1212
    -1213
    -1214
    -1215
    -1216
    -1217
    -1218
    -1219
    -
    // Bitcoin Dev Kit
    -// Written in 2020 by Alekos Filini <alekos.filini@gmail.com>
    -//
    -// Copyright (c) 2020-2021 Bitcoin Dev Kit Developers
    -//
    -// This file is licensed under the Apache License, Version 2.0 <LICENSE-APACHE
    -// or http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
    -// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your option.
    -// You may not use this file except in accordance with one or both of these
    -// licenses.
    -
    -//! Descriptors DSL
    -
    -#[doc(hidden)]
    -#[macro_export]
    -macro_rules! impl_top_level_sh {
    -    // disallow `sortedmulti` in `bare()`
    -    ( Bare, new, new, Legacy, sortedmulti $( $inner:tt )* ) => {
    +dsl.rs - source
    1
    +2
    +3
    +4
    +5
    +6
    +7
    +8
    +9
    +10
    +11
    +12
    +13
    +14
    +15
    +16
    +17
    +18
    +19
    +20
    +21
    +22
    +23
    +24
    +25
    +26
    +27
    +28
    +29
    +30
    +31
    +32
    +33
    +34
    +35
    +36
    +37
    +38
    +39
    +40
    +41
    +42
    +43
    +44
    +45
    +46
    +47
    +48
    +49
    +50
    +51
    +52
    +53
    +54
    +55
    +56
    +57
    +58
    +59
    +60
    +61
    +62
    +63
    +64
    +65
    +66
    +67
    +68
    +69
    +70
    +71
    +72
    +73
    +74
    +75
    +76
    +77
    +78
    +79
    +80
    +81
    +82
    +83
    +84
    +85
    +86
    +87
    +88
    +89
    +90
    +91
    +92
    +93
    +94
    +95
    +96
    +97
    +98
    +99
    +100
    +101
    +102
    +103
    +104
    +105
    +106
    +107
    +108
    +109
    +110
    +111
    +112
    +113
    +114
    +115
    +116
    +117
    +118
    +119
    +120
    +121
    +122
    +123
    +124
    +125
    +126
    +127
    +128
    +129
    +130
    +131
    +132
    +133
    +134
    +135
    +136
    +137
    +138
    +139
    +140
    +141
    +142
    +143
    +144
    +145
    +146
    +147
    +148
    +149
    +150
    +151
    +152
    +153
    +154
    +155
    +156
    +157
    +158
    +159
    +160
    +161
    +162
    +163
    +164
    +165
    +166
    +167
    +168
    +169
    +170
    +171
    +172
    +173
    +174
    +175
    +176
    +177
    +178
    +179
    +180
    +181
    +182
    +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
    +245
    +246
    +247
    +248
    +249
    +250
    +251
    +252
    +253
    +254
    +255
    +256
    +257
    +258
    +259
    +260
    +261
    +262
    +263
    +264
    +265
    +266
    +267
    +268
    +269
    +270
    +271
    +272
    +273
    +274
    +275
    +276
    +277
    +278
    +279
    +280
    +281
    +282
    +283
    +284
    +285
    +286
    +287
    +288
    +289
    +290
    +291
    +292
    +293
    +294
    +295
    +296
    +297
    +298
    +299
    +300
    +301
    +302
    +303
    +304
    +305
    +306
    +307
    +308
    +309
    +310
    +311
    +312
    +313
    +314
    +315
    +316
    +317
    +318
    +319
    +320
    +321
    +322
    +323
    +324
    +325
    +326
    +327
    +328
    +329
    +330
    +331
    +332
    +333
    +334
    +335
    +336
    +337
    +338
    +339
    +340
    +341
    +342
    +343
    +344
    +345
    +346
    +347
    +348
    +349
    +350
    +351
    +352
    +353
    +354
    +355
    +356
    +357
    +358
    +359
    +360
    +361
    +362
    +363
    +364
    +365
    +366
    +367
    +368
    +369
    +370
    +371
    +372
    +373
    +374
    +375
    +376
    +377
    +378
    +379
    +380
    +381
    +382
    +383
    +384
    +385
    +386
    +387
    +388
    +389
    +390
    +391
    +392
    +393
    +394
    +395
    +396
    +397
    +398
    +399
    +400
    +401
    +402
    +403
    +404
    +405
    +406
    +407
    +408
    +409
    +410
    +411
    +412
    +413
    +414
    +415
    +416
    +417
    +418
    +419
    +420
    +421
    +422
    +423
    +424
    +425
    +426
    +427
    +428
    +429
    +430
    +431
    +432
    +433
    +434
    +435
    +436
    +437
    +438
    +439
    +440
    +441
    +442
    +443
    +444
    +445
    +446
    +447
    +448
    +449
    +450
    +451
    +452
    +453
    +454
    +455
    +456
    +457
    +458
    +459
    +460
    +461
    +462
    +463
    +464
    +465
    +466
    +467
    +468
    +469
    +470
    +471
    +472
    +473
    +474
    +475
    +476
    +477
    +478
    +479
    +480
    +481
    +482
    +483
    +484
    +485
    +486
    +487
    +488
    +489
    +490
    +491
    +492
    +493
    +494
    +495
    +496
    +497
    +498
    +499
    +500
    +501
    +502
    +503
    +504
    +505
    +506
    +507
    +508
    +509
    +510
    +511
    +512
    +513
    +514
    +515
    +516
    +517
    +518
    +519
    +520
    +521
    +522
    +523
    +524
    +525
    +526
    +527
    +528
    +529
    +530
    +531
    +532
    +533
    +534
    +535
    +536
    +537
    +538
    +539
    +540
    +541
    +542
    +543
    +544
    +545
    +546
    +547
    +548
    +549
    +550
    +551
    +552
    +553
    +554
    +555
    +556
    +557
    +558
    +559
    +560
    +561
    +562
    +563
    +564
    +565
    +566
    +567
    +568
    +569
    +570
    +571
    +572
    +573
    +574
    +575
    +576
    +577
    +578
    +579
    +580
    +581
    +582
    +583
    +584
    +585
    +586
    +587
    +588
    +589
    +590
    +591
    +592
    +593
    +594
    +595
    +596
    +597
    +598
    +599
    +600
    +601
    +602
    +603
    +604
    +605
    +606
    +607
    +608
    +609
    +610
    +611
    +612
    +613
    +614
    +615
    +616
    +617
    +618
    +619
    +620
    +621
    +622
    +623
    +624
    +625
    +626
    +627
    +628
    +629
    +630
    +631
    +632
    +633
    +634
    +635
    +636
    +637
    +638
    +639
    +640
    +641
    +642
    +643
    +644
    +645
    +646
    +647
    +648
    +649
    +650
    +651
    +652
    +653
    +654
    +655
    +656
    +657
    +658
    +659
    +660
    +661
    +662
    +663
    +664
    +665
    +666
    +667
    +668
    +669
    +670
    +671
    +672
    +673
    +674
    +675
    +676
    +677
    +678
    +679
    +680
    +681
    +682
    +683
    +684
    +685
    +686
    +687
    +688
    +689
    +690
    +691
    +692
    +693
    +694
    +695
    +696
    +697
    +698
    +699
    +700
    +701
    +702
    +703
    +704
    +705
    +706
    +707
    +708
    +709
    +710
    +711
    +712
    +713
    +714
    +715
    +716
    +717
    +718
    +719
    +720
    +721
    +722
    +723
    +724
    +725
    +726
    +727
    +728
    +729
    +730
    +731
    +732
    +733
    +734
    +735
    +736
    +737
    +738
    +739
    +740
    +741
    +742
    +743
    +744
    +745
    +746
    +747
    +748
    +749
    +750
    +751
    +752
    +753
    +754
    +755
    +756
    +757
    +758
    +759
    +760
    +761
    +762
    +763
    +764
    +765
    +766
    +767
    +768
    +769
    +770
    +771
    +772
    +773
    +774
    +775
    +776
    +777
    +778
    +779
    +780
    +781
    +782
    +783
    +784
    +785
    +786
    +787
    +788
    +789
    +790
    +791
    +792
    +793
    +794
    +795
    +796
    +797
    +798
    +799
    +800
    +801
    +802
    +803
    +804
    +805
    +806
    +807
    +808
    +809
    +810
    +811
    +812
    +813
    +814
    +815
    +816
    +817
    +818
    +819
    +820
    +821
    +822
    +823
    +824
    +825
    +826
    +827
    +828
    +829
    +830
    +831
    +832
    +833
    +834
    +835
    +836
    +837
    +838
    +839
    +840
    +841
    +842
    +843
    +844
    +845
    +846
    +847
    +848
    +849
    +850
    +851
    +852
    +853
    +854
    +855
    +856
    +857
    +858
    +859
    +860
    +861
    +862
    +863
    +864
    +865
    +866
    +867
    +868
    +869
    +870
    +871
    +872
    +873
    +874
    +875
    +876
    +877
    +878
    +879
    +880
    +881
    +882
    +883
    +884
    +885
    +886
    +887
    +888
    +889
    +890
    +891
    +892
    +893
    +894
    +895
    +896
    +897
    +898
    +899
    +900
    +901
    +902
    +903
    +904
    +905
    +906
    +907
    +908
    +909
    +910
    +911
    +912
    +913
    +914
    +915
    +916
    +917
    +918
    +919
    +920
    +921
    +922
    +923
    +924
    +925
    +926
    +927
    +928
    +929
    +930
    +931
    +932
    +933
    +934
    +935
    +936
    +937
    +938
    +939
    +940
    +941
    +942
    +943
    +944
    +945
    +946
    +947
    +948
    +949
    +950
    +951
    +952
    +953
    +954
    +955
    +956
    +957
    +958
    +959
    +960
    +961
    +962
    +963
    +964
    +965
    +966
    +967
    +968
    +969
    +970
    +971
    +972
    +973
    +974
    +975
    +976
    +977
    +978
    +979
    +980
    +981
    +982
    +983
    +984
    +985
    +986
    +987
    +988
    +989
    +990
    +991
    +992
    +993
    +994
    +995
    +996
    +997
    +998
    +999
    +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
    +1028
    +1029
    +1030
    +1031
    +1032
    +1033
    +1034
    +1035
    +1036
    +1037
    +1038
    +1039
    +1040
    +1041
    +1042
    +1043
    +1044
    +1045
    +1046
    +1047
    +1048
    +1049
    +1050
    +1051
    +1052
    +1053
    +1054
    +1055
    +1056
    +1057
    +1058
    +1059
    +1060
    +1061
    +1062
    +1063
    +1064
    +1065
    +1066
    +1067
    +1068
    +1069
    +1070
    +1071
    +1072
    +1073
    +1074
    +1075
    +1076
    +1077
    +1078
    +1079
    +1080
    +1081
    +1082
    +1083
    +1084
    +1085
    +1086
    +1087
    +1088
    +1089
    +1090
    +1091
    +1092
    +1093
    +1094
    +1095
    +1096
    +1097
    +1098
    +1099
    +1100
    +1101
    +1102
    +1103
    +1104
    +1105
    +1106
    +1107
    +1108
    +1109
    +1110
    +1111
    +1112
    +1113
    +1114
    +1115
    +1116
    +1117
    +1118
    +1119
    +1120
    +1121
    +1122
    +1123
    +1124
    +1125
    +1126
    +1127
    +1128
    +1129
    +1130
    +1131
    +1132
    +1133
    +1134
    +1135
    +1136
    +1137
    +1138
    +1139
    +1140
    +1141
    +1142
    +1143
    +1144
    +1145
    +1146
    +1147
    +1148
    +1149
    +1150
    +1151
    +1152
    +1153
    +1154
    +1155
    +1156
    +1157
    +1158
    +1159
    +1160
    +1161
    +1162
    +1163
    +1164
    +1165
    +1166
    +1167
    +1168
    +1169
    +1170
    +1171
    +1172
    +1173
    +1174
    +1175
    +1176
    +1177
    +1178
    +1179
    +1180
    +1181
    +1182
    +1183
    +1184
    +1185
    +1186
    +1187
    +1188
    +1189
    +1190
    +1191
    +1192
    +1193
    +1194
    +1195
    +1196
    +1197
    +1198
    +1199
    +1200
    +1201
    +1202
    +1203
    +1204
    +1205
    +1206
    +1207
    +1208
    +1209
    +1210
    +1211
    +1212
    +1213
    +1214
    +1215
    +1216
    +1217
    +1218
    +1219
    +
    // Bitcoin Dev Kit
    +// Written in 2020 by Alekos Filini <alekos.filini@gmail.com>
    +//
    +// Copyright (c) 2020-2021 Bitcoin Dev Kit Developers
    +//
    +// This file is licensed under the Apache License, Version 2.0 <LICENSE-APACHE
    +// or http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
    +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your option.
    +// You may not use this file except in accordance with one or both of these
    +// licenses.
    +
    +//! Descriptors DSL
    +
    +#[doc(hidden)]
    +#[macro_export]
    +macro_rules! impl_top_level_sh {
    +    // disallow `sortedmulti` in `bare()`
    +    ( Bare, new, new, Legacy, sortedmulti $( $inner:tt )* ) => {
             compile_error!("`bare()` descriptors can't contain any `sortedmulti()` operands");
         };
    -    ( Bare, new, new, Legacy, sortedmulti_vec $( $inner:tt )* ) => {
    +    ( Bare, new, new, Legacy, sortedmulti_vec $( $inner:tt )* ) => {
             compile_error!("`bare()` descriptors can't contain any `sortedmulti_vec()` operands");
         };
     
    -    ( $inner_struct:ident, $constructor:ident, $sortedmulti_constructor:ident, $ctx:ident, sortedmulti $( $inner:tt )* ) => {{
    -        use std::marker::PhantomData;
    +    ( $inner_struct:ident, $constructor:ident, $sortedmulti_constructor:ident, $ctx:ident, sortedmulti $( $inner:tt )* ) => {{
    +        use std::marker::PhantomData;
     
    -        use $crate::miniscript::descriptor::{$inner_struct, Descriptor, DescriptorPublicKey};
    -        use $crate::miniscript::$ctx;
    +        use $crate::miniscript::descriptor::{$inner_struct, Descriptor, DescriptorPublicKey};
    +        use $crate::miniscript::$ctx;
     
    -        let build_desc = |k, pks| {
    -            Ok((Descriptor::<DescriptorPublicKey>::$inner_struct($inner_struct::$sortedmulti_constructor(k, pks)?), PhantomData::<$ctx>))
    +        let build_desc = |k, pks| {
    +            Ok((Descriptor::<DescriptorPublicKey>::$inner_struct($inner_struct::$sortedmulti_constructor(k, pks)?), PhantomData::<$ctx>))
             };
     
    -        $crate::impl_sortedmulti!(build_desc, sortedmulti $( $inner )*)
    +        $crate::impl_sortedmulti!(build_desc, sortedmulti $( $inner )*)
         }};
    -    ( $inner_struct:ident, $constructor:ident, $sortedmulti_constructor:ident, $ctx:ident, sortedmulti_vec $( $inner:tt )* ) => {{
    -        use std::marker::PhantomData;
    +    ( $inner_struct:ident, $constructor:ident, $sortedmulti_constructor:ident, $ctx:ident, sortedmulti_vec $( $inner:tt )* ) => {{
    +        use std::marker::PhantomData;
     
    -        use $crate::miniscript::descriptor::{$inner_struct, Descriptor, DescriptorPublicKey};
    -        use $crate::miniscript::$ctx;
    +        use $crate::miniscript::descriptor::{$inner_struct, Descriptor, DescriptorPublicKey};
    +        use $crate::miniscript::$ctx;
     
    -        let build_desc = |k, pks| {
    -            Ok((Descriptor::<DescriptorPublicKey>::$inner_struct($inner_struct::$sortedmulti_constructor(k, pks)?), PhantomData::<$ctx>))
    +        let build_desc = |k, pks| {
    +            Ok((Descriptor::<DescriptorPublicKey>::$inner_struct($inner_struct::$sortedmulti_constructor(k, pks)?), PhantomData::<$ctx>))
             };
     
    -        $crate::impl_sortedmulti!(build_desc, sortedmulti_vec $( $inner )*)
    +        $crate::impl_sortedmulti!(build_desc, sortedmulti_vec $( $inner )*)
         }};
     
    -    ( $inner_struct:ident, $constructor:ident, $sortedmulti_constructor:ident, $ctx:ident, $( $minisc:tt )* ) => {{
    -        use $crate::miniscript::descriptor::{$inner_struct, Descriptor, DescriptorPublicKey};
    +    ( $inner_struct:ident, $constructor:ident, $sortedmulti_constructor:ident, $ctx:ident, $( $minisc:tt )* ) => {{
    +        use $crate::miniscript::descriptor::{$inner_struct, Descriptor, DescriptorPublicKey};
     
    -        $crate::fragment!($( $minisc )*)
    -            .and_then(|(minisc, keymap, networks)| Ok(($inner_struct::$constructor(minisc)?, keymap, networks)))
    -            .and_then(|(inner, key_map, valid_networks)| Ok((Descriptor::<DescriptorPublicKey>::$inner_struct(inner), key_map, valid_networks)))
    +        $crate::fragment!($( $minisc )*)
    +            .and_then(|(minisc, keymap, networks)| Ok(($inner_struct::$constructor(minisc)?, keymap, networks)))
    +            .and_then(|(inner, key_map, valid_networks)| Ok((Descriptor::<DescriptorPublicKey>::$inner_struct(inner), key_map, valid_networks)))
         }};
     }
     
    -#[doc(hidden)]
    -#[macro_export]
    -macro_rules! impl_top_level_pk {
    -    ( $inner_type:ident, $ctx:ty, $key:expr ) => {{
    -        use $crate::miniscript::descriptor::$inner_type;
    +#[doc(hidden)]
    +#[macro_export]
    +macro_rules! impl_top_level_pk {
    +    ( $inner_type:ident, $ctx:ty, $key:expr ) => {{
    +        use $crate::miniscript::descriptor::$inner_type;
     
    -        #[allow(unused_imports)]
    -        use $crate::keys::{DescriptorKey, IntoDescriptorKey};
    -        let secp = $crate::bitcoin::secp256k1::Secp256k1::new();
    +        #[allow(unused_imports)]
    +        use $crate::keys::{DescriptorKey, IntoDescriptorKey};
    +        let secp = $crate::bitcoin::secp256k1::Secp256k1::new();
     
    -        $key.into_descriptor_key()
    -            .and_then(|key: DescriptorKey<$ctx>| key.extract(&secp))
    -            .map_err($crate::descriptor::DescriptorError::Key)
    -            .map(|(pk, key_map, valid_networks)| ($inner_type::new(pk), key_map, valid_networks))
    +        $key.into_descriptor_key()
    +            .and_then(|key: DescriptorKey<$ctx>| key.extract(&secp))
    +            .map_err($crate::descriptor::DescriptorError::Key)
    +            .map(|(pk, key_map, valid_networks)| ($inner_type::new(pk), key_map, valid_networks))
         }};
     }
     
    -#[doc(hidden)]
    -#[macro_export]
    -macro_rules! impl_top_level_tr {
    -    ( $internal_key:expr, $tap_tree:expr ) => {{
    -        use $crate::miniscript::descriptor::{
    -            Descriptor, DescriptorPublicKey, KeyMap, TapTree, Tr,
    +#[doc(hidden)]
    +#[macro_export]
    +macro_rules! impl_top_level_tr {
    +    ( $internal_key:expr, $tap_tree:expr ) => {{
    +        use $crate::miniscript::descriptor::{
    +            Descriptor, DescriptorPublicKey, KeyMap, TapTree, Tr,
             };
    -        use $crate::miniscript::Tap;
    -
    -        #[allow(unused_imports)]
    -        use $crate::keys::{DescriptorKey, IntoDescriptorKey, ValidNetworks};
    -
    -        let secp = $crate::bitcoin::secp256k1::Secp256k1::new();
    -
    -        $internal_key
    -            .into_descriptor_key()
    -            .and_then(|key: DescriptorKey<Tap>| key.extract(&secp))
    -            .map_err($crate::descriptor::DescriptorError::Key)
    -            .and_then(|(pk, mut key_map, mut valid_networks)| {
    -                let tap_tree = $tap_tree.map(
    -                    |(tap_tree, tree_keymap, tree_networks): (
    -                        TapTree<DescriptorPublicKey>,
    -                        KeyMap,
    -                        ValidNetworks,
    -                    )| {
    -                        key_map.extend(tree_keymap.into_iter());
    -                        valid_networks =
    -                            $crate::keys::merge_networks(&valid_networks, &tree_networks);
    -
    -                        tap_tree
    +        use $crate::miniscript::Tap;
    +
    +        #[allow(unused_imports)]
    +        use $crate::keys::{DescriptorKey, IntoDescriptorKey, ValidNetworks};
    +
    +        let secp = $crate::bitcoin::secp256k1::Secp256k1::new();
    +
    +        $internal_key
    +            .into_descriptor_key()
    +            .and_then(|key: DescriptorKey<Tap>| key.extract(&secp))
    +            .map_err($crate::descriptor::DescriptorError::Key)
    +            .and_then(|(pk, mut key_map, mut valid_networks)| {
    +                let tap_tree = $tap_tree.map(
    +                    |(tap_tree, tree_keymap, tree_networks): (
    +                        TapTree<DescriptorPublicKey>,
    +                        KeyMap,
    +                        ValidNetworks,
    +                    )| {
    +                        key_map.extend(tree_keymap.into_iter());
    +                        valid_networks =
    +                            $crate::keys::merge_networks(&valid_networks, &tree_networks);
    +
    +                        tap_tree
                         },
                     );
     
                     Ok((
    -                    Descriptor::<DescriptorPublicKey>::Tr(Tr::new(pk, tap_tree)?),
    -                    key_map,
    -                    valid_networks,
    +                    Descriptor::<DescriptorPublicKey>::Tr(Tr::new(pk, tap_tree)?),
    +                    key_map,
    +                    valid_networks,
                     ))
                 })
         }};
     }
     
    -#[doc(hidden)]
    -#[macro_export]
    -macro_rules! impl_leaf_opcode {
    -    ( $terminal_variant:ident ) => {{
    -        use $crate::descriptor::CheckMiniscript;
    +#[doc(hidden)]
    +#[macro_export]
    +macro_rules! impl_leaf_opcode {
    +    ( $terminal_variant:ident ) => {{
    +        use $crate::descriptor::CheckMiniscript;
     
    -        $crate::miniscript::Miniscript::from_ast(
    -            $crate::miniscript::miniscript::decode::Terminal::$terminal_variant,
    +        $crate::miniscript::Miniscript::from_ast(
    +            $crate::miniscript::miniscript::decode::Terminal::$terminal_variant,
             )
    -        .map_err($crate::descriptor::DescriptorError::Miniscript)
    -        .and_then(|minisc| {
    -            minisc.check_miniscript()?;
    -            Ok(minisc)
    +        .map_err($crate::descriptor::DescriptorError::Miniscript)
    +        .and_then(|minisc| {
    +            minisc.check_miniscript()?;
    +            Ok(minisc)
             })
    -        .map(|minisc| {
    +        .map(|minisc| {
                 (
    -                minisc,
    -                $crate::miniscript::descriptor::KeyMap::default(),
    -                $crate::keys::any_network(),
    +                minisc,
    +                $crate::miniscript::descriptor::KeyMap::default(),
    +                $crate::keys::any_network(),
                 )
             })
         }};
     }
     
    -#[doc(hidden)]
    -#[macro_export]
    -macro_rules! impl_leaf_opcode_value {
    -    ( $terminal_variant:ident, $value:expr ) => {{
    -        use $crate::descriptor::CheckMiniscript;
    +#[doc(hidden)]
    +#[macro_export]
    +macro_rules! impl_leaf_opcode_value {
    +    ( $terminal_variant:ident, $value:expr ) => {{
    +        use $crate::descriptor::CheckMiniscript;
     
    -        $crate::miniscript::Miniscript::from_ast(
    -            $crate::miniscript::miniscript::decode::Terminal::$terminal_variant($value),
    +        $crate::miniscript::Miniscript::from_ast(
    +            $crate::miniscript::miniscript::decode::Terminal::$terminal_variant($value),
             )
    -        .map_err($crate::descriptor::DescriptorError::Miniscript)
    -        .and_then(|minisc| {
    -            minisc.check_miniscript()?;
    -            Ok(minisc)
    +        .map_err($crate::descriptor::DescriptorError::Miniscript)
    +        .and_then(|minisc| {
    +            minisc.check_miniscript()?;
    +            Ok(minisc)
             })
    -        .map(|minisc| {
    +        .map(|minisc| {
                 (
    -                minisc,
    -                $crate::miniscript::descriptor::KeyMap::default(),
    -                $crate::keys::any_network(),
    +                minisc,
    +                $crate::miniscript::descriptor::KeyMap::default(),
    +                $crate::keys::any_network(),
                 )
             })
         }};
     }
     
    -#[doc(hidden)]
    -#[macro_export]
    -macro_rules! impl_leaf_opcode_value_two {
    -    ( $terminal_variant:ident, $one:expr, $two:expr ) => {{
    -        use $crate::descriptor::CheckMiniscript;
    +#[doc(hidden)]
    +#[macro_export]
    +macro_rules! impl_leaf_opcode_value_two {
    +    ( $terminal_variant:ident, $one:expr, $two:expr ) => {{
    +        use $crate::descriptor::CheckMiniscript;
     
    -        $crate::miniscript::Miniscript::from_ast(
    -            $crate::miniscript::miniscript::decode::Terminal::$terminal_variant($one, $two),
    +        $crate::miniscript::Miniscript::from_ast(
    +            $crate::miniscript::miniscript::decode::Terminal::$terminal_variant($one, $two),
             )
    -        .map_err($crate::descriptor::DescriptorError::Miniscript)
    -        .and_then(|minisc| {
    -            minisc.check_miniscript()?;
    -            Ok(minisc)
    +        .map_err($crate::descriptor::DescriptorError::Miniscript)
    +        .and_then(|minisc| {
    +            minisc.check_miniscript()?;
    +            Ok(minisc)
             })
    -        .map(|minisc| {
    +        .map(|minisc| {
                 (
    -                minisc,
    -                $crate::miniscript::descriptor::KeyMap::default(),
    -                $crate::keys::any_network(),
    +                minisc,
    +                $crate::miniscript::descriptor::KeyMap::default(),
    +                $crate::keys::any_network(),
                 )
             })
         }};
     }
     
    -#[doc(hidden)]
    -#[macro_export]
    -macro_rules! impl_node_opcode_two {
    -    ( $terminal_variant:ident, $( $inner:tt )* ) => ({
    -        use $crate::descriptor::CheckMiniscript;
    +#[doc(hidden)]
    +#[macro_export]
    +macro_rules! impl_node_opcode_two {
    +    ( $terminal_variant:ident, $( $inner:tt )* ) => ({
    +        use $crate::descriptor::CheckMiniscript;
     
    -        let inner = $crate::fragment_internal!( @t $( $inner )* );
    -        let (a, b) = $crate::descriptor::dsl::TupleTwo::from(inner).flattened();
    +        let inner = $crate::fragment_internal!( @t $( $inner )* );
    +        let (a, b) = $crate::descriptor::dsl::TupleTwo::from(inner).flattened();
     
    -        a
    -            .and_then(|a| Ok((a, b?)))
    -            .and_then(|((a_minisc, mut a_keymap, a_networks), (b_minisc, b_keymap, b_networks))| {
    -                // join key_maps
    -                a_keymap.extend(b_keymap.into_iter());
    +        a
    +            .and_then(|a| Ok((a, b?)))
    +            .and_then(|((a_minisc, mut a_keymap, a_networks), (b_minisc, b_keymap, b_networks))| {
    +                // join key_maps
    +                a_keymap.extend(b_keymap.into_iter());
     
    -                let minisc = $crate::miniscript::Miniscript::from_ast($crate::miniscript::miniscript::decode::Terminal::$terminal_variant(
    -                    std::sync::Arc::new(a_minisc),
    -                    std::sync::Arc::new(b_minisc),
    +                let minisc = $crate::miniscript::Miniscript::from_ast($crate::miniscript::miniscript::decode::Terminal::$terminal_variant(
    +                    std::sync::Arc::new(a_minisc),
    +                    std::sync::Arc::new(b_minisc),
                     ))?;
     
    -                minisc.check_miniscript()?;
    +                minisc.check_miniscript()?;
     
    -                Ok((minisc, a_keymap, $crate::keys::merge_networks(&a_networks, &b_networks)))
    +                Ok((minisc, a_keymap, $crate::keys::merge_networks(&a_networks, &b_networks)))
                 })
         });
     }
     
    -#[doc(hidden)]
    -#[macro_export]
    -macro_rules! impl_node_opcode_three {
    -    ( $terminal_variant:ident, $( $inner:tt )* ) => ({
    -        use $crate::descriptor::CheckMiniscript;
    -
    -        let inner = $crate::fragment_internal!( @t $( $inner )* );
    -        let (a, b, c) = $crate::descriptor::dsl::TupleThree::from(inner).flattened();
    -
    -        a
    -            .and_then(|a| Ok((a, b?, c?)))
    -            .and_then(|((a_minisc, mut a_keymap, a_networks), (b_minisc, b_keymap, b_networks), (c_minisc, c_keymap, c_networks))| {
    -                // join key_maps
    -                a_keymap.extend(b_keymap.into_iter());
    -                a_keymap.extend(c_keymap.into_iter());
    -
    -                let networks = $crate::keys::merge_networks(&a_networks, &b_networks);
    -                let networks = $crate::keys::merge_networks(&networks, &c_networks);
    -
    -                let minisc = $crate::miniscript::Miniscript::from_ast($crate::miniscript::miniscript::decode::Terminal::$terminal_variant(
    -                    std::sync::Arc::new(a_minisc),
    -                    std::sync::Arc::new(b_minisc),
    -                    std::sync::Arc::new(c_minisc),
    +#[doc(hidden)]
    +#[macro_export]
    +macro_rules! impl_node_opcode_three {
    +    ( $terminal_variant:ident, $( $inner:tt )* ) => ({
    +        use $crate::descriptor::CheckMiniscript;
    +
    +        let inner = $crate::fragment_internal!( @t $( $inner )* );
    +        let (a, b, c) = $crate::descriptor::dsl::TupleThree::from(inner).flattened();
    +
    +        a
    +            .and_then(|a| Ok((a, b?, c?)))
    +            .and_then(|((a_minisc, mut a_keymap, a_networks), (b_minisc, b_keymap, b_networks), (c_minisc, c_keymap, c_networks))| {
    +                // join key_maps
    +                a_keymap.extend(b_keymap.into_iter());
    +                a_keymap.extend(c_keymap.into_iter());
    +
    +                let networks = $crate::keys::merge_networks(&a_networks, &b_networks);
    +                let networks = $crate::keys::merge_networks(&networks, &c_networks);
    +
    +                let minisc = $crate::miniscript::Miniscript::from_ast($crate::miniscript::miniscript::decode::Terminal::$terminal_variant(
    +                    std::sync::Arc::new(a_minisc),
    +                    std::sync::Arc::new(b_minisc),
    +                    std::sync::Arc::new(c_minisc),
                     ))?;
     
    -                minisc.check_miniscript()?;
    +                minisc.check_miniscript()?;
     
    -                Ok((minisc, a_keymap, networks))
    +                Ok((minisc, a_keymap, networks))
                 })
         });
     }
     
    -#[doc(hidden)]
    -#[macro_export]
    -macro_rules! impl_sortedmulti {
    -    ( $build_desc:expr, sortedmulti_vec ( $thresh:expr, $keys:expr ) ) => ({
    -        let secp = $crate::bitcoin::secp256k1::Secp256k1::new();
    -        $crate::keys::make_sortedmulti($thresh, $keys, $build_desc, &secp)
    +#[doc(hidden)]
    +#[macro_export]
    +macro_rules! impl_sortedmulti {
    +    ( $build_desc:expr, sortedmulti_vec ( $thresh:expr, $keys:expr ) ) => ({
    +        let secp = $crate::bitcoin::secp256k1::Secp256k1::new();
    +        $crate::keys::make_sortedmulti($thresh, $keys, $build_desc, &secp)
         });
    -    ( $build_desc:expr, sortedmulti ( $thresh:expr $(, $key:expr )+ ) ) => ({
    -        use $crate::keys::IntoDescriptorKey;
    -        let secp = $crate::bitcoin::secp256k1::Secp256k1::new();
    +    ( $build_desc:expr, sortedmulti ( $thresh:expr $(, $key:expr )+ ) ) => ({
    +        use $crate::keys::IntoDescriptorKey;
    +        let secp = $crate::bitcoin::secp256k1::Secp256k1::new();
     
    -        let keys = vec![
    +        let keys = vec![
                 $(
    -                $key.into_descriptor_key(),
    -            )*
    +                $key.into_descriptor_key(),
    +            )*
             ];
     
    -        keys.into_iter().collect::<Result<Vec<_>, _>>()
    -            .map_err($crate::descriptor::DescriptorError::Key)
    -            .and_then(|keys| $crate::keys::make_sortedmulti($thresh, keys, $build_desc, &secp))
    +        keys.into_iter().collect::<Result<Vec<_>, _>>()
    +            .map_err($crate::descriptor::DescriptorError::Key)
    +            .and_then(|keys| $crate::keys::make_sortedmulti($thresh, keys, $build_desc, &secp))
         });
     
     }
     
    -#[doc(hidden)]
    -#[macro_export]
    -macro_rules! parse_tap_tree {
    -    ( @merge $tree_a:expr, $tree_b:expr) => {{
    -        use std::sync::Arc;
    -        use $crate::miniscript::descriptor::TapTree;
    -
    -        $tree_a
    -            .and_then(|tree_a| Ok((tree_a, $tree_b?)))
    -            .and_then(|((a_tree, mut a_keymap, a_networks), (b_tree, b_keymap, b_networks))| {
    -                a_keymap.extend(b_keymap.into_iter());
    -                Ok((TapTree::Tree(Arc::new(a_tree), Arc::new(b_tree)), a_keymap, $crate::keys::merge_networks(&a_networks, &b_networks)))
    +#[doc(hidden)]
    +#[macro_export]
    +macro_rules! parse_tap_tree {
    +    ( @merge $tree_a:expr, $tree_b:expr) => {{
    +        use std::sync::Arc;
    +        use $crate::miniscript::descriptor::TapTree;
    +
    +        $tree_a
    +            .and_then(|tree_a| Ok((tree_a, $tree_b?)))
    +            .and_then(|((a_tree, mut a_keymap, a_networks), (b_tree, b_keymap, b_networks))| {
    +                a_keymap.extend(b_keymap.into_iter());
    +                Ok((TapTree::Tree(Arc::new(a_tree), Arc::new(b_tree)), a_keymap, $crate::keys::merge_networks(&a_networks, &b_networks)))
                 })
     
         }};
     
    -    // Two sub-trees
    -    ( { { $( $tree_a:tt )* }, { $( $tree_b:tt )* } } ) => {{
    -        let tree_a = $crate::parse_tap_tree!( { $( $tree_a )* } );
    -        let tree_b = $crate::parse_tap_tree!( { $( $tree_b )* } );
    +    // Two sub-trees
    +    ( { { $( $tree_a:tt )* }, { $( $tree_b:tt )* } } ) => {{
    +        let tree_a = $crate::parse_tap_tree!( { $( $tree_a )* } );
    +        let tree_b = $crate::parse_tap_tree!( { $( $tree_b )* } );
     
    -        $crate::parse_tap_tree!(@merge tree_a, tree_b)
    +        $crate::parse_tap_tree!(@merge tree_a, tree_b)
         }};
     
    -    // One leaf and a sub-tree
    -    ( { $op_a:ident ( $( $minisc_a:tt )* ), { $( $tree_b:tt )* } } ) => {{
    -        let tree_a = $crate::parse_tap_tree!( $op_a ( $( $minisc_a )* ) );
    -        let tree_b = $crate::parse_tap_tree!( { $( $tree_b )* } );
    +    // One leaf and a sub-tree
    +    ( { $op_a:ident ( $( $minisc_a:tt )* ), { $( $tree_b:tt )* } } ) => {{
    +        let tree_a = $crate::parse_tap_tree!( $op_a ( $( $minisc_a )* ) );
    +        let tree_b = $crate::parse_tap_tree!( { $( $tree_b )* } );
     
    -        $crate::parse_tap_tree!(@merge tree_a, tree_b)
    +        $crate::parse_tap_tree!(@merge tree_a, tree_b)
         }};
    -    ( { { $( $tree_a:tt )* }, $op_b:ident ( $( $minisc_b:tt )* ) } ) => {{
    -        let tree_a = $crate::parse_tap_tree!( { $( $tree_a )* } );
    -        let tree_b = $crate::parse_tap_tree!( $op_b ( $( $minisc_b )* ) );
    +    ( { { $( $tree_a:tt )* }, $op_b:ident ( $( $minisc_b:tt )* ) } ) => {{
    +        let tree_a = $crate::parse_tap_tree!( { $( $tree_a )* } );
    +        let tree_b = $crate::parse_tap_tree!( $op_b ( $( $minisc_b )* ) );
     
    -        $crate::parse_tap_tree!(@merge tree_a, tree_b)
    +        $crate::parse_tap_tree!(@merge tree_a, tree_b)
         }};
     
    -    // Two leaves
    -    ( { $op_a:ident ( $( $minisc_a:tt )* ), $op_b:ident ( $( $minisc_b:tt )* ) } ) => {{
    -        let tree_a = $crate::parse_tap_tree!( $op_a ( $( $minisc_a )* ) );
    -        let tree_b = $crate::parse_tap_tree!( $op_b ( $( $minisc_b )* ) );
    +    // Two leaves
    +    ( { $op_a:ident ( $( $minisc_a:tt )* ), $op_b:ident ( $( $minisc_b:tt )* ) } ) => {{
    +        let tree_a = $crate::parse_tap_tree!( $op_a ( $( $minisc_a )* ) );
    +        let tree_b = $crate::parse_tap_tree!( $op_b ( $( $minisc_b )* ) );
     
    -        $crate::parse_tap_tree!(@merge tree_a, tree_b)
    +        $crate::parse_tap_tree!(@merge tree_a, tree_b)
         }};
     
    -    // Single leaf
    -    ( $op:ident ( $( $minisc:tt )* ) ) => {{
    -        use std::sync::Arc;
    -        use $crate::miniscript::descriptor::TapTree;
    +    // Single leaf
    +    ( $op:ident ( $( $minisc:tt )* ) ) => {{
    +        use std::sync::Arc;
    +        use $crate::miniscript::descriptor::TapTree;
     
    -        $crate::fragment!( $op ( $( $minisc )* ) )
    -            .map(|(a_minisc, a_keymap, a_networks)| (TapTree::Leaf(Arc::new(a_minisc)), a_keymap, a_networks))
    +        $crate::fragment!( $op ( $( $minisc )* ) )
    +            .map(|(a_minisc, a_keymap, a_networks)| (TapTree::Leaf(Arc::new(a_minisc)), a_keymap, a_networks))
         }};
     }
     
    -#[doc(hidden)]
    -#[macro_export]
    -macro_rules! apply_modifier {
    -    ( $terminal_variant:ident, $inner:expr ) => {{
    -        use $crate::descriptor::CheckMiniscript;
    -
    -        $inner
    -            .map_err(|e| -> $crate::descriptor::DescriptorError { e.into() })
    -            .and_then(|(minisc, keymap, networks)| {
    -                let minisc = $crate::miniscript::Miniscript::from_ast(
    -                    $crate::miniscript::miniscript::decode::Terminal::$terminal_variant(
    -                        std::sync::Arc::new(minisc),
    +#[doc(hidden)]
    +#[macro_export]
    +macro_rules! apply_modifier {
    +    ( $terminal_variant:ident, $inner:expr ) => {{
    +        use $crate::descriptor::CheckMiniscript;
    +
    +        $inner
    +            .map_err(|e| -> $crate::descriptor::DescriptorError { e.into() })
    +            .and_then(|(minisc, keymap, networks)| {
    +                let minisc = $crate::miniscript::Miniscript::from_ast(
    +                    $crate::miniscript::miniscript::decode::Terminal::$terminal_variant(
    +                        std::sync::Arc::new(minisc),
                         ),
                     )?;
     
    -                minisc.check_miniscript()?;
    +                minisc.check_miniscript()?;
     
    -                Ok((minisc, keymap, networks))
    +                Ok((minisc, keymap, networks))
                 })
         }};
     
    -    ( a: $inner:expr ) => {{
    -        $crate::apply_modifier!(Alt, $inner)
    +    ( a: $inner:expr ) => {{
    +        $crate::apply_modifier!(Alt, $inner)
         }};
    -    ( s: $inner:expr ) => {{
    -        $crate::apply_modifier!(Swap, $inner)
    +    ( s: $inner:expr ) => {{
    +        $crate::apply_modifier!(Swap, $inner)
         }};
    -    ( c: $inner:expr ) => {{
    -        $crate::apply_modifier!(Check, $inner)
    +    ( c: $inner:expr ) => {{
    +        $crate::apply_modifier!(Check, $inner)
         }};
    -    ( d: $inner:expr ) => {{
    -        $crate::apply_modifier!(DupIf, $inner)
    +    ( d: $inner:expr ) => {{
    +        $crate::apply_modifier!(DupIf, $inner)
         }};
    -    ( v: $inner:expr ) => {{
    -        $crate::apply_modifier!(Verify, $inner)
    +    ( v: $inner:expr ) => {{
    +        $crate::apply_modifier!(Verify, $inner)
         }};
    -    ( j: $inner:expr ) => {{
    -        $crate::apply_modifier!(NonZero, $inner)
    +    ( j: $inner:expr ) => {{
    +        $crate::apply_modifier!(NonZero, $inner)
         }};
    -    ( n: $inner:expr ) => {{
    -        $crate::apply_modifier!(ZeroNotEqual, $inner)
    +    ( n: $inner:expr ) => {{
    +        $crate::apply_modifier!(ZeroNotEqual, $inner)
         }};
     
    -    // Modifiers expanded to other operators
    -    ( t: $inner:expr ) => {{
    -        $inner.and_then(|(a_minisc, a_keymap, a_networks)| {
    +    // Modifiers expanded to other operators
    +    ( t: $inner:expr ) => {{
    +        $inner.and_then(|(a_minisc, a_keymap, a_networks)| {
                 $crate::impl_leaf_opcode_value_two!(
                     AndV,
    -                std::sync::Arc::new(a_minisc),
    -                std::sync::Arc::new($crate::fragment!(true).unwrap().0)
    +                std::sync::Arc::new(a_minisc),
    +                std::sync::Arc::new($crate::fragment!(true).unwrap().0)
                 )
    -            .map(|(minisc, _, _)| (minisc, a_keymap, a_networks))
    +            .map(|(minisc, _, _)| (minisc, a_keymap, a_networks))
             })
         }};
    -    ( l: $inner:expr ) => {{
    -        $inner.and_then(|(a_minisc, a_keymap, a_networks)| {
    +    ( l: $inner:expr ) => {{
    +        $inner.and_then(|(a_minisc, a_keymap, a_networks)| {
                 $crate::impl_leaf_opcode_value_two!(
                     OrI,
    -                std::sync::Arc::new($crate::fragment!(false).unwrap().0),
    -                std::sync::Arc::new(a_minisc)
    +                std::sync::Arc::new($crate::fragment!(false).unwrap().0),
    +                std::sync::Arc::new(a_minisc)
                 )
    -            .map(|(minisc, _, _)| (minisc, a_keymap, a_networks))
    +            .map(|(minisc, _, _)| (minisc, a_keymap, a_networks))
             })
         }};
    -    ( u: $inner:expr ) => {{
    -        $inner.and_then(|(a_minisc, a_keymap, a_networks)| {
    +    ( u: $inner:expr ) => {{
    +        $inner.and_then(|(a_minisc, a_keymap, a_networks)| {
                 $crate::impl_leaf_opcode_value_two!(
                     OrI,
    -                std::sync::Arc::new(a_minisc),
    -                std::sync::Arc::new($crate::fragment!(false).unwrap().0)
    +                std::sync::Arc::new(a_minisc),
    +                std::sync::Arc::new($crate::fragment!(false).unwrap().0)
                 )
    -            .map(|(minisc, _, _)| (minisc, a_keymap, a_networks))
    +            .map(|(minisc, _, _)| (minisc, a_keymap, a_networks))
             })
         }};
     }
     
    -/// Macro to write full descriptors with code
    -///
    -/// This macro expands to a `Result` of
    -/// [`DescriptorTemplateOut`](super::template::DescriptorTemplateOut) and [`DescriptorError`](crate::descriptor::DescriptorError)
    -///
    -/// The syntax is very similar to the normal descriptor syntax, with the exception that modifiers
    -/// cannot be grouped together. For instance, a descriptor fragment like `sdv:older(144)` has to be
    -/// broken up to `s:d:v:older(144)`.
    -///
    -/// The `pk()`, `pk_k()` and `pk_h()` operands can take as argument any type that implements
    -/// [`IntoDescriptorKey`]. This means that keys can also be written inline as strings, but in that
    -/// case they must be wrapped in quotes, which is another difference compared to the standard
    -/// descriptor syntax.
    -///
    -/// [`IntoDescriptorKey`]: crate::keys::IntoDescriptorKey
    -///
    -/// ## Example
    -///
    -/// Signature plus timelock descriptor:
    -///
    -/// ```
    -/// # use std::str::FromStr;
    -/// let (my_descriptor, my_keys_map, networks) = bdk::descriptor!(sh(wsh(and_v(v:pk("cVt4o7BGAig1UXywgGSmARhxMdzP5qvQsxKkSsc1XEkw3tDTQFpy"),older(50)))))?;
    -/// # Ok::<(), Box<dyn std::error::Error>>(())
    -/// ```
    -///
    -/// -------
    -///
    -/// 2-of-3 that becomes a 1-of-3 after a timelock has expired. Both `descriptor_a` and `descriptor_b` are equivalent: the first
    -/// syntax is more suitable for a fixed number of items known at compile time, while the other accepts a
    -/// [`Vec`] of items, which makes it more suitable for writing dynamic descriptors.
    -///
    -/// They both produce the descriptor: `wsh(thresh(2,pk(...),s:pk(...),sndv:older(...)))`
    -///
    -/// ```
    -/// # use std::str::FromStr;
    -/// let my_key_1 = bitcoin::PublicKey::from_str(
    -///     "02e96fe52ef0e22d2f131dd425ce1893073a3c6ad20e8cac36726393dfb4856a4c",
    -/// )?;
    -/// let my_key_2 =
    -///     bitcoin::PrivateKey::from_wif("cVt4o7BGAig1UXywgGSmARhxMdzP5qvQsxKkSsc1XEkw3tDTQFpy")?;
    -/// let my_timelock = 50;
    -///
    -/// let (descriptor_a, key_map_a, networks) = bdk::descriptor! {
    -///     wsh (
    -///         thresh(2, pk(my_key_1), s:pk(my_key_2), s:n:d:v:older(my_timelock))
    -///     )
    -/// }?;
    -///
    -/// #[rustfmt::skip]
    -/// let b_items = vec![
    -///     bdk::fragment!(pk(my_key_1))?,
    -///     bdk::fragment!(s:pk(my_key_2))?,
    -///     bdk::fragment!(s:n:d:v:older(my_timelock))?,
    -/// ];
    -/// let (descriptor_b, mut key_map_b, networks) = bdk::descriptor!(wsh(thresh_vec(2, b_items)))?;
    -///
    -/// assert_eq!(descriptor_a, descriptor_b);
    -/// assert_eq!(key_map_a.len(), key_map_b.len());
    -/// # Ok::<(), Box<dyn std::error::Error>>(())
    -/// ```
    -///
    -/// ------
    -///
    -/// Simple 2-of-2 multi-signature, equivalent to: `wsh(multi(2, ...))`
    -///
    -/// ```
    -/// # use std::str::FromStr;
    -/// let my_key_1 = bitcoin::PublicKey::from_str(
    -///     "02e96fe52ef0e22d2f131dd425ce1893073a3c6ad20e8cac36726393dfb4856a4c",
    -/// )?;
    -/// let my_key_2 =
    -///     bitcoin::PrivateKey::from_wif("cVt4o7BGAig1UXywgGSmARhxMdzP5qvQsxKkSsc1XEkw3tDTQFpy")?;
    -///
    -/// let (descriptor, key_map, networks) = bdk::descriptor! {
    -///     wsh (
    -///         multi(2, my_key_1, my_key_2)
    -///     )
    -/// }?;
    -/// # Ok::<(), Box<dyn std::error::Error>>(())
    -/// ```
    -///
    -/// ------
    -///
    -/// Native-Segwit single-sig, equivalent to: `wpkh(...)`
    -///
    -/// ```
    -/// let my_key =
    -///     bitcoin::PrivateKey::from_wif("cVt4o7BGAig1UXywgGSmARhxMdzP5qvQsxKkSsc1XEkw3tDTQFpy")?;
    -///
    -/// let (descriptor, key_map, networks) = bdk::descriptor!(wpkh(my_key))?;
    -/// # Ok::<(), Box<dyn std::error::Error>>(())
    -/// ```
    -#[macro_export]
    -macro_rules! descriptor {
    -    ( bare ( $( $minisc:tt )* ) ) => ({
    -        $crate::impl_top_level_sh!(Bare, new, new, Legacy, $( $minisc )*)
    +/// Macro to write full descriptors with code
    +///
    +/// This macro expands to a `Result` of
    +/// [`DescriptorTemplateOut`](super::template::DescriptorTemplateOut) and [`DescriptorError`](crate::descriptor::DescriptorError)
    +///
    +/// The syntax is very similar to the normal descriptor syntax, with the exception that modifiers
    +/// cannot be grouped together. For instance, a descriptor fragment like `sdv:older(144)` has to be
    +/// broken up to `s:d:v:older(144)`.
    +///
    +/// The `pk()`, `pk_k()` and `pk_h()` operands can take as argument any type that implements
    +/// [`IntoDescriptorKey`]. This means that keys can also be written inline as strings, but in that
    +/// case they must be wrapped in quotes, which is another difference compared to the standard
    +/// descriptor syntax.
    +///
    +/// [`IntoDescriptorKey`]: crate::keys::IntoDescriptorKey
    +///
    +/// ## Example
    +///
    +/// Signature plus timelock descriptor:
    +///
    +/// ```
    +/// # use std::str::FromStr;
    +/// let (my_descriptor, my_keys_map, networks) = bdk::descriptor!(sh(wsh(and_v(v:pk("cVt4o7BGAig1UXywgGSmARhxMdzP5qvQsxKkSsc1XEkw3tDTQFpy"),older(50)))))?;
    +/// # Ok::<(), Box<dyn std::error::Error>>(())
    +/// ```
    +///
    +/// -------
    +///
    +/// 2-of-3 that becomes a 1-of-3 after a timelock has expired. Both `descriptor_a` and `descriptor_b` are equivalent: the first
    +/// syntax is more suitable for a fixed number of items known at compile time, while the other accepts a
    +/// [`Vec`] of items, which makes it more suitable for writing dynamic descriptors.
    +///
    +/// They both produce the descriptor: `wsh(thresh(2,pk(...),s:pk(...),sndv:older(...)))`
    +///
    +/// ```
    +/// # use std::str::FromStr;
    +/// let my_key_1 = bitcoin::PublicKey::from_str(
    +///     "02e96fe52ef0e22d2f131dd425ce1893073a3c6ad20e8cac36726393dfb4856a4c",
    +/// )?;
    +/// let my_key_2 =
    +///     bitcoin::PrivateKey::from_wif("cVt4o7BGAig1UXywgGSmARhxMdzP5qvQsxKkSsc1XEkw3tDTQFpy")?;
    +/// let my_timelock = 50;
    +///
    +/// let (descriptor_a, key_map_a, networks) = bdk::descriptor! {
    +///     wsh (
    +///         thresh(2, pk(my_key_1), s:pk(my_key_2), s:n:d:v:older(my_timelock))
    +///     )
    +/// }?;
    +///
    +/// #[rustfmt::skip]
    +/// let b_items = vec![
    +///     bdk::fragment!(pk(my_key_1))?,
    +///     bdk::fragment!(s:pk(my_key_2))?,
    +///     bdk::fragment!(s:n:d:v:older(my_timelock))?,
    +/// ];
    +/// let (descriptor_b, mut key_map_b, networks) = bdk::descriptor!(wsh(thresh_vec(2, b_items)))?;
    +///
    +/// assert_eq!(descriptor_a, descriptor_b);
    +/// assert_eq!(key_map_a.len(), key_map_b.len());
    +/// # Ok::<(), Box<dyn std::error::Error>>(())
    +/// ```
    +///
    +/// ------
    +///
    +/// Simple 2-of-2 multi-signature, equivalent to: `wsh(multi(2, ...))`
    +///
    +/// ```
    +/// # use std::str::FromStr;
    +/// let my_key_1 = bitcoin::PublicKey::from_str(
    +///     "02e96fe52ef0e22d2f131dd425ce1893073a3c6ad20e8cac36726393dfb4856a4c",
    +/// )?;
    +/// let my_key_2 =
    +///     bitcoin::PrivateKey::from_wif("cVt4o7BGAig1UXywgGSmARhxMdzP5qvQsxKkSsc1XEkw3tDTQFpy")?;
    +///
    +/// let (descriptor, key_map, networks) = bdk::descriptor! {
    +///     wsh (
    +///         multi(2, my_key_1, my_key_2)
    +///     )
    +/// }?;
    +/// # Ok::<(), Box<dyn std::error::Error>>(())
    +/// ```
    +///
    +/// ------
    +///
    +/// Native-Segwit single-sig, equivalent to: `wpkh(...)`
    +///
    +/// ```
    +/// let my_key =
    +///     bitcoin::PrivateKey::from_wif("cVt4o7BGAig1UXywgGSmARhxMdzP5qvQsxKkSsc1XEkw3tDTQFpy")?;
    +///
    +/// let (descriptor, key_map, networks) = bdk::descriptor!(wpkh(my_key))?;
    +/// # Ok::<(), Box<dyn std::error::Error>>(())
    +/// ```
    +#[macro_export]
    +macro_rules! descriptor {
    +    ( bare ( $( $minisc:tt )* ) ) => ({
    +        $crate::impl_top_level_sh!(Bare, new, new, Legacy, $( $minisc )*)
         });
    -    ( sh ( wsh ( $( $minisc:tt )* ) ) ) => ({
    -        $crate::descriptor!(shwsh ($( $minisc )*))
    +    ( sh ( wsh ( $( $minisc:tt )* ) ) ) => ({
    +        $crate::descriptor!(shwsh ($( $minisc )*))
         });
    -    ( shwsh ( $( $minisc:tt )* ) ) => ({
    -        $crate::impl_top_level_sh!(Sh, new_wsh, new_wsh_sortedmulti, Segwitv0, $( $minisc )*)
    +    ( shwsh ( $( $minisc:tt )* ) ) => ({
    +        $crate::impl_top_level_sh!(Sh, new_wsh, new_wsh_sortedmulti, Segwitv0, $( $minisc )*)
         });
    -    ( pk ( $key:expr ) ) => ({
    -        // `pk()` is actually implemented as `bare(pk())`
    -        $crate::descriptor!( bare ( pk ( $key ) ) )
    +    ( pk ( $key:expr ) ) => ({
    +        // `pk()` is actually implemented as `bare(pk())`
    +        $crate::descriptor!( bare ( pk ( $key ) ) )
         });
    -    ( pkh ( $key:expr ) ) => ({
    -        use $crate::miniscript::descriptor::{Descriptor, DescriptorPublicKey};
    +    ( pkh ( $key:expr ) ) => ({
    +        use $crate::miniscript::descriptor::{Descriptor, DescriptorPublicKey};
     
    -        $crate::impl_top_level_pk!(Pkh, $crate::miniscript::Legacy, $key)
    -            .map(|(a, b, c)| (Descriptor::<DescriptorPublicKey>::Pkh(a), b, c))
    +        $crate::impl_top_level_pk!(Pkh, $crate::miniscript::Legacy, $key)
    +            .map(|(a, b, c)| (Descriptor::<DescriptorPublicKey>::Pkh(a), b, c))
         });
    -    ( wpkh ( $key:expr ) ) => ({
    -        use $crate::miniscript::descriptor::{Descriptor, DescriptorPublicKey};
    +    ( wpkh ( $key:expr ) ) => ({
    +        use $crate::miniscript::descriptor::{Descriptor, DescriptorPublicKey};
     
    -        $crate::impl_top_level_pk!(Wpkh, $crate::miniscript::Segwitv0, $key)
    -            .and_then(|(a, b, c)| Ok((a?, b, c)))
    -            .map(|(a, b, c)| (Descriptor::<DescriptorPublicKey>::Wpkh(a), b, c))
    +        $crate::impl_top_level_pk!(Wpkh, $crate::miniscript::Segwitv0, $key)
    +            .and_then(|(a, b, c)| Ok((a?, b, c)))
    +            .map(|(a, b, c)| (Descriptor::<DescriptorPublicKey>::Wpkh(a), b, c))
         });
    -    ( sh ( wpkh ( $key:expr ) ) ) => ({
    -        $crate::descriptor!(shwpkh ( $key ))
    +    ( sh ( wpkh ( $key:expr ) ) ) => ({
    +        $crate::descriptor!(shwpkh ( $key ))
         });
    -    ( shwpkh ( $key:expr ) ) => ({
    -        use $crate::miniscript::descriptor::{Descriptor, DescriptorPublicKey, Sh};
    +    ( shwpkh ( $key:expr ) ) => ({
    +        use $crate::miniscript::descriptor::{Descriptor, DescriptorPublicKey, Sh};
     
    -        $crate::impl_top_level_pk!(Wpkh, $crate::miniscript::Segwitv0, $key)
    -            .and_then(|(a, b, c)| Ok((a?, b, c)))
    -            .and_then(|(a, b, c)| Ok((Descriptor::<DescriptorPublicKey>::Sh(Sh::new_wpkh(a.into_inner())?), b, c)))
    +        $crate::impl_top_level_pk!(Wpkh, $crate::miniscript::Segwitv0, $key)
    +            .and_then(|(a, b, c)| Ok((a?, b, c)))
    +            .and_then(|(a, b, c)| Ok((Descriptor::<DescriptorPublicKey>::Sh(Sh::new_wpkh(a.into_inner())?), b, c)))
         });
    -    ( sh ( $( $minisc:tt )* ) ) => ({
    -        $crate::impl_top_level_sh!(Sh, new, new_sortedmulti, Legacy, $( $minisc )*)
    +    ( sh ( $( $minisc:tt )* ) ) => ({
    +        $crate::impl_top_level_sh!(Sh, new, new_sortedmulti, Legacy, $( $minisc )*)
         });
    -    ( wsh ( $( $minisc:tt )* ) ) => ({
    -        $crate::impl_top_level_sh!(Wsh, new, new_sortedmulti, Segwitv0, $( $minisc )*)
    +    ( wsh ( $( $minisc:tt )* ) ) => ({
    +        $crate::impl_top_level_sh!(Wsh, new, new_sortedmulti, Segwitv0, $( $minisc )*)
         });
     
    -    ( tr ( $internal_key:expr ) ) => ({
    -        $crate::impl_top_level_tr!($internal_key, None)
    +    ( tr ( $internal_key:expr ) ) => ({
    +        $crate::impl_top_level_tr!($internal_key, None)
         });
    -    ( tr ( $internal_key:expr, $( $taptree:tt )* ) ) => ({
    -        let tap_tree = $crate::parse_tap_tree!( $( $taptree )* );
    -        tap_tree
    -            .and_then(|tap_tree| $crate::impl_top_level_tr!($internal_key, Some(tap_tree)))
    +    ( tr ( $internal_key:expr, $( $taptree:tt )* ) ) => ({
    +        let tap_tree = $crate::parse_tap_tree!( $( $taptree )* );
    +        tap_tree
    +            .and_then(|tap_tree| $crate::impl_top_level_tr!($internal_key, Some(tap_tree)))
         });
     }
     
    -#[doc(hidden)]
    -pub struct TupleTwo<A, B> {
    -    pub a: A,
    -    pub b: B,
    +#[doc(hidden)]
    +pub struct TupleTwo<A, B> {
    +    pub a: A,
    +    pub b: B,
     }
     
    -impl<A, B> TupleTwo<A, B> {
    -    pub fn flattened(self) -> (A, B) {
    -        (self.a, self.b)
    +impl<A, B> TupleTwo<A, B> {
    +    pub fn flattened(self) -> (A, B) {
    +        (self.a, self.b)
         }
     }
     
    -impl<A, B> From<(A, (B, ()))> for TupleTwo<A, B> {
    -    fn from((a, (b, _)): (A, (B, ()))) -> Self {
    -        TupleTwo { a, b }
    +impl<A, B> From<(A, (B, ()))> for TupleTwo<A, B> {
    +    fn from((a, (b, _)): (A, (B, ()))) -> Self {
    +        TupleTwo { a, b }
         }
     }
     
    -#[doc(hidden)]
    -pub struct TupleThree<A, B, C> {
    -    pub a: A,
    -    pub b: B,
    -    pub c: C,
    +#[doc(hidden)]
    +pub struct TupleThree<A, B, C> {
    +    pub a: A,
    +    pub b: B,
    +    pub c: C,
     }
     
    -impl<A, B, C> TupleThree<A, B, C> {
    -    pub fn flattened(self) -> (A, B, C) {
    -        (self.a, self.b, self.c)
    +impl<A, B, C> TupleThree<A, B, C> {
    +    pub fn flattened(self) -> (A, B, C) {
    +        (self.a, self.b, self.c)
         }
     }
     
    -impl<A, B, C> From<(A, (B, (C, ())))> for TupleThree<A, B, C> {
    -    fn from((a, (b, (c, _))): (A, (B, (C, ())))) -> Self {
    -        TupleThree { a, b, c }
    +impl<A, B, C> From<(A, (B, (C, ())))> for TupleThree<A, B, C> {
    +    fn from((a, (b, (c, _))): (A, (B, (C, ())))) -> Self {
    +        TupleThree { a, b, c }
         }
     }
     
    -#[doc(hidden)]
    -#[macro_export]
    -macro_rules! group_multi_keys {
    -    ( $( $key:expr ),+ ) => {{
    -        use $crate::keys::IntoDescriptorKey;
    +#[doc(hidden)]
    +#[macro_export]
    +macro_rules! group_multi_keys {
    +    ( $( $key:expr ),+ ) => {{
    +        use $crate::keys::IntoDescriptorKey;
     
    -        let keys = vec![
    +        let keys = vec![
                 $(
    -                $key.into_descriptor_key(),
    -            )*
    +                $key.into_descriptor_key(),
    +            )*
             ];
     
    -        keys.into_iter().collect::<Result<Vec<_>, _>>()
    -            .map_err($crate::descriptor::DescriptorError::Key)
    +        keys.into_iter().collect::<Result<Vec<_>, _>>()
    +            .map_err($crate::descriptor::DescriptorError::Key)
         }};
     }
     
    -#[doc(hidden)]
    -#[macro_export]
    -macro_rules! fragment_internal {
    -    // The @v prefix is used to parse a sequence of operands and return them in a vector. This is
    -    // used by operands that take a variable number of arguments, like `thresh()` and `multi()`.
    -    ( @v $op:ident ( $( $args:tt )* ) $( $tail:tt )* ) => ({
    -        let mut v = vec![$crate::fragment!( $op ( $( $args )* ) )];
    -        v.append(&mut $crate::fragment_internal!( @v $( $tail )* ));
    +#[doc(hidden)]
    +#[macro_export]
    +macro_rules! fragment_internal {
    +    // The @v prefix is used to parse a sequence of operands and return them in a vector. This is
    +    // used by operands that take a variable number of arguments, like `thresh()` and `multi()`.
    +    ( @v $op:ident ( $( $args:tt )* ) $( $tail:tt )* ) => ({
    +        let mut v = vec![$crate::fragment!( $op ( $( $args )* ) )];
    +        v.append(&mut $crate::fragment_internal!( @v $( $tail )* ));
     
    -        v
    +        v
         });
    -    // Match modifiers
    -    ( @v $modif:tt : $( $tail:tt )* ) => ({
    -        let mut v = $crate::fragment_internal!( @v $( $tail )* );
    -        let first = v.drain(..1).next().unwrap();
    +    // Match modifiers
    +    ( @v $modif:tt : $( $tail:tt )* ) => ({
    +        let mut v = $crate::fragment_internal!( @v $( $tail )* );
    +        let first = v.drain(..1).next().unwrap();
     
    -        let first = $crate::apply_modifier!($modif:first);
    +        let first = $crate::apply_modifier!($modif:first);
     
    -        let mut v_final = vec![first];
    -        v_final.append(&mut v);
    +        let mut v_final = vec![first];
    +        v_final.append(&mut v);
     
    -        v_final
    +        v_final
         });
    -    // Remove commas between operands
    -    ( @v , $( $tail:tt )* ) => ({
    -        $crate::fragment_internal!( @v $( $tail )* )
    +    // Remove commas between operands
    +    ( @v , $( $tail:tt )* ) => ({
    +        $crate::fragment_internal!( @v $( $tail )* )
         });
    -    ( @v ) => ({
    +    ( @v ) => ({
             vec![]
         });
     
    -    // The @t prefix is used to parse a sequence of operands and return them in a tuple. This
    -    // allows checking at compile-time the number of arguments passed to an operand. For this
    -    // reason it's used by `and_*()`, `or_*()`, etc.
    -    //
    -    // Unfortunately, due to the fact that concatenating tuples is pretty hard, the final result
    -    // adds in the first spot the parsed operand and in the second spot the result of parsing
    -    // all the following ones. For two operands the type then corresponds to: (X, (X, ())). For
    -    // three operands it's (X, (X, (X, ()))), etc.
    -    //
    -    // To check that the right number of arguments has been passed we can "cast" those tuples to
    -    // more convenient structures like `TupleTwo`. If the conversion succeeds, the right number of
    -    // args was passed. Otherwise the compilation fails entirely.
    -    ( @t $op:ident ( $( $args:tt )* ) $( $tail:tt )* ) => ({
    -        ($crate::fragment!( $op ( $( $args )* ) ), $crate::fragment_internal!( @t $( $tail )* ))
    +    // The @t prefix is used to parse a sequence of operands and return them in a tuple. This
    +    // allows checking at compile-time the number of arguments passed to an operand. For this
    +    // reason it's used by `and_*()`, `or_*()`, etc.
    +    //
    +    // Unfortunately, due to the fact that concatenating tuples is pretty hard, the final result
    +    // adds in the first spot the parsed operand and in the second spot the result of parsing
    +    // all the following ones. For two operands the type then corresponds to: (X, (X, ())). For
    +    // three operands it's (X, (X, (X, ()))), etc.
    +    //
    +    // To check that the right number of arguments has been passed we can "cast" those tuples to
    +    // more convenient structures like `TupleTwo`. If the conversion succeeds, the right number of
    +    // args was passed. Otherwise the compilation fails entirely.
    +    ( @t $op:ident ( $( $args:tt )* ) $( $tail:tt )* ) => ({
    +        ($crate::fragment!( $op ( $( $args )* ) ), $crate::fragment_internal!( @t $( $tail )* ))
         });
    -    // Match modifiers
    -    ( @t $modif:tt : $( $tail:tt )* ) => ({
    -        let (first, tail) = $crate::fragment_internal!( @t $( $tail )* );
    -        ($crate::apply_modifier!($modif:first), tail)
    +    // Match modifiers
    +    ( @t $modif:tt : $( $tail:tt )* ) => ({
    +        let (first, tail) = $crate::fragment_internal!( @t $( $tail )* );
    +        ($crate::apply_modifier!($modif:first), tail)
         });
    -    // Remove commas between operands
    -    ( @t , $( $tail:tt )* ) => ({
    -        $crate::fragment_internal!( @t $( $tail )* )
    +    // Remove commas between operands
    +    ( @t , $( $tail:tt )* ) => ({
    +        $crate::fragment_internal!( @t $( $tail )* )
         });
    -    ( @t ) => ({});
    +    ( @t ) => ({});
     
    -    // Fallback to calling `fragment!()`
    -    ( $( $tokens:tt )* ) => ({
    -        $crate::fragment!($( $tokens )*)
    +    // Fallback to calling `fragment!()`
    +    ( $( $tokens:tt )* ) => ({
    +        $crate::fragment!($( $tokens )*)
         });
     }
     
    -/// Macro to write descriptor fragments with code
    -///
    -/// This macro will be expanded to an object of type `Result<(Miniscript<DescriptorPublicKey, _>, KeyMap, ValidNetworks), DescriptorError>`. It allows writing
    -/// fragments of larger descriptors that can be pieced together using `fragment!(thresh_vec(m, ...))`.
    -///
    -/// The syntax to write macro fragment is the same as documented for the [`descriptor`] macro.
    -#[macro_export]
    -macro_rules! fragment {
    -    // Modifiers
    -    ( $modif:tt : $( $tail:tt )* ) => ({
    -        let op = $crate::fragment!( $( $tail )* );
    -        $crate::apply_modifier!($modif:op)
    +/// Macro to write descriptor fragments with code
    +///
    +/// This macro will be expanded to an object of type `Result<(Miniscript<DescriptorPublicKey, _>, KeyMap, ValidNetworks), DescriptorError>`. It allows writing
    +/// fragments of larger descriptors that can be pieced together using `fragment!(thresh_vec(m, ...))`.
    +///
    +/// The syntax to write macro fragment is the same as documented for the [`descriptor`] macro.
    +#[macro_export]
    +macro_rules! fragment {
    +    // Modifiers
    +    ( $modif:tt : $( $tail:tt )* ) => ({
    +        let op = $crate::fragment!( $( $tail )* );
    +        $crate::apply_modifier!($modif:op)
         });
     
    -    // Miniscript
    -    ( true ) => ({
    +    // Miniscript
    +    ( true ) => ({
             $crate::impl_leaf_opcode!(True)
         });
    -    ( false ) => ({
    +    ( false ) => ({
             $crate::impl_leaf_opcode!(False)
         });
    -    ( pk_k ( $key:expr ) ) => ({
    -        let secp = $crate::bitcoin::secp256k1::Secp256k1::new();
    -        $crate::keys::make_pk($key, &secp)
    +    ( pk_k ( $key:expr ) ) => ({
    +        let secp = $crate::bitcoin::secp256k1::Secp256k1::new();
    +        $crate::keys::make_pk($key, &secp)
         });
    -    ( pk ( $key:expr ) ) => ({
    -        $crate::fragment!(c:pk_k ( $key ))
    +    ( pk ( $key:expr ) ) => ({
    +        $crate::fragment!(c:pk_k ( $key ))
         });
    -    ( pk_h ( $key:expr ) ) => ({
    -        let secp = $crate::bitcoin::secp256k1::Secp256k1::new();
    -        $crate::keys::make_pkh($key, &secp)
    +    ( pk_h ( $key:expr ) ) => ({
    +        let secp = $crate::bitcoin::secp256k1::Secp256k1::new();
    +        $crate::keys::make_pkh($key, &secp)
         });
    -    ( after ( $value:expr ) ) => ({
    -        $crate::impl_leaf_opcode_value!(After, $crate::bitcoin::PackedLockTime($value)) // TODO!! https://github.com/rust-bitcoin/rust-bitcoin/issues/1302
    +    ( after ( $value:expr ) ) => ({
    +        $crate::impl_leaf_opcode_value!(After, $crate::bitcoin::PackedLockTime($value)) // TODO!! https://github.com/rust-bitcoin/rust-bitcoin/issues/1302
    +    });
    +    ( older ( $value:expr ) ) => ({
    +        $crate::impl_leaf_opcode_value!(Older, $crate::bitcoin::Sequence($value)) // TODO!!
    +    });
    +    ( sha256 ( $hash:expr ) ) => ({
    +        $crate::impl_leaf_opcode_value!(Sha256, $hash)
         });
    -    ( older ( $value:expr ) ) => ({
    -        $crate::impl_leaf_opcode_value!(Older, $crate::bitcoin::Sequence($value)) // TODO!!
    +    ( hash256 ( $hash:expr ) ) => ({
    +        $crate::impl_leaf_opcode_value!(Hash256, $hash)
         });
    -    ( sha256 ( $hash:expr ) ) => ({
    -        $crate::impl_leaf_opcode_value!(Sha256, $hash)
    +    ( ripemd160 ( $hash:expr ) ) => ({
    +        $crate::impl_leaf_opcode_value!(Ripemd160, $hash)
         });
    -    ( hash256 ( $hash:expr ) ) => ({
    -        $crate::impl_leaf_opcode_value!(Hash256, $hash)
    +    ( hash160 ( $hash:expr ) ) => ({
    +        $crate::impl_leaf_opcode_value!(Hash160, $hash)
         });
    -    ( ripemd160 ( $hash:expr ) ) => ({
    -        $crate::impl_leaf_opcode_value!(Ripemd160, $hash)
    +    ( and_v ( $( $inner:tt )* ) ) => ({
    +        $crate::impl_node_opcode_two!(AndV, $( $inner )*)
         });
    -    ( hash160 ( $hash:expr ) ) => ({
    -        $crate::impl_leaf_opcode_value!(Hash160, $hash)
    +    ( and_b ( $( $inner:tt )* ) ) => ({
    +        $crate::impl_node_opcode_two!(AndB, $( $inner )*)
         });
    -    ( and_v ( $( $inner:tt )* ) ) => ({
    -        $crate::impl_node_opcode_two!(AndV, $( $inner )*)
    +    ( and_or ( $( $inner:tt )* ) ) => ({
    +        $crate::impl_node_opcode_three!(AndOr, $( $inner )*)
         });
    -    ( and_b ( $( $inner:tt )* ) ) => ({
    -        $crate::impl_node_opcode_two!(AndB, $( $inner )*)
    +    ( andor ( $( $inner:tt )* ) ) => ({
    +        $crate::impl_node_opcode_three!(AndOr, $( $inner )*)
         });
    -    ( and_or ( $( $inner:tt )* ) ) => ({
    -        $crate::impl_node_opcode_three!(AndOr, $( $inner )*)
    +    ( or_b ( $( $inner:tt )* ) ) => ({
    +        $crate::impl_node_opcode_two!(OrB, $( $inner )*)
         });
    -    ( andor ( $( $inner:tt )* ) ) => ({
    -        $crate::impl_node_opcode_three!(AndOr, $( $inner )*)
    +    ( or_d ( $( $inner:tt )* ) ) => ({
    +        $crate::impl_node_opcode_two!(OrD, $( $inner )*)
         });
    -    ( or_b ( $( $inner:tt )* ) ) => ({
    -        $crate::impl_node_opcode_two!(OrB, $( $inner )*)
    +    ( or_c ( $( $inner:tt )* ) ) => ({
    +        $crate::impl_node_opcode_two!(OrC, $( $inner )*)
         });
    -    ( or_d ( $( $inner:tt )* ) ) => ({
    -        $crate::impl_node_opcode_two!(OrD, $( $inner )*)
    +    ( or_i ( $( $inner:tt )* ) ) => ({
    +        $crate::impl_node_opcode_two!(OrI, $( $inner )*)
         });
    -    ( or_c ( $( $inner:tt )* ) ) => ({
    -        $crate::impl_node_opcode_two!(OrC, $( $inner )*)
    -    });
    -    ( or_i ( $( $inner:tt )* ) ) => ({
    -        $crate::impl_node_opcode_two!(OrI, $( $inner )*)
    -    });
    -    ( thresh_vec ( $thresh:expr, $items:expr ) ) => ({
    -        use $crate::miniscript::descriptor::KeyMap;
    +    ( thresh_vec ( $thresh:expr, $items:expr ) ) => ({
    +        use $crate::miniscript::descriptor::KeyMap;
     
    -        let (items, key_maps_networks): (Vec<_>, Vec<_>) = $items.into_iter().map(|(a, b, c)| (a, (b, c))).unzip();
    -        let items = items.into_iter().map(std::sync::Arc::new).collect();
    +        let (items, key_maps_networks): (Vec<_>, Vec<_>) = $items.into_iter().map(|(a, b, c)| (a, (b, c))).unzip();
    +        let items = items.into_iter().map(std::sync::Arc::new).collect();
     
    -        let (key_maps, valid_networks) = key_maps_networks.into_iter().fold((KeyMap::default(), $crate::keys::any_network()), |(mut keys_acc, net_acc), (key, net)| {
    -            keys_acc.extend(key.into_iter());
    -            let net_acc = $crate::keys::merge_networks(&net_acc, &net);
    +        let (key_maps, valid_networks) = key_maps_networks.into_iter().fold((KeyMap::default(), $crate::keys::any_network()), |(mut keys_acc, net_acc), (key, net)| {
    +            keys_acc.extend(key.into_iter());
    +            let net_acc = $crate::keys::merge_networks(&net_acc, &net);
     
    -            (keys_acc, net_acc)
    +            (keys_acc, net_acc)
             });
     
    -        $crate::impl_leaf_opcode_value_two!(Thresh, $thresh, items)
    -            .map(|(minisc, _, _)| (minisc, key_maps, valid_networks))
    +        $crate::impl_leaf_opcode_value_two!(Thresh, $thresh, items)
    +            .map(|(minisc, _, _)| (minisc, key_maps, valid_networks))
         });
    -    ( thresh ( $thresh:expr, $( $inner:tt )* ) ) => ({
    -        let items = $crate::fragment_internal!( @v $( $inner )* );
    +    ( thresh ( $thresh:expr, $( $inner:tt )* ) ) => ({
    +        let items = $crate::fragment_internal!( @v $( $inner )* );
     
    -        items.into_iter().collect::<Result<Vec<_>, _>>()
    -            .and_then(|items| $crate::fragment!(thresh_vec($thresh, items)))
    +        items.into_iter().collect::<Result<Vec<_>, _>>()
    +            .and_then(|items| $crate::fragment!(thresh_vec($thresh, items)))
         });
    -    ( multi_vec ( $thresh:expr, $keys:expr ) ) => ({
    -        let secp = $crate::bitcoin::secp256k1::Secp256k1::new();
    +    ( multi_vec ( $thresh:expr, $keys:expr ) ) => ({
    +        let secp = $crate::bitcoin::secp256k1::Secp256k1::new();
     
    -        $crate::keys::make_multi($thresh, $crate::miniscript::Terminal::Multi, $keys, &secp)
    +        $crate::keys::make_multi($thresh, $crate::miniscript::Terminal::Multi, $keys, &secp)
         });
    -    ( multi ( $thresh:expr $(, $key:expr )+ ) ) => ({
    -        $crate::group_multi_keys!( $( $key ),* )
    -            .and_then(|keys| $crate::fragment!( multi_vec ( $thresh, keys ) ))
    +    ( multi ( $thresh:expr $(, $key:expr )+ ) ) => ({
    +        $crate::group_multi_keys!( $( $key ),* )
    +            .and_then(|keys| $crate::fragment!( multi_vec ( $thresh, keys ) ))
         });
    -    ( multi_a_vec ( $thresh:expr, $keys:expr ) ) => ({
    -        let secp = $crate::bitcoin::secp256k1::Secp256k1::new();
    +    ( multi_a_vec ( $thresh:expr, $keys:expr ) ) => ({
    +        let secp = $crate::bitcoin::secp256k1::Secp256k1::new();
     
    -        $crate::keys::make_multi($thresh, $crate::miniscript::Terminal::MultiA, $keys, &secp)
    +        $crate::keys::make_multi($thresh, $crate::miniscript::Terminal::MultiA, $keys, &secp)
         });
    -    ( multi_a ( $thresh:expr $(, $key:expr )+ ) ) => ({
    -        $crate::group_multi_keys!( $( $key ),* )
    -            .and_then(|keys| $crate::fragment!( multi_a_vec ( $thresh, keys ) ))
    +    ( multi_a ( $thresh:expr $(, $key:expr )+ ) ) => ({
    +        $crate::group_multi_keys!( $( $key ),* )
    +            .and_then(|keys| $crate::fragment!( multi_a_vec ( $thresh, keys ) ))
         });
     
    -    // `sortedmulti()` is handled separately
    -    ( sortedmulti ( $( $inner:tt )* ) ) => ({
    +    // `sortedmulti()` is handled separately
    +    ( sortedmulti ( $( $inner:tt )* ) ) => ({
             compile_error!("`sortedmulti` can only be used as the root operand of a descriptor");
         });
    -    ( sortedmulti_vec ( $( $inner:tt )* ) ) => ({
    +    ( sortedmulti_vec ( $( $inner:tt )* ) ) => ({
             compile_error!("`sortedmulti_vec` can only be used as the root operand of a descriptor");
         });
     }
     
    -#[cfg(test)]
    -mod test {
    -    use bitcoin::hashes::hex::ToHex;
    -    use bitcoin::secp256k1::Secp256k1;
    -    use miniscript::descriptor::{DescriptorPublicKey, KeyMap};
    -    use miniscript::{Descriptor, Legacy, Segwitv0};
    -
    -    use std::str::FromStr;
    -
    -    use crate::descriptor::{DescriptorError, DescriptorMeta};
    -    use crate::keys::{DescriptorKey, IntoDescriptorKey, ValidNetworks};
    -    use bitcoin::network::constants::Network::{Bitcoin, Regtest, Signet, Testnet};
    -    use bitcoin::util::bip32;
    -    use bitcoin::PrivateKey;
    -
    -    // test the descriptor!() macro
    -
    -    // verify descriptor generates expected script(s) (if bare or pk) or address(es)
    -    fn check(
    -        desc: Result<(Descriptor<DescriptorPublicKey>, KeyMap, ValidNetworks), DescriptorError>,
    -        is_witness: bool,
    -        is_fixed: bool,
    -        expected: &[&str],
    +#[cfg(test)]
    +mod test {
    +    use bitcoin::hashes::hex::ToHex;
    +    use bitcoin::secp256k1::Secp256k1;
    +    use miniscript::descriptor::{DescriptorPublicKey, KeyMap};
    +    use miniscript::{Descriptor, Legacy, Segwitv0};
    +
    +    use std::str::FromStr;
    +
    +    use crate::descriptor::{DescriptorError, DescriptorMeta};
    +    use crate::keys::{DescriptorKey, IntoDescriptorKey, ValidNetworks};
    +    use bitcoin::network::constants::Network::{Bitcoin, Regtest, Signet, Testnet};
    +    use bitcoin::util::bip32;
    +    use bitcoin::PrivateKey;
    +
    +    // test the descriptor!() macro
    +
    +    // verify descriptor generates expected script(s) (if bare or pk) or address(es)
    +    fn check(
    +        desc: Result<(Descriptor<DescriptorPublicKey>, KeyMap, ValidNetworks), DescriptorError>,
    +        is_witness: bool,
    +        is_fixed: bool,
    +        expected: &[&str],
         ) {
    -        let (desc, _key_map, _networks) = desc.unwrap();
    -        assert_eq!(desc.is_witness(), is_witness);
    -        assert_eq!(!desc.has_wildcard(), is_fixed);
    -        for i in 0..expected.len() {
    -            let index = i as u32;
    -            let child_desc = if !desc.has_wildcard() {
    -                desc.at_derivation_index(0)
    -            } else {
    -                desc.at_derivation_index(index)
    +        let (desc, _key_map, _networks) = desc.unwrap();
    +        assert_eq!(desc.is_witness(), is_witness);
    +        assert_eq!(!desc.has_wildcard(), is_fixed);
    +        for i in 0..expected.len() {
    +            let index = i as u32;
    +            let child_desc = if !desc.has_wildcard() {
    +                desc.at_derivation_index(0)
    +            } else {
    +                desc.at_derivation_index(index)
                 };
    -            let address = child_desc.address(Regtest);
    -            if let Ok(address) = address {
    -                assert_eq!(address.to_string(), *expected.get(i).unwrap());
    -            } else {
    -                let script = child_desc.script_pubkey();
    -                assert_eq!(script.to_hex().as_str(), *expected.get(i).unwrap());
    +            let address = child_desc.address(Regtest);
    +            if let Ok(address) = address {
    +                assert_eq!(address.to_string(), *expected.get(i).unwrap());
    +            } else {
    +                let script = child_desc.script_pubkey();
    +                assert_eq!(script.to_hex().as_str(), *expected.get(i).unwrap());
                 }
             }
         }
     
    -    // - at least one of each "type" of operator; i.e. one modifier, one leaf_opcode, one leaf_opcode_value, etc.
    -    // - mixing up key types that implement IntoDescriptorKey in multi() or thresh()
    +    // - at least one of each "type" of operator; i.e. one modifier, one leaf_opcode, one leaf_opcode_value, etc.
    +    // - mixing up key types that implement IntoDescriptorKey in multi() or thresh()
     
    -    // expected script for pk and bare manually created
    -    // expected addresses created with `bitcoin-cli getdescriptorinfo` (for hash) and `bitcoin-cli deriveaddresses`
    +    // expected script for pk and bare manually created
    +    // expected addresses created with `bitcoin-cli getdescriptorinfo` (for hash) and `bitcoin-cli deriveaddresses`
     
    -    #[test]
    -    fn test_fixed_legacy_descriptors() {
    -        let pubkey1 = bitcoin::PublicKey::from_str(
    +    #[test]
    +    fn test_fixed_legacy_descriptors() {
    +        let pubkey1 = bitcoin::PublicKey::from_str(
                 "03a34b99f22c790c4e36b2b3c2c35a36db06226e41c692fc82b8b56ac1c540c5bd",
             )
    -        .unwrap();
    -        let pubkey2 = bitcoin::PublicKey::from_str(
    +        .unwrap();
    +        let pubkey2 = bitcoin::PublicKey::from_str(
                 "032e58afe51f9ed8ad3cc7897f634d881fdbe49a81564629ded8156bebd2ffd1af",
             )
    -        .unwrap();
    +        .unwrap();
     
    -        check(
    -            descriptor!(bare(multi(1,pubkey1,pubkey2))),
    +        check(
    +            descriptor!(bare(multi(1,pubkey1,pubkey2))),
                 false,
                 true,
                 &["512103a34b99f22c790c4e36b2b3c2c35a36db06226e41c692fc82b8b56ac1c540c5bd21032e58afe51f9ed8ad3cc7897f634d881fdbe49a81564629ded8156bebd2ffd1af52ae"],
             );
    -        check(
    -            descriptor!(pk(pubkey1)),
    +        check(
    +            descriptor!(pk(pubkey1)),
                 false,
                 true,
                 &["2103a34b99f22c790c4e36b2b3c2c35a36db06226e41c692fc82b8b56ac1c540c5bdac"],
             );
    -        check(
    -            descriptor!(pkh(pubkey1)),
    +        check(
    +            descriptor!(pkh(pubkey1)),
                 false,
                 true,
                 &["muZpTpBYhxmRFuCjLc7C6BBDF32C8XVJUi"],
             );
    -        check(
    -            descriptor!(sh(multi(1, pubkey1, pubkey2))),
    +        check(
    +            descriptor!(sh(multi(1, pubkey1, pubkey2))),
                 false,
                 true,
                 &["2MymURoV1bzuMnWMGiXzyomDkeuxXY7Suey"],
             );
         }
     
    -    #[test]
    -    fn test_fixed_segwitv0_descriptors() {
    -        let pubkey1 = bitcoin::PublicKey::from_str(
    +    #[test]
    +    fn test_fixed_segwitv0_descriptors() {
    +        let pubkey1 = bitcoin::PublicKey::from_str(
                 "03a34b99f22c790c4e36b2b3c2c35a36db06226e41c692fc82b8b56ac1c540c5bd",
             )
    -        .unwrap();
    -        let pubkey2 = bitcoin::PublicKey::from_str(
    +        .unwrap();
    +        let pubkey2 = bitcoin::PublicKey::from_str(
                 "032e58afe51f9ed8ad3cc7897f634d881fdbe49a81564629ded8156bebd2ffd1af",
             )
    -        .unwrap();
    +        .unwrap();
     
    -        check(
    -            descriptor!(wpkh(pubkey1)),
    +        check(
    +            descriptor!(wpkh(pubkey1)),
                 true,
                 true,
                 &["bcrt1qngw83fg8dz0k749cg7k3emc7v98wy0c7azaa6h"],
             );
    -        check(
    -            descriptor!(sh(wpkh(pubkey1))),
    +        check(
    +            descriptor!(sh(wpkh(pubkey1))),
                 true,
                 true,
                 &["2N5LiC3CqzxDamRTPG1kiNv1FpNJQ7x28sb"],
             );
    -        check(
    -            descriptor!(wsh(multi(1, pubkey1, pubkey2))),
    +        check(
    +            descriptor!(wsh(multi(1, pubkey1, pubkey2))),
                 true,
                 true,
                 &["bcrt1qgw8jvv2hsrvjfa6q66rk6har7d32lrqm5unnf5cl63q9phxfvgps5fyfqe"],
             );
    -        check(
    -            descriptor!(sh(wsh(multi(1, pubkey1, pubkey2)))),
    +        check(
    +            descriptor!(sh(wsh(multi(1, pubkey1, pubkey2)))),
                 true,
                 true,
                 &["2NCidRJysy7apkmE6JF5mLLaJFkrN3Ub9iy"],
             );
         }
     
    -    #[test]
    -    fn test_fixed_threeop_descriptors() {
    -        let redeem_key = bitcoin::PublicKey::from_str(
    +    #[test]
    +    fn test_fixed_threeop_descriptors() {
    +        let redeem_key = bitcoin::PublicKey::from_str(
                 "03a34b99f22c790c4e36b2b3c2c35a36db06226e41c692fc82b8b56ac1c540c5bd",
             )
    -        .unwrap();
    -        let move_key = bitcoin::PublicKey::from_str(
    +        .unwrap();
    +        let move_key = bitcoin::PublicKey::from_str(
                 "032e58afe51f9ed8ad3cc7897f634d881fdbe49a81564629ded8156bebd2ffd1af",
             )
    -        .unwrap();
    +        .unwrap();
     
    -        check(
    -            descriptor!(sh(wsh(and_or(pk(redeem_key), older(1000), pk(move_key))))),
    +        check(
    +            descriptor!(sh(wsh(and_or(pk(redeem_key), older(1000), pk(move_key))))),
                 true,
                 true,
                 &["2MypGwr5eQWAWWJtiJgUEToVxc4zuokjQRe"],
             );
         }
     
    -    #[test]
    -    fn test_bip32_legacy_descriptors() {
    -        let xprv = bip32::ExtendedPrivKey::from_str("tprv8ZgxMBicQKsPcx5nBGsR63Pe8KnRUqmbJNENAfGftF3yuXoMMoVJJcYeUw5eVkm9WBPjWYt6HMWYJNesB5HaNVBaFc1M6dRjWSYnmewUMYy").unwrap();
    +    #[test]
    +    fn test_bip32_legacy_descriptors() {
    +        let xprv = bip32::ExtendedPrivKey::from_str("tprv8ZgxMBicQKsPcx5nBGsR63Pe8KnRUqmbJNENAfGftF3yuXoMMoVJJcYeUw5eVkm9WBPjWYt6HMWYJNesB5HaNVBaFc1M6dRjWSYnmewUMYy").unwrap();
     
    -        let path = bip32::DerivationPath::from_str("m/0").unwrap();
    -        let desc_key = (xprv, path.clone()).into_descriptor_key().unwrap();
    -        check(
    -            descriptor!(pk(desc_key)),
    +        let path = bip32::DerivationPath::from_str("m/0").unwrap();
    +        let desc_key = (xprv, path.clone()).into_descriptor_key().unwrap();
    +        check(
    +            descriptor!(pk(desc_key)),
                 false,
                 false,
                 &[
    @@ -2177,9 +2171,9 @@
                 ],
             );
     
    -        let desc_key = (xprv, path.clone()).into_descriptor_key().unwrap();
    -        check(
    -            descriptor!(pkh(desc_key)),
    +        let desc_key = (xprv, path.clone()).into_descriptor_key().unwrap();
    +        check(
    +            descriptor!(pkh(desc_key)),
                 false,
                 false,
                 &[
    @@ -2189,12 +2183,12 @@
                 ],
             );
     
    -        let path2 = bip32::DerivationPath::from_str("m/2147483647'/0").unwrap();
    -        let desc_key1 = (xprv, path).into_descriptor_key().unwrap();
    -        let desc_key2 = (xprv, path2).into_descriptor_key().unwrap();
    +        let path2 = bip32::DerivationPath::from_str("m/2147483647'/0").unwrap();
    +        let desc_key1 = (xprv, path).into_descriptor_key().unwrap();
    +        let desc_key2 = (xprv, path2).into_descriptor_key().unwrap();
     
    -        check(
    -            descriptor!(sh(multi(1, desc_key1, desc_key2))),
    +        check(
    +            descriptor!(sh(multi(1, desc_key1, desc_key2))),
                 false,
                 false,
                 &[
    @@ -2205,14 +2199,14 @@
             );
         }
     
    -    #[test]
    -    fn test_bip32_segwitv0_descriptors() {
    -        let xprv = bip32::ExtendedPrivKey::from_str("tprv8ZgxMBicQKsPcx5nBGsR63Pe8KnRUqmbJNENAfGftF3yuXoMMoVJJcYeUw5eVkm9WBPjWYt6HMWYJNesB5HaNVBaFc1M6dRjWSYnmewUMYy").unwrap();
    +    #[test]
    +    fn test_bip32_segwitv0_descriptors() {
    +        let xprv = bip32::ExtendedPrivKey::from_str("tprv8ZgxMBicQKsPcx5nBGsR63Pe8KnRUqmbJNENAfGftF3yuXoMMoVJJcYeUw5eVkm9WBPjWYt6HMWYJNesB5HaNVBaFc1M6dRjWSYnmewUMYy").unwrap();
     
    -        let path = bip32::DerivationPath::from_str("m/0").unwrap();
    -        let desc_key = (xprv, path.clone()).into_descriptor_key().unwrap();
    -        check(
    -            descriptor!(wpkh(desc_key)),
    +        let path = bip32::DerivationPath::from_str("m/0").unwrap();
    +        let desc_key = (xprv, path.clone()).into_descriptor_key().unwrap();
    +        check(
    +            descriptor!(wpkh(desc_key)),
                 true,
                 false,
                 &[
    @@ -2222,9 +2216,9 @@
                 ],
             );
     
    -        let desc_key = (xprv, path.clone()).into_descriptor_key().unwrap();
    -        check(
    -            descriptor!(sh(wpkh(desc_key))),
    +        let desc_key = (xprv, path.clone()).into_descriptor_key().unwrap();
    +        check(
    +            descriptor!(sh(wpkh(desc_key))),
                 true,
                 false,
                 &[
    @@ -2234,11 +2228,11 @@
                 ],
             );
     
    -        let path2 = bip32::DerivationPath::from_str("m/2147483647'/0").unwrap();
    -        let desc_key1 = (xprv, path.clone()).into_descriptor_key().unwrap();
    -        let desc_key2 = (xprv, path2.clone()).into_descriptor_key().unwrap();
    -        check(
    -            descriptor!(wsh(multi(1, desc_key1, desc_key2))),
    +        let path2 = bip32::DerivationPath::from_str("m/2147483647'/0").unwrap();
    +        let desc_key1 = (xprv, path.clone()).into_descriptor_key().unwrap();
    +        let desc_key2 = (xprv, path2.clone()).into_descriptor_key().unwrap();
    +        check(
    +            descriptor!(wsh(multi(1, desc_key1, desc_key2))),
                 true,
                 false,
                 &[
    @@ -2248,10 +2242,10 @@
                 ],
             );
     
    -        let desc_key1 = (xprv, path).into_descriptor_key().unwrap();
    -        let desc_key2 = (xprv, path2).into_descriptor_key().unwrap();
    -        check(
    -            descriptor!(sh(wsh(multi(1, desc_key1, desc_key2)))),
    +        let desc_key1 = (xprv, path).into_descriptor_key().unwrap();
    +        let desc_key2 = (xprv, path2).into_descriptor_key().unwrap();
    +        check(
    +            descriptor!(sh(wsh(multi(1, desc_key1, desc_key2)))),
                 true,
                 false,
                 &[
    @@ -2262,19 +2256,19 @@
             );
         }
     
    -    #[test]
    -    fn test_dsl_sortedmulti() {
    -        let key_1 = bip32::ExtendedPrivKey::from_str("tprv8ZgxMBicQKsPcx5nBGsR63Pe8KnRUqmbJNENAfGftF3yuXoMMoVJJcYeUw5eVkm9WBPjWYt6HMWYJNesB5HaNVBaFc1M6dRjWSYnmewUMYy").unwrap();
    -        let path_1 = bip32::DerivationPath::from_str("m/0").unwrap();
    +    #[test]
    +    fn test_dsl_sortedmulti() {
    +        let key_1 = bip32::ExtendedPrivKey::from_str("tprv8ZgxMBicQKsPcx5nBGsR63Pe8KnRUqmbJNENAfGftF3yuXoMMoVJJcYeUw5eVkm9WBPjWYt6HMWYJNesB5HaNVBaFc1M6dRjWSYnmewUMYy").unwrap();
    +        let path_1 = bip32::DerivationPath::from_str("m/0").unwrap();
     
    -        let key_2 = bip32::ExtendedPrivKey::from_str("tprv8ZgxMBicQKsPegBHHnq7YEgM815dG24M2Jk5RVqipgDxF1HJ1tsnT815X5Fd5FRfMVUs8NZs9XCb6y9an8hRPThnhfwfXJ36intaekySHGF").unwrap();
    -        let path_2 = bip32::DerivationPath::from_str("m/1").unwrap();
    +        let key_2 = bip32::ExtendedPrivKey::from_str("tprv8ZgxMBicQKsPegBHHnq7YEgM815dG24M2Jk5RVqipgDxF1HJ1tsnT815X5Fd5FRfMVUs8NZs9XCb6y9an8hRPThnhfwfXJ36intaekySHGF").unwrap();
    +        let path_2 = bip32::DerivationPath::from_str("m/1").unwrap();
     
    -        let desc_key1 = (key_1, path_1);
    -        let desc_key2 = (key_2, path_2);
    +        let desc_key1 = (key_1, path_1);
    +        let desc_key2 = (key_2, path_2);
     
    -        check(
    -            descriptor!(sh(sortedmulti(1, desc_key1.clone(), desc_key2.clone()))),
    +        check(
    +            descriptor!(sh(sortedmulti(1, desc_key1.clone(), desc_key2.clone()))),
                 false,
                 false,
                 &[
    @@ -2287,11 +2281,11 @@
                 ],
             );
     
    -        check(
    -            descriptor!(sh(wsh(sortedmulti(
    +        check(
    +            descriptor!(sh(wsh(sortedmulti(
                     1,
    -                desc_key1.clone(),
    -                desc_key2.clone()
    +                desc_key1.clone(),
    +                desc_key2.clone()
                 )))),
                 true,
                 false,
    @@ -2305,8 +2299,8 @@
                 ],
             );
     
    -        check(
    -            descriptor!(wsh(sortedmulti_vec(1, vec![desc_key1, desc_key2]))),
    +        check(
    +            descriptor!(wsh(sortedmulti_vec(1, vec![desc_key1, desc_key2]))),
                 true,
                 false,
                 &[
    @@ -2320,129 +2314,128 @@
             );
         }
     
    -    // - verify the valid_networks returned is correctly computed based on the keys present in the descriptor
    -    #[test]
    -    fn test_valid_networks() {
    -        let xprv = bip32::ExtendedPrivKey::from_str("tprv8ZgxMBicQKsPcx5nBGsR63Pe8KnRUqmbJNENAfGftF3yuXoMMoVJJcYeUw5eVkm9WBPjWYt6HMWYJNesB5HaNVBaFc1M6dRjWSYnmewUMYy").unwrap();
    -        let path = bip32::DerivationPath::from_str("m/0").unwrap();
    -        let desc_key = (xprv, path).into_descriptor_key().unwrap();
    +    // - verify the valid_networks returned is correctly computed based on the keys present in the descriptor
    +    #[test]
    +    fn test_valid_networks() {
    +        let xprv = bip32::ExtendedPrivKey::from_str("tprv8ZgxMBicQKsPcx5nBGsR63Pe8KnRUqmbJNENAfGftF3yuXoMMoVJJcYeUw5eVkm9WBPjWYt6HMWYJNesB5HaNVBaFc1M6dRjWSYnmewUMYy").unwrap();
    +        let path = bip32::DerivationPath::from_str("m/0").unwrap();
    +        let desc_key = (xprv, path).into_descriptor_key().unwrap();
     
    -        let (_desc, _key_map, valid_networks) = descriptor!(pkh(desc_key)).unwrap();
    +        let (_desc, _key_map, valid_networks) = descriptor!(pkh(desc_key)).unwrap();
             assert_eq!(
    -            valid_networks,
    -            [Testnet, Regtest, Signet].iter().cloned().collect()
    +            valid_networks,
    +            [Testnet, Regtest, Signet].iter().cloned().collect()
             );
     
    -        let xprv = bip32::ExtendedPrivKey::from_str("xprv9s21ZrQH143K3QTDL4LXw2F7HEK3wJUD2nW2nRk4stbPy6cq3jPPqjiChkVvvNKmPGJxWUtg6LnF5kejMRNNU3TGtRBeJgk33yuGBxrMPHi").unwrap();
    -        let path = bip32::DerivationPath::from_str("m/10/20/30/40").unwrap();
    -        let desc_key = (xprv, path).into_descriptor_key().unwrap();
    -
    -        let (_desc, _key_map, valid_networks) = descriptor!(wpkh(desc_key)).unwrap();
    -        assert_eq!(valid_networks, [Bitcoin].iter().cloned().collect());
    -    }
    +        let xprv = bip32::ExtendedPrivKey::from_str("xprv9s21ZrQH143K3QTDL4LXw2F7HEK3wJUD2nW2nRk4stbPy6cq3jPPqjiChkVvvNKmPGJxWUtg6LnF5kejMRNNU3TGtRBeJgk33yuGBxrMPHi").unwrap();
    +        let path = bip32::DerivationPath::from_str("m/10/20/30/40").unwrap();
    +        let desc_key = (xprv, path).into_descriptor_key().unwrap();
     
    -    // - verify the key_maps are correctly merged together
    -    #[test]
    -    fn test_key_maps_merged() {
    -        let secp = Secp256k1::new();
    -
    -        let xprv1 = bip32::ExtendedPrivKey::from_str("tprv8ZgxMBicQKsPcx5nBGsR63Pe8KnRUqmbJNENAfGftF3yuXoMMoVJJcYeUw5eVkm9WBPjWYt6HMWYJNesB5HaNVBaFc1M6dRjWSYnmewUMYy").unwrap();
    -        let path1 = bip32::DerivationPath::from_str("m/0").unwrap();
    -        let desc_key1 = (xprv1, path1.clone()).into_descriptor_key().unwrap();
    -
    -        let xprv2 = bip32::ExtendedPrivKey::from_str("tprv8ZgxMBicQKsPegBHHnq7YEgM815dG24M2Jk5RVqipgDxF1HJ1tsnT815X5Fd5FRfMVUs8NZs9XCb6y9an8hRPThnhfwfXJ36intaekySHGF").unwrap();
    -        let path2 = bip32::DerivationPath::from_str("m/2147483647'/0").unwrap();
    -        let desc_key2 = (xprv2, path2.clone()).into_descriptor_key().unwrap();
    -
    -        let xprv3 = bip32::ExtendedPrivKey::from_str("tprv8ZgxMBicQKsPdZXrcHNLf5JAJWFAoJ2TrstMRdSKtEggz6PddbuSkvHKM9oKJyFgZV1B7rw8oChspxyYbtmEXYyg1AjfWbL3ho3XHDpHRZf").unwrap();
    -        let path3 = bip32::DerivationPath::from_str("m/10/20/30/40").unwrap();
    -        let desc_key3 = (xprv3, path3.clone()).into_descriptor_key().unwrap();
    -
    -        let (_desc, key_map, _valid_networks) =
    -            descriptor!(sh(wsh(multi(2, desc_key1, desc_key2, desc_key3)))).unwrap();
    -        assert_eq!(key_map.len(), 3);
    -
    -        let desc_key1: DescriptorKey<Segwitv0> = (xprv1, path1).into_descriptor_key().unwrap();
    -        let desc_key2: DescriptorKey<Segwitv0> = (xprv2, path2).into_descriptor_key().unwrap();
    -        let desc_key3: DescriptorKey<Segwitv0> = (xprv3, path3).into_descriptor_key().unwrap();
    -
    -        let (key1, _key_map, _valid_networks) = desc_key1.extract(&secp).unwrap();
    -        let (key2, _key_map, _valid_networks) = desc_key2.extract(&secp).unwrap();
    -        let (key3, _key_map, _valid_networks) = desc_key3.extract(&secp).unwrap();
    -        assert_eq!(key_map.get(&key1).unwrap().to_string(), "tprv8ZgxMBicQKsPcx5nBGsR63Pe8KnRUqmbJNENAfGftF3yuXoMMoVJJcYeUw5eVkm9WBPjWYt6HMWYJNesB5HaNVBaFc1M6dRjWSYnmewUMYy/0/*");
    -        assert_eq!(key_map.get(&key2).unwrap().to_string(), "tprv8ZgxMBicQKsPegBHHnq7YEgM815dG24M2Jk5RVqipgDxF1HJ1tsnT815X5Fd5FRfMVUs8NZs9XCb6y9an8hRPThnhfwfXJ36intaekySHGF/2147483647'/0/*");
    -        assert_eq!(key_map.get(&key3).unwrap().to_string(), "tprv8ZgxMBicQKsPdZXrcHNLf5JAJWFAoJ2TrstMRdSKtEggz6PddbuSkvHKM9oKJyFgZV1B7rw8oChspxyYbtmEXYyg1AjfWbL3ho3XHDpHRZf/10/20/30/40/*");
    +        let (_desc, _key_map, valid_networks) = descriptor!(wpkh(desc_key)).unwrap();
    +        assert_eq!(valid_networks, [Bitcoin].iter().cloned().collect());
         }
     
    -    // - verify the ScriptContext is correctly validated (i.e. passing a type that only impl IntoDescriptorKey<Segwitv0> to a pkh() descriptor should throw a compilation error
    -    #[test]
    -    fn test_script_context_validation() {
    -        // this compiles
    -        let xprv = bip32::ExtendedPrivKey::from_str("tprv8ZgxMBicQKsPcx5nBGsR63Pe8KnRUqmbJNENAfGftF3yuXoMMoVJJcYeUw5eVkm9WBPjWYt6HMWYJNesB5HaNVBaFc1M6dRjWSYnmewUMYy").unwrap();
    -        let path = bip32::DerivationPath::from_str("m/0").unwrap();
    -        let desc_key: DescriptorKey<Legacy> = (xprv, path).into_descriptor_key().unwrap();
    -
    -        let (desc, _key_map, _valid_networks) = descriptor!(pkh(desc_key)).unwrap();
    -        assert_eq!(desc.to_string(), "pkh(tpubD6NzVbkrYhZ4WR7a4vY1VT3khMJMeAxVsfq9TBJyJWrNk247zCJtV7AWf6UJP7rAVsn8NNKdJi3gFyKPTmWZS9iukb91xbn2HbFSMQm2igY/0/*)#yrnz9pp2");
    -
    -        // as expected this does not compile due to invalid context
    -        //let desc_key:DescriptorKey<Segwitv0> = (xprv, path.clone()).into_descriptor_key().unwrap();
    -        //let (desc, _key_map, _valid_networks) = descriptor!(pkh(desc_key)).unwrap();
    +    // - verify the key_maps are correctly merged together
    +    #[test]
    +    fn test_key_maps_merged() {
    +        let secp = Secp256k1::new();
    +
    +        let xprv1 = bip32::ExtendedPrivKey::from_str("tprv8ZgxMBicQKsPcx5nBGsR63Pe8KnRUqmbJNENAfGftF3yuXoMMoVJJcYeUw5eVkm9WBPjWYt6HMWYJNesB5HaNVBaFc1M6dRjWSYnmewUMYy").unwrap();
    +        let path1 = bip32::DerivationPath::from_str("m/0").unwrap();
    +        let desc_key1 = (xprv1, path1.clone()).into_descriptor_key().unwrap();
    +
    +        let xprv2 = bip32::ExtendedPrivKey::from_str("tprv8ZgxMBicQKsPegBHHnq7YEgM815dG24M2Jk5RVqipgDxF1HJ1tsnT815X5Fd5FRfMVUs8NZs9XCb6y9an8hRPThnhfwfXJ36intaekySHGF").unwrap();
    +        let path2 = bip32::DerivationPath::from_str("m/2147483647'/0").unwrap();
    +        let desc_key2 = (xprv2, path2.clone()).into_descriptor_key().unwrap();
    +
    +        let xprv3 = bip32::ExtendedPrivKey::from_str("tprv8ZgxMBicQKsPdZXrcHNLf5JAJWFAoJ2TrstMRdSKtEggz6PddbuSkvHKM9oKJyFgZV1B7rw8oChspxyYbtmEXYyg1AjfWbL3ho3XHDpHRZf").unwrap();
    +        let path3 = bip32::DerivationPath::from_str("m/10/20/30/40").unwrap();
    +        let desc_key3 = (xprv3, path3.clone()).into_descriptor_key().unwrap();
    +
    +        let (_desc, key_map, _valid_networks) =
    +            descriptor!(sh(wsh(multi(2, desc_key1, desc_key2, desc_key3)))).unwrap();
    +        assert_eq!(key_map.len(), 3);
    +
    +        let desc_key1: DescriptorKey<Segwitv0> = (xprv1, path1).into_descriptor_key().unwrap();
    +        let desc_key2: DescriptorKey<Segwitv0> = (xprv2, path2).into_descriptor_key().unwrap();
    +        let desc_key3: DescriptorKey<Segwitv0> = (xprv3, path3).into_descriptor_key().unwrap();
    +
    +        let (key1, _key_map, _valid_networks) = desc_key1.extract(&secp).unwrap();
    +        let (key2, _key_map, _valid_networks) = desc_key2.extract(&secp).unwrap();
    +        let (key3, _key_map, _valid_networks) = desc_key3.extract(&secp).unwrap();
    +        assert_eq!(key_map.get(&key1).unwrap().to_string(), "tprv8ZgxMBicQKsPcx5nBGsR63Pe8KnRUqmbJNENAfGftF3yuXoMMoVJJcYeUw5eVkm9WBPjWYt6HMWYJNesB5HaNVBaFc1M6dRjWSYnmewUMYy/0/*");
    +        assert_eq!(key_map.get(&key2).unwrap().to_string(), "tprv8ZgxMBicQKsPegBHHnq7YEgM815dG24M2Jk5RVqipgDxF1HJ1tsnT815X5Fd5FRfMVUs8NZs9XCb6y9an8hRPThnhfwfXJ36intaekySHGF/2147483647'/0/*");
    +        assert_eq!(key_map.get(&key3).unwrap().to_string(), "tprv8ZgxMBicQKsPdZXrcHNLf5JAJWFAoJ2TrstMRdSKtEggz6PddbuSkvHKM9oKJyFgZV1B7rw8oChspxyYbtmEXYyg1AjfWbL3ho3XHDpHRZf/10/20/30/40/*");
         }
     
    -    #[test]
    -    fn test_dsl_modifiers() {
    -        let private_key =
    -            PrivateKey::from_wif("cSQPHDBwXGjVzWRqAHm6zfvQhaTuj1f2bFH58h55ghbjtFwvmeXR").unwrap();
    -        let (descriptor, _, _) =
    -            descriptor!(wsh(thresh(2,n:d:v:older(1),s:pk(private_key),s:pk(private_key)))).unwrap();
    -
    -        assert_eq!(descriptor.to_string(), "wsh(thresh(2,ndv:older(1),s:pk(02e96fe52ef0e22d2f131dd425ce1893073a3c6ad20e8cac36726393dfb4856a4c),s:pk(02e96fe52ef0e22d2f131dd425ce1893073a3c6ad20e8cac36726393dfb4856a4c)))#zzk3ux8g")
    +    // - verify the ScriptContext is correctly validated (i.e. passing a type that only impl IntoDescriptorKey<Segwitv0> to a pkh() descriptor should throw a compilation error
    +    #[test]
    +    fn test_script_context_validation() {
    +        // this compiles
    +        let xprv = bip32::ExtendedPrivKey::from_str("tprv8ZgxMBicQKsPcx5nBGsR63Pe8KnRUqmbJNENAfGftF3yuXoMMoVJJcYeUw5eVkm9WBPjWYt6HMWYJNesB5HaNVBaFc1M6dRjWSYnmewUMYy").unwrap();
    +        let path = bip32::DerivationPath::from_str("m/0").unwrap();
    +        let desc_key: DescriptorKey<Legacy> = (xprv, path).into_descriptor_key().unwrap();
    +
    +        let (desc, _key_map, _valid_networks) = descriptor!(pkh(desc_key)).unwrap();
    +        assert_eq!(desc.to_string(), "pkh(tpubD6NzVbkrYhZ4WR7a4vY1VT3khMJMeAxVsfq9TBJyJWrNk247zCJtV7AWf6UJP7rAVsn8NNKdJi3gFyKPTmWZS9iukb91xbn2HbFSMQm2igY/0/*)#yrnz9pp2");
    +
    +        // as expected this does not compile due to invalid context
    +        //let desc_key:DescriptorKey<Segwitv0> = (xprv, path.clone()).into_descriptor_key().unwrap();
    +        //let (desc, _key_map, _valid_networks) = descriptor!(pkh(desc_key)).unwrap();
    +    }
    +
    +    #[test]
    +    fn test_dsl_modifiers() {
    +        let private_key =
    +            PrivateKey::from_wif("cSQPHDBwXGjVzWRqAHm6zfvQhaTuj1f2bFH58h55ghbjtFwvmeXR").unwrap();
    +        let (descriptor, _, _) =
    +            descriptor!(wsh(thresh(2,n:d:v:older(1),s:pk(private_key),s:pk(private_key)))).unwrap();
    +
    +        assert_eq!(descriptor.to_string(), "wsh(thresh(2,ndv:older(1),s:pk(02e96fe52ef0e22d2f131dd425ce1893073a3c6ad20e8cac36726393dfb4856a4c),s:pk(02e96fe52ef0e22d2f131dd425ce1893073a3c6ad20e8cac36726393dfb4856a4c)))#zzk3ux8g")
         }
     
    -    #[test]
    -    #[should_panic(
    -        expected = "Miniscript(ContextError(CompressedOnly(\"04b4632d08485ff1df2db55b9dafd23347d1c47a457072a1e87be26896549a87378ec38ff91d43e8c2092ebda601780485263da089465619e0358a5c1be7ac91f4\")))"
    -    )]
    -    fn test_dsl_miniscript_checks() {
    -        let mut uncompressed_pk =
    -            PrivateKey::from_wif("L5EZftvrYaSudiozVRzTqLcHLNDoVn7H5HSfM9BAN6tMJX8oTWz6").unwrap();
    -        uncompressed_pk.compressed = false;
    +    #[test]
    +    #[should_panic(
    +        expected = "Miniscript(ContextError(CompressedOnly(\"04b4632d08485ff1df2db55b9dafd23347d1c47a457072a1e87be26896549a87378ec38ff91d43e8c2092ebda601780485263da089465619e0358a5c1be7ac91f4\")))"
    +    )]
    +    fn test_dsl_miniscript_checks() {
    +        let mut uncompressed_pk =
    +            PrivateKey::from_wif("L5EZftvrYaSudiozVRzTqLcHLNDoVn7H5HSfM9BAN6tMJX8oTWz6").unwrap();
    +        uncompressed_pk.compressed = false;
     
    -        descriptor!(wsh(v: pk(uncompressed_pk))).unwrap();
    +        descriptor!(wsh(v: pk(uncompressed_pk))).unwrap();
         }
     
    -    #[test]
    -    fn test_dsl_tr_only_key() {
    -        let private_key =
    -            PrivateKey::from_wif("cSQPHDBwXGjVzWRqAHm6zfvQhaTuj1f2bFH58h55ghbjtFwvmeXR").unwrap();
    -        let (descriptor, _, _) = descriptor!(tr(private_key)).unwrap();
    +    #[test]
    +    fn test_dsl_tr_only_key() {
    +        let private_key =
    +            PrivateKey::from_wif("cSQPHDBwXGjVzWRqAHm6zfvQhaTuj1f2bFH58h55ghbjtFwvmeXR").unwrap();
    +        let (descriptor, _, _) = descriptor!(tr(private_key)).unwrap();
     
             assert_eq!(
    -            descriptor.to_string(),
    -            "tr(02e96fe52ef0e22d2f131dd425ce1893073a3c6ad20e8cac36726393dfb4856a4c)#heq9m95v"
    -        )
    +            descriptor.to_string(),
    +            "tr(02e96fe52ef0e22d2f131dd425ce1893073a3c6ad20e8cac36726393dfb4856a4c)#heq9m95v"
    +        )
         }
     
    -    #[test]
    -    fn test_dsl_tr_simple_tree() {
    -        let private_key =
    -            PrivateKey::from_wif("cSQPHDBwXGjVzWRqAHm6zfvQhaTuj1f2bFH58h55ghbjtFwvmeXR").unwrap();
    -        let (descriptor, _, _) =
    -            descriptor!(tr(private_key, { pk(private_key), pk(private_key) })).unwrap();
    +    #[test]
    +    fn test_dsl_tr_simple_tree() {
    +        let private_key =
    +            PrivateKey::from_wif("cSQPHDBwXGjVzWRqAHm6zfvQhaTuj1f2bFH58h55ghbjtFwvmeXR").unwrap();
    +        let (descriptor, _, _) =
    +            descriptor!(tr(private_key, { pk(private_key), pk(private_key) })).unwrap();
     
    -        assert_eq!(descriptor.to_string(), "tr(02e96fe52ef0e22d2f131dd425ce1893073a3c6ad20e8cac36726393dfb4856a4c,{pk(02e96fe52ef0e22d2f131dd425ce1893073a3c6ad20e8cac36726393dfb4856a4c),pk(02e96fe52ef0e22d2f131dd425ce1893073a3c6ad20e8cac36726393dfb4856a4c)})#xy5fjw6d")
    +        assert_eq!(descriptor.to_string(), "tr(02e96fe52ef0e22d2f131dd425ce1893073a3c6ad20e8cac36726393dfb4856a4c,{pk(02e96fe52ef0e22d2f131dd425ce1893073a3c6ad20e8cac36726393dfb4856a4c),pk(02e96fe52ef0e22d2f131dd425ce1893073a3c6ad20e8cac36726393dfb4856a4c)})#xy5fjw6d")
         }
     
    -    #[test]
    -    fn test_dsl_tr_single_leaf() {
    -        let private_key =
    -            PrivateKey::from_wif("cSQPHDBwXGjVzWRqAHm6zfvQhaTuj1f2bFH58h55ghbjtFwvmeXR").unwrap();
    -        let (descriptor, _, _) = descriptor!(tr(private_key, pk(private_key))).unwrap();
    +    #[test]
    +    fn test_dsl_tr_single_leaf() {
    +        let private_key =
    +            PrivateKey::from_wif("cSQPHDBwXGjVzWRqAHm6zfvQhaTuj1f2bFH58h55ghbjtFwvmeXR").unwrap();
    +        let (descriptor, _, _) = descriptor!(tr(private_key, pk(private_key))).unwrap();
     
    -        assert_eq!(descriptor.to_string(), "tr(02e96fe52ef0e22d2f131dd425ce1893073a3c6ad20e8cac36726393dfb4856a4c,pk(02e96fe52ef0e22d2f131dd425ce1893073a3c6ad20e8cac36726393dfb4856a4c))#lzl2vmc7")
    +        assert_eq!(descriptor.to_string(), "tr(02e96fe52ef0e22d2f131dd425ce1893073a3c6ad20e8cac36726393dfb4856a4c,pk(02e96fe52ef0e22d2f131dd425ce1893073a3c6ad20e8cac36726393dfb4856a4c))#lzl2vmc7")
         }
     }
     
    -
    - \ No newline at end of file +
    \ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/src/bdk/descriptor/error.rs.html b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/src/bdk/descriptor/error.rs.html index 64a26916ff..aefbcfe264 100644 --- a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/src/bdk/descriptor/error.rs.html +++ b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/src/bdk/descriptor/error.rs.html @@ -1,144 +1,137 @@ -error.rs - source - -
     1
    - 2
    - 3
    - 4
    - 5
    - 6
    - 7
    - 8
    - 9
    -10
    -11
    -12
    -13
    -14
    -15
    -16
    -17
    -18
    -19
    -20
    -21
    -22
    -23
    -24
    -25
    -26
    -27
    -28
    -29
    -30
    -31
    -32
    -33
    -34
    -35
    -36
    -37
    -38
    -39
    -40
    -41
    -42
    -43
    -44
    -45
    -46
    -47
    -48
    -49
    -50
    -51
    -52
    -53
    -54
    -55
    -56
    -57
    -58
    -59
    -60
    -61
    -62
    -63
    -64
    -65
    -66
    -67
    -
    // Bitcoin Dev Kit
    -// Written in 2020 by Alekos Filini <alekos.filini@gmail.com>
    -//
    -// Copyright (c) 2020-2021 Bitcoin Dev Kit Developers
    -//
    -// This file is licensed under the Apache License, Version 2.0 <LICENSE-APACHE
    -// or http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
    -// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your option.
    -// You may not use this file except in accordance with one or both of these
    -// licenses.
    +error.rs - source
    1
    +2
    +3
    +4
    +5
    +6
    +7
    +8
    +9
    +10
    +11
    +12
    +13
    +14
    +15
    +16
    +17
    +18
    +19
    +20
    +21
    +22
    +23
    +24
    +25
    +26
    +27
    +28
    +29
    +30
    +31
    +32
    +33
    +34
    +35
    +36
    +37
    +38
    +39
    +40
    +41
    +42
    +43
    +44
    +45
    +46
    +47
    +48
    +49
    +50
    +51
    +52
    +53
    +54
    +55
    +56
    +57
    +58
    +59
    +60
    +61
    +62
    +63
    +64
    +65
    +66
    +67
    +
    // Bitcoin Dev Kit
    +// Written in 2020 by Alekos Filini <alekos.filini@gmail.com>
    +//
    +// Copyright (c) 2020-2021 Bitcoin Dev Kit Developers
    +//
    +// This file is licensed under the Apache License, Version 2.0 <LICENSE-APACHE
    +// or http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
    +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your option.
    +// You may not use this file except in accordance with one or both of these
    +// licenses.
     
    -//! Descriptor errors
    +//! Descriptor errors
     
    -/// Errors related to the parsing and usage of descriptors
    -#[derive(Debug)]
    -pub enum Error {
    -    /// Invalid HD Key path, such as having a wildcard but a length != 1
    -    InvalidHdKeyPath,
    -    /// The provided descriptor doesn't match its checksum
    -    InvalidDescriptorChecksum,
    -    /// The descriptor contains hardened derivation steps on public extended keys
    -    HardenedDerivationXpub,
    +/// Errors related to the parsing and usage of descriptors
    +#[derive(Debug)]
    +pub enum Error {
    +    /// Invalid HD Key path, such as having a wildcard but a length != 1
    +    InvalidHdKeyPath,
    +    /// The provided descriptor doesn't match its checksum
    +    InvalidDescriptorChecksum,
    +    /// The descriptor contains hardened derivation steps on public extended keys
    +    HardenedDerivationXpub,
     
    -    /// Error thrown while working with [`keys`](crate::keys)
    -    Key(crate::keys::KeyError),
    -    /// Error while extracting and manipulating policies
    -    Policy(crate::descriptor::policy::PolicyError),
    +    /// Error thrown while working with [`keys`](crate::keys)
    +    Key(crate::keys::KeyError),
    +    /// Error while extracting and manipulating policies
    +    Policy(crate::descriptor::policy::PolicyError),
     
    -    /// Invalid byte found in the descriptor checksum
    -    InvalidDescriptorCharacter(u8),
    +    /// Invalid byte found in the descriptor checksum
    +    InvalidDescriptorCharacter(u8),
     
    -    /// BIP32 error
    -    Bip32(bitcoin::util::bip32::Error),
    -    /// Error during base58 decoding
    -    Base58(bitcoin::util::base58::Error),
    -    /// Key-related error
    -    Pk(bitcoin::util::key::Error),
    -    /// Miniscript error
    -    Miniscript(miniscript::Error),
    -    /// Hex decoding error
    -    Hex(bitcoin::hashes::hex::Error),
    +    /// BIP32 error
    +    Bip32(bitcoin::util::bip32::Error),
    +    /// Error during base58 decoding
    +    Base58(bitcoin::util::base58::Error),
    +    /// Key-related error
    +    Pk(bitcoin::util::key::Error),
    +    /// Miniscript error
    +    Miniscript(miniscript::Error),
    +    /// Hex decoding error
    +    Hex(bitcoin::hashes::hex::Error),
     }
     
    -impl From<crate::keys::KeyError> for Error {
    -    fn from(key_error: crate::keys::KeyError) -> Error {
    -        match key_error {
    -            crate::keys::KeyError::Miniscript(inner) => Error::Miniscript(inner),
    -            crate::keys::KeyError::Bip32(inner) => Error::Bip32(inner),
    -            e => Error::Key(e),
    +impl From<crate::keys::KeyError> for Error {
    +    fn from(key_error: crate::keys::KeyError) -> Error {
    +        match key_error {
    +            crate::keys::KeyError::Miniscript(inner) => Error::Miniscript(inner),
    +            crate::keys::KeyError::Bip32(inner) => Error::Bip32(inner),
    +            e => Error::Key(e),
             }
         }
     }
     
    -impl std::fmt::Display for Error {
    -    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
    -        write!(f, "{:?}", self)
    +impl std::fmt::Display for Error {
    +    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
    +        write!(f, "{:?}", self)
         }
     }
     
    -impl std::error::Error for Error {}
    +impl std::error::Error for Error {}
     
    -impl_error!(bitcoin::util::bip32::Error, Bip32);
    -impl_error!(bitcoin::util::base58::Error, Base58);
    -impl_error!(bitcoin::util::key::Error, Pk);
    -impl_error!(miniscript::Error, Miniscript);
    -impl_error!(bitcoin::hashes::hex::Error, Hex);
    -impl_error!(crate::descriptor::policy::PolicyError, Policy);
    +impl_error!(bitcoin::util::bip32::Error, Bip32);
    +impl_error!(bitcoin::util::base58::Error, Base58);
    +impl_error!(bitcoin::util::key::Error, Pk);
    +impl_error!(miniscript::Error, Miniscript);
    +impl_error!(bitcoin::hashes::hex::Error, Hex);
    +impl_error!(crate::descriptor::policy::PolicyError, Policy);
     
    -
    - \ No newline at end of file +
    \ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/src/bdk/descriptor/mod.rs.html b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/src/bdk/descriptor/mod.rs.html index 089b7b97b9..54b63ae618 100644 --- a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/src/bdk/descriptor/mod.rs.html +++ b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/src/bdk/descriptor/mod.rs.html @@ -1,1521 +1,1515 @@ -mod.rs - source - -
      1
    -  2
    -  3
    -  4
    -  5
    -  6
    -  7
    -  8
    -  9
    - 10
    - 11
    - 12
    - 13
    - 14
    - 15
    - 16
    - 17
    - 18
    - 19
    - 20
    - 21
    - 22
    - 23
    - 24
    - 25
    - 26
    - 27
    - 28
    - 29
    - 30
    - 31
    - 32
    - 33
    - 34
    - 35
    - 36
    - 37
    - 38
    - 39
    - 40
    - 41
    - 42
    - 43
    - 44
    - 45
    - 46
    - 47
    - 48
    - 49
    - 50
    - 51
    - 52
    - 53
    - 54
    - 55
    - 56
    - 57
    - 58
    - 59
    - 60
    - 61
    - 62
    - 63
    - 64
    - 65
    - 66
    - 67
    - 68
    - 69
    - 70
    - 71
    - 72
    - 73
    - 74
    - 75
    - 76
    - 77
    - 78
    - 79
    - 80
    - 81
    - 82
    - 83
    - 84
    - 85
    - 86
    - 87
    - 88
    - 89
    - 90
    - 91
    - 92
    - 93
    - 94
    - 95
    - 96
    - 97
    - 98
    - 99
    -100
    -101
    -102
    -103
    -104
    -105
    -106
    -107
    -108
    -109
    -110
    -111
    -112
    -113
    -114
    -115
    -116
    -117
    -118
    -119
    -120
    -121
    -122
    -123
    -124
    -125
    -126
    -127
    -128
    -129
    -130
    -131
    -132
    -133
    -134
    -135
    -136
    -137
    -138
    -139
    -140
    -141
    -142
    -143
    -144
    -145
    -146
    -147
    -148
    -149
    -150
    -151
    -152
    -153
    -154
    -155
    -156
    -157
    -158
    -159
    -160
    -161
    -162
    -163
    -164
    -165
    -166
    -167
    -168
    -169
    -170
    -171
    -172
    -173
    -174
    -175
    -176
    -177
    -178
    -179
    -180
    -181
    -182
    -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
    -245
    -246
    -247
    -248
    -249
    -250
    -251
    -252
    -253
    -254
    -255
    -256
    -257
    -258
    -259
    -260
    -261
    -262
    -263
    -264
    -265
    -266
    -267
    -268
    -269
    -270
    -271
    -272
    -273
    -274
    -275
    -276
    -277
    -278
    -279
    -280
    -281
    -282
    -283
    -284
    -285
    -286
    -287
    -288
    -289
    -290
    -291
    -292
    -293
    -294
    -295
    -296
    -297
    -298
    -299
    -300
    -301
    -302
    -303
    -304
    -305
    -306
    -307
    -308
    -309
    -310
    -311
    -312
    -313
    -314
    -315
    -316
    -317
    -318
    -319
    -320
    -321
    -322
    -323
    -324
    -325
    -326
    -327
    -328
    -329
    -330
    -331
    -332
    -333
    -334
    -335
    -336
    -337
    -338
    -339
    -340
    -341
    -342
    -343
    -344
    -345
    -346
    -347
    -348
    -349
    -350
    -351
    -352
    -353
    -354
    -355
    -356
    -357
    -358
    -359
    -360
    -361
    -362
    -363
    -364
    -365
    -366
    -367
    -368
    -369
    -370
    -371
    -372
    -373
    -374
    -375
    -376
    -377
    -378
    -379
    -380
    -381
    -382
    -383
    -384
    -385
    -386
    -387
    -388
    -389
    -390
    -391
    -392
    -393
    -394
    -395
    -396
    -397
    -398
    -399
    -400
    -401
    -402
    -403
    -404
    -405
    -406
    -407
    -408
    -409
    -410
    -411
    -412
    -413
    -414
    -415
    -416
    -417
    -418
    -419
    -420
    -421
    -422
    -423
    -424
    -425
    -426
    -427
    -428
    -429
    -430
    -431
    -432
    -433
    -434
    -435
    -436
    -437
    -438
    -439
    -440
    -441
    -442
    -443
    -444
    -445
    -446
    -447
    -448
    -449
    -450
    -451
    -452
    -453
    -454
    -455
    -456
    -457
    -458
    -459
    -460
    -461
    -462
    -463
    -464
    -465
    -466
    -467
    -468
    -469
    -470
    -471
    -472
    -473
    -474
    -475
    -476
    -477
    -478
    -479
    -480
    -481
    -482
    -483
    -484
    -485
    -486
    -487
    -488
    -489
    -490
    -491
    -492
    -493
    -494
    -495
    -496
    -497
    -498
    -499
    -500
    -501
    -502
    -503
    -504
    -505
    -506
    -507
    -508
    -509
    -510
    -511
    -512
    -513
    -514
    -515
    -516
    -517
    -518
    -519
    -520
    -521
    -522
    -523
    -524
    -525
    -526
    -527
    -528
    -529
    -530
    -531
    -532
    -533
    -534
    -535
    -536
    -537
    -538
    -539
    -540
    -541
    -542
    -543
    -544
    -545
    -546
    -547
    -548
    -549
    -550
    -551
    -552
    -553
    -554
    -555
    -556
    -557
    -558
    -559
    -560
    -561
    -562
    -563
    -564
    -565
    -566
    -567
    -568
    -569
    -570
    -571
    -572
    -573
    -574
    -575
    -576
    -577
    -578
    -579
    -580
    -581
    -582
    -583
    -584
    -585
    -586
    -587
    -588
    -589
    -590
    -591
    -592
    -593
    -594
    -595
    -596
    -597
    -598
    -599
    -600
    -601
    -602
    -603
    -604
    -605
    -606
    -607
    -608
    -609
    -610
    -611
    -612
    -613
    -614
    -615
    -616
    -617
    -618
    -619
    -620
    -621
    -622
    -623
    -624
    -625
    -626
    -627
    -628
    -629
    -630
    -631
    -632
    -633
    -634
    -635
    -636
    -637
    -638
    -639
    -640
    -641
    -642
    -643
    -644
    -645
    -646
    -647
    -648
    -649
    -650
    -651
    -652
    -653
    -654
    -655
    -656
    -657
    -658
    -659
    -660
    -661
    -662
    -663
    -664
    -665
    -666
    -667
    -668
    -669
    -670
    -671
    -672
    -673
    -674
    -675
    -676
    -677
    -678
    -679
    -680
    -681
    -682
    -683
    -684
    -685
    -686
    -687
    -688
    -689
    -690
    -691
    -692
    -693
    -694
    -695
    -696
    -697
    -698
    -699
    -700
    -701
    -702
    -703
    -704
    -705
    -706
    -707
    -708
    -709
    -710
    -711
    -712
    -713
    -714
    -715
    -716
    -717
    -718
    -719
    -720
    -721
    -722
    -723
    -724
    -725
    -726
    -727
    -728
    -729
    -730
    -731
    -732
    -733
    -734
    -735
    -736
    -737
    -738
    -739
    -740
    -741
    -742
    -743
    -744
    -745
    -746
    -747
    -748
    -749
    -750
    -751
    -752
    -753
    -754
    -755
    -756
    -757
    -758
    -759
    -760
    -761
    -762
    -763
    -764
    -765
    -766
    -767
    -768
    -769
    -770
    -771
    -772
    -773
    -774
    -775
    -776
    -777
    -778
    -779
    -780
    -781
    -782
    -783
    -784
    -785
    -786
    -787
    -788
    -789
    -790
    -791
    -792
    -793
    -794
    -795
    -796
    -797
    -798
    -799
    -800
    -801
    -802
    -803
    -804
    -805
    -806
    -807
    -808
    -809
    -810
    -811
    -812
    -813
    -814
    -815
    -816
    -817
    -818
    -819
    -820
    -821
    -822
    -823
    -824
    -825
    -826
    -827
    -828
    -829
    -830
    -831
    -832
    -833
    -834
    -835
    -836
    -837
    -838
    -839
    -840
    -841
    -842
    -843
    -844
    -845
    -846
    -847
    -848
    -849
    -850
    -851
    -852
    -853
    -854
    -855
    -856
    -857
    -858
    -859
    -860
    -861
    -862
    -863
    -864
    -865
    -866
    -867
    -868
    -869
    -870
    -871
    -872
    -873
    -874
    -875
    -876
    -877
    -878
    -879
    -880
    -881
    -882
    -883
    -884
    -885
    -886
    -887
    -888
    -
    // Bitcoin Dev Kit
    -// Written in 2020 by Alekos Filini <alekos.filini@gmail.com>
    -//
    -// Copyright (c) 2020-2021 Bitcoin Dev Kit Developers
    -//
    -// This file is licensed under the Apache License, Version 2.0 <LICENSE-APACHE
    -// or http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
    -// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your option.
    -// You may not use this file except in accordance with one or both of these
    -// licenses.
    -
    -//! Descriptors
    -//!
    -//! This module contains generic utilities to work with descriptors, plus some re-exported types
    -//! from [`miniscript`].
    -
    -use std::collections::BTreeMap;
    -
    -use bitcoin::util::bip32::{ChildNumber, DerivationPath, ExtendedPubKey, Fingerprint, KeySource};
    -use bitcoin::util::{psbt, taproot};
    -use bitcoin::{secp256k1, PublicKey, XOnlyPublicKey};
    -use bitcoin::{Network, TxOut};
    -
    -use miniscript::descriptor::{
    -    DefiniteDescriptorKey, DescriptorSecretKey, DescriptorType, InnerXKey, SinglePubKey,
    +mod.rs - source
    1
    +2
    +3
    +4
    +5
    +6
    +7
    +8
    +9
    +10
    +11
    +12
    +13
    +14
    +15
    +16
    +17
    +18
    +19
    +20
    +21
    +22
    +23
    +24
    +25
    +26
    +27
    +28
    +29
    +30
    +31
    +32
    +33
    +34
    +35
    +36
    +37
    +38
    +39
    +40
    +41
    +42
    +43
    +44
    +45
    +46
    +47
    +48
    +49
    +50
    +51
    +52
    +53
    +54
    +55
    +56
    +57
    +58
    +59
    +60
    +61
    +62
    +63
    +64
    +65
    +66
    +67
    +68
    +69
    +70
    +71
    +72
    +73
    +74
    +75
    +76
    +77
    +78
    +79
    +80
    +81
    +82
    +83
    +84
    +85
    +86
    +87
    +88
    +89
    +90
    +91
    +92
    +93
    +94
    +95
    +96
    +97
    +98
    +99
    +100
    +101
    +102
    +103
    +104
    +105
    +106
    +107
    +108
    +109
    +110
    +111
    +112
    +113
    +114
    +115
    +116
    +117
    +118
    +119
    +120
    +121
    +122
    +123
    +124
    +125
    +126
    +127
    +128
    +129
    +130
    +131
    +132
    +133
    +134
    +135
    +136
    +137
    +138
    +139
    +140
    +141
    +142
    +143
    +144
    +145
    +146
    +147
    +148
    +149
    +150
    +151
    +152
    +153
    +154
    +155
    +156
    +157
    +158
    +159
    +160
    +161
    +162
    +163
    +164
    +165
    +166
    +167
    +168
    +169
    +170
    +171
    +172
    +173
    +174
    +175
    +176
    +177
    +178
    +179
    +180
    +181
    +182
    +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
    +245
    +246
    +247
    +248
    +249
    +250
    +251
    +252
    +253
    +254
    +255
    +256
    +257
    +258
    +259
    +260
    +261
    +262
    +263
    +264
    +265
    +266
    +267
    +268
    +269
    +270
    +271
    +272
    +273
    +274
    +275
    +276
    +277
    +278
    +279
    +280
    +281
    +282
    +283
    +284
    +285
    +286
    +287
    +288
    +289
    +290
    +291
    +292
    +293
    +294
    +295
    +296
    +297
    +298
    +299
    +300
    +301
    +302
    +303
    +304
    +305
    +306
    +307
    +308
    +309
    +310
    +311
    +312
    +313
    +314
    +315
    +316
    +317
    +318
    +319
    +320
    +321
    +322
    +323
    +324
    +325
    +326
    +327
    +328
    +329
    +330
    +331
    +332
    +333
    +334
    +335
    +336
    +337
    +338
    +339
    +340
    +341
    +342
    +343
    +344
    +345
    +346
    +347
    +348
    +349
    +350
    +351
    +352
    +353
    +354
    +355
    +356
    +357
    +358
    +359
    +360
    +361
    +362
    +363
    +364
    +365
    +366
    +367
    +368
    +369
    +370
    +371
    +372
    +373
    +374
    +375
    +376
    +377
    +378
    +379
    +380
    +381
    +382
    +383
    +384
    +385
    +386
    +387
    +388
    +389
    +390
    +391
    +392
    +393
    +394
    +395
    +396
    +397
    +398
    +399
    +400
    +401
    +402
    +403
    +404
    +405
    +406
    +407
    +408
    +409
    +410
    +411
    +412
    +413
    +414
    +415
    +416
    +417
    +418
    +419
    +420
    +421
    +422
    +423
    +424
    +425
    +426
    +427
    +428
    +429
    +430
    +431
    +432
    +433
    +434
    +435
    +436
    +437
    +438
    +439
    +440
    +441
    +442
    +443
    +444
    +445
    +446
    +447
    +448
    +449
    +450
    +451
    +452
    +453
    +454
    +455
    +456
    +457
    +458
    +459
    +460
    +461
    +462
    +463
    +464
    +465
    +466
    +467
    +468
    +469
    +470
    +471
    +472
    +473
    +474
    +475
    +476
    +477
    +478
    +479
    +480
    +481
    +482
    +483
    +484
    +485
    +486
    +487
    +488
    +489
    +490
    +491
    +492
    +493
    +494
    +495
    +496
    +497
    +498
    +499
    +500
    +501
    +502
    +503
    +504
    +505
    +506
    +507
    +508
    +509
    +510
    +511
    +512
    +513
    +514
    +515
    +516
    +517
    +518
    +519
    +520
    +521
    +522
    +523
    +524
    +525
    +526
    +527
    +528
    +529
    +530
    +531
    +532
    +533
    +534
    +535
    +536
    +537
    +538
    +539
    +540
    +541
    +542
    +543
    +544
    +545
    +546
    +547
    +548
    +549
    +550
    +551
    +552
    +553
    +554
    +555
    +556
    +557
    +558
    +559
    +560
    +561
    +562
    +563
    +564
    +565
    +566
    +567
    +568
    +569
    +570
    +571
    +572
    +573
    +574
    +575
    +576
    +577
    +578
    +579
    +580
    +581
    +582
    +583
    +584
    +585
    +586
    +587
    +588
    +589
    +590
    +591
    +592
    +593
    +594
    +595
    +596
    +597
    +598
    +599
    +600
    +601
    +602
    +603
    +604
    +605
    +606
    +607
    +608
    +609
    +610
    +611
    +612
    +613
    +614
    +615
    +616
    +617
    +618
    +619
    +620
    +621
    +622
    +623
    +624
    +625
    +626
    +627
    +628
    +629
    +630
    +631
    +632
    +633
    +634
    +635
    +636
    +637
    +638
    +639
    +640
    +641
    +642
    +643
    +644
    +645
    +646
    +647
    +648
    +649
    +650
    +651
    +652
    +653
    +654
    +655
    +656
    +657
    +658
    +659
    +660
    +661
    +662
    +663
    +664
    +665
    +666
    +667
    +668
    +669
    +670
    +671
    +672
    +673
    +674
    +675
    +676
    +677
    +678
    +679
    +680
    +681
    +682
    +683
    +684
    +685
    +686
    +687
    +688
    +689
    +690
    +691
    +692
    +693
    +694
    +695
    +696
    +697
    +698
    +699
    +700
    +701
    +702
    +703
    +704
    +705
    +706
    +707
    +708
    +709
    +710
    +711
    +712
    +713
    +714
    +715
    +716
    +717
    +718
    +719
    +720
    +721
    +722
    +723
    +724
    +725
    +726
    +727
    +728
    +729
    +730
    +731
    +732
    +733
    +734
    +735
    +736
    +737
    +738
    +739
    +740
    +741
    +742
    +743
    +744
    +745
    +746
    +747
    +748
    +749
    +750
    +751
    +752
    +753
    +754
    +755
    +756
    +757
    +758
    +759
    +760
    +761
    +762
    +763
    +764
    +765
    +766
    +767
    +768
    +769
    +770
    +771
    +772
    +773
    +774
    +775
    +776
    +777
    +778
    +779
    +780
    +781
    +782
    +783
    +784
    +785
    +786
    +787
    +788
    +789
    +790
    +791
    +792
    +793
    +794
    +795
    +796
    +797
    +798
    +799
    +800
    +801
    +802
    +803
    +804
    +805
    +806
    +807
    +808
    +809
    +810
    +811
    +812
    +813
    +814
    +815
    +816
    +817
    +818
    +819
    +820
    +821
    +822
    +823
    +824
    +825
    +826
    +827
    +828
    +829
    +830
    +831
    +832
    +833
    +834
    +835
    +836
    +837
    +838
    +839
    +840
    +841
    +842
    +843
    +844
    +845
    +846
    +847
    +848
    +849
    +850
    +851
    +852
    +853
    +854
    +855
    +856
    +857
    +858
    +859
    +860
    +861
    +862
    +863
    +864
    +865
    +866
    +867
    +868
    +869
    +870
    +871
    +872
    +873
    +874
    +875
    +876
    +877
    +878
    +879
    +880
    +881
    +882
    +883
    +884
    +885
    +886
    +887
    +888
    +
    // Bitcoin Dev Kit
    +// Written in 2020 by Alekos Filini <alekos.filini@gmail.com>
    +//
    +// Copyright (c) 2020-2021 Bitcoin Dev Kit Developers
    +//
    +// This file is licensed under the Apache License, Version 2.0 <LICENSE-APACHE
    +// or http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
    +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your option.
    +// You may not use this file except in accordance with one or both of these
    +// licenses.
    +
    +//! Descriptors
    +//!
    +//! This module contains generic utilities to work with descriptors, plus some re-exported types
    +//! from [`miniscript`].
    +
    +use std::collections::BTreeMap;
    +
    +use bitcoin::util::bip32::{ChildNumber, DerivationPath, ExtendedPubKey, Fingerprint, KeySource};
    +use bitcoin::util::{psbt, taproot};
    +use bitcoin::{secp256k1, PublicKey, XOnlyPublicKey};
    +use bitcoin::{Network, TxOut};
    +
    +use miniscript::descriptor::{
    +    DefiniteDescriptorKey, DescriptorSecretKey, DescriptorType, InnerXKey, SinglePubKey,
     };
    -pub use miniscript::{
    -    descriptor::DescriptorXKey, descriptor::KeyMap, descriptor::Wildcard, Descriptor,
    -    DescriptorPublicKey, Legacy, Miniscript, ScriptContext, Segwitv0,
    +pub use miniscript::{
    +    descriptor::DescriptorXKey, descriptor::KeyMap, descriptor::Wildcard, Descriptor,
    +    DescriptorPublicKey, Legacy, Miniscript, ScriptContext, Segwitv0,
     };
    -use miniscript::{ForEachKey, MiniscriptKey, TranslatePk};
    -
    -use crate::descriptor::policy::BuildSatisfaction;
    -
    -pub mod checksum;
    -#[doc(hidden)]
    -pub mod dsl;
    -pub mod error;
    -pub mod policy;
    -pub mod template;
    -
    -pub use self::checksum::calc_checksum;
    -use self::checksum::calc_checksum_bytes;
    -pub use self::error::Error as DescriptorError;
    -pub use self::policy::Policy;
    -use self::template::DescriptorTemplateOut;
    -use crate::keys::{IntoDescriptorKey, KeyError};
    -use crate::wallet::signer::SignersContainer;
    -use crate::wallet::utils::SecpCtx;
    -
    -/// Alias for a [`Descriptor`] that can contain extended keys using [`DescriptorPublicKey`]
    -pub type ExtendedDescriptor = Descriptor<DescriptorPublicKey>;
    -
    -/// Alias for a [`Descriptor`] that contains extended **derived** keys
    -pub type DerivedDescriptor = Descriptor<DefiniteDescriptorKey>;
    -
    -/// Alias for the type of maps that represent derivation paths in a [`psbt::Input`] or
    -/// [`psbt::Output`]
    -///
    -/// [`psbt::Input`]: bitcoin::util::psbt::Input
    -/// [`psbt::Output`]: bitcoin::util::psbt::Output
    -pub type HdKeyPaths = BTreeMap<secp256k1::PublicKey, KeySource>;
    -
    -/// Alias for the type of maps that represent taproot key origins in a [`psbt::Input`] or
    -/// [`psbt::Output`]
    -///
    -/// [`psbt::Input`]: bitcoin::util::psbt::Input
    -/// [`psbt::Output`]: bitcoin::util::psbt::Output
    -pub type TapKeyOrigins = BTreeMap<bitcoin::XOnlyPublicKey, (Vec<taproot::TapLeafHash>, KeySource)>;
    -
    -/// Trait for types which can be converted into an [`ExtendedDescriptor`] and a [`KeyMap`] usable by a wallet in a specific [`Network`]
    -pub trait IntoWalletDescriptor {
    -    /// Convert to wallet descriptor
    -    fn into_wallet_descriptor(
    +use miniscript::{ForEachKey, MiniscriptKey, TranslatePk};
    +
    +use crate::descriptor::policy::BuildSatisfaction;
    +
    +pub mod checksum;
    +#[doc(hidden)]
    +pub mod dsl;
    +pub mod error;
    +pub mod policy;
    +pub mod template;
    +
    +pub use self::checksum::calc_checksum;
    +use self::checksum::calc_checksum_bytes;
    +pub use self::error::Error as DescriptorError;
    +pub use self::policy::Policy;
    +use self::template::DescriptorTemplateOut;
    +use crate::keys::{IntoDescriptorKey, KeyError};
    +use crate::wallet::signer::SignersContainer;
    +use crate::wallet::utils::SecpCtx;
    +
    +/// Alias for a [`Descriptor`] that can contain extended keys using [`DescriptorPublicKey`]
    +pub type ExtendedDescriptor = Descriptor<DescriptorPublicKey>;
    +
    +/// Alias for a [`Descriptor`] that contains extended **derived** keys
    +pub type DerivedDescriptor = Descriptor<DefiniteDescriptorKey>;
    +
    +/// Alias for the type of maps that represent derivation paths in a [`psbt::Input`] or
    +/// [`psbt::Output`]
    +///
    +/// [`psbt::Input`]: bitcoin::util::psbt::Input
    +/// [`psbt::Output`]: bitcoin::util::psbt::Output
    +pub type HdKeyPaths = BTreeMap<secp256k1::PublicKey, KeySource>;
    +
    +/// Alias for the type of maps that represent taproot key origins in a [`psbt::Input`] or
    +/// [`psbt::Output`]
    +///
    +/// [`psbt::Input`]: bitcoin::util::psbt::Input
    +/// [`psbt::Output`]: bitcoin::util::psbt::Output
    +pub type TapKeyOrigins = BTreeMap<bitcoin::XOnlyPublicKey, (Vec<taproot::TapLeafHash>, KeySource)>;
    +
    +/// Trait for types which can be converted into an [`ExtendedDescriptor`] and a [`KeyMap`] usable by a wallet in a specific [`Network`]
    +pub trait IntoWalletDescriptor {
    +    /// Convert to wallet descriptor
    +    fn into_wallet_descriptor(
             self,
    -        secp: &SecpCtx,
    -        network: Network,
    -    ) -> Result<(ExtendedDescriptor, KeyMap), DescriptorError>;
    +        secp: &SecpCtx,
    +        network: Network,
    +    ) -> Result<(ExtendedDescriptor, KeyMap), DescriptorError>;
     }
     
    -impl IntoWalletDescriptor for &str {
    -    fn into_wallet_descriptor(
    +impl IntoWalletDescriptor for &str {
    +    fn into_wallet_descriptor(
             self,
    -        secp: &SecpCtx,
    -        network: Network,
    -    ) -> Result<(ExtendedDescriptor, KeyMap), DescriptorError> {
    -        let descriptor = match self.split_once('#') {
    -            Some((desc, original_checksum)) => {
    -                let checksum = calc_checksum_bytes(desc)?;
    -                if original_checksum.as_bytes() != checksum {
    -                    return Err(DescriptorError::InvalidDescriptorChecksum);
    +        secp: &SecpCtx,
    +        network: Network,
    +    ) -> Result<(ExtendedDescriptor, KeyMap), DescriptorError> {
    +        let descriptor = match self.split_once('#') {
    +            Some((desc, original_checksum)) => {
    +                let checksum = calc_checksum_bytes(desc)?;
    +                if original_checksum.as_bytes() != checksum {
    +                    return Err(DescriptorError::InvalidDescriptorChecksum);
                     }
    -                desc
    +                desc
                 }
    -            None => self,
    +            None => self,
             };
     
    -        ExtendedDescriptor::parse_descriptor(secp, descriptor)?
    -            .into_wallet_descriptor(secp, network)
    +        ExtendedDescriptor::parse_descriptor(secp, descriptor)?
    +            .into_wallet_descriptor(secp, network)
         }
     }
     
    -impl IntoWalletDescriptor for &String {
    -    fn into_wallet_descriptor(
    +impl IntoWalletDescriptor for &String {
    +    fn into_wallet_descriptor(
             self,
    -        secp: &SecpCtx,
    -        network: Network,
    -    ) -> Result<(ExtendedDescriptor, KeyMap), DescriptorError> {
    -        self.as_str().into_wallet_descriptor(secp, network)
    +        secp: &SecpCtx,
    +        network: Network,
    +    ) -> Result<(ExtendedDescriptor, KeyMap), DescriptorError> {
    +        self.as_str().into_wallet_descriptor(secp, network)
         }
     }
     
    -impl IntoWalletDescriptor for ExtendedDescriptor {
    -    fn into_wallet_descriptor(
    +impl IntoWalletDescriptor for ExtendedDescriptor {
    +    fn into_wallet_descriptor(
             self,
    -        secp: &SecpCtx,
    -        network: Network,
    -    ) -> Result<(ExtendedDescriptor, KeyMap), DescriptorError> {
    -        (self, KeyMap::default()).into_wallet_descriptor(secp, network)
    +        secp: &SecpCtx,
    +        network: Network,
    +    ) -> Result<(ExtendedDescriptor, KeyMap), DescriptorError> {
    +        (self, KeyMap::default()).into_wallet_descriptor(secp, network)
         }
     }
     
    -impl IntoWalletDescriptor for (ExtendedDescriptor, KeyMap) {
    -    fn into_wallet_descriptor(
    +impl IntoWalletDescriptor for (ExtendedDescriptor, KeyMap) {
    +    fn into_wallet_descriptor(
             self,
    -        secp: &SecpCtx,
    -        network: Network,
    -    ) -> Result<(ExtendedDescriptor, KeyMap), DescriptorError> {
    -        use crate::keys::DescriptorKey;
    -
    -        struct Translator<'s, 'd> {
    -            secp: &'s SecpCtx,
    -            descriptor: &'d ExtendedDescriptor,
    -            network: Network,
    +        secp: &SecpCtx,
    +        network: Network,
    +    ) -> Result<(ExtendedDescriptor, KeyMap), DescriptorError> {
    +        use crate::keys::DescriptorKey;
    +
    +        struct Translator<'s, 'd> {
    +            secp: &'s SecpCtx,
    +            descriptor: &'d ExtendedDescriptor,
    +            network: Network,
             }
     
    -        impl<'s, 'd>
    -            miniscript::Translator<DescriptorPublicKey, miniscript::DummyKey, DescriptorError>
    -            for Translator<'s, 'd>
    +        impl<'s, 'd>
    +            miniscript::Translator<DescriptorPublicKey, miniscript::DummyKey, DescriptorError>
    +            for Translator<'s, 'd>
             {
    -            fn pk(
    -                &mut self,
    -                pk: &DescriptorPublicKey,
    -            ) -> Result<miniscript::DummyKey, DescriptorError> {
    -                let secp = &self.secp;
    -
    -                let (_, _, networks) = if self.descriptor.is_taproot() {
    -                    let descriptor_key: DescriptorKey<miniscript::Tap> =
    -                        pk.clone().into_descriptor_key()?;
    -                    descriptor_key.extract(secp)?
    -                } else if self.descriptor.is_witness() {
    -                    let descriptor_key: DescriptorKey<miniscript::Segwitv0> =
    -                        pk.clone().into_descriptor_key()?;
    -                    descriptor_key.extract(secp)?
    -                } else {
    -                    let descriptor_key: DescriptorKey<miniscript::Legacy> =
    -                        pk.clone().into_descriptor_key()?;
    -                    descriptor_key.extract(secp)?
    -                };
    -
    -                if networks.contains(&self.network) {
    -                    Ok(miniscript::DummyKey)
    -                } else {
    -                    Err(DescriptorError::Key(KeyError::InvalidNetwork))
    +            fn pk(
    +                &mut self,
    +                pk: &DescriptorPublicKey,
    +            ) -> Result<miniscript::DummyKey, DescriptorError> {
    +                let secp = &self.secp;
    +
    +                let (_, _, networks) = if self.descriptor.is_taproot() {
    +                    let descriptor_key: DescriptorKey<miniscript::Tap> =
    +                        pk.clone().into_descriptor_key()?;
    +                    descriptor_key.extract(secp)?
    +                } else if self.descriptor.is_witness() {
    +                    let descriptor_key: DescriptorKey<miniscript::Segwitv0> =
    +                        pk.clone().into_descriptor_key()?;
    +                    descriptor_key.extract(secp)?
    +                } else {
    +                    let descriptor_key: DescriptorKey<miniscript::Legacy> =
    +                        pk.clone().into_descriptor_key()?;
    +                    descriptor_key.extract(secp)?
    +                };
    +
    +                if networks.contains(&self.network) {
    +                    Ok(miniscript::DummyKey)
    +                } else {
    +                    Err(DescriptorError::Key(KeyError::InvalidNetwork))
                     }
                 }
    -            fn sha256(
    -                &mut self,
    -                _sha256: &<DescriptorPublicKey as MiniscriptKey>::Sha256,
    -            ) -> Result<miniscript::DummySha256Hash, DescriptorError> {
    -                Ok(Default::default())
    +            fn sha256(
    +                &mut self,
    +                _sha256: &<DescriptorPublicKey as MiniscriptKey>::Sha256,
    +            ) -> Result<miniscript::DummySha256Hash, DescriptorError> {
    +                Ok(Default::default())
                 }
    -            fn hash256(
    -                &mut self,
    -                _hash256: &<DescriptorPublicKey as MiniscriptKey>::Hash256,
    -            ) -> Result<miniscript::DummyHash256Hash, DescriptorError> {
    -                Ok(Default::default())
    +            fn hash256(
    +                &mut self,
    +                _hash256: &<DescriptorPublicKey as MiniscriptKey>::Hash256,
    +            ) -> Result<miniscript::DummyHash256Hash, DescriptorError> {
    +                Ok(Default::default())
                 }
    -            fn ripemd160(
    -                &mut self,
    -                _ripemd160: &<DescriptorPublicKey as MiniscriptKey>::Ripemd160,
    -            ) -> Result<miniscript::DummyRipemd160Hash, DescriptorError> {
    -                Ok(Default::default())
    +            fn ripemd160(
    +                &mut self,
    +                _ripemd160: &<DescriptorPublicKey as MiniscriptKey>::Ripemd160,
    +            ) -> Result<miniscript::DummyRipemd160Hash, DescriptorError> {
    +                Ok(Default::default())
                 }
    -            fn hash160(
    -                &mut self,
    -                _hash160: &<DescriptorPublicKey as MiniscriptKey>::Hash160,
    -            ) -> Result<miniscript::DummyHash160Hash, DescriptorError> {
    -                Ok(Default::default())
    +            fn hash160(
    +                &mut self,
    +                _hash160: &<DescriptorPublicKey as MiniscriptKey>::Hash160,
    +            ) -> Result<miniscript::DummyHash160Hash, DescriptorError> {
    +                Ok(Default::default())
                 }
             }
     
    -        // check the network for the keys
    -        self.0.translate_pk(&mut Translator {
    -            secp,
    -            network,
    -            descriptor: &self.0,
    +        // check the network for the keys
    +        self.0.translate_pk(&mut Translator {
    +            secp,
    +            network,
    +            descriptor: &self.0,
             })?;
     
             Ok(self)
         }
     }
     
    -impl IntoWalletDescriptor for DescriptorTemplateOut {
    -    fn into_wallet_descriptor(
    +impl IntoWalletDescriptor for DescriptorTemplateOut {
    +    fn into_wallet_descriptor(
             self,
    -        _secp: &SecpCtx,
    -        network: Network,
    -    ) -> Result<(ExtendedDescriptor, KeyMap), DescriptorError> {
    -        struct Translator {
    -            network: Network,
    +        _secp: &SecpCtx,
    +        network: Network,
    +    ) -> Result<(ExtendedDescriptor, KeyMap), DescriptorError> {
    +        struct Translator {
    +            network: Network,
             }
     
    -        impl miniscript::Translator<DescriptorPublicKey, DescriptorPublicKey, DescriptorError>
    -            for Translator
    +        impl miniscript::Translator<DescriptorPublicKey, DescriptorPublicKey, DescriptorError>
    +            for Translator
             {
    -            fn pk(
    -                &mut self,
    -                pk: &DescriptorPublicKey,
    -            ) -> Result<DescriptorPublicKey, DescriptorError> {
    -                // workaround for xpubs generated by other key types, like bip39: since when the
    -                // conversion is made one network has to be chosen, what we generally choose
    -                // "mainnet", but then override the set of valid networks to specify that all of
    -                // them are valid. here we reset the network to make sure the wallet struct gets a
    -                // descriptor with the right network everywhere.
    -                let pk = match pk {
    -                    DescriptorPublicKey::XPub(ref xpub) => {
    -                        let mut xpub = xpub.clone();
    -                        xpub.xkey.network = self.network;
    -
    -                        DescriptorPublicKey::XPub(xpub)
    +            fn pk(
    +                &mut self,
    +                pk: &DescriptorPublicKey,
    +            ) -> Result<DescriptorPublicKey, DescriptorError> {
    +                // workaround for xpubs generated by other key types, like bip39: since when the
    +                // conversion is made one network has to be chosen, what we generally choose
    +                // "mainnet", but then override the set of valid networks to specify that all of
    +                // them are valid. here we reset the network to make sure the wallet struct gets a
    +                // descriptor with the right network everywhere.
    +                let pk = match pk {
    +                    DescriptorPublicKey::XPub(ref xpub) => {
    +                        let mut xpub = xpub.clone();
    +                        xpub.xkey.network = self.network;
    +
    +                        DescriptorPublicKey::XPub(xpub)
                         }
    -                    other => other.clone(),
    +                    other => other.clone(),
                     };
     
    -                Ok(pk)
    +                Ok(pk)
                 }
                 miniscript::translate_hash_clone!(
    -                DescriptorPublicKey,
    -                DescriptorPublicKey,
    -                DescriptorError
    +                DescriptorPublicKey,
    +                DescriptorPublicKey,
    +                DescriptorError
                 );
             }
     
    -        let (desc, keymap, networks) = self;
    +        let (desc, keymap, networks) = self;
     
    -        if !networks.contains(&network) {
    -            return Err(DescriptorError::Key(KeyError::InvalidNetwork));
    +        if !networks.contains(&network) {
    +            return Err(DescriptorError::Key(KeyError::InvalidNetwork));
             }
     
    -        // fixup the network for keys that need it in the descriptor
    -        let translated = desc.translate_pk(&mut Translator { network })?;
    -        // ...and in the key map
    -        let fixed_keymap = keymap
    -            .into_iter()
    -            .map(|(mut k, mut v)| {
    -                match (&mut k, &mut v) {
    -                    (DescriptorPublicKey::XPub(xpub), DescriptorSecretKey::XPrv(xprv)) => {
    -                        xpub.xkey.network = network;
    -                        xprv.xkey.network = network;
    +        // fixup the network for keys that need it in the descriptor
    +        let translated = desc.translate_pk(&mut Translator { network })?;
    +        // ...and in the key map
    +        let fixed_keymap = keymap
    +            .into_iter()
    +            .map(|(mut k, mut v)| {
    +                match (&mut k, &mut v) {
    +                    (DescriptorPublicKey::XPub(xpub), DescriptorSecretKey::XPrv(xprv)) => {
    +                        xpub.xkey.network = network;
    +                        xprv.xkey.network = network;
                         }
    -                    (_, DescriptorSecretKey::Single(key)) => {
    -                        key.key.network = network;
    +                    (_, DescriptorSecretKey::Single(key)) => {
    +                        key.key.network = network;
                         }
    -                    _ => {}
    +                    _ => {}
                     }
     
    -                (k, v)
    +                (k, v)
                 })
    -            .collect();
    +            .collect();
     
    -        Ok((translated, fixed_keymap))
    +        Ok((translated, fixed_keymap))
         }
     }
     
    -/// Wrapper for `IntoWalletDescriptor` that performs additional checks on the keys contained in the
    -/// descriptor
    -pub(crate) fn into_wallet_descriptor_checked<T: IntoWalletDescriptor>(
    -    inner: T,
    -    secp: &SecpCtx,
    -    network: Network,
    -) -> Result<(ExtendedDescriptor, KeyMap), DescriptorError> {
    -    let (descriptor, keymap) = inner.into_wallet_descriptor(secp, network)?;
    -
    -    // Ensure the keys don't contain any hardened derivation steps or hardened wildcards
    -    let descriptor_contains_hardened_steps = descriptor.for_any_key(|k| {
    -        if let DescriptorPublicKey::XPub(DescriptorXKey {
    -            derivation_path,
    -            wildcard,
    +/// Wrapper for `IntoWalletDescriptor` that performs additional checks on the keys contained in the
    +/// descriptor
    +pub(crate) fn into_wallet_descriptor_checked<T: IntoWalletDescriptor>(
    +    inner: T,
    +    secp: &SecpCtx,
    +    network: Network,
    +) -> Result<(ExtendedDescriptor, KeyMap), DescriptorError> {
    +    let (descriptor, keymap) = inner.into_wallet_descriptor(secp, network)?;
    +
    +    // Ensure the keys don't contain any hardened derivation steps or hardened wildcards
    +    let descriptor_contains_hardened_steps = descriptor.for_any_key(|k| {
    +        if let DescriptorPublicKey::XPub(DescriptorXKey {
    +            derivation_path,
    +            wildcard,
                 ..
    -        }) = k
    +        }) = k
             {
    -            return *wildcard == Wildcard::Hardened
    -                || derivation_path.into_iter().any(ChildNumber::is_hardened);
    +            return *wildcard == Wildcard::Hardened
    +                || derivation_path.into_iter().any(ChildNumber::is_hardened);
             }
     
    -        false
    -    });
    -    if descriptor_contains_hardened_steps {
    -        return Err(DescriptorError::HardenedDerivationXpub);
    +        false
    +    });
    +    if descriptor_contains_hardened_steps {
    +        return Err(DescriptorError::HardenedDerivationXpub);
         }
     
    -    // Run miniscript's sanity check, which will look for duplicated keys and other potential
    -    // issues
    -    descriptor.sanity_check()?;
    +    // Run miniscript's sanity check, which will look for duplicated keys and other potential
    +    // issues
    +    descriptor.sanity_check()?;
     
    -    Ok((descriptor, keymap))
    +    Ok((descriptor, keymap))
     }
     
    -#[doc(hidden)]
    -/// Used internally mainly by the `descriptor!()` and `fragment!()` macros
    -pub trait CheckMiniscript<Ctx: miniscript::ScriptContext> {
    -    fn check_miniscript(&self) -> Result<(), miniscript::Error>;
    +#[doc(hidden)]
    +/// Used internally mainly by the `descriptor!()` and `fragment!()` macros
    +pub trait CheckMiniscript<Ctx: miniscript::ScriptContext> {
    +    fn check_miniscript(&self) -> Result<(), miniscript::Error>;
     }
     
    -impl<Ctx: miniscript::ScriptContext, Pk: miniscript::MiniscriptKey> CheckMiniscript<Ctx>
    -    for miniscript::Miniscript<Pk, Ctx>
    +impl<Ctx: miniscript::ScriptContext, Pk: miniscript::MiniscriptKey> CheckMiniscript<Ctx>
    +    for miniscript::Miniscript<Pk, Ctx>
     {
    -    fn check_miniscript(&self) -> Result<(), miniscript::Error> {
    -        Ctx::check_global_validity(self)?;
    +    fn check_miniscript(&self) -> Result<(), miniscript::Error> {
    +        Ctx::check_global_validity(self)?;
     
             Ok(())
         }
     }
     
    -/// Trait implemented on [`Descriptor`]s to add a method to extract the spending [`policy`]
    -pub trait ExtractPolicy {
    -    /// Extract the spending [`policy`]
    -    fn extract_policy(
    +/// Trait implemented on [`Descriptor`]s to add a method to extract the spending [`policy`]
    +pub trait ExtractPolicy {
    +    /// Extract the spending [`policy`]
    +    fn extract_policy(
             &self,
    -        signers: &SignersContainer,
    -        psbt: BuildSatisfaction,
    -        secp: &SecpCtx,
    -    ) -> Result<Option<Policy>, DescriptorError>;
    +        signers: &SignersContainer,
    +        psbt: BuildSatisfaction,
    +        secp: &SecpCtx,
    +    ) -> Result<Option<Policy>, DescriptorError>;
     }
     
    -pub(crate) trait XKeyUtils {
    -    fn root_fingerprint(&self, secp: &SecpCtx) -> Fingerprint;
    +pub(crate) trait XKeyUtils {
    +    fn root_fingerprint(&self, secp: &SecpCtx) -> Fingerprint;
     }
     
    -impl<T> XKeyUtils for DescriptorXKey<T>
    -where
    -    T: InnerXKey,
    +impl<T> XKeyUtils for DescriptorXKey<T>
    +where
    +    T: InnerXKey,
     {
    -    fn root_fingerprint(&self, secp: &SecpCtx) -> Fingerprint {
    -        match self.origin {
    -            Some((fingerprint, _)) => fingerprint,
    -            None => self.xkey.xkey_fingerprint(secp),
    +    fn root_fingerprint(&self, secp: &SecpCtx) -> Fingerprint {
    +        match self.origin {
    +            Some((fingerprint, _)) => fingerprint,
    +            None => self.xkey.xkey_fingerprint(secp),
             }
         }
     }
     
    -pub(crate) trait DescriptorMeta {
    -    fn is_witness(&self) -> bool;
    -    fn is_taproot(&self) -> bool;
    -    fn get_extended_keys(&self) -> Result<Vec<DescriptorXKey<ExtendedPubKey>>, DescriptorError>;
    -    fn derive_from_hd_keypaths<'s>(
    +pub(crate) trait DescriptorMeta {
    +    fn is_witness(&self) -> bool;
    +    fn is_taproot(&self) -> bool;
    +    fn get_extended_keys(&self) -> Result<Vec<DescriptorXKey<ExtendedPubKey>>, DescriptorError>;
    +    fn derive_from_hd_keypaths<'s>(
             &self,
    -        hd_keypaths: &HdKeyPaths,
    -        secp: &'s SecpCtx,
    -    ) -> Option<DerivedDescriptor>;
    -    fn derive_from_tap_key_origins<'s>(
    +        hd_keypaths: &HdKeyPaths,
    +        secp: &'s SecpCtx,
    +    ) -> Option<DerivedDescriptor>;
    +    fn derive_from_tap_key_origins<'s>(
             &self,
    -        tap_key_origins: &TapKeyOrigins,
    -        secp: &'s SecpCtx,
    -    ) -> Option<DerivedDescriptor>;
    -    fn derive_from_psbt_key_origins<'s>(
    +        tap_key_origins: &TapKeyOrigins,
    +        secp: &'s SecpCtx,
    +    ) -> Option<DerivedDescriptor>;
    +    fn derive_from_psbt_key_origins<'s>(
             &self,
    -        key_origins: BTreeMap<Fingerprint, (&DerivationPath, SinglePubKey)>,
    -        secp: &'s SecpCtx,
    -    ) -> Option<DerivedDescriptor>;
    -    fn derive_from_psbt_input<'s>(
    +        key_origins: BTreeMap<Fingerprint, (&DerivationPath, SinglePubKey)>,
    +        secp: &'s SecpCtx,
    +    ) -> Option<DerivedDescriptor>;
    +    fn derive_from_psbt_input<'s>(
             &self,
    -        psbt_input: &psbt::Input,
    -        utxo: Option<TxOut>,
    -        secp: &'s SecpCtx,
    -    ) -> Option<DerivedDescriptor>;
    +        psbt_input: &psbt::Input,
    +        utxo: Option<TxOut>,
    +        secp: &'s SecpCtx,
    +    ) -> Option<DerivedDescriptor>;
     }
     
    -impl DescriptorMeta for ExtendedDescriptor {
    -    fn is_witness(&self) -> bool {
    +impl DescriptorMeta for ExtendedDescriptor {
    +    fn is_witness(&self) -> bool {
             matches!(
    -            self.desc_type(),
    -            DescriptorType::Wpkh
    -                | DescriptorType::ShWpkh
    -                | DescriptorType::Wsh
    -                | DescriptorType::ShWsh
    -                | DescriptorType::ShWshSortedMulti
    -                | DescriptorType::WshSortedMulti
    +            self.desc_type(),
    +            DescriptorType::Wpkh
    +                | DescriptorType::ShWpkh
    +                | DescriptorType::Wsh
    +                | DescriptorType::ShWsh
    +                | DescriptorType::ShWshSortedMulti
    +                | DescriptorType::WshSortedMulti
             )
         }
     
    -    fn is_taproot(&self) -> bool {
    -        self.desc_type() == DescriptorType::Tr
    +    fn is_taproot(&self) -> bool {
    +        self.desc_type() == DescriptorType::Tr
         }
     
    -    fn get_extended_keys(&self) -> Result<Vec<DescriptorXKey<ExtendedPubKey>>, DescriptorError> {
    -        let mut answer = Vec::new();
    +    fn get_extended_keys(&self) -> Result<Vec<DescriptorXKey<ExtendedPubKey>>, DescriptorError> {
    +        let mut answer = Vec::new();
     
    -        self.for_each_key(|pk| {
    -            if let DescriptorPublicKey::XPub(xpub) = pk {
    -                answer.push(xpub.clone());
    +        self.for_each_key(|pk| {
    +            if let DescriptorPublicKey::XPub(xpub) = pk {
    +                answer.push(xpub.clone());
                 }
     
    -            true
    -        });
    +            true
    +        });
     
    -        Ok(answer)
    +        Ok(answer)
         }
     
    -    fn derive_from_psbt_key_origins<'s>(
    +    fn derive_from_psbt_key_origins<'s>(
             &self,
    -        key_origins: BTreeMap<Fingerprint, (&DerivationPath, SinglePubKey)>,
    -        secp: &'s SecpCtx,
    -    ) -> Option<DerivedDescriptor> {
    -        // Ensure that deriving `xpub` with `path` yields `expected`
    -        let verify_key = |xpub: &DescriptorXKey<ExtendedPubKey>,
    -                          path: &DerivationPath,
    -                          expected: &SinglePubKey| {
    -            let derived = xpub
    -                .xkey
    -                .derive_pub(secp, path)
    -                .expect("The path should never contain hardened derivation steps")
    -                .public_key;
    -
    -            match expected {
    -                SinglePubKey::FullKey(pk) if &PublicKey::new(derived) == pk => true,
    -                SinglePubKey::XOnly(pk) if &XOnlyPublicKey::from(derived) == pk => true,
    -                _ => false,
    +        key_origins: BTreeMap<Fingerprint, (&DerivationPath, SinglePubKey)>,
    +        secp: &'s SecpCtx,
    +    ) -> Option<DerivedDescriptor> {
    +        // Ensure that deriving `xpub` with `path` yields `expected`
    +        let verify_key = |xpub: &DescriptorXKey<ExtendedPubKey>,
    +                          path: &DerivationPath,
    +                          expected: &SinglePubKey| {
    +            let derived = xpub
    +                .xkey
    +                .derive_pub(secp, path)
    +                .expect("The path should never contain hardened derivation steps")
    +                .public_key;
    +
    +            match expected {
    +                SinglePubKey::FullKey(pk) if &PublicKey::new(derived) == pk => true,
    +                SinglePubKey::XOnly(pk) if &XOnlyPublicKey::from(derived) == pk => true,
    +                _ => false,
                 }
             };
     
    -        let mut path_found = None;
    -
    -        // using `for_any_key` should make this stop as soon as we return `true`
    -        self.for_any_key(|key| {
    -            if let DescriptorPublicKey::XPub(xpub) = key {
    -                // Check if the key matches one entry in our `key_origins`. If it does, `matches()` will
    -                // return the "prefix" that matched, so we remove that prefix from the full path
    -                // found in `key_origins` and save it in `derive_path`. We expect this to be a derivation
    -                // path of length 1 if the key is `wildcard` and an empty path otherwise.
    -                let root_fingerprint = xpub.root_fingerprint(secp);
    -                let derive_path = key_origins
    -                    .get_key_value(&root_fingerprint)
    -                    .and_then(|(fingerprint, (path, expected))| {
    -                        xpub.matches(&(*fingerprint, (*path).clone()), secp)
    -                            .zip(Some((path, expected)))
    +        let mut path_found = None;
    +
    +        // using `for_any_key` should make this stop as soon as we return `true`
    +        self.for_any_key(|key| {
    +            if let DescriptorPublicKey::XPub(xpub) = key {
    +                // Check if the key matches one entry in our `key_origins`. If it does, `matches()` will
    +                // return the "prefix" that matched, so we remove that prefix from the full path
    +                // found in `key_origins` and save it in `derive_path`. We expect this to be a derivation
    +                // path of length 1 if the key is `wildcard` and an empty path otherwise.
    +                let root_fingerprint = xpub.root_fingerprint(secp);
    +                let derive_path = key_origins
    +                    .get_key_value(&root_fingerprint)
    +                    .and_then(|(fingerprint, (path, expected))| {
    +                        xpub.matches(&(*fingerprint, (*path).clone()), secp)
    +                            .zip(Some((path, expected)))
                         })
    -                    .and_then(|(prefix, (full_path, expected))| {
    -                        let derive_path = full_path
    -                            .into_iter()
    -                            .skip(prefix.into_iter().count())
    -                            .cloned()
    -                            .collect::<DerivationPath>();
    -
    -                        // `derive_path` only contains the replacement index for the wildcard, if present, or
    -                        // an empty path for fixed descriptors. To verify the key we also need the normal steps
    -                        // that come before the wildcard, so we take them directly from `xpub` and then append
    -                        // the final index
    -                        if verify_key(
    -                            xpub,
    -                            &xpub.derivation_path.extend(derive_path.clone()),
    -                            expected,
    +                    .and_then(|(prefix, (full_path, expected))| {
    +                        let derive_path = full_path
    +                            .into_iter()
    +                            .skip(prefix.into_iter().count())
    +                            .cloned()
    +                            .collect::<DerivationPath>();
    +
    +                        // `derive_path` only contains the replacement index for the wildcard, if present, or
    +                        // an empty path for fixed descriptors. To verify the key we also need the normal steps
    +                        // that come before the wildcard, so we take them directly from `xpub` and then append
    +                        // the final index
    +                        if verify_key(
    +                            xpub,
    +                            &xpub.derivation_path.extend(derive_path.clone()),
    +                            expected,
                             ) {
    -                            Some(derive_path)
    -                        } else {
    +                            Some(derive_path)
    +                        } else {
                                 log::debug!(
                                     "Key `{}` derived with {} yields an unexpected key",
    -                                root_fingerprint,
    -                                derive_path
    +                                root_fingerprint,
    +                                derive_path
                                 );
    -                            None
    -                        }
    +                            None
    +                        }
                         });
     
    -                match derive_path {
    -                    Some(path) if xpub.wildcard != Wildcard::None && path.len() == 1 => {
    -                        // Ignore hardened wildcards
    -                        if let ChildNumber::Normal { index } = path[0] {
    -                            path_found = Some(index);
    -                            return true;
    +                match derive_path {
    +                    Some(path) if xpub.wildcard != Wildcard::None && path.len() == 1 => {
    +                        // Ignore hardened wildcards
    +                        if let ChildNumber::Normal { index } = path[0] {
    +                            path_found = Some(index);
    +                            return true;
                             }
                         }
    -                    Some(path) if xpub.wildcard == Wildcard::None && path.is_empty() => {
    -                        path_found = Some(0);
    -                        return true;
    +                    Some(path) if xpub.wildcard == Wildcard::None && path.is_empty() => {
    +                        path_found = Some(0);
    +                        return true;
                         }
    -                    _ => {}
    +                    _ => {}
                     }
                 }
     
    -            false
    -        });
    +            false
    +        });
     
    -        path_found.map(|path| self.at_derivation_index(path))
    +        path_found.map(|path| self.at_derivation_index(path))
         }
     
    -    fn derive_from_hd_keypaths<'s>(
    +    fn derive_from_hd_keypaths<'s>(
             &self,
    -        hd_keypaths: &HdKeyPaths,
    -        secp: &'s SecpCtx,
    -    ) -> Option<DerivedDescriptor> {
    -        // "Convert" an hd_keypaths map to the format required by `derive_from_psbt_key_origins`
    -        let key_origins = hd_keypaths
    -            .iter()
    -            .map(|(pk, (fingerprint, path))| {
    +        hd_keypaths: &HdKeyPaths,
    +        secp: &'s SecpCtx,
    +    ) -> Option<DerivedDescriptor> {
    +        // "Convert" an hd_keypaths map to the format required by `derive_from_psbt_key_origins`
    +        let key_origins = hd_keypaths
    +            .iter()
    +            .map(|(pk, (fingerprint, path))| {
                     (
    -                    *fingerprint,
    -                    (path, SinglePubKey::FullKey(PublicKey::new(*pk))),
    +                    *fingerprint,
    +                    (path, SinglePubKey::FullKey(PublicKey::new(*pk))),
                     )
                 })
    -            .collect();
    -        self.derive_from_psbt_key_origins(key_origins, secp)
    +            .collect();
    +        self.derive_from_psbt_key_origins(key_origins, secp)
         }
     
    -    fn derive_from_tap_key_origins<'s>(
    +    fn derive_from_tap_key_origins<'s>(
             &self,
    -        tap_key_origins: &TapKeyOrigins,
    -        secp: &'s SecpCtx,
    -    ) -> Option<DerivedDescriptor> {
    -        // "Convert" a tap_key_origins map to the format required by `derive_from_psbt_key_origins`
    -        let key_origins = tap_key_origins
    -            .iter()
    -            .map(|(pk, (_, (fingerprint, path)))| (*fingerprint, (path, SinglePubKey::XOnly(*pk))))
    -            .collect();
    -        self.derive_from_psbt_key_origins(key_origins, secp)
    +        tap_key_origins: &TapKeyOrigins,
    +        secp: &'s SecpCtx,
    +    ) -> Option<DerivedDescriptor> {
    +        // "Convert" a tap_key_origins map to the format required by `derive_from_psbt_key_origins`
    +        let key_origins = tap_key_origins
    +            .iter()
    +            .map(|(pk, (_, (fingerprint, path)))| (*fingerprint, (path, SinglePubKey::XOnly(*pk))))
    +            .collect();
    +        self.derive_from_psbt_key_origins(key_origins, secp)
         }
     
    -    fn derive_from_psbt_input<'s>(
    +    fn derive_from_psbt_input<'s>(
             &self,
    -        psbt_input: &psbt::Input,
    -        utxo: Option<TxOut>,
    -        secp: &'s SecpCtx,
    -    ) -> Option<DerivedDescriptor> {
    -        if let Some(derived) = self.derive_from_hd_keypaths(&psbt_input.bip32_derivation, secp) {
    -            return Some(derived);
    +        psbt_input: &psbt::Input,
    +        utxo: Option<TxOut>,
    +        secp: &'s SecpCtx,
    +    ) -> Option<DerivedDescriptor> {
    +        if let Some(derived) = self.derive_from_hd_keypaths(&psbt_input.bip32_derivation, secp) {
    +            return Some(derived);
             }
    -        if let Some(derived) = self.derive_from_tap_key_origins(&psbt_input.tap_key_origins, secp) {
    -            return Some(derived);
    +        if let Some(derived) = self.derive_from_tap_key_origins(&psbt_input.tap_key_origins, secp) {
    +            return Some(derived);
             }
    -        if self.has_wildcard() {
    -            // We can't try to bruteforce the derivation index, exit here
    -            return None;
    +        if self.has_wildcard() {
    +            // We can't try to bruteforce the derivation index, exit here
    +            return None;
             }
     
    -        let descriptor = self.at_derivation_index(0);
    -        match descriptor.desc_type() {
    -            // TODO: add pk() here
    -            DescriptorType::Pkh
    -            | DescriptorType::Wpkh
    -            | DescriptorType::ShWpkh
    -            | DescriptorType::Tr
    -                if utxo.is_some()
    -                    && descriptor.script_pubkey() == utxo.as_ref().unwrap().script_pubkey =>
    +        let descriptor = self.at_derivation_index(0);
    +        match descriptor.desc_type() {
    +            // TODO: add pk() here
    +            DescriptorType::Pkh
    +            | DescriptorType::Wpkh
    +            | DescriptorType::ShWpkh
    +            | DescriptorType::Tr
    +                if utxo.is_some()
    +                    && descriptor.script_pubkey() == utxo.as_ref().unwrap().script_pubkey =>
                 {
    -                Some(descriptor)
    +                Some(descriptor)
                 }
    -            DescriptorType::Bare | DescriptorType::Sh | DescriptorType::ShSortedMulti
    -                if psbt_input.redeem_script.is_some()
    -                    && &descriptor.explicit_script().unwrap()
    -                        == psbt_input.redeem_script.as_ref().unwrap() =>
    +            DescriptorType::Bare | DescriptorType::Sh | DescriptorType::ShSortedMulti
    +                if psbt_input.redeem_script.is_some()
    +                    && &descriptor.explicit_script().unwrap()
    +                        == psbt_input.redeem_script.as_ref().unwrap() =>
                 {
    -                Some(descriptor)
    +                Some(descriptor)
                 }
    -            DescriptorType::Wsh
    -            | DescriptorType::ShWsh
    -            | DescriptorType::ShWshSortedMulti
    -            | DescriptorType::WshSortedMulti
    -                if psbt_input.witness_script.is_some()
    -                    && &descriptor.explicit_script().unwrap()
    -                        == psbt_input.witness_script.as_ref().unwrap() =>
    +            DescriptorType::Wsh
    +            | DescriptorType::ShWsh
    +            | DescriptorType::ShWshSortedMulti
    +            | DescriptorType::WshSortedMulti
    +                if psbt_input.witness_script.is_some()
    +                    && &descriptor.explicit_script().unwrap()
    +                        == psbt_input.witness_script.as_ref().unwrap() =>
                 {
    -                Some(descriptor)
    +                Some(descriptor)
                 }
    -            _ => None,
    +            _ => None,
             }
         }
     }
     
    -#[cfg(test)]
    -mod test {
    -    use std::str::FromStr;
    +#[cfg(test)]
    +mod test {
    +    use std::str::FromStr;
     
    -    use bitcoin::consensus::encode::deserialize;
    -    use bitcoin::hashes::hex::FromHex;
    -    use bitcoin::secp256k1::Secp256k1;
    -    use bitcoin::util::{bip32, psbt};
    -    use bitcoin::Script;
    +    use bitcoin::consensus::encode::deserialize;
    +    use bitcoin::hashes::hex::FromHex;
    +    use bitcoin::secp256k1::Secp256k1;
    +    use bitcoin::util::{bip32, psbt};
    +    use bitcoin::Script;
     
    -    use super::*;
    -    use crate::psbt::PsbtUtils;
    +    use super::*;
    +    use crate::psbt::PsbtUtils;
     
    -    #[test]
    -    fn test_derive_from_psbt_input_wpkh_wif() {
    -        let descriptor = Descriptor::<DescriptorPublicKey>::from_str(
    +    #[test]
    +    fn test_derive_from_psbt_input_wpkh_wif() {
    +        let descriptor = Descriptor::<DescriptorPublicKey>::from_str(
                 "wpkh(02b4632d08485ff1df2db55b9dafd23347d1c47a457072a1e87be26896549a8737)",
             )
    -        .unwrap();
    -        let psbt: psbt::PartiallySignedTransaction = deserialize(
    -            &Vec::<u8>::from_hex(
    +        .unwrap();
    +        let psbt: psbt::PartiallySignedTransaction = deserialize(
    +            &Vec::<u8>::from_hex(
                     "70736274ff010052010000000162307be8e431fbaff807cdf9cdc3fde44d7402\
                      11bc8342c31ffd6ec11fe35bcc0100000000ffffffff01328601000000000016\
                      001493ce48570b55c42c2af816aeaba06cfee1224fae000000000001011fa086\
                      01000000000016001493ce48570b55c42c2af816aeaba06cfee1224fae010304\
                      010000000000",
                 )
    -            .unwrap(),
    +            .unwrap(),
             )
    -        .unwrap();
    +        .unwrap();
     
    -        assert!(descriptor
    -            .derive_from_psbt_input(&psbt.inputs[0], psbt.get_utxo_for(0), &Secp256k1::new())
    -            .is_some());
    +        assert!(descriptor
    +            .derive_from_psbt_input(&psbt.inputs[0], psbt.get_utxo_for(0), &Secp256k1::new())
    +            .is_some());
         }
     
    -    #[test]
    -    fn test_derive_from_psbt_input_pkh_tpub() {
    -        let descriptor = Descriptor::<DescriptorPublicKey>::from_str(
    +    #[test]
    +    fn test_derive_from_psbt_input_pkh_tpub() {
    +        let descriptor = Descriptor::<DescriptorPublicKey>::from_str(
                 "pkh([0f056943/44h/0h/0h]tpubDDpWvmUrPZrhSPmUzCMBHffvC3HyMAPnWDSAQNBTnj1iZeJa7BZQEttFiP4DS4GCcXQHezdXhn86Hj6LHX5EDstXPWrMaSneRWM8yUf6NFd/10/*)",
             )
    -        .unwrap();
    -        let psbt: psbt::PartiallySignedTransaction = deserialize(
    -            &Vec::<u8>::from_hex(
    +        .unwrap();
    +        let psbt: psbt::PartiallySignedTransaction = deserialize(
    +            &Vec::<u8>::from_hex(
                     "70736274ff010053010000000145843b86be54a3cd8c9e38444e1162676c00df\
                      e7964122a70df491ea12fd67090100000000ffffffff01c19598000000000017\
                      a91432bb94283282f72b2e034709e348c44d5a4db0ef8700000000000100f902\
    @@ -1530,23 +1524,23 @@
                      0603433b83583f8c4879b329dd08bbc7da935e4cc02f637ff746e05f0466ffb2\
                      a6a2180f0569432c00008000000080000000800a000000000000000000",
                 )
    -            .unwrap(),
    +            .unwrap(),
             )
    -        .unwrap();
    +        .unwrap();
     
    -        assert!(descriptor
    -            .derive_from_psbt_input(&psbt.inputs[0], psbt.get_utxo_for(0), &Secp256k1::new())
    -            .is_some());
    +        assert!(descriptor
    +            .derive_from_psbt_input(&psbt.inputs[0], psbt.get_utxo_for(0), &Secp256k1::new())
    +            .is_some());
         }
     
    -    #[test]
    -    fn test_derive_from_psbt_input_wsh() {
    -        let descriptor = Descriptor::<DescriptorPublicKey>::from_str(
    +    #[test]
    +    fn test_derive_from_psbt_input_wsh() {
    +        let descriptor = Descriptor::<DescriptorPublicKey>::from_str(
                 "wsh(and_v(v:pk(03b6633fef2397a0a9de9d7b6f23aef8368a6e362b0581f0f0af70d5ecfd254b14),older(6)))",
             )
    -        .unwrap();
    -        let psbt: psbt::PartiallySignedTransaction = deserialize(
    -            &Vec::<u8>::from_hex(
    +        .unwrap();
    +        let psbt: psbt::PartiallySignedTransaction = deserialize(
    +            &Vec::<u8>::from_hex(
                     "70736274ff01005302000000011c8116eea34408ab6529223c9a176606742207\
                      67a1ff1d46a6e3c4a88243ea6e01000000000600000001109698000000000017\
                      a914ad105f61102e0d01d7af40d06d6a5c3ae2f7fde387000000000001012b80\
    @@ -1554,23 +1548,23 @@
                      336030f9059345091044010304010000000105252103b6633fef2397a0a9de9d\
                      7b6f23aef8368a6e362b0581f0f0af70d5ecfd254b14ad56b20000",
                 )
    -            .unwrap(),
    +            .unwrap(),
             )
    -        .unwrap();
    +        .unwrap();
     
    -        assert!(descriptor
    -            .derive_from_psbt_input(&psbt.inputs[0], psbt.get_utxo_for(0), &Secp256k1::new())
    -            .is_some());
    +        assert!(descriptor
    +            .derive_from_psbt_input(&psbt.inputs[0], psbt.get_utxo_for(0), &Secp256k1::new())
    +            .is_some());
         }
     
    -    #[test]
    -    fn test_derive_from_psbt_input_sh() {
    -        let descriptor = Descriptor::<DescriptorPublicKey>::from_str(
    +    #[test]
    +    fn test_derive_from_psbt_input_sh() {
    +        let descriptor = Descriptor::<DescriptorPublicKey>::from_str(
                 "sh(and_v(v:pk(021403881a5587297818fcaf17d239cefca22fce84a45b3b1d23e836c4af671dbb),after(630000)))",
             )
    -        .unwrap();
    -        let psbt: psbt::PartiallySignedTransaction = deserialize(
    -            &Vec::<u8>::from_hex(
    +        .unwrap();
    +        let psbt: psbt::PartiallySignedTransaction = deserialize(
    +            &Vec::<u8>::from_hex(
                     "70736274ff0100530100000001bc8c13df445dfadcc42afa6dc841f85d22b01d\
                      a6270ebf981740f4b7b1d800390000000000feffffff01ba9598000000000017\
                      a91457b148ba4d3e5fa8608a8657875124e3d1c9390887f09c0900000100e002\
    @@ -1584,203 +1578,202 @@
                      03040100000001042821021403881a5587297818fcaf17d239cefca22fce84a4\
                      5b3b1d23e836c4af671dbbad03f09c09b10000",
                 )
    -            .unwrap(),
    +            .unwrap(),
             )
    -        .unwrap();
    +        .unwrap();
     
    -        assert!(descriptor
    -            .derive_from_psbt_input(&psbt.inputs[0], psbt.get_utxo_for(0), &Secp256k1::new())
    -            .is_some());
    +        assert!(descriptor
    +            .derive_from_psbt_input(&psbt.inputs[0], psbt.get_utxo_for(0), &Secp256k1::new())
    +            .is_some());
         }
     
    -    #[test]
    -    fn test_to_wallet_descriptor_fixup_networks() {
    -        use crate::keys::{any_network, IntoDescriptorKey};
    -
    -        let secp = Secp256k1::new();
    -
    -        let xprv = bip32::ExtendedPrivKey::from_str("xprv9s21ZrQH143K3c3gF1DUWpWNr2SG2XrG8oYPpqYh7hoWsJy9NjabErnzriJPpnGHyKz5NgdXmq1KVbqS1r4NXdCoKitWg5e86zqXHa8kxyB").unwrap();
    -        let path = bip32::DerivationPath::from_str("m/0").unwrap();
    -
    -        // here `to_descriptor_key` will set the valid networks for the key to only mainnet, since
    -        // we are using an "xpub"
    -        let key = (xprv, path.clone()).into_descriptor_key().unwrap();
    -        // override it with any. this happens in some key conversions, like bip39
    -        let key = key.override_valid_networks(any_network());
    -
    -        // make a descriptor out of it
    -        let desc = crate::descriptor!(wpkh(key)).unwrap();
    -        // this should convert the key that supports "any_network" to the right network (testnet)
    -        let (wallet_desc, keymap) = desc
    -            .into_wallet_descriptor(&secp, Network::Testnet)
    -            .unwrap();
    -
    -        let mut xprv_testnet = xprv;
    -        xprv_testnet.network = Network::Testnet;
    -
    -        let xpub_testnet = bip32::ExtendedPubKey::from_priv(&secp, &xprv_testnet);
    -        let desc_pubkey = DescriptorPublicKey::XPub(DescriptorXKey {
    -            xkey: xpub_testnet,
    -            origin: None,
    -            derivation_path: path,
    -            wildcard: Wildcard::Unhardened,
    +    #[test]
    +    fn test_to_wallet_descriptor_fixup_networks() {
    +        use crate::keys::{any_network, IntoDescriptorKey};
    +
    +        let secp = Secp256k1::new();
    +
    +        let xprv = bip32::ExtendedPrivKey::from_str("xprv9s21ZrQH143K3c3gF1DUWpWNr2SG2XrG8oYPpqYh7hoWsJy9NjabErnzriJPpnGHyKz5NgdXmq1KVbqS1r4NXdCoKitWg5e86zqXHa8kxyB").unwrap();
    +        let path = bip32::DerivationPath::from_str("m/0").unwrap();
    +
    +        // here `to_descriptor_key` will set the valid networks for the key to only mainnet, since
    +        // we are using an "xpub"
    +        let key = (xprv, path.clone()).into_descriptor_key().unwrap();
    +        // override it with any. this happens in some key conversions, like bip39
    +        let key = key.override_valid_networks(any_network());
    +
    +        // make a descriptor out of it
    +        let desc = crate::descriptor!(wpkh(key)).unwrap();
    +        // this should convert the key that supports "any_network" to the right network (testnet)
    +        let (wallet_desc, keymap) = desc
    +            .into_wallet_descriptor(&secp, Network::Testnet)
    +            .unwrap();
    +
    +        let mut xprv_testnet = xprv;
    +        xprv_testnet.network = Network::Testnet;
    +
    +        let xpub_testnet = bip32::ExtendedPubKey::from_priv(&secp, &xprv_testnet);
    +        let desc_pubkey = DescriptorPublicKey::XPub(DescriptorXKey {
    +            xkey: xpub_testnet,
    +            origin: None,
    +            derivation_path: path,
    +            wildcard: Wildcard::Unhardened,
             });
     
    -        assert_eq!(wallet_desc.to_string(), "wpkh(tpubD6NzVbkrYhZ4XtJzoDja5snUjBNQRP5B3f4Hyn1T1x6PVPxzzVjvw6nJx2D8RBCxog9GEVjZoyStfepTz7TtKoBVdkCtnc7VCJh9dD4RAU9/0/*)#a3svx0ha");
    +        assert_eq!(wallet_desc.to_string(), "wpkh(tpubD6NzVbkrYhZ4XtJzoDja5snUjBNQRP5B3f4Hyn1T1x6PVPxzzVjvw6nJx2D8RBCxog9GEVjZoyStfepTz7TtKoBVdkCtnc7VCJh9dD4RAU9/0/*)#a3svx0ha");
             assert_eq!(
    -            keymap
    -                .get(&desc_pubkey)
    -                .map(|key| key.to_public(&secp).unwrap()),
    -            Some(desc_pubkey)
    +            keymap
    +                .get(&desc_pubkey)
    +                .map(|key| key.to_public(&secp).unwrap()),
    +            Some(desc_pubkey)
             );
         }
     
    -    // test IntoWalletDescriptor trait from &str with and without checksum appended
    -    #[test]
    -    fn test_descriptor_from_str_with_checksum() {
    -        let secp = Secp256k1::new();
    +    // test IntoWalletDescriptor trait from &str with and without checksum appended
    +    #[test]
    +    fn test_descriptor_from_str_with_checksum() {
    +        let secp = Secp256k1::new();
     
    -        let desc = "wpkh(tprv8ZgxMBicQKsPdpkqS7Eair4YxjcuuvDPNYmKX3sCniCf16tHEVrjjiSXEkFRnUH77yXc6ZcwHHcLNfjdi5qUvw3VDfgYiH5mNsj5izuiu2N/1/2/*)#tqz0nc62"
    -            .into_wallet_descriptor(&secp, Network::Testnet);
    -        assert!(desc.is_ok());
    +        let desc = "wpkh(tprv8ZgxMBicQKsPdpkqS7Eair4YxjcuuvDPNYmKX3sCniCf16tHEVrjjiSXEkFRnUH77yXc6ZcwHHcLNfjdi5qUvw3VDfgYiH5mNsj5izuiu2N/1/2/*)#tqz0nc62"
    +            .into_wallet_descriptor(&secp, Network::Testnet);
    +        assert!(desc.is_ok());
     
    -        let desc = "wpkh(tprv8ZgxMBicQKsPdpkqS7Eair4YxjcuuvDPNYmKX3sCniCf16tHEVrjjiSXEkFRnUH77yXc6ZcwHHcLNfjdi5qUvw3VDfgYiH5mNsj5izuiu2N/1/2/*)"
    -            .into_wallet_descriptor(&secp, Network::Testnet);
    -        assert!(desc.is_ok());
    +        let desc = "wpkh(tprv8ZgxMBicQKsPdpkqS7Eair4YxjcuuvDPNYmKX3sCniCf16tHEVrjjiSXEkFRnUH77yXc6ZcwHHcLNfjdi5qUvw3VDfgYiH5mNsj5izuiu2N/1/2/*)"
    +            .into_wallet_descriptor(&secp, Network::Testnet);
    +        assert!(desc.is_ok());
     
    -        let desc = "wpkh(tpubD6NzVbkrYhZ4XHndKkuB8FifXm8r5FQHwrN6oZuWCz13qb93rtgKvD4PQsqC4HP4yhV3tA2fqr2RbY5mNXfM7RxXUoeABoDtsFUq2zJq6YK/1/2/*)#67ju93jw"
    -            .into_wallet_descriptor(&secp, Network::Testnet);
    -        assert!(desc.is_ok());
    +        let desc = "wpkh(tpubD6NzVbkrYhZ4XHndKkuB8FifXm8r5FQHwrN6oZuWCz13qb93rtgKvD4PQsqC4HP4yhV3tA2fqr2RbY5mNXfM7RxXUoeABoDtsFUq2zJq6YK/1/2/*)#67ju93jw"
    +            .into_wallet_descriptor(&secp, Network::Testnet);
    +        assert!(desc.is_ok());
     
    -        let desc = "wpkh(tpubD6NzVbkrYhZ4XHndKkuB8FifXm8r5FQHwrN6oZuWCz13qb93rtgKvD4PQsqC4HP4yhV3tA2fqr2RbY5mNXfM7RxXUoeABoDtsFUq2zJq6YK/1/2/*)"
    -            .into_wallet_descriptor(&secp, Network::Testnet);
    -        assert!(desc.is_ok());
    +        let desc = "wpkh(tpubD6NzVbkrYhZ4XHndKkuB8FifXm8r5FQHwrN6oZuWCz13qb93rtgKvD4PQsqC4HP4yhV3tA2fqr2RbY5mNXfM7RxXUoeABoDtsFUq2zJq6YK/1/2/*)"
    +            .into_wallet_descriptor(&secp, Network::Testnet);
    +        assert!(desc.is_ok());
     
    -        let desc = "wpkh(tprv8ZgxMBicQKsPdpkqS7Eair4YxjcuuvDPNYmKX3sCniCf16tHEVrjjiSXEkFRnUH77yXc6ZcwHHcLNfjdi5qUvw3VDfgYiH5mNsj5izuiu2N/1/2/*)#67ju93jw"
    -            .into_wallet_descriptor(&secp, Network::Testnet);
    +        let desc = "wpkh(tprv8ZgxMBicQKsPdpkqS7Eair4YxjcuuvDPNYmKX3sCniCf16tHEVrjjiSXEkFRnUH77yXc6ZcwHHcLNfjdi5qUvw3VDfgYiH5mNsj5izuiu2N/1/2/*)#67ju93jw"
    +            .into_wallet_descriptor(&secp, Network::Testnet);
             assert!(matches!(
    -            desc.err(),
    -            Some(DescriptorError::InvalidDescriptorChecksum)
    +            desc.err(),
    +            Some(DescriptorError::InvalidDescriptorChecksum)
             ));
     
    -        let desc = "wpkh(tprv8ZgxMBicQKsPdpkqS7Eair4YxjcuuvDPNYmKX3sCniCf16tHEVrjjiSXEkFRnUH77yXc6ZcwHHcLNfjdi5qUvw3VDfgYiH5mNsj5izuiu2N/1/2/*)#67ju93jw"
    -            .into_wallet_descriptor(&secp, Network::Testnet);
    +        let desc = "wpkh(tprv8ZgxMBicQKsPdpkqS7Eair4YxjcuuvDPNYmKX3sCniCf16tHEVrjjiSXEkFRnUH77yXc6ZcwHHcLNfjdi5qUvw3VDfgYiH5mNsj5izuiu2N/1/2/*)#67ju93jw"
    +            .into_wallet_descriptor(&secp, Network::Testnet);
             assert!(matches!(
    -            desc.err(),
    -            Some(DescriptorError::InvalidDescriptorChecksum)
    +            desc.err(),
    +            Some(DescriptorError::InvalidDescriptorChecksum)
             ));
         }
     
    -    // test IntoWalletDescriptor trait from &str with keys from right and wrong network
    -    #[test]
    -    fn test_descriptor_from_str_with_keys_network() {
    -        let secp = Secp256k1::new();
    +    // test IntoWalletDescriptor trait from &str with keys from right and wrong network
    +    #[test]
    +    fn test_descriptor_from_str_with_keys_network() {
    +        let secp = Secp256k1::new();
     
    -        let desc = "wpkh(tprv8ZgxMBicQKsPdpkqS7Eair4YxjcuuvDPNYmKX3sCniCf16tHEVrjjiSXEkFRnUH77yXc6ZcwHHcLNfjdi5qUvw3VDfgYiH5mNsj5izuiu2N/1/2/*)"
    -            .into_wallet_descriptor(&secp, Network::Testnet);
    -        assert!(desc.is_ok());
    +        let desc = "wpkh(tprv8ZgxMBicQKsPdpkqS7Eair4YxjcuuvDPNYmKX3sCniCf16tHEVrjjiSXEkFRnUH77yXc6ZcwHHcLNfjdi5qUvw3VDfgYiH5mNsj5izuiu2N/1/2/*)"
    +            .into_wallet_descriptor(&secp, Network::Testnet);
    +        assert!(desc.is_ok());
     
    -        let desc = "wpkh(tprv8ZgxMBicQKsPdpkqS7Eair4YxjcuuvDPNYmKX3sCniCf16tHEVrjjiSXEkFRnUH77yXc6ZcwHHcLNfjdi5qUvw3VDfgYiH5mNsj5izuiu2N/1/2/*)"
    -            .into_wallet_descriptor(&secp, Network::Regtest);
    -        assert!(desc.is_ok());
    +        let desc = "wpkh(tprv8ZgxMBicQKsPdpkqS7Eair4YxjcuuvDPNYmKX3sCniCf16tHEVrjjiSXEkFRnUH77yXc6ZcwHHcLNfjdi5qUvw3VDfgYiH5mNsj5izuiu2N/1/2/*)"
    +            .into_wallet_descriptor(&secp, Network::Regtest);
    +        assert!(desc.is_ok());
     
    -        let desc = "wpkh(tpubD6NzVbkrYhZ4XHndKkuB8FifXm8r5FQHwrN6oZuWCz13qb93rtgKvD4PQsqC4HP4yhV3tA2fqr2RbY5mNXfM7RxXUoeABoDtsFUq2zJq6YK/1/2/*)"
    -            .into_wallet_descriptor(&secp, Network::Testnet);
    -        assert!(desc.is_ok());
    +        let desc = "wpkh(tpubD6NzVbkrYhZ4XHndKkuB8FifXm8r5FQHwrN6oZuWCz13qb93rtgKvD4PQsqC4HP4yhV3tA2fqr2RbY5mNXfM7RxXUoeABoDtsFUq2zJq6YK/1/2/*)"
    +            .into_wallet_descriptor(&secp, Network::Testnet);
    +        assert!(desc.is_ok());
     
    -        let desc = "wpkh(tpubD6NzVbkrYhZ4XHndKkuB8FifXm8r5FQHwrN6oZuWCz13qb93rtgKvD4PQsqC4HP4yhV3tA2fqr2RbY5mNXfM7RxXUoeABoDtsFUq2zJq6YK/1/2/*)"
    -            .into_wallet_descriptor(&secp, Network::Regtest);
    -        assert!(desc.is_ok());
    +        let desc = "wpkh(tpubD6NzVbkrYhZ4XHndKkuB8FifXm8r5FQHwrN6oZuWCz13qb93rtgKvD4PQsqC4HP4yhV3tA2fqr2RbY5mNXfM7RxXUoeABoDtsFUq2zJq6YK/1/2/*)"
    +            .into_wallet_descriptor(&secp, Network::Regtest);
    +        assert!(desc.is_ok());
     
    -        let desc = "sh(wpkh(02864bb4ad00cefa806098a69e192bbda937494e69eb452b87bb3f20f6283baedb))"
    -            .into_wallet_descriptor(&secp, Network::Testnet);
    -        assert!(desc.is_ok());
    +        let desc = "sh(wpkh(02864bb4ad00cefa806098a69e192bbda937494e69eb452b87bb3f20f6283baedb))"
    +            .into_wallet_descriptor(&secp, Network::Testnet);
    +        assert!(desc.is_ok());
     
    -        let desc = "sh(wpkh(02864bb4ad00cefa806098a69e192bbda937494e69eb452b87bb3f20f6283baedb))"
    -            .into_wallet_descriptor(&secp, Network::Bitcoin);
    -        assert!(desc.is_ok());
    +        let desc = "sh(wpkh(02864bb4ad00cefa806098a69e192bbda937494e69eb452b87bb3f20f6283baedb))"
    +            .into_wallet_descriptor(&secp, Network::Bitcoin);
    +        assert!(desc.is_ok());
     
    -        let desc = "wpkh(tprv8ZgxMBicQKsPdpkqS7Eair4YxjcuuvDPNYmKX3sCniCf16tHEVrjjiSXEkFRnUH77yXc6ZcwHHcLNfjdi5qUvw3VDfgYiH5mNsj5izuiu2N/1/2/*)"
    -            .into_wallet_descriptor(&secp, Network::Bitcoin);
    +        let desc = "wpkh(tprv8ZgxMBicQKsPdpkqS7Eair4YxjcuuvDPNYmKX3sCniCf16tHEVrjjiSXEkFRnUH77yXc6ZcwHHcLNfjdi5qUvw3VDfgYiH5mNsj5izuiu2N/1/2/*)"
    +            .into_wallet_descriptor(&secp, Network::Bitcoin);
             assert!(matches!(
    -            desc.err(),
    -            Some(DescriptorError::Key(KeyError::InvalidNetwork))
    +            desc.err(),
    +            Some(DescriptorError::Key(KeyError::InvalidNetwork))
             ));
     
    -        let desc = "wpkh(tpubD6NzVbkrYhZ4XHndKkuB8FifXm8r5FQHwrN6oZuWCz13qb93rtgKvD4PQsqC4HP4yhV3tA2fqr2RbY5mNXfM7RxXUoeABoDtsFUq2zJq6YK/1/2/*)"
    -            .into_wallet_descriptor(&secp, Network::Bitcoin);
    +        let desc = "wpkh(tpubD6NzVbkrYhZ4XHndKkuB8FifXm8r5FQHwrN6oZuWCz13qb93rtgKvD4PQsqC4HP4yhV3tA2fqr2RbY5mNXfM7RxXUoeABoDtsFUq2zJq6YK/1/2/*)"
    +            .into_wallet_descriptor(&secp, Network::Bitcoin);
             assert!(matches!(
    -            desc.err(),
    -            Some(DescriptorError::Key(KeyError::InvalidNetwork))
    +            desc.err(),
    +            Some(DescriptorError::Key(KeyError::InvalidNetwork))
             ));
         }
     
    -    // test IntoWalletDescriptor trait from the output of the descriptor!() macro
    -    #[test]
    -    fn test_descriptor_from_str_from_output_of_macro() {
    -        let secp = Secp256k1::new();
    +    // test IntoWalletDescriptor trait from the output of the descriptor!() macro
    +    #[test]
    +    fn test_descriptor_from_str_from_output_of_macro() {
    +        let secp = Secp256k1::new();
     
    -        let tpub = bip32::ExtendedPubKey::from_str("tpubD6NzVbkrYhZ4XHndKkuB8FifXm8r5FQHwrN6oZuWCz13qb93rtgKvD4PQsqC4HP4yhV3tA2fqr2RbY5mNXfM7RxXUoeABoDtsFUq2zJq6YK").unwrap();
    -        let path = bip32::DerivationPath::from_str("m/1/2").unwrap();
    -        let key = (tpub, path).into_descriptor_key().unwrap();
    +        let tpub = bip32::ExtendedPubKey::from_str("tpubD6NzVbkrYhZ4XHndKkuB8FifXm8r5FQHwrN6oZuWCz13qb93rtgKvD4PQsqC4HP4yhV3tA2fqr2RbY5mNXfM7RxXUoeABoDtsFUq2zJq6YK").unwrap();
    +        let path = bip32::DerivationPath::from_str("m/1/2").unwrap();
    +        let key = (tpub, path).into_descriptor_key().unwrap();
     
    -        // make a descriptor out of it
    -        let desc = crate::descriptor!(wpkh(key)).unwrap();
    +        // make a descriptor out of it
    +        let desc = crate::descriptor!(wpkh(key)).unwrap();
     
    -        let (wallet_desc, _) = desc
    -            .into_wallet_descriptor(&secp, Network::Testnet)
    -            .unwrap();
    -        let wallet_desc_str = wallet_desc.to_string();
    -        assert_eq!(wallet_desc_str, "wpkh(tpubD6NzVbkrYhZ4XHndKkuB8FifXm8r5FQHwrN6oZuWCz13qb93rtgKvD4PQsqC4HP4yhV3tA2fqr2RbY5mNXfM7RxXUoeABoDtsFUq2zJq6YK/1/2/*)#67ju93jw");
    +        let (wallet_desc, _) = desc
    +            .into_wallet_descriptor(&secp, Network::Testnet)
    +            .unwrap();
    +        let wallet_desc_str = wallet_desc.to_string();
    +        assert_eq!(wallet_desc_str, "wpkh(tpubD6NzVbkrYhZ4XHndKkuB8FifXm8r5FQHwrN6oZuWCz13qb93rtgKvD4PQsqC4HP4yhV3tA2fqr2RbY5mNXfM7RxXUoeABoDtsFUq2zJq6YK/1/2/*)#67ju93jw");
     
    -        let (wallet_desc2, _) = wallet_desc_str
    -            .into_wallet_descriptor(&secp, Network::Testnet)
    -            .unwrap();
    -        assert_eq!(wallet_desc, wallet_desc2)
    +        let (wallet_desc2, _) = wallet_desc_str
    +            .into_wallet_descriptor(&secp, Network::Testnet)
    +            .unwrap();
    +        assert_eq!(wallet_desc, wallet_desc2)
         }
     
    -    #[test]
    -    fn test_into_wallet_descriptor_checked() {
    -        let secp = Secp256k1::new();
    +    #[test]
    +    fn test_into_wallet_descriptor_checked() {
    +        let secp = Secp256k1::new();
     
    -        let descriptor = "wpkh(tpubD6NzVbkrYhZ4XHndKkuB8FifXm8r5FQHwrN6oZuWCz13qb93rtgKvD4PQsqC4HP4yhV3tA2fqr2RbY5mNXfM7RxXUoeABoDtsFUq2zJq6YK/0'/1/2/*)";
    -        let result = into_wallet_descriptor_checked(descriptor, &secp, Network::Testnet);
    +        let descriptor = "wpkh(tpubD6NzVbkrYhZ4XHndKkuB8FifXm8r5FQHwrN6oZuWCz13qb93rtgKvD4PQsqC4HP4yhV3tA2fqr2RbY5mNXfM7RxXUoeABoDtsFUq2zJq6YK/0'/1/2/*)";
    +        let result = into_wallet_descriptor_checked(descriptor, &secp, Network::Testnet);
     
    -        assert!(result.is_err());
    +        assert!(result.is_err());
             assert!(matches!(
    -            result.unwrap_err(),
    -            DescriptorError::HardenedDerivationXpub
    +            result.unwrap_err(),
    +            DescriptorError::HardenedDerivationXpub
             ));
     
    -        let descriptor = "wsh(multi(2,tpubD6NzVbkrYhZ4XHndKkuB8FifXm8r5FQHwrN6oZuWCz13qb93rtgKvD4PQsqC4HP4yhV3tA2fqr2RbY5mNXfM7RxXUoeABoDtsFUq2zJq6YK/0/*,tpubD6NzVbkrYhZ4XHndKkuB8FifXm8r5FQHwrN6oZuWCz13qb93rtgKvD4PQsqC4HP4yhV3tA2fqr2RbY5mNXfM7RxXUoeABoDtsFUq2zJq6YK/0/*))";
    -        let result = into_wallet_descriptor_checked(descriptor, &secp, Network::Testnet);
    +        let descriptor = "wsh(multi(2,tpubD6NzVbkrYhZ4XHndKkuB8FifXm8r5FQHwrN6oZuWCz13qb93rtgKvD4PQsqC4HP4yhV3tA2fqr2RbY5mNXfM7RxXUoeABoDtsFUq2zJq6YK/0/*,tpubD6NzVbkrYhZ4XHndKkuB8FifXm8r5FQHwrN6oZuWCz13qb93rtgKvD4PQsqC4HP4yhV3tA2fqr2RbY5mNXfM7RxXUoeABoDtsFUq2zJq6YK/0/*))";
    +        let result = into_wallet_descriptor_checked(descriptor, &secp, Network::Testnet);
     
    -        assert!(result.is_err());
    +        assert!(result.is_err());
         }
     
    -    #[test]
    -    fn test_sh_wsh_sortedmulti_redeemscript() {
    -        use miniscript::psbt::PsbtInputExt;
    +    #[test]
    +    fn test_sh_wsh_sortedmulti_redeemscript() {
    +        use miniscript::psbt::PsbtInputExt;
     
    -        let secp = Secp256k1::new();
    +        let secp = Secp256k1::new();
     
    -        let descriptor = "sh(wsh(sortedmulti(3,tpubDEsqS36T4DVsKJd9UH8pAKzrkGBYPLEt9jZMwpKtzh1G6mgYehfHt9WCgk7MJG5QGSFWf176KaBNoXbcuFcuadAFKxDpUdMDKGBha7bY3QM/0/*,tpubDF3cpwfs7fMvXXuoQbohXtLjNM6ehwYT287LWtmLsd4r77YLg6MZg4vTETx5MSJ2zkfigbYWu31VA2Z2Vc1cZugCYXgS7FQu6pE8V6TriEH/0/*,tpubDE1SKfcW76Tb2AASv5bQWMuScYNAdoqLHoexw13sNDXwmUhQDBbCD3QAedKGLhxMrWQdMDKENzYtnXPDRvexQPNuDrLj52wAjHhNEm8sJ4p/0/*,tpubDFLc6oXwJmhm3FGGzXkfJNTh2KitoY3WhmmQvuAjMhD8YbyWn5mAqckbxXfm2etM3p5J6JoTpSrMqRSTfMLtNW46poDaEZJ1kjd3csRSjwH/0/*,tpubDEWD9NBeWP59xXmdqSNt4VYdtTGwbpyP8WS962BuqpQeMZmX9Pur14dhXdZT5a7wR1pK6dPtZ9fP5WR493hPzemnBvkfLLYxnUjAKj1JCQV/0/*,tpubDEHyZkkwd7gZWCTgQuYQ9C4myF2hMEmyHsBCCmLssGqoqUxeT3gzohF5uEVURkf9TtmeepJgkSUmteac38FwZqirjApzNX59XSHLcwaTZCH/0/*,tpubDEqLouCekwnMUWN486kxGzD44qVgeyuqHyxUypNEiQt5RnUZNJe386TKPK99fqRV1vRkZjYAjtXGTECz98MCsdLcnkM67U6KdYRzVubeCgZ/0/*)))";
    -        let (descriptor, _) =
    -            into_wallet_descriptor_checked(descriptor, &secp, Network::Testnet).unwrap();
    +        let descriptor = "sh(wsh(sortedmulti(3,tpubDEsqS36T4DVsKJd9UH8pAKzrkGBYPLEt9jZMwpKtzh1G6mgYehfHt9WCgk7MJG5QGSFWf176KaBNoXbcuFcuadAFKxDpUdMDKGBha7bY3QM/0/*,tpubDF3cpwfs7fMvXXuoQbohXtLjNM6ehwYT287LWtmLsd4r77YLg6MZg4vTETx5MSJ2zkfigbYWu31VA2Z2Vc1cZugCYXgS7FQu6pE8V6TriEH/0/*,tpubDE1SKfcW76Tb2AASv5bQWMuScYNAdoqLHoexw13sNDXwmUhQDBbCD3QAedKGLhxMrWQdMDKENzYtnXPDRvexQPNuDrLj52wAjHhNEm8sJ4p/0/*,tpubDFLc6oXwJmhm3FGGzXkfJNTh2KitoY3WhmmQvuAjMhD8YbyWn5mAqckbxXfm2etM3p5J6JoTpSrMqRSTfMLtNW46poDaEZJ1kjd3csRSjwH/0/*,tpubDEWD9NBeWP59xXmdqSNt4VYdtTGwbpyP8WS962BuqpQeMZmX9Pur14dhXdZT5a7wR1pK6dPtZ9fP5WR493hPzemnBvkfLLYxnUjAKj1JCQV/0/*,tpubDEHyZkkwd7gZWCTgQuYQ9C4myF2hMEmyHsBCCmLssGqoqUxeT3gzohF5uEVURkf9TtmeepJgkSUmteac38FwZqirjApzNX59XSHLcwaTZCH/0/*,tpubDEqLouCekwnMUWN486kxGzD44qVgeyuqHyxUypNEiQt5RnUZNJe386TKPK99fqRV1vRkZjYAjtXGTECz98MCsdLcnkM67U6KdYRzVubeCgZ/0/*)))";
    +        let (descriptor, _) =
    +            into_wallet_descriptor_checked(descriptor, &secp, Network::Testnet).unwrap();
     
    -        let descriptor = descriptor.at_derivation_index(0);
    +        let descriptor = descriptor.at_derivation_index(0);
     
    -        let script = Script::from_str("5321022f533b667e2ea3b36e21961c9fe9dca340fbe0af5210173a83ae0337ab20a57621026bb53a98e810bd0ee61a0ed1164ba6c024786d76554e793e202dc6ce9c78c4ea2102d5b8a7d66a41ffdb6f4c53d61994022e886b4f45001fb158b95c9164d45f8ca3210324b75eead2c1f9c60e8adeb5e7009fec7a29afcdb30d829d82d09562fe8bae8521032d34f8932200833487bd294aa219dcbe000b9f9b3d824799541430009f0fa55121037468f8ea99b6c64788398b5ad25480cad08f4b0d65be54ce3a55fd206b5ae4722103f72d3d96663b0ea99b0aeb0d7f273cab11a8de37885f1dddc8d9112adb87169357ae").unwrap();
    +        let script = Script::from_str("5321022f533b667e2ea3b36e21961c9fe9dca340fbe0af5210173a83ae0337ab20a57621026bb53a98e810bd0ee61a0ed1164ba6c024786d76554e793e202dc6ce9c78c4ea2102d5b8a7d66a41ffdb6f4c53d61994022e886b4f45001fb158b95c9164d45f8ca3210324b75eead2c1f9c60e8adeb5e7009fec7a29afcdb30d829d82d09562fe8bae8521032d34f8932200833487bd294aa219dcbe000b9f9b3d824799541430009f0fa55121037468f8ea99b6c64788398b5ad25480cad08f4b0d65be54ce3a55fd206b5ae4722103f72d3d96663b0ea99b0aeb0d7f273cab11a8de37885f1dddc8d9112adb87169357ae").unwrap();
     
    -        let mut psbt_input = psbt::Input::default();
    -        psbt_input
    -            .update_with_descriptor_unchecked(&descriptor)
    -            .unwrap();
    +        let mut psbt_input = psbt::Input::default();
    +        psbt_input
    +            .update_with_descriptor_unchecked(&descriptor)
    +            .unwrap();
     
    -        assert_eq!(psbt_input.redeem_script, Some(script.to_v0_p2wsh()));
    -        assert_eq!(psbt_input.witness_script, Some(script));
    +        assert_eq!(psbt_input.redeem_script, Some(script.to_v0_p2wsh()));
    +        assert_eq!(psbt_input.witness_script, Some(script));
         }
     }
     
    -
    - \ No newline at end of file +
    \ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/src/bdk/descriptor/policy.rs.html b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/src/bdk/descriptor/policy.rs.html index 4e89c3b5e7..439662a4d4 100644 --- a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/src/bdk/descriptor/policy.rs.html +++ b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/src/bdk/descriptor/policy.rs.html @@ -1,2272 +1,2266 @@ -policy.rs - source - -
       1
    -   2
    -   3
    -   4
    -   5
    -   6
    -   7
    -   8
    -   9
    -  10
    -  11
    -  12
    -  13
    -  14
    -  15
    -  16
    -  17
    -  18
    -  19
    -  20
    -  21
    -  22
    -  23
    -  24
    -  25
    -  26
    -  27
    -  28
    -  29
    -  30
    -  31
    -  32
    -  33
    -  34
    -  35
    -  36
    -  37
    -  38
    -  39
    -  40
    -  41
    -  42
    -  43
    -  44
    -  45
    -  46
    -  47
    -  48
    -  49
    -  50
    -  51
    -  52
    -  53
    -  54
    -  55
    -  56
    -  57
    -  58
    -  59
    -  60
    -  61
    -  62
    -  63
    -  64
    -  65
    -  66
    -  67
    -  68
    -  69
    -  70
    -  71
    -  72
    -  73
    -  74
    -  75
    -  76
    -  77
    -  78
    -  79
    -  80
    -  81
    -  82
    -  83
    -  84
    -  85
    -  86
    -  87
    -  88
    -  89
    -  90
    -  91
    -  92
    -  93
    -  94
    -  95
    -  96
    -  97
    -  98
    -  99
    - 100
    - 101
    - 102
    - 103
    - 104
    - 105
    - 106
    - 107
    - 108
    - 109
    - 110
    - 111
    - 112
    - 113
    - 114
    - 115
    - 116
    - 117
    - 118
    - 119
    - 120
    - 121
    - 122
    - 123
    - 124
    - 125
    - 126
    - 127
    - 128
    - 129
    - 130
    - 131
    - 132
    - 133
    - 134
    - 135
    - 136
    - 137
    - 138
    - 139
    - 140
    - 141
    - 142
    - 143
    - 144
    - 145
    - 146
    - 147
    - 148
    - 149
    - 150
    - 151
    - 152
    - 153
    - 154
    - 155
    - 156
    - 157
    - 158
    - 159
    - 160
    - 161
    - 162
    - 163
    - 164
    - 165
    - 166
    - 167
    - 168
    - 169
    - 170
    - 171
    - 172
    - 173
    - 174
    - 175
    - 176
    - 177
    - 178
    - 179
    - 180
    - 181
    - 182
    - 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
    - 245
    - 246
    - 247
    - 248
    - 249
    - 250
    - 251
    - 252
    - 253
    - 254
    - 255
    - 256
    - 257
    - 258
    - 259
    - 260
    - 261
    - 262
    - 263
    - 264
    - 265
    - 266
    - 267
    - 268
    - 269
    - 270
    - 271
    - 272
    - 273
    - 274
    - 275
    - 276
    - 277
    - 278
    - 279
    - 280
    - 281
    - 282
    - 283
    - 284
    - 285
    - 286
    - 287
    - 288
    - 289
    - 290
    - 291
    - 292
    - 293
    - 294
    - 295
    - 296
    - 297
    - 298
    - 299
    - 300
    - 301
    - 302
    - 303
    - 304
    - 305
    - 306
    - 307
    - 308
    - 309
    - 310
    - 311
    - 312
    - 313
    - 314
    - 315
    - 316
    - 317
    - 318
    - 319
    - 320
    - 321
    - 322
    - 323
    - 324
    - 325
    - 326
    - 327
    - 328
    - 329
    - 330
    - 331
    - 332
    - 333
    - 334
    - 335
    - 336
    - 337
    - 338
    - 339
    - 340
    - 341
    - 342
    - 343
    - 344
    - 345
    - 346
    - 347
    - 348
    - 349
    - 350
    - 351
    - 352
    - 353
    - 354
    - 355
    - 356
    - 357
    - 358
    - 359
    - 360
    - 361
    - 362
    - 363
    - 364
    - 365
    - 366
    - 367
    - 368
    - 369
    - 370
    - 371
    - 372
    - 373
    - 374
    - 375
    - 376
    - 377
    - 378
    - 379
    - 380
    - 381
    - 382
    - 383
    - 384
    - 385
    - 386
    - 387
    - 388
    - 389
    - 390
    - 391
    - 392
    - 393
    - 394
    - 395
    - 396
    - 397
    - 398
    - 399
    - 400
    - 401
    - 402
    - 403
    - 404
    - 405
    - 406
    - 407
    - 408
    - 409
    - 410
    - 411
    - 412
    - 413
    - 414
    - 415
    - 416
    - 417
    - 418
    - 419
    - 420
    - 421
    - 422
    - 423
    - 424
    - 425
    - 426
    - 427
    - 428
    - 429
    - 430
    - 431
    - 432
    - 433
    - 434
    - 435
    - 436
    - 437
    - 438
    - 439
    - 440
    - 441
    - 442
    - 443
    - 444
    - 445
    - 446
    - 447
    - 448
    - 449
    - 450
    - 451
    - 452
    - 453
    - 454
    - 455
    - 456
    - 457
    - 458
    - 459
    - 460
    - 461
    - 462
    - 463
    - 464
    - 465
    - 466
    - 467
    - 468
    - 469
    - 470
    - 471
    - 472
    - 473
    - 474
    - 475
    - 476
    - 477
    - 478
    - 479
    - 480
    - 481
    - 482
    - 483
    - 484
    - 485
    - 486
    - 487
    - 488
    - 489
    - 490
    - 491
    - 492
    - 493
    - 494
    - 495
    - 496
    - 497
    - 498
    - 499
    - 500
    - 501
    - 502
    - 503
    - 504
    - 505
    - 506
    - 507
    - 508
    - 509
    - 510
    - 511
    - 512
    - 513
    - 514
    - 515
    - 516
    - 517
    - 518
    - 519
    - 520
    - 521
    - 522
    - 523
    - 524
    - 525
    - 526
    - 527
    - 528
    - 529
    - 530
    - 531
    - 532
    - 533
    - 534
    - 535
    - 536
    - 537
    - 538
    - 539
    - 540
    - 541
    - 542
    - 543
    - 544
    - 545
    - 546
    - 547
    - 548
    - 549
    - 550
    - 551
    - 552
    - 553
    - 554
    - 555
    - 556
    - 557
    - 558
    - 559
    - 560
    - 561
    - 562
    - 563
    - 564
    - 565
    - 566
    - 567
    - 568
    - 569
    - 570
    - 571
    - 572
    - 573
    - 574
    - 575
    - 576
    - 577
    - 578
    - 579
    - 580
    - 581
    - 582
    - 583
    - 584
    - 585
    - 586
    - 587
    - 588
    - 589
    - 590
    - 591
    - 592
    - 593
    - 594
    - 595
    - 596
    - 597
    - 598
    - 599
    - 600
    - 601
    - 602
    - 603
    - 604
    - 605
    - 606
    - 607
    - 608
    - 609
    - 610
    - 611
    - 612
    - 613
    - 614
    - 615
    - 616
    - 617
    - 618
    - 619
    - 620
    - 621
    - 622
    - 623
    - 624
    - 625
    - 626
    - 627
    - 628
    - 629
    - 630
    - 631
    - 632
    - 633
    - 634
    - 635
    - 636
    - 637
    - 638
    - 639
    - 640
    - 641
    - 642
    - 643
    - 644
    - 645
    - 646
    - 647
    - 648
    - 649
    - 650
    - 651
    - 652
    - 653
    - 654
    - 655
    - 656
    - 657
    - 658
    - 659
    - 660
    - 661
    - 662
    - 663
    - 664
    - 665
    - 666
    - 667
    - 668
    - 669
    - 670
    - 671
    - 672
    - 673
    - 674
    - 675
    - 676
    - 677
    - 678
    - 679
    - 680
    - 681
    - 682
    - 683
    - 684
    - 685
    - 686
    - 687
    - 688
    - 689
    - 690
    - 691
    - 692
    - 693
    - 694
    - 695
    - 696
    - 697
    - 698
    - 699
    - 700
    - 701
    - 702
    - 703
    - 704
    - 705
    - 706
    - 707
    - 708
    - 709
    - 710
    - 711
    - 712
    - 713
    - 714
    - 715
    - 716
    - 717
    - 718
    - 719
    - 720
    - 721
    - 722
    - 723
    - 724
    - 725
    - 726
    - 727
    - 728
    - 729
    - 730
    - 731
    - 732
    - 733
    - 734
    - 735
    - 736
    - 737
    - 738
    - 739
    - 740
    - 741
    - 742
    - 743
    - 744
    - 745
    - 746
    - 747
    - 748
    - 749
    - 750
    - 751
    - 752
    - 753
    - 754
    - 755
    - 756
    - 757
    - 758
    - 759
    - 760
    - 761
    - 762
    - 763
    - 764
    - 765
    - 766
    - 767
    - 768
    - 769
    - 770
    - 771
    - 772
    - 773
    - 774
    - 775
    - 776
    - 777
    - 778
    - 779
    - 780
    - 781
    - 782
    - 783
    - 784
    - 785
    - 786
    - 787
    - 788
    - 789
    - 790
    - 791
    - 792
    - 793
    - 794
    - 795
    - 796
    - 797
    - 798
    - 799
    - 800
    - 801
    - 802
    - 803
    - 804
    - 805
    - 806
    - 807
    - 808
    - 809
    - 810
    - 811
    - 812
    - 813
    - 814
    - 815
    - 816
    - 817
    - 818
    - 819
    - 820
    - 821
    - 822
    - 823
    - 824
    - 825
    - 826
    - 827
    - 828
    - 829
    - 830
    - 831
    - 832
    - 833
    - 834
    - 835
    - 836
    - 837
    - 838
    - 839
    - 840
    - 841
    - 842
    - 843
    - 844
    - 845
    - 846
    - 847
    - 848
    - 849
    - 850
    - 851
    - 852
    - 853
    - 854
    - 855
    - 856
    - 857
    - 858
    - 859
    - 860
    - 861
    - 862
    - 863
    - 864
    - 865
    - 866
    - 867
    - 868
    - 869
    - 870
    - 871
    - 872
    - 873
    - 874
    - 875
    - 876
    - 877
    - 878
    - 879
    - 880
    - 881
    - 882
    - 883
    - 884
    - 885
    - 886
    - 887
    - 888
    - 889
    - 890
    - 891
    - 892
    - 893
    - 894
    - 895
    - 896
    - 897
    - 898
    - 899
    - 900
    - 901
    - 902
    - 903
    - 904
    - 905
    - 906
    - 907
    - 908
    - 909
    - 910
    - 911
    - 912
    - 913
    - 914
    - 915
    - 916
    - 917
    - 918
    - 919
    - 920
    - 921
    - 922
    - 923
    - 924
    - 925
    - 926
    - 927
    - 928
    - 929
    - 930
    - 931
    - 932
    - 933
    - 934
    - 935
    - 936
    - 937
    - 938
    - 939
    - 940
    - 941
    - 942
    - 943
    - 944
    - 945
    - 946
    - 947
    - 948
    - 949
    - 950
    - 951
    - 952
    - 953
    - 954
    - 955
    - 956
    - 957
    - 958
    - 959
    - 960
    - 961
    - 962
    - 963
    - 964
    - 965
    - 966
    - 967
    - 968
    - 969
    - 970
    - 971
    - 972
    - 973
    - 974
    - 975
    - 976
    - 977
    - 978
    - 979
    - 980
    - 981
    - 982
    - 983
    - 984
    - 985
    - 986
    - 987
    - 988
    - 989
    - 990
    - 991
    - 992
    - 993
    - 994
    - 995
    - 996
    - 997
    - 998
    - 999
    -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
    -1028
    -1029
    -1030
    -1031
    -1032
    -1033
    -1034
    -1035
    -1036
    -1037
    -1038
    -1039
    -1040
    -1041
    -1042
    -1043
    -1044
    -1045
    -1046
    -1047
    -1048
    -1049
    -1050
    -1051
    -1052
    -1053
    -1054
    -1055
    -1056
    -1057
    -1058
    -1059
    -1060
    -1061
    -1062
    -1063
    -1064
    -1065
    -1066
    -1067
    -1068
    -1069
    -1070
    -1071
    -1072
    -1073
    -1074
    -1075
    -1076
    -1077
    -1078
    -1079
    -1080
    -1081
    -1082
    -1083
    -1084
    -1085
    -1086
    -1087
    -1088
    -1089
    -1090
    -1091
    -1092
    -1093
    -1094
    -1095
    -1096
    -1097
    -1098
    -1099
    -1100
    -1101
    -1102
    -1103
    -1104
    -1105
    -1106
    -1107
    -1108
    -1109
    -1110
    -1111
    -1112
    -1113
    -1114
    -1115
    -1116
    -1117
    -1118
    -1119
    -1120
    -1121
    -1122
    -1123
    -1124
    -1125
    -1126
    -1127
    -1128
    -1129
    -1130
    -1131
    -1132
    -1133
    -1134
    -1135
    -1136
    -1137
    -1138
    -1139
    -1140
    -1141
    -1142
    -1143
    -1144
    -1145
    -1146
    -1147
    -1148
    -1149
    -1150
    -1151
    -1152
    -1153
    -1154
    -1155
    -1156
    -1157
    -1158
    -1159
    -1160
    -1161
    -1162
    -1163
    -1164
    -1165
    -1166
    -1167
    -1168
    -1169
    -1170
    -1171
    -1172
    -1173
    -1174
    -1175
    -1176
    -1177
    -1178
    -1179
    -1180
    -1181
    -1182
    -1183
    -1184
    -1185
    -1186
    -1187
    -1188
    -1189
    -1190
    -1191
    -1192
    -1193
    -1194
    -1195
    -1196
    -1197
    -1198
    -1199
    -1200
    -1201
    -1202
    -1203
    -1204
    -1205
    -1206
    -1207
    -1208
    -1209
    -1210
    -1211
    -1212
    -1213
    -1214
    -1215
    -1216
    -1217
    -1218
    -1219
    -1220
    -1221
    -1222
    -1223
    -1224
    -1225
    -1226
    -1227
    -1228
    -1229
    -1230
    -1231
    -1232
    -1233
    -1234
    -1235
    -1236
    -1237
    -1238
    -1239
    -1240
    -1241
    -1242
    -1243
    -1244
    -1245
    -1246
    -1247
    -1248
    -1249
    -1250
    -1251
    -1252
    -1253
    -1254
    -1255
    -1256
    -1257
    -1258
    -1259
    -1260
    -1261
    -1262
    -1263
    -1264
    -1265
    -1266
    -1267
    -1268
    -1269
    -1270
    -1271
    -1272
    -1273
    -1274
    -1275
    -1276
    -1277
    -1278
    -1279
    -1280
    -1281
    -1282
    -1283
    -1284
    -1285
    -1286
    -1287
    -1288
    -1289
    -1290
    -1291
    -1292
    -1293
    -1294
    -1295
    -1296
    -1297
    -1298
    -1299
    -1300
    -1301
    -1302
    -1303
    -1304
    -1305
    -1306
    -1307
    -1308
    -1309
    -1310
    -1311
    -1312
    -1313
    -1314
    -1315
    -1316
    -1317
    -1318
    -1319
    -1320
    -1321
    -1322
    -1323
    -1324
    -1325
    -1326
    -1327
    -1328
    -1329
    -1330
    -1331
    -1332
    -1333
    -1334
    -1335
    -1336
    -1337
    -1338
    -1339
    -1340
    -1341
    -1342
    -1343
    -1344
    -1345
    -1346
    -1347
    -1348
    -1349
    -1350
    -1351
    -1352
    -1353
    -1354
    -1355
    -1356
    -1357
    -1358
    -1359
    -1360
    -1361
    -1362
    -1363
    -1364
    -1365
    -1366
    -1367
    -1368
    -1369
    -1370
    -1371
    -1372
    -1373
    -1374
    -1375
    -1376
    -1377
    -1378
    -1379
    -1380
    -1381
    -1382
    -1383
    -1384
    -1385
    -1386
    -1387
    -1388
    -1389
    -1390
    -1391
    -1392
    -1393
    -1394
    -1395
    -1396
    -1397
    -1398
    -1399
    -1400
    -1401
    -1402
    -1403
    -1404
    -1405
    -1406
    -1407
    -1408
    -1409
    -1410
    -1411
    -1412
    -1413
    -1414
    -1415
    -1416
    -1417
    -1418
    -1419
    -1420
    -1421
    -1422
    -1423
    -1424
    -1425
    -1426
    -1427
    -1428
    -1429
    -1430
    -1431
    -1432
    -1433
    -1434
    -1435
    -1436
    -1437
    -1438
    -1439
    -1440
    -1441
    -1442
    -1443
    -1444
    -1445
    -1446
    -1447
    -1448
    -1449
    -1450
    -1451
    -1452
    -1453
    -1454
    -1455
    -1456
    -1457
    -1458
    -1459
    -1460
    -1461
    -1462
    -1463
    -1464
    -1465
    -1466
    -1467
    -1468
    -1469
    -1470
    -1471
    -1472
    -1473
    -1474
    -1475
    -1476
    -1477
    -1478
    -1479
    -1480
    -1481
    -1482
    -1483
    -1484
    -1485
    -1486
    -1487
    -1488
    -1489
    -1490
    -1491
    -1492
    -1493
    -1494
    -1495
    -1496
    -1497
    -1498
    -1499
    -1500
    -1501
    -1502
    -1503
    -1504
    -1505
    -1506
    -1507
    -1508
    -1509
    -1510
    -1511
    -1512
    -1513
    -1514
    -1515
    -1516
    -1517
    -1518
    -1519
    -1520
    -1521
    -1522
    -1523
    -1524
    -1525
    -1526
    -1527
    -1528
    -1529
    -1530
    -1531
    -1532
    -1533
    -1534
    -1535
    -1536
    -1537
    -1538
    -1539
    -1540
    -1541
    -1542
    -1543
    -1544
    -1545
    -1546
    -1547
    -1548
    -1549
    -1550
    -1551
    -1552
    -1553
    -1554
    -1555
    -1556
    -1557
    -1558
    -1559
    -1560
    -1561
    -1562
    -1563
    -1564
    -1565
    -1566
    -1567
    -1568
    -1569
    -1570
    -1571
    -1572
    -1573
    -1574
    -1575
    -1576
    -1577
    -1578
    -1579
    -1580
    -1581
    -1582
    -1583
    -1584
    -1585
    -1586
    -1587
    -1588
    -1589
    -1590
    -1591
    -1592
    -1593
    -1594
    -1595
    -1596
    -1597
    -1598
    -1599
    -1600
    -1601
    -1602
    -1603
    -1604
    -1605
    -1606
    -1607
    -1608
    -1609
    -1610
    -1611
    -1612
    -1613
    -1614
    -1615
    -1616
    -1617
    -1618
    -1619
    -1620
    -1621
    -1622
    -1623
    -1624
    -1625
    -1626
    -1627
    -1628
    -1629
    -1630
    -1631
    -1632
    -1633
    -1634
    -1635
    -1636
    -1637
    -1638
    -1639
    -1640
    -1641
    -1642
    -1643
    -1644
    -1645
    -1646
    -1647
    -1648
    -1649
    -1650
    -1651
    -1652
    -1653
    -1654
    -1655
    -1656
    -1657
    -1658
    -1659
    -1660
    -1661
    -1662
    -1663
    -1664
    -1665
    -1666
    -1667
    -1668
    -1669
    -1670
    -1671
    -1672
    -1673
    -1674
    -1675
    -1676
    -1677
    -1678
    -1679
    -1680
    -1681
    -1682
    -1683
    -1684
    -1685
    -1686
    -1687
    -1688
    -1689
    -1690
    -1691
    -1692
    -1693
    -1694
    -1695
    -1696
    -1697
    -1698
    -1699
    -1700
    -1701
    -1702
    -1703
    -1704
    -1705
    -1706
    -1707
    -1708
    -1709
    -1710
    -1711
    -1712
    -1713
    -1714
    -1715
    -1716
    -1717
    -1718
    -1719
    -1720
    -1721
    -1722
    -1723
    -1724
    -1725
    -1726
    -1727
    -1728
    -1729
    -1730
    -1731
    -1732
    -1733
    -1734
    -1735
    -1736
    -1737
    -1738
    -1739
    -1740
    -1741
    -1742
    -1743
    -1744
    -1745
    -1746
    -1747
    -1748
    -1749
    -1750
    -1751
    -1752
    -1753
    -1754
    -1755
    -1756
    -1757
    -1758
    -1759
    -1760
    -1761
    -1762
    -1763
    -1764
    -1765
    -1766
    -1767
    -1768
    -1769
    -1770
    -1771
    -1772
    -1773
    -1774
    -1775
    -1776
    -1777
    -1778
    -1779
    -1780
    -1781
    -1782
    -1783
    -1784
    -1785
    -1786
    -1787
    -1788
    -1789
    -1790
    -1791
    -1792
    -1793
    -1794
    -1795
    -1796
    -1797
    -1798
    -1799
    -1800
    -1801
    -1802
    -1803
    -1804
    -1805
    -1806
    -1807
    -1808
    -1809
    -1810
    -1811
    -1812
    -1813
    -1814
    -1815
    -1816
    -1817
    -1818
    -1819
    -1820
    -1821
    -1822
    -1823
    -1824
    -1825
    -1826
    -1827
    -1828
    -1829
    -1830
    -1831
    -1832
    -1833
    -1834
    -1835
    -1836
    -1837
    -1838
    -1839
    -1840
    -1841
    -1842
    -1843
    -1844
    -1845
    -1846
    -1847
    -1848
    -1849
    -1850
    -1851
    -1852
    -1853
    -1854
    -1855
    -1856
    -1857
    -1858
    -1859
    -1860
    -1861
    -1862
    -1863
    -1864
    -1865
    -1866
    -1867
    -1868
    -1869
    -1870
    -1871
    -1872
    -1873
    -1874
    -1875
    -1876
    -1877
    -1878
    -1879
    -1880
    -1881
    -1882
    -1883
    -1884
    -1885
    -1886
    -1887
    -1888
    -1889
    -1890
    -1891
    -1892
    -1893
    -1894
    -1895
    -1896
    -1897
    -1898
    -1899
    -1900
    -1901
    -1902
    -1903
    -1904
    -1905
    -1906
    -1907
    -1908
    -1909
    -1910
    -1911
    -1912
    -1913
    -1914
    -1915
    -1916
    -1917
    -1918
    -1919
    -1920
    -1921
    -1922
    -
    // Bitcoin Dev Kit
    -// Written in 2020 by Alekos Filini <alekos.filini@gmail.com>
    -//
    -// Copyright (c) 2020-2021 Bitcoin Dev Kit Developers
    -//
    -// This file is licensed under the Apache License, Version 2.0 <LICENSE-APACHE
    -// or http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
    -// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your option.
    -// You may not use this file except in accordance with one or both of these
    -// licenses.
    -
    -//! Descriptor policy
    -//!
    -//! This module implements the logic to extract and represent the spending policies of a descriptor
    -//! in a more human-readable format.
    -//!
    -//! This is an **EXPERIMENTAL** feature, API and other major changes are expected.
    -//!
    -//! ## Example
    -//!
    -//! ```
    -//! # use std::sync::Arc;
    -//! # use bdk::descriptor::*;
    -//! # use bdk::wallet::signer::*;
    -//! # use bdk::bitcoin::secp256k1::Secp256k1;
    -//! use bdk::descriptor::policy::BuildSatisfaction;
    -//! let secp = Secp256k1::new();
    -//! let desc = "wsh(and_v(v:pk(cV3oCth6zxZ1UVsHLnGothsWNsaoxRhC6aeNi5VbSdFpwUkgkEci),or_d(pk(cVMTy7uebJgvFaSBwcgvwk8qn8xSLc97dKow4MBetjrrahZoimm2),older(12960))))";
    -//!
    -//! let (extended_desc, key_map) = ExtendedDescriptor::parse_descriptor(&secp, desc)?;
    -//! println!("{:?}", extended_desc);
    -//!
    -//! let signers = Arc::new(SignersContainer::build(key_map, &extended_desc, &secp));
    -//! let policy = extended_desc.extract_policy(&signers, BuildSatisfaction::None, &secp)?;
    -//! println!("policy: {}", serde_json::to_string(&policy)?);
    -//! # Ok::<(), bdk::Error>(())
    -//! ```
    -
    -use std::cmp::max;
    -use std::collections::{BTreeMap, HashSet, VecDeque};
    -use std::fmt;
    -
    -use serde::ser::SerializeMap;
    -use serde::{Serialize, Serializer};
    -
    -use bitcoin::hashes::{hash160, ripemd160, sha256};
    -use bitcoin::util::bip32::Fingerprint;
    -use bitcoin::{LockTime, PublicKey, Sequence, XOnlyPublicKey};
    -
    -use miniscript::descriptor::{
    -    DescriptorPublicKey, ShInner, SinglePub, SinglePubKey, SortedMultiVec, WshInner,
    +policy.rs - source
    1
    +2
    +3
    +4
    +5
    +6
    +7
    +8
    +9
    +10
    +11
    +12
    +13
    +14
    +15
    +16
    +17
    +18
    +19
    +20
    +21
    +22
    +23
    +24
    +25
    +26
    +27
    +28
    +29
    +30
    +31
    +32
    +33
    +34
    +35
    +36
    +37
    +38
    +39
    +40
    +41
    +42
    +43
    +44
    +45
    +46
    +47
    +48
    +49
    +50
    +51
    +52
    +53
    +54
    +55
    +56
    +57
    +58
    +59
    +60
    +61
    +62
    +63
    +64
    +65
    +66
    +67
    +68
    +69
    +70
    +71
    +72
    +73
    +74
    +75
    +76
    +77
    +78
    +79
    +80
    +81
    +82
    +83
    +84
    +85
    +86
    +87
    +88
    +89
    +90
    +91
    +92
    +93
    +94
    +95
    +96
    +97
    +98
    +99
    +100
    +101
    +102
    +103
    +104
    +105
    +106
    +107
    +108
    +109
    +110
    +111
    +112
    +113
    +114
    +115
    +116
    +117
    +118
    +119
    +120
    +121
    +122
    +123
    +124
    +125
    +126
    +127
    +128
    +129
    +130
    +131
    +132
    +133
    +134
    +135
    +136
    +137
    +138
    +139
    +140
    +141
    +142
    +143
    +144
    +145
    +146
    +147
    +148
    +149
    +150
    +151
    +152
    +153
    +154
    +155
    +156
    +157
    +158
    +159
    +160
    +161
    +162
    +163
    +164
    +165
    +166
    +167
    +168
    +169
    +170
    +171
    +172
    +173
    +174
    +175
    +176
    +177
    +178
    +179
    +180
    +181
    +182
    +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
    +245
    +246
    +247
    +248
    +249
    +250
    +251
    +252
    +253
    +254
    +255
    +256
    +257
    +258
    +259
    +260
    +261
    +262
    +263
    +264
    +265
    +266
    +267
    +268
    +269
    +270
    +271
    +272
    +273
    +274
    +275
    +276
    +277
    +278
    +279
    +280
    +281
    +282
    +283
    +284
    +285
    +286
    +287
    +288
    +289
    +290
    +291
    +292
    +293
    +294
    +295
    +296
    +297
    +298
    +299
    +300
    +301
    +302
    +303
    +304
    +305
    +306
    +307
    +308
    +309
    +310
    +311
    +312
    +313
    +314
    +315
    +316
    +317
    +318
    +319
    +320
    +321
    +322
    +323
    +324
    +325
    +326
    +327
    +328
    +329
    +330
    +331
    +332
    +333
    +334
    +335
    +336
    +337
    +338
    +339
    +340
    +341
    +342
    +343
    +344
    +345
    +346
    +347
    +348
    +349
    +350
    +351
    +352
    +353
    +354
    +355
    +356
    +357
    +358
    +359
    +360
    +361
    +362
    +363
    +364
    +365
    +366
    +367
    +368
    +369
    +370
    +371
    +372
    +373
    +374
    +375
    +376
    +377
    +378
    +379
    +380
    +381
    +382
    +383
    +384
    +385
    +386
    +387
    +388
    +389
    +390
    +391
    +392
    +393
    +394
    +395
    +396
    +397
    +398
    +399
    +400
    +401
    +402
    +403
    +404
    +405
    +406
    +407
    +408
    +409
    +410
    +411
    +412
    +413
    +414
    +415
    +416
    +417
    +418
    +419
    +420
    +421
    +422
    +423
    +424
    +425
    +426
    +427
    +428
    +429
    +430
    +431
    +432
    +433
    +434
    +435
    +436
    +437
    +438
    +439
    +440
    +441
    +442
    +443
    +444
    +445
    +446
    +447
    +448
    +449
    +450
    +451
    +452
    +453
    +454
    +455
    +456
    +457
    +458
    +459
    +460
    +461
    +462
    +463
    +464
    +465
    +466
    +467
    +468
    +469
    +470
    +471
    +472
    +473
    +474
    +475
    +476
    +477
    +478
    +479
    +480
    +481
    +482
    +483
    +484
    +485
    +486
    +487
    +488
    +489
    +490
    +491
    +492
    +493
    +494
    +495
    +496
    +497
    +498
    +499
    +500
    +501
    +502
    +503
    +504
    +505
    +506
    +507
    +508
    +509
    +510
    +511
    +512
    +513
    +514
    +515
    +516
    +517
    +518
    +519
    +520
    +521
    +522
    +523
    +524
    +525
    +526
    +527
    +528
    +529
    +530
    +531
    +532
    +533
    +534
    +535
    +536
    +537
    +538
    +539
    +540
    +541
    +542
    +543
    +544
    +545
    +546
    +547
    +548
    +549
    +550
    +551
    +552
    +553
    +554
    +555
    +556
    +557
    +558
    +559
    +560
    +561
    +562
    +563
    +564
    +565
    +566
    +567
    +568
    +569
    +570
    +571
    +572
    +573
    +574
    +575
    +576
    +577
    +578
    +579
    +580
    +581
    +582
    +583
    +584
    +585
    +586
    +587
    +588
    +589
    +590
    +591
    +592
    +593
    +594
    +595
    +596
    +597
    +598
    +599
    +600
    +601
    +602
    +603
    +604
    +605
    +606
    +607
    +608
    +609
    +610
    +611
    +612
    +613
    +614
    +615
    +616
    +617
    +618
    +619
    +620
    +621
    +622
    +623
    +624
    +625
    +626
    +627
    +628
    +629
    +630
    +631
    +632
    +633
    +634
    +635
    +636
    +637
    +638
    +639
    +640
    +641
    +642
    +643
    +644
    +645
    +646
    +647
    +648
    +649
    +650
    +651
    +652
    +653
    +654
    +655
    +656
    +657
    +658
    +659
    +660
    +661
    +662
    +663
    +664
    +665
    +666
    +667
    +668
    +669
    +670
    +671
    +672
    +673
    +674
    +675
    +676
    +677
    +678
    +679
    +680
    +681
    +682
    +683
    +684
    +685
    +686
    +687
    +688
    +689
    +690
    +691
    +692
    +693
    +694
    +695
    +696
    +697
    +698
    +699
    +700
    +701
    +702
    +703
    +704
    +705
    +706
    +707
    +708
    +709
    +710
    +711
    +712
    +713
    +714
    +715
    +716
    +717
    +718
    +719
    +720
    +721
    +722
    +723
    +724
    +725
    +726
    +727
    +728
    +729
    +730
    +731
    +732
    +733
    +734
    +735
    +736
    +737
    +738
    +739
    +740
    +741
    +742
    +743
    +744
    +745
    +746
    +747
    +748
    +749
    +750
    +751
    +752
    +753
    +754
    +755
    +756
    +757
    +758
    +759
    +760
    +761
    +762
    +763
    +764
    +765
    +766
    +767
    +768
    +769
    +770
    +771
    +772
    +773
    +774
    +775
    +776
    +777
    +778
    +779
    +780
    +781
    +782
    +783
    +784
    +785
    +786
    +787
    +788
    +789
    +790
    +791
    +792
    +793
    +794
    +795
    +796
    +797
    +798
    +799
    +800
    +801
    +802
    +803
    +804
    +805
    +806
    +807
    +808
    +809
    +810
    +811
    +812
    +813
    +814
    +815
    +816
    +817
    +818
    +819
    +820
    +821
    +822
    +823
    +824
    +825
    +826
    +827
    +828
    +829
    +830
    +831
    +832
    +833
    +834
    +835
    +836
    +837
    +838
    +839
    +840
    +841
    +842
    +843
    +844
    +845
    +846
    +847
    +848
    +849
    +850
    +851
    +852
    +853
    +854
    +855
    +856
    +857
    +858
    +859
    +860
    +861
    +862
    +863
    +864
    +865
    +866
    +867
    +868
    +869
    +870
    +871
    +872
    +873
    +874
    +875
    +876
    +877
    +878
    +879
    +880
    +881
    +882
    +883
    +884
    +885
    +886
    +887
    +888
    +889
    +890
    +891
    +892
    +893
    +894
    +895
    +896
    +897
    +898
    +899
    +900
    +901
    +902
    +903
    +904
    +905
    +906
    +907
    +908
    +909
    +910
    +911
    +912
    +913
    +914
    +915
    +916
    +917
    +918
    +919
    +920
    +921
    +922
    +923
    +924
    +925
    +926
    +927
    +928
    +929
    +930
    +931
    +932
    +933
    +934
    +935
    +936
    +937
    +938
    +939
    +940
    +941
    +942
    +943
    +944
    +945
    +946
    +947
    +948
    +949
    +950
    +951
    +952
    +953
    +954
    +955
    +956
    +957
    +958
    +959
    +960
    +961
    +962
    +963
    +964
    +965
    +966
    +967
    +968
    +969
    +970
    +971
    +972
    +973
    +974
    +975
    +976
    +977
    +978
    +979
    +980
    +981
    +982
    +983
    +984
    +985
    +986
    +987
    +988
    +989
    +990
    +991
    +992
    +993
    +994
    +995
    +996
    +997
    +998
    +999
    +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
    +1028
    +1029
    +1030
    +1031
    +1032
    +1033
    +1034
    +1035
    +1036
    +1037
    +1038
    +1039
    +1040
    +1041
    +1042
    +1043
    +1044
    +1045
    +1046
    +1047
    +1048
    +1049
    +1050
    +1051
    +1052
    +1053
    +1054
    +1055
    +1056
    +1057
    +1058
    +1059
    +1060
    +1061
    +1062
    +1063
    +1064
    +1065
    +1066
    +1067
    +1068
    +1069
    +1070
    +1071
    +1072
    +1073
    +1074
    +1075
    +1076
    +1077
    +1078
    +1079
    +1080
    +1081
    +1082
    +1083
    +1084
    +1085
    +1086
    +1087
    +1088
    +1089
    +1090
    +1091
    +1092
    +1093
    +1094
    +1095
    +1096
    +1097
    +1098
    +1099
    +1100
    +1101
    +1102
    +1103
    +1104
    +1105
    +1106
    +1107
    +1108
    +1109
    +1110
    +1111
    +1112
    +1113
    +1114
    +1115
    +1116
    +1117
    +1118
    +1119
    +1120
    +1121
    +1122
    +1123
    +1124
    +1125
    +1126
    +1127
    +1128
    +1129
    +1130
    +1131
    +1132
    +1133
    +1134
    +1135
    +1136
    +1137
    +1138
    +1139
    +1140
    +1141
    +1142
    +1143
    +1144
    +1145
    +1146
    +1147
    +1148
    +1149
    +1150
    +1151
    +1152
    +1153
    +1154
    +1155
    +1156
    +1157
    +1158
    +1159
    +1160
    +1161
    +1162
    +1163
    +1164
    +1165
    +1166
    +1167
    +1168
    +1169
    +1170
    +1171
    +1172
    +1173
    +1174
    +1175
    +1176
    +1177
    +1178
    +1179
    +1180
    +1181
    +1182
    +1183
    +1184
    +1185
    +1186
    +1187
    +1188
    +1189
    +1190
    +1191
    +1192
    +1193
    +1194
    +1195
    +1196
    +1197
    +1198
    +1199
    +1200
    +1201
    +1202
    +1203
    +1204
    +1205
    +1206
    +1207
    +1208
    +1209
    +1210
    +1211
    +1212
    +1213
    +1214
    +1215
    +1216
    +1217
    +1218
    +1219
    +1220
    +1221
    +1222
    +1223
    +1224
    +1225
    +1226
    +1227
    +1228
    +1229
    +1230
    +1231
    +1232
    +1233
    +1234
    +1235
    +1236
    +1237
    +1238
    +1239
    +1240
    +1241
    +1242
    +1243
    +1244
    +1245
    +1246
    +1247
    +1248
    +1249
    +1250
    +1251
    +1252
    +1253
    +1254
    +1255
    +1256
    +1257
    +1258
    +1259
    +1260
    +1261
    +1262
    +1263
    +1264
    +1265
    +1266
    +1267
    +1268
    +1269
    +1270
    +1271
    +1272
    +1273
    +1274
    +1275
    +1276
    +1277
    +1278
    +1279
    +1280
    +1281
    +1282
    +1283
    +1284
    +1285
    +1286
    +1287
    +1288
    +1289
    +1290
    +1291
    +1292
    +1293
    +1294
    +1295
    +1296
    +1297
    +1298
    +1299
    +1300
    +1301
    +1302
    +1303
    +1304
    +1305
    +1306
    +1307
    +1308
    +1309
    +1310
    +1311
    +1312
    +1313
    +1314
    +1315
    +1316
    +1317
    +1318
    +1319
    +1320
    +1321
    +1322
    +1323
    +1324
    +1325
    +1326
    +1327
    +1328
    +1329
    +1330
    +1331
    +1332
    +1333
    +1334
    +1335
    +1336
    +1337
    +1338
    +1339
    +1340
    +1341
    +1342
    +1343
    +1344
    +1345
    +1346
    +1347
    +1348
    +1349
    +1350
    +1351
    +1352
    +1353
    +1354
    +1355
    +1356
    +1357
    +1358
    +1359
    +1360
    +1361
    +1362
    +1363
    +1364
    +1365
    +1366
    +1367
    +1368
    +1369
    +1370
    +1371
    +1372
    +1373
    +1374
    +1375
    +1376
    +1377
    +1378
    +1379
    +1380
    +1381
    +1382
    +1383
    +1384
    +1385
    +1386
    +1387
    +1388
    +1389
    +1390
    +1391
    +1392
    +1393
    +1394
    +1395
    +1396
    +1397
    +1398
    +1399
    +1400
    +1401
    +1402
    +1403
    +1404
    +1405
    +1406
    +1407
    +1408
    +1409
    +1410
    +1411
    +1412
    +1413
    +1414
    +1415
    +1416
    +1417
    +1418
    +1419
    +1420
    +1421
    +1422
    +1423
    +1424
    +1425
    +1426
    +1427
    +1428
    +1429
    +1430
    +1431
    +1432
    +1433
    +1434
    +1435
    +1436
    +1437
    +1438
    +1439
    +1440
    +1441
    +1442
    +1443
    +1444
    +1445
    +1446
    +1447
    +1448
    +1449
    +1450
    +1451
    +1452
    +1453
    +1454
    +1455
    +1456
    +1457
    +1458
    +1459
    +1460
    +1461
    +1462
    +1463
    +1464
    +1465
    +1466
    +1467
    +1468
    +1469
    +1470
    +1471
    +1472
    +1473
    +1474
    +1475
    +1476
    +1477
    +1478
    +1479
    +1480
    +1481
    +1482
    +1483
    +1484
    +1485
    +1486
    +1487
    +1488
    +1489
    +1490
    +1491
    +1492
    +1493
    +1494
    +1495
    +1496
    +1497
    +1498
    +1499
    +1500
    +1501
    +1502
    +1503
    +1504
    +1505
    +1506
    +1507
    +1508
    +1509
    +1510
    +1511
    +1512
    +1513
    +1514
    +1515
    +1516
    +1517
    +1518
    +1519
    +1520
    +1521
    +1522
    +1523
    +1524
    +1525
    +1526
    +1527
    +1528
    +1529
    +1530
    +1531
    +1532
    +1533
    +1534
    +1535
    +1536
    +1537
    +1538
    +1539
    +1540
    +1541
    +1542
    +1543
    +1544
    +1545
    +1546
    +1547
    +1548
    +1549
    +1550
    +1551
    +1552
    +1553
    +1554
    +1555
    +1556
    +1557
    +1558
    +1559
    +1560
    +1561
    +1562
    +1563
    +1564
    +1565
    +1566
    +1567
    +1568
    +1569
    +1570
    +1571
    +1572
    +1573
    +1574
    +1575
    +1576
    +1577
    +1578
    +1579
    +1580
    +1581
    +1582
    +1583
    +1584
    +1585
    +1586
    +1587
    +1588
    +1589
    +1590
    +1591
    +1592
    +1593
    +1594
    +1595
    +1596
    +1597
    +1598
    +1599
    +1600
    +1601
    +1602
    +1603
    +1604
    +1605
    +1606
    +1607
    +1608
    +1609
    +1610
    +1611
    +1612
    +1613
    +1614
    +1615
    +1616
    +1617
    +1618
    +1619
    +1620
    +1621
    +1622
    +1623
    +1624
    +1625
    +1626
    +1627
    +1628
    +1629
    +1630
    +1631
    +1632
    +1633
    +1634
    +1635
    +1636
    +1637
    +1638
    +1639
    +1640
    +1641
    +1642
    +1643
    +1644
    +1645
    +1646
    +1647
    +1648
    +1649
    +1650
    +1651
    +1652
    +1653
    +1654
    +1655
    +1656
    +1657
    +1658
    +1659
    +1660
    +1661
    +1662
    +1663
    +1664
    +1665
    +1666
    +1667
    +1668
    +1669
    +1670
    +1671
    +1672
    +1673
    +1674
    +1675
    +1676
    +1677
    +1678
    +1679
    +1680
    +1681
    +1682
    +1683
    +1684
    +1685
    +1686
    +1687
    +1688
    +1689
    +1690
    +1691
    +1692
    +1693
    +1694
    +1695
    +1696
    +1697
    +1698
    +1699
    +1700
    +1701
    +1702
    +1703
    +1704
    +1705
    +1706
    +1707
    +1708
    +1709
    +1710
    +1711
    +1712
    +1713
    +1714
    +1715
    +1716
    +1717
    +1718
    +1719
    +1720
    +1721
    +1722
    +1723
    +1724
    +1725
    +1726
    +1727
    +1728
    +1729
    +1730
    +1731
    +1732
    +1733
    +1734
    +1735
    +1736
    +1737
    +1738
    +1739
    +1740
    +1741
    +1742
    +1743
    +1744
    +1745
    +1746
    +1747
    +1748
    +1749
    +1750
    +1751
    +1752
    +1753
    +1754
    +1755
    +1756
    +1757
    +1758
    +1759
    +1760
    +1761
    +1762
    +1763
    +1764
    +1765
    +1766
    +1767
    +1768
    +1769
    +1770
    +1771
    +1772
    +1773
    +1774
    +1775
    +1776
    +1777
    +1778
    +1779
    +1780
    +1781
    +1782
    +1783
    +1784
    +1785
    +1786
    +1787
    +1788
    +1789
    +1790
    +1791
    +1792
    +1793
    +1794
    +1795
    +1796
    +1797
    +1798
    +1799
    +1800
    +1801
    +1802
    +1803
    +1804
    +1805
    +1806
    +1807
    +1808
    +1809
    +1810
    +1811
    +1812
    +1813
    +1814
    +1815
    +1816
    +1817
    +1818
    +1819
    +1820
    +1821
    +1822
    +1823
    +1824
    +1825
    +1826
    +1827
    +1828
    +1829
    +1830
    +1831
    +1832
    +1833
    +1834
    +1835
    +1836
    +1837
    +1838
    +1839
    +1840
    +1841
    +1842
    +1843
    +1844
    +1845
    +1846
    +1847
    +1848
    +1849
    +1850
    +1851
    +1852
    +1853
    +1854
    +1855
    +1856
    +1857
    +1858
    +1859
    +1860
    +1861
    +1862
    +1863
    +1864
    +1865
    +1866
    +1867
    +1868
    +1869
    +1870
    +1871
    +1872
    +1873
    +1874
    +1875
    +1876
    +1877
    +1878
    +1879
    +1880
    +1881
    +1882
    +1883
    +1884
    +1885
    +1886
    +1887
    +1888
    +1889
    +1890
    +1891
    +1892
    +1893
    +1894
    +1895
    +1896
    +1897
    +1898
    +1899
    +1900
    +1901
    +1902
    +1903
    +1904
    +1905
    +1906
    +1907
    +1908
    +1909
    +1910
    +1911
    +1912
    +1913
    +1914
    +1915
    +1916
    +1917
    +1918
    +1919
    +1920
    +1921
    +1922
    +
    // Bitcoin Dev Kit
    +// Written in 2020 by Alekos Filini <alekos.filini@gmail.com>
    +//
    +// Copyright (c) 2020-2021 Bitcoin Dev Kit Developers
    +//
    +// This file is licensed under the Apache License, Version 2.0 <LICENSE-APACHE
    +// or http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
    +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your option.
    +// You may not use this file except in accordance with one or both of these
    +// licenses.
    +
    +//! Descriptor policy
    +//!
    +//! This module implements the logic to extract and represent the spending policies of a descriptor
    +//! in a more human-readable format.
    +//!
    +//! This is an **EXPERIMENTAL** feature, API and other major changes are expected.
    +//!
    +//! ## Example
    +//!
    +//! ```
    +//! # use std::sync::Arc;
    +//! # use bdk::descriptor::*;
    +//! # use bdk::wallet::signer::*;
    +//! # use bdk::bitcoin::secp256k1::Secp256k1;
    +//! use bdk::descriptor::policy::BuildSatisfaction;
    +//! let secp = Secp256k1::new();
    +//! let desc = "wsh(and_v(v:pk(cV3oCth6zxZ1UVsHLnGothsWNsaoxRhC6aeNi5VbSdFpwUkgkEci),or_d(pk(cVMTy7uebJgvFaSBwcgvwk8qn8xSLc97dKow4MBetjrrahZoimm2),older(12960))))";
    +//!
    +//! let (extended_desc, key_map) = ExtendedDescriptor::parse_descriptor(&secp, desc)?;
    +//! println!("{:?}", extended_desc);
    +//!
    +//! let signers = Arc::new(SignersContainer::build(key_map, &extended_desc, &secp));
    +//! let policy = extended_desc.extract_policy(&signers, BuildSatisfaction::None, &secp)?;
    +//! println!("policy: {}", serde_json::to_string(&policy)?);
    +//! # Ok::<(), bdk::Error>(())
    +//! ```
    +
    +use std::cmp::max;
    +use std::collections::{BTreeMap, HashSet, VecDeque};
    +use std::fmt;
    +
    +use serde::ser::SerializeMap;
    +use serde::{Serialize, Serializer};
    +
    +use bitcoin::hashes::{hash160, ripemd160, sha256};
    +use bitcoin::util::bip32::Fingerprint;
    +use bitcoin::{LockTime, PublicKey, Sequence, XOnlyPublicKey};
    +
    +use miniscript::descriptor::{
    +    DescriptorPublicKey, ShInner, SinglePub, SinglePubKey, SortedMultiVec, WshInner,
     };
    -use miniscript::hash256;
    -use miniscript::{
    -    Descriptor, Miniscript, Satisfier, ScriptContext, SigType, Terminal, ToPublicKey,
    +use miniscript::hash256;
    +use miniscript::{
    +    Descriptor, Miniscript, Satisfier, ScriptContext, SigType, Terminal, ToPublicKey,
     };
     
    -#[allow(unused_imports)]
    -use log::{debug, error, info, trace};
    -
    -use crate::descriptor::ExtractPolicy;
    -use crate::keys::ExtScriptContext;
    -use crate::wallet::signer::{SignerId, SignersContainer};
    -use crate::wallet::utils::{After, Older, SecpCtx};
    -
    -use super::checksum::calc_checksum;
    -use super::error::Error;
    -use super::XKeyUtils;
    -use bitcoin::util::psbt::{Input as PsbtInput, PartiallySignedTransaction as Psbt};
    -use miniscript::psbt::PsbtInputSatisfier;
    -
    -/// A unique identifier for a key
    -#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize)]
    -#[serde(rename_all = "snake_case")]
    -pub enum PkOrF {
    -    /// A legacy public key
    -    Pubkey(PublicKey),
    -    /// A x-only public key
    -    XOnlyPubkey(XOnlyPublicKey),
    -    /// An extended key fingerprint
    -    Fingerprint(Fingerprint),
    +#[allow(unused_imports)]
    +use log::{debug, error, info, trace};
    +
    +use crate::descriptor::ExtractPolicy;
    +use crate::keys::ExtScriptContext;
    +use crate::wallet::signer::{SignerId, SignersContainer};
    +use crate::wallet::utils::{After, Older, SecpCtx};
    +
    +use super::checksum::calc_checksum;
    +use super::error::Error;
    +use super::XKeyUtils;
    +use bitcoin::util::psbt::{Input as PsbtInput, PartiallySignedTransaction as Psbt};
    +use miniscript::psbt::PsbtInputSatisfier;
    +
    +/// A unique identifier for a key
    +#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize)]
    +#[serde(rename_all = "snake_case")]
    +pub enum PkOrF {
    +    /// A legacy public key
    +    Pubkey(PublicKey),
    +    /// A x-only public key
    +    XOnlyPubkey(XOnlyPublicKey),
    +    /// An extended key fingerprint
    +    Fingerprint(Fingerprint),
     }
     
    -impl PkOrF {
    -    fn from_key(k: &DescriptorPublicKey, secp: &SecpCtx) -> Self {
    -        match k {
    -            DescriptorPublicKey::Single(SinglePub {
    -                key: SinglePubKey::FullKey(pk),
    +impl PkOrF {
    +    fn from_key(k: &DescriptorPublicKey, secp: &SecpCtx) -> Self {
    +        match k {
    +            DescriptorPublicKey::Single(SinglePub {
    +                key: SinglePubKey::FullKey(pk),
                     ..
    -            }) => PkOrF::Pubkey(*pk),
    -            DescriptorPublicKey::Single(SinglePub {
    -                key: SinglePubKey::XOnly(pk),
    +            }) => PkOrF::Pubkey(*pk),
    +            DescriptorPublicKey::Single(SinglePub {
    +                key: SinglePubKey::XOnly(pk),
                     ..
    -            }) => PkOrF::XOnlyPubkey(*pk),
    -            DescriptorPublicKey::XPub(xpub) => PkOrF::Fingerprint(xpub.root_fingerprint(secp)),
    +            }) => PkOrF::XOnlyPubkey(*pk),
    +            DescriptorPublicKey::XPub(xpub) => PkOrF::Fingerprint(xpub.root_fingerprint(secp)),
             }
         }
     }
     
    -/// An item that needs to be satisfied
    -#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
    -#[serde(tag = "type", rename_all = "UPPERCASE")]
    -pub enum SatisfiableItem {
    -    // Leaves
    -    /// ECDSA Signature for a raw public key
    -    EcdsaSignature(PkOrF),
    -    /// Schnorr Signature for a raw public key
    -    SchnorrSignature(PkOrF),
    -    /// SHA256 preimage hash
    -    Sha256Preimage {
    -        /// The digest value
    -        hash: sha256::Hash,
    +/// An item that needs to be satisfied
    +#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
    +#[serde(tag = "type", rename_all = "UPPERCASE")]
    +pub enum SatisfiableItem {
    +    // Leaves
    +    /// ECDSA Signature for a raw public key
    +    EcdsaSignature(PkOrF),
    +    /// Schnorr Signature for a raw public key
    +    SchnorrSignature(PkOrF),
    +    /// SHA256 preimage hash
    +    Sha256Preimage {
    +        /// The digest value
    +        hash: sha256::Hash,
         },
    -    /// Double SHA256 preimage hash
    -    Hash256Preimage {
    -        /// The digest value
    -        hash: hash256::Hash,
    +    /// Double SHA256 preimage hash
    +    Hash256Preimage {
    +        /// The digest value
    +        hash: hash256::Hash,
         },
    -    /// RIPEMD160 preimage hash
    -    Ripemd160Preimage {
    -        /// The digest value
    -        hash: ripemd160::Hash,
    +    /// RIPEMD160 preimage hash
    +    Ripemd160Preimage {
    +        /// The digest value
    +        hash: ripemd160::Hash,
         },
    -    /// SHA256 then RIPEMD160 preimage hash
    -    Hash160Preimage {
    -        /// The digest value
    -        hash: hash160::Hash,
    +    /// SHA256 then RIPEMD160 preimage hash
    +    Hash160Preimage {
    +        /// The digest value
    +        hash: hash160::Hash,
         },
    -    /// Absolute timeclock timestamp
    -    AbsoluteTimelock {
    -        /// The timelock value
    -        value: LockTime,
    +    /// Absolute timeclock timestamp
    +    AbsoluteTimelock {
    +        /// The timelock value
    +        value: LockTime,
         },
    -    /// Relative timelock locktime
    -    RelativeTimelock {
    -        /// The timelock value
    -        value: Sequence,
    +    /// Relative timelock locktime
    +    RelativeTimelock {
    +        /// The timelock value
    +        value: Sequence,
         },
    -    /// Multi-signature public keys with threshold count
    -    Multisig {
    -        /// The raw public key or extended key fingerprint
    -        keys: Vec<PkOrF>,
    -        /// The required threshold count
    -        threshold: usize,
    +    /// Multi-signature public keys with threshold count
    +    Multisig {
    +        /// The raw public key or extended key fingerprint
    +        keys: Vec<PkOrF>,
    +        /// The required threshold count
    +        threshold: usize,
         },
     
    -    // Complex item
    -    /// Threshold items with threshold count
    -    Thresh {
    -        /// The policy items
    -        items: Vec<Policy>,
    -        /// The required threshold count
    -        threshold: usize,
    +    // Complex item
    +    /// Threshold items with threshold count
    +    Thresh {
    +        /// The policy items
    +        items: Vec<Policy>,
    +        /// The required threshold count
    +        threshold: usize,
         },
     }
     
    -impl SatisfiableItem {
    -    /// Returns whether the [`SatisfiableItem`] is a leaf item
    -    pub fn is_leaf(&self) -> bool {
    -        !matches!(
    +impl SatisfiableItem {
    +    /// Returns whether the [`SatisfiableItem`] is a leaf item
    +    pub fn is_leaf(&self) -> bool {
    +        !matches!(
                 self,
    -            SatisfiableItem::Thresh {
    -                items: _,
    -                threshold: _,
    +            SatisfiableItem::Thresh {
    +                items: _,
    +                threshold: _,
                 }
             )
         }
     
    -    /// Returns a unique id for the [`SatisfiableItem`]
    -    pub fn id(&self) -> String {
    -        calc_checksum(&serde_json::to_string(self).expect("Failed to serialize a SatisfiableItem"))
    -            .expect("Failed to compute a SatisfiableItem id")
    +    /// Returns a unique id for the [`SatisfiableItem`]
    +    pub fn id(&self) -> String {
    +        calc_checksum(&serde_json::to_string(self).expect("Failed to serialize a SatisfiableItem"))
    +            .expect("Failed to compute a SatisfiableItem id")
         }
     }
     
    -fn combinations(vec: &[usize], size: usize) -> Vec<Vec<usize>> {
    -    assert!(vec.len() >= size);
    +fn combinations(vec: &[usize], size: usize) -> Vec<Vec<usize>> {
    +    assert!(vec.len() >= size);
     
    -    let mut answer = Vec::new();
    +    let mut answer = Vec::new();
     
    -    let mut queue = VecDeque::new();
    -    for (index, val) in vec.iter().enumerate() {
    -        let mut new_vec = Vec::with_capacity(size);
    -        new_vec.push(*val);
    -        queue.push_back((index, new_vec));
    +    let mut queue = VecDeque::new();
    +    for (index, val) in vec.iter().enumerate() {
    +        let mut new_vec = Vec::with_capacity(size);
    +        new_vec.push(*val);
    +        queue.push_back((index, new_vec));
         }
     
    -    while let Some((index, vals)) = queue.pop_front() {
    -        if vals.len() >= size {
    -            answer.push(vals);
    -        } else {
    -            for (new_index, val) in vec.iter().skip(index + 1).enumerate() {
    -                let mut cloned = vals.clone();
    -                cloned.push(*val);
    -                queue.push_front((new_index, cloned));
    +    while let Some((index, vals)) = queue.pop_front() {
    +        if vals.len() >= size {
    +            answer.push(vals);
    +        } else {
    +            for (new_index, val) in vec.iter().skip(index + 1).enumerate() {
    +                let mut cloned = vals.clone();
    +                cloned.push(*val);
    +                queue.push_front((new_index, cloned));
                 }
             }
         }
     
    -    answer
    +    answer
     }
     
    -fn mix<T: Clone>(vec: Vec<Vec<T>>) -> Vec<Vec<T>> {
    -    if vec.is_empty() || vec.iter().any(Vec::is_empty) {
    -        return vec![];
    +fn mix<T: Clone>(vec: Vec<Vec<T>>) -> Vec<Vec<T>> {
    +    if vec.is_empty() || vec.iter().any(Vec::is_empty) {
    +        return vec![];
         }
     
    -    let mut answer = Vec::new();
    -    let size = vec.len();
    +    let mut answer = Vec::new();
    +    let size = vec.len();
     
    -    let mut queue = VecDeque::new();
    -    for i in &vec[0] {
    -        let mut new_vec = Vec::with_capacity(size);
    -        new_vec.push(i.clone());
    -        queue.push_back(new_vec);
    +    let mut queue = VecDeque::new();
    +    for i in &vec[0] {
    +        let mut new_vec = Vec::with_capacity(size);
    +        new_vec.push(i.clone());
    +        queue.push_back(new_vec);
         }
     
    -    while let Some(vals) = queue.pop_front() {
    -        if vals.len() >= size {
    -            answer.push(vals);
    -        } else {
    -            let level = vals.len();
    -            for i in &vec[level] {
    -                let mut cloned = vals.clone();
    -                cloned.push(i.clone());
    -                queue.push_front(cloned);
    +    while let Some(vals) = queue.pop_front() {
    +        if vals.len() >= size {
    +            answer.push(vals);
    +        } else {
    +            let level = vals.len();
    +            for i in &vec[level] {
    +                let mut cloned = vals.clone();
    +                cloned.push(i.clone());
    +                queue.push_front(cloned);
                 }
             }
         }
     
    -    answer
    +    answer
     }
     
    -/// Type for a map of sets of [`Condition`] items keyed by each set's index
    -pub type ConditionMap = BTreeMap<usize, HashSet<Condition>>;
    -/// Type for a map of folded sets of [`Condition`] items keyed by a vector of the combined set's indexes
    -pub type FoldedConditionMap = BTreeMap<Vec<usize>, HashSet<Condition>>;
    -
    -fn serialize_folded_cond_map<S>(
    -    input_map: &FoldedConditionMap,
    -    serializer: S,
    -) -> Result<S::Ok, S::Error>
    -where
    -    S: Serializer,
    +/// Type for a map of sets of [`Condition`] items keyed by each set's index
    +pub type ConditionMap = BTreeMap<usize, HashSet<Condition>>;
    +/// Type for a map of folded sets of [`Condition`] items keyed by a vector of the combined set's indexes
    +pub type FoldedConditionMap = BTreeMap<Vec<usize>, HashSet<Condition>>;
    +
    +fn serialize_folded_cond_map<S>(
    +    input_map: &FoldedConditionMap,
    +    serializer: S,
    +) -> Result<S::Ok, S::Error>
    +where
    +    S: Serializer,
     {
    -    let mut map = serializer.serialize_map(Some(input_map.len()))?;
    -    for (k, v) in input_map {
    -        let k_string = format!("{:?}", k);
    -        map.serialize_entry(&k_string, v)?;
    +    let mut map = serializer.serialize_map(Some(input_map.len()))?;
    +    for (k, v) in input_map {
    +        let k_string = format!("{:?}", k);
    +        map.serialize_entry(&k_string, v)?;
         }
    -    map.end()
    +    map.end()
     }
     
    -/// Represent if and how much a policy item is satisfied by the wallet's descriptor
    -#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
    -#[serde(tag = "type", rename_all = "UPPERCASE")]
    -pub enum Satisfaction {
    -    /// Only a partial satisfaction of some kind of threshold policy
    -    Partial {
    -        /// Total number of items
    -        n: usize,
    -        /// Threshold
    -        m: usize,
    -        /// The items that can be satisfied by the descriptor or are satisfied in the PSBT
    -        items: Vec<usize>,
    -        #[serde(skip_serializing_if = "Option::is_none")]
    -        /// Whether the items are sorted in lexicographic order (used by `sortedmulti`)
    -        sorted: Option<bool>,
    -        #[serde(skip_serializing_if = "BTreeMap::is_empty")]
    -        /// Extra conditions that also need to be satisfied
    -        conditions: ConditionMap,
    +/// Represent if and how much a policy item is satisfied by the wallet's descriptor
    +#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
    +#[serde(tag = "type", rename_all = "UPPERCASE")]
    +pub enum Satisfaction {
    +    /// Only a partial satisfaction of some kind of threshold policy
    +    Partial {
    +        /// Total number of items
    +        n: usize,
    +        /// Threshold
    +        m: usize,
    +        /// The items that can be satisfied by the descriptor or are satisfied in the PSBT
    +        items: Vec<usize>,
    +        #[serde(skip_serializing_if = "Option::is_none")]
    +        /// Whether the items are sorted in lexicographic order (used by `sortedmulti`)
    +        sorted: Option<bool>,
    +        #[serde(skip_serializing_if = "BTreeMap::is_empty")]
    +        /// Extra conditions that also need to be satisfied
    +        conditions: ConditionMap,
         },
    -    /// Can reach the threshold of some kind of threshold policy
    -    PartialComplete {
    -        /// Total number of items
    -        n: usize,
    -        /// Threshold
    -        m: usize,
    -        /// The items that can be satisfied by the descriptor
    -        items: Vec<usize>,
    -        #[serde(skip_serializing_if = "Option::is_none")]
    -        /// Whether the items are sorted in lexicographic order (used by `sortedmulti`)
    -        sorted: Option<bool>,
    -        #[serde(
    -            serialize_with = "serialize_folded_cond_map",
    -            skip_serializing_if = "BTreeMap::is_empty"
    -        )]
    -        /// Extra conditions that also need to be satisfied
    -        conditions: FoldedConditionMap,
    +    /// Can reach the threshold of some kind of threshold policy
    +    PartialComplete {
    +        /// Total number of items
    +        n: usize,
    +        /// Threshold
    +        m: usize,
    +        /// The items that can be satisfied by the descriptor
    +        items: Vec<usize>,
    +        #[serde(skip_serializing_if = "Option::is_none")]
    +        /// Whether the items are sorted in lexicographic order (used by `sortedmulti`)
    +        sorted: Option<bool>,
    +        #[serde(
    +            serialize_with = "serialize_folded_cond_map",
    +            skip_serializing_if = "BTreeMap::is_empty"
    +        )]
    +        /// Extra conditions that also need to be satisfied
    +        conditions: FoldedConditionMap,
         },
     
    -    /// Can satisfy the policy item
    -    Complete {
    -        /// Extra conditions that also need to be satisfied
    -        condition: Condition,
    +    /// Can satisfy the policy item
    +    Complete {
    +        /// Extra conditions that also need to be satisfied
    +        condition: Condition,
         },
    -    /// Cannot satisfy or contribute to the policy item
    -    None,
    +    /// Cannot satisfy or contribute to the policy item
    +    None,
     }
     
    -impl Satisfaction {
    -    /// Returns whether the [`Satisfaction`] is a leaf item
    -    pub fn is_leaf(&self) -> bool {
    -        match self {
    -            Satisfaction::None | Satisfaction::Complete { .. } => true,
    -            Satisfaction::PartialComplete { .. } | Satisfaction::Partial { .. } => false,
    +impl Satisfaction {
    +    /// Returns whether the [`Satisfaction`] is a leaf item
    +    pub fn is_leaf(&self) -> bool {
    +        match self {
    +            Satisfaction::None | Satisfaction::Complete { .. } => true,
    +            Satisfaction::PartialComplete { .. } | Satisfaction::Partial { .. } => false,
             }
         }
     
    -    // add `inner` as one of self's partial items. this only makes sense on partials
    -    fn add(&mut self, inner: &Satisfaction, inner_index: usize) -> Result<(), PolicyError> {
    -        match self {
    -            Satisfaction::None | Satisfaction::Complete { .. } => Err(PolicyError::AddOnLeaf),
    -            Satisfaction::PartialComplete { .. } => Err(PolicyError::AddOnPartialComplete),
    -            Satisfaction::Partial {
    -                n,
    -                ref mut conditions,
    -                ref mut items,
    +    // add `inner` as one of self's partial items. this only makes sense on partials
    +    fn add(&mut self, inner: &Satisfaction, inner_index: usize) -> Result<(), PolicyError> {
    +        match self {
    +            Satisfaction::None | Satisfaction::Complete { .. } => Err(PolicyError::AddOnLeaf),
    +            Satisfaction::PartialComplete { .. } => Err(PolicyError::AddOnPartialComplete),
    +            Satisfaction::Partial {
    +                n,
    +                ref mut conditions,
    +                ref mut items,
                     ..
                 } => {
    -                if inner_index >= *n || items.contains(&inner_index) {
    -                    return Err(PolicyError::IndexOutOfRange(inner_index));
    +                if inner_index >= *n || items.contains(&inner_index) {
    +                    return Err(PolicyError::IndexOutOfRange(inner_index));
                     }
     
    -                match inner {
    -                    // not relevant if not completed yet
    -                    Satisfaction::None | Satisfaction::Partial { .. } => return Ok(()),
    -                    Satisfaction::Complete { condition } => {
    -                        items.push(inner_index);
    -                        conditions.insert(inner_index, vec![*condition].into_iter().collect());
    +                match inner {
    +                    // not relevant if not completed yet
    +                    Satisfaction::None | Satisfaction::Partial { .. } => return Ok(()),
    +                    Satisfaction::Complete { condition } => {
    +                        items.push(inner_index);
    +                        conditions.insert(inner_index, vec![*condition].into_iter().collect());
                         }
    -                    Satisfaction::PartialComplete {
    -                        conditions: other_conditions,
    +                    Satisfaction::PartialComplete {
    +                        conditions: other_conditions,
                             ..
                         } => {
    -                        items.push(inner_index);
    -                        let conditions_set = other_conditions
    -                            .values()
    -                            .fold(HashSet::new(), |set, i| set.union(i).cloned().collect());
    -                        conditions.insert(inner_index, conditions_set);
    +                        items.push(inner_index);
    +                        let conditions_set = other_conditions
    +                            .values()
    +                            .fold(HashSet::new(), |set, i| set.union(i).cloned().collect());
    +                        conditions.insert(inner_index, conditions_set);
                         }
                     }
     
    @@ -2275,1580 +2269,1579 @@
             }
         }
     
    -    fn finalize(&mut self) {
    -        // if partial try to bump it to a partialcomplete
    -        if let Satisfaction::Partial {
    -            n,
    -            m,
    -            items,
    -            conditions,
    -            sorted,
    -        } = self
    -        {
    -            if items.len() >= *m {
    -                let mut map = BTreeMap::new();
    -                let indexes = combinations(items, *m);
    -                // `indexes` at this point is a Vec<Vec<usize>>, with the "n choose k" of items (m of n)
    -                indexes
    -                    .into_iter()
    -                    // .inspect(|x| println!("--- orig --- {:?}", x))
    -                    // we map each of the combinations of elements into a tuple of ([chosen items], [conditions]). unfortunately, those items have potentially more than one
    -                    // condition (think about ORs), so we also use `mix` to expand those, i.e. [[0], [1, 2]] becomes [[0, 1], [0, 2]]. This is necessary to make sure that we
    -                    // consider every possible options and check whether or not they are compatible.
    -                    // since this step can turn one item of the iterator into multiple ones, we use `flat_map()` to expand them out
    -                    .flat_map(|i_vec| {
    -                        mix(i_vec
    -                            .iter()
    -                            .map(|i| {
    -                                conditions
    -                                    .get(i)
    -                                    .map(|set| set.clone().into_iter().collect())
    -                                    .unwrap_or_default()
    +    fn finalize(&mut self) {
    +        // if partial try to bump it to a partialcomplete
    +        if let Satisfaction::Partial {
    +            n,
    +            m,
    +            items,
    +            conditions,
    +            sorted,
    +        } = self
    +        {
    +            if items.len() >= *m {
    +                let mut map = BTreeMap::new();
    +                let indexes = combinations(items, *m);
    +                // `indexes` at this point is a Vec<Vec<usize>>, with the "n choose k" of items (m of n)
    +                indexes
    +                    .into_iter()
    +                    // .inspect(|x| println!("--- orig --- {:?}", x))
    +                    // we map each of the combinations of elements into a tuple of ([chosen items], [conditions]). unfortunately, those items have potentially more than one
    +                    // condition (think about ORs), so we also use `mix` to expand those, i.e. [[0], [1, 2]] becomes [[0, 1], [0, 2]]. This is necessary to make sure that we
    +                    // consider every possible options and check whether or not they are compatible.
    +                    // since this step can turn one item of the iterator into multiple ones, we use `flat_map()` to expand them out
    +                    .flat_map(|i_vec| {
    +                        mix(i_vec
    +                            .iter()
    +                            .map(|i| {
    +                                conditions
    +                                    .get(i)
    +                                    .map(|set| set.clone().into_iter().collect())
    +                                    .unwrap_or_default()
                                 })
    -                            .collect())
    -                        .into_iter()
    -                        .map(|x| (i_vec.clone(), x))
    -                        .collect::<Vec<(Vec<usize>, Vec<Condition>)>>()
    +                            .collect())
    +                        .into_iter()
    +                        .map(|x| (i_vec.clone(), x))
    +                        .collect::<Vec<(Vec<usize>, Vec<Condition>)>>()
                         })
    -                    // .inspect(|x| println!("flat {:?}", x))
    -                    // try to fold all the conditions for this specific combination of indexes/options. if they are not compatible, try_fold will be Err
    -                    .map(|(key, val)| {
    +                    // .inspect(|x| println!("flat {:?}", x))
    +                    // try to fold all the conditions for this specific combination of indexes/options. if they are not compatible, try_fold will be Err
    +                    .map(|(key, val)| {
                             (
    -                            key,
    -                            val.into_iter()
    -                                .try_fold(Condition::default(), |acc, v| acc.merge(&v)),
    +                            key,
    +                            val.into_iter()
    +                                .try_fold(Condition::default(), |acc, v| acc.merge(&v)),
                             )
                         })
    -                    // .inspect(|x| println!("try_fold {:?}", x))
    -                    // filter out all the incompatible combinations
    -                    .filter(|(_, val)| val.is_ok())
    -                    // .inspect(|x| println!("filter {:?}", x))
    -                    // push them into the map
    -                    .for_each(|(key, val)| {
    -                        map.entry(key)
    -                            .or_insert_with(HashSet::new)
    -                            .insert(val.unwrap());
    +                    // .inspect(|x| println!("try_fold {:?}", x))
    +                    // filter out all the incompatible combinations
    +                    .filter(|(_, val)| val.is_ok())
    +                    // .inspect(|x| println!("filter {:?}", x))
    +                    // push them into the map
    +                    .for_each(|(key, val)| {
    +                        map.entry(key)
    +                            .or_insert_with(HashSet::new)
    +                            .insert(val.unwrap());
                         });
    -                // TODO: if the map is empty, the conditions are not compatible, return an error?
    -                *self = Satisfaction::PartialComplete {
    -                    n: *n,
    -                    m: *m,
    -                    items: items.clone(),
    -                    conditions: map,
    -                    sorted: *sorted,
    +                // TODO: if the map is empty, the conditions are not compatible, return an error?
    +                *self = Satisfaction::PartialComplete {
    +                    n: *n,
    +                    m: *m,
    +                    items: items.clone(),
    +                    conditions: map,
    +                    sorted: *sorted,
                     };
                 }
             }
         }
     }
     
    -impl From<bool> for Satisfaction {
    -    fn from(other: bool) -> Self {
    -        if other {
    -            Satisfaction::Complete {
    -                condition: Default::default(),
    +impl From<bool> for Satisfaction {
    +    fn from(other: bool) -> Self {
    +        if other {
    +            Satisfaction::Complete {
    +                condition: Default::default(),
                 }
    -        } else {
    -            Satisfaction::None
    +        } else {
    +            Satisfaction::None
             }
         }
     }
     
    -/// Descriptor spending policy
    -#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
    -pub struct Policy {
    -    /// Identifier for this policy node
    -    pub id: String,
    -
    -    /// Type of this policy node
    -    #[serde(flatten)]
    -    pub item: SatisfiableItem,
    -    /// How much a given PSBT already satisfies this policy node in terms of signatures
    -    pub satisfaction: Satisfaction,
    -    /// How the wallet's descriptor can satisfy this policy node
    -    pub contribution: Satisfaction,
    +/// Descriptor spending policy
    +#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
    +pub struct Policy {
    +    /// Identifier for this policy node
    +    pub id: String,
    +
    +    /// Type of this policy node
    +    #[serde(flatten)]
    +    pub item: SatisfiableItem,
    +    /// How much a given PSBT already satisfies this policy node in terms of signatures
    +    pub satisfaction: Satisfaction,
    +    /// How the wallet's descriptor can satisfy this policy node
    +    pub contribution: Satisfaction,
     }
     
    -/// An extra condition that must be satisfied but that is out of control of the user
    -/// TODO: use `bitcoin::LockTime` and `bitcoin::Sequence`
    -#[derive(Hash, Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Default, Serialize)]
    -pub struct Condition {
    -    /// Optional CheckSequenceVerify condition
    -    #[serde(skip_serializing_if = "Option::is_none")]
    -    pub csv: Option<Sequence>,
    -    /// Optional timelock condition
    -    #[serde(skip_serializing_if = "Option::is_none")]
    -    pub timelock: Option<LockTime>,
    +/// An extra condition that must be satisfied but that is out of control of the user
    +/// TODO: use `bitcoin::LockTime` and `bitcoin::Sequence`
    +#[derive(Hash, Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Default, Serialize)]
    +pub struct Condition {
    +    /// Optional CheckSequenceVerify condition
    +    #[serde(skip_serializing_if = "Option::is_none")]
    +    pub csv: Option<Sequence>,
    +    /// Optional timelock condition
    +    #[serde(skip_serializing_if = "Option::is_none")]
    +    pub timelock: Option<LockTime>,
     }
     
    -impl Condition {
    -    fn merge_nlocktime(a: LockTime, b: LockTime) -> Result<LockTime, PolicyError> {
    -        if !a.is_same_unit(b) {
    -            Err(PolicyError::MixedTimelockUnits)
    -        } else if a > b {
    -            Ok(a)
    -        } else {
    -            Ok(b)
    +impl Condition {
    +    fn merge_nlocktime(a: LockTime, b: LockTime) -> Result<LockTime, PolicyError> {
    +        if !a.is_same_unit(b) {
    +            Err(PolicyError::MixedTimelockUnits)
    +        } else if a > b {
    +            Ok(a)
    +        } else {
    +            Ok(b)
             }
         }
     
    -    fn merge_nsequence(a: Sequence, b: Sequence) -> Result<Sequence, PolicyError> {
    -        if a.is_time_locked() != b.is_time_locked() {
    -            Err(PolicyError::MixedTimelockUnits)
    -        } else {
    -            Ok(max(a, b))
    +    fn merge_nsequence(a: Sequence, b: Sequence) -> Result<Sequence, PolicyError> {
    +        if a.is_time_locked() != b.is_time_locked() {
    +            Err(PolicyError::MixedTimelockUnits)
    +        } else {
    +            Ok(max(a, b))
             }
         }
     
    -    pub(crate) fn merge(mut self, other: &Condition) -> Result<Self, PolicyError> {
    -        match (self.csv, other.csv) {
    -            (Some(a), Some(b)) => self.csv = Some(Self::merge_nsequence(a, b)?),
    -            (None, any) => self.csv = any,
    -            _ => {}
    +    pub(crate) fn merge(mut self, other: &Condition) -> Result<Self, PolicyError> {
    +        match (self.csv, other.csv) {
    +            (Some(a), Some(b)) => self.csv = Some(Self::merge_nsequence(a, b)?),
    +            (None, any) => self.csv = any,
    +            _ => {}
             }
     
    -        match (self.timelock, other.timelock) {
    -            (Some(a), Some(b)) => self.timelock = Some(Self::merge_nlocktime(a, b)?),
    -            (None, any) => self.timelock = any,
    -            _ => {}
    +        match (self.timelock, other.timelock) {
    +            (Some(a), Some(b)) => self.timelock = Some(Self::merge_nlocktime(a, b)?),
    +            (None, any) => self.timelock = any,
    +            _ => {}
             }
     
             Ok(self)
         }
     
    -    /// Returns `true` if there are no extra conditions to verify
    -    pub fn is_null(&self) -> bool {
    -        self.csv.is_none() && self.timelock.is_none()
    +    /// Returns `true` if there are no extra conditions to verify
    +    pub fn is_null(&self) -> bool {
    +        self.csv.is_none() && self.timelock.is_none()
         }
     }
     
    -/// Errors that can happen while extracting and manipulating policies
    -#[derive(Debug, PartialEq, Eq)]
    -pub enum PolicyError {
    -    /// Not enough items are selected to satisfy a [`SatisfiableItem::Thresh`] or a [`SatisfiableItem::Multisig`]
    -    NotEnoughItemsSelected(String),
    -    /// Index out of range for an item to satisfy a [`SatisfiableItem::Thresh`] or a [`SatisfiableItem::Multisig`]
    -    IndexOutOfRange(usize),
    -    /// Can not add to an item that is [`Satisfaction::None`] or [`Satisfaction::Complete`]
    -    AddOnLeaf,
    -    /// Can not add to an item that is [`Satisfaction::PartialComplete`]
    -    AddOnPartialComplete,
    -    /// Can not merge CSV or timelock values unless both are less than or both are equal or greater than 500_000_000
    -    MixedTimelockUnits,
    -    /// Incompatible conditions (not currently used)
    -    IncompatibleConditions,
    +/// Errors that can happen while extracting and manipulating policies
    +#[derive(Debug, PartialEq, Eq)]
    +pub enum PolicyError {
    +    /// Not enough items are selected to satisfy a [`SatisfiableItem::Thresh`] or a [`SatisfiableItem::Multisig`]
    +    NotEnoughItemsSelected(String),
    +    /// Index out of range for an item to satisfy a [`SatisfiableItem::Thresh`] or a [`SatisfiableItem::Multisig`]
    +    IndexOutOfRange(usize),
    +    /// Can not add to an item that is [`Satisfaction::None`] or [`Satisfaction::Complete`]
    +    AddOnLeaf,
    +    /// Can not add to an item that is [`Satisfaction::PartialComplete`]
    +    AddOnPartialComplete,
    +    /// Can not merge CSV or timelock values unless both are less than or both are equal or greater than 500_000_000
    +    MixedTimelockUnits,
    +    /// Incompatible conditions (not currently used)
    +    IncompatibleConditions,
     }
     
    -impl fmt::Display for PolicyError {
    -    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
    -        write!(f, "{:?}", self)
    +impl fmt::Display for PolicyError {
    +    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
    +        write!(f, "{:?}", self)
         }
     }
     
    -impl std::error::Error for PolicyError {}
    +impl std::error::Error for PolicyError {}
     
    -impl Policy {
    -    fn new(item: SatisfiableItem) -> Self {
    -        Policy {
    -            id: item.id(),
    -            item,
    -            satisfaction: Satisfaction::None,
    -            contribution: Satisfaction::None,
    +impl Policy {
    +    fn new(item: SatisfiableItem) -> Self {
    +        Policy {
    +            id: item.id(),
    +            item,
    +            satisfaction: Satisfaction::None,
    +            contribution: Satisfaction::None,
             }
         }
     
    -    fn make_and(a: Option<Policy>, b: Option<Policy>) -> Result<Option<Policy>, PolicyError> {
    -        match (a, b) {
    +    fn make_and(a: Option<Policy>, b: Option<Policy>) -> Result<Option<Policy>, PolicyError> {
    +        match (a, b) {
                 (None, None) => Ok(None),
    -            (Some(x), None) | (None, Some(x)) => Ok(Some(x)),
    -            (Some(a), Some(b)) => Self::make_thresh(vec![a, b], 2),
    +            (Some(x), None) | (None, Some(x)) => Ok(Some(x)),
    +            (Some(a), Some(b)) => Self::make_thresh(vec![a, b], 2),
             }
         }
     
    -    fn make_or(a: Option<Policy>, b: Option<Policy>) -> Result<Option<Policy>, PolicyError> {
    -        match (a, b) {
    +    fn make_or(a: Option<Policy>, b: Option<Policy>) -> Result<Option<Policy>, PolicyError> {
    +        match (a, b) {
                 (None, None) => Ok(None),
    -            (Some(x), None) | (None, Some(x)) => Ok(Some(x)),
    -            (Some(a), Some(b)) => Self::make_thresh(vec![a, b], 1),
    +            (Some(x), None) | (None, Some(x)) => Ok(Some(x)),
    +            (Some(a), Some(b)) => Self::make_thresh(vec![a, b], 1),
             }
         }
     
    -    fn make_thresh(items: Vec<Policy>, threshold: usize) -> Result<Option<Policy>, PolicyError> {
    -        if threshold == 0 {
    -            return Ok(None);
    +    fn make_thresh(items: Vec<Policy>, threshold: usize) -> Result<Option<Policy>, PolicyError> {
    +        if threshold == 0 {
    +            return Ok(None);
             }
     
    -        let mut contribution = Satisfaction::Partial {
    -            n: items.len(),
    -            m: threshold,
    -            items: vec![],
    -            conditions: Default::default(),
    -            sorted: None,
    +        let mut contribution = Satisfaction::Partial {
    +            n: items.len(),
    +            m: threshold,
    +            items: vec![],
    +            conditions: Default::default(),
    +            sorted: None,
             };
    -        let mut satisfaction = contribution.clone();
    -        for (index, item) in items.iter().enumerate() {
    -            contribution.add(&item.contribution, index)?;
    -            satisfaction.add(&item.satisfaction, index)?;
    +        let mut satisfaction = contribution.clone();
    +        for (index, item) in items.iter().enumerate() {
    +            contribution.add(&item.contribution, index)?;
    +            satisfaction.add(&item.satisfaction, index)?;
             }
     
    -        contribution.finalize();
    -        satisfaction.finalize();
    +        contribution.finalize();
    +        satisfaction.finalize();
     
    -        let mut policy: Policy = SatisfiableItem::Thresh { items, threshold }.into();
    -        policy.contribution = contribution;
    -        policy.satisfaction = satisfaction;
    +        let mut policy: Policy = SatisfiableItem::Thresh { items, threshold }.into();
    +        policy.contribution = contribution;
    +        policy.satisfaction = satisfaction;
     
    -        Ok(Some(policy))
    +        Ok(Some(policy))
         }
     
    -    fn make_multisig<Ctx: ScriptContext + 'static>(
    -        keys: &[DescriptorPublicKey],
    -        signers: &SignersContainer,
    -        build_sat: BuildSatisfaction,
    -        threshold: usize,
    -        sorted: bool,
    -        secp: &SecpCtx,
    -    ) -> Result<Option<Policy>, PolicyError> {
    -        if threshold == 0 {
    -            return Ok(None);
    +    fn make_multisig<Ctx: ScriptContext + 'static>(
    +        keys: &[DescriptorPublicKey],
    +        signers: &SignersContainer,
    +        build_sat: BuildSatisfaction,
    +        threshold: usize,
    +        sorted: bool,
    +        secp: &SecpCtx,
    +    ) -> Result<Option<Policy>, PolicyError> {
    +        if threshold == 0 {
    +            return Ok(None);
             }
     
    -        let parsed_keys = keys.iter().map(|k| PkOrF::from_key(k, secp)).collect();
    +        let parsed_keys = keys.iter().map(|k| PkOrF::from_key(k, secp)).collect();
     
    -        let mut contribution = Satisfaction::Partial {
    -            n: keys.len(),
    -            m: threshold,
    -            items: vec![],
    -            conditions: Default::default(),
    -            sorted: Some(sorted),
    +        let mut contribution = Satisfaction::Partial {
    +            n: keys.len(),
    +            m: threshold,
    +            items: vec![],
    +            conditions: Default::default(),
    +            sorted: Some(sorted),
             };
    -        let mut satisfaction = contribution.clone();
    +        let mut satisfaction = contribution.clone();
     
    -        for (index, key) in keys.iter().enumerate() {
    -            if signers.find(signer_id(key, secp)).is_some() {
    -                contribution.add(
    -                    &Satisfaction::Complete {
    -                        condition: Default::default(),
    +        for (index, key) in keys.iter().enumerate() {
    +            if signers.find(signer_id(key, secp)).is_some() {
    +                contribution.add(
    +                    &Satisfaction::Complete {
    +                        condition: Default::default(),
                         },
    -                    index,
    +                    index,
                     )?;
                 }
     
    -            if let Some(psbt) = build_sat.psbt() {
    -                if Ctx::find_signature(psbt, key, secp) {
    -                    satisfaction.add(
    -                        &Satisfaction::Complete {
    -                            condition: Default::default(),
    +            if let Some(psbt) = build_sat.psbt() {
    +                if Ctx::find_signature(psbt, key, secp) {
    +                    satisfaction.add(
    +                        &Satisfaction::Complete {
    +                            condition: Default::default(),
                             },
    -                        index,
    +                        index,
                         )?;
                     }
                 }
             }
    -        satisfaction.finalize();
    -        contribution.finalize();
    +        satisfaction.finalize();
    +        contribution.finalize();
     
    -        let mut policy: Policy = SatisfiableItem::Multisig {
    -            keys: parsed_keys,
    -            threshold,
    +        let mut policy: Policy = SatisfiableItem::Multisig {
    +            keys: parsed_keys,
    +            threshold,
             }
    -        .into();
    -        policy.contribution = contribution;
    -        policy.satisfaction = satisfaction;
    +        .into();
    +        policy.contribution = contribution;
    +        policy.satisfaction = satisfaction;
     
    -        Ok(Some(policy))
    +        Ok(Some(policy))
         }
     
    -    /// Return whether or not a specific path in the policy tree is required to unambiguously
    -    /// create a transaction
    -    ///
    -    /// What this means is that for some spending policies the user should select which paths in
    -    /// the tree it intends to satisfy while signing, because the transaction must be created differently based
    -    /// on that.
    -    pub fn requires_path(&self) -> bool {
    -        self.get_condition(&BTreeMap::new()).is_err()
    +    /// Return whether or not a specific path in the policy tree is required to unambiguously
    +    /// create a transaction
    +    ///
    +    /// What this means is that for some spending policies the user should select which paths in
    +    /// the tree it intends to satisfy while signing, because the transaction must be created differently based
    +    /// on that.
    +    pub fn requires_path(&self) -> bool {
    +        self.get_condition(&BTreeMap::new()).is_err()
         }
     
    -    /// Return the conditions that are set by the spending policy for a given path in the
    -    /// policy tree
    -    pub fn get_condition(
    +    /// Return the conditions that are set by the spending policy for a given path in the
    +    /// policy tree
    +    pub fn get_condition(
             &self,
    -        path: &BTreeMap<String, Vec<usize>>,
    -    ) -> Result<Condition, PolicyError> {
    -        // if items.len() == threshold, selected can be omitted and we take all of them by default
    -        let default = match &self.item {
    -            SatisfiableItem::Thresh { items, threshold } if items.len() == *threshold => {
    -                (0..*threshold).collect()
    +        path: &BTreeMap<String, Vec<usize>>,
    +    ) -> Result<Condition, PolicyError> {
    +        // if items.len() == threshold, selected can be omitted and we take all of them by default
    +        let default = match &self.item {
    +            SatisfiableItem::Thresh { items, threshold } if items.len() == *threshold => {
    +                (0..*threshold).collect()
                 }
    -            SatisfiableItem::Multisig { keys, .. } => (0..keys.len()).collect(),
    -            _ => vec![],
    +            SatisfiableItem::Multisig { keys, .. } => (0..keys.len()).collect(),
    +            _ => vec![],
             };
    -        let selected = match path.get(&self.id) {
    -            Some(arr) => arr,
    -            _ => &default,
    +        let selected = match path.get(&self.id) {
    +            Some(arr) => arr,
    +            _ => &default,
             };
     
    -        match &self.item {
    -            SatisfiableItem::Thresh { items, threshold } => {
    -                let mapped_req = items
    -                    .iter()
    -                    .map(|i| i.get_condition(path))
    -                    .collect::<Result<Vec<_>, _>>()?;
    -
    -                // if all the requirements are null we don't care about `selected` because there
    -                // are no requirements
    -                if mapped_req.iter().all(Condition::is_null) {
    -                    return Ok(Condition::default());
    +        match &self.item {
    +            SatisfiableItem::Thresh { items, threshold } => {
    +                let mapped_req = items
    +                    .iter()
    +                    .map(|i| i.get_condition(path))
    +                    .collect::<Result<Vec<_>, _>>()?;
    +
    +                // if all the requirements are null we don't care about `selected` because there
    +                // are no requirements
    +                if mapped_req.iter().all(Condition::is_null) {
    +                    return Ok(Condition::default());
                     }
     
    -                // if we have something, make sure we have enough items. note that the user can set
    -                // an empty value for this step in case of n-of-n, because `selected` is set to all
    -                // the elements above
    -                if selected.len() < *threshold {
    -                    return Err(PolicyError::NotEnoughItemsSelected(self.id.clone()));
    +                // if we have something, make sure we have enough items. note that the user can set
    +                // an empty value for this step in case of n-of-n, because `selected` is set to all
    +                // the elements above
    +                if selected.len() < *threshold {
    +                    return Err(PolicyError::NotEnoughItemsSelected(self.id.clone()));
                     }
     
    -                // check the selected items, see if there are conflicting requirements
    -                let mut requirements = Condition::default();
    -                for item_index in selected {
    -                    requirements = requirements.merge(
    -                        mapped_req
    -                            .get(*item_index)
    -                            .ok_or(PolicyError::IndexOutOfRange(*item_index))?,
    +                // check the selected items, see if there are conflicting requirements
    +                let mut requirements = Condition::default();
    +                for item_index in selected {
    +                    requirements = requirements.merge(
    +                        mapped_req
    +                            .get(*item_index)
    +                            .ok_or(PolicyError::IndexOutOfRange(*item_index))?,
                         )?;
                     }
     
    -                Ok(requirements)
    +                Ok(requirements)
                 }
    -            SatisfiableItem::Multisig { keys, threshold } => {
    -                if selected.len() < *threshold {
    -                    return Err(PolicyError::NotEnoughItemsSelected(self.id.clone()));
    +            SatisfiableItem::Multisig { keys, threshold } => {
    +                if selected.len() < *threshold {
    +                    return Err(PolicyError::NotEnoughItemsSelected(self.id.clone()));
                     }
    -                if let Some(item) = selected.iter().find(|i| **i >= keys.len()) {
    -                    return Err(PolicyError::IndexOutOfRange(*item));
    +                if let Some(item) = selected.iter().find(|i| **i >= keys.len()) {
    +                    return Err(PolicyError::IndexOutOfRange(*item));
                     }
     
    -                Ok(Condition::default())
    +                Ok(Condition::default())
                 }
    -            SatisfiableItem::AbsoluteTimelock { value } => Ok(Condition {
    -                csv: None,
    -                timelock: Some(*value),
    +            SatisfiableItem::AbsoluteTimelock { value } => Ok(Condition {
    +                csv: None,
    +                timelock: Some(*value),
                 }),
    -            SatisfiableItem::RelativeTimelock { value } => Ok(Condition {
    -                csv: Some(*value),
    -                timelock: None,
    +            SatisfiableItem::RelativeTimelock { value } => Ok(Condition {
    +                csv: Some(*value),
    +                timelock: None,
                 }),
    -            _ => Ok(Condition::default()),
    +            _ => Ok(Condition::default()),
             }
         }
     }
     
    -impl From<SatisfiableItem> for Policy {
    -    fn from(other: SatisfiableItem) -> Self {
    -        Self::new(other)
    +impl From<SatisfiableItem> for Policy {
    +    fn from(other: SatisfiableItem) -> Self {
    +        Self::new(other)
         }
     }
     
    -fn signer_id(key: &DescriptorPublicKey, secp: &SecpCtx) -> SignerId {
    -    // For consistency we always compute the key hash in "ecdsa" form (with the leading sign
    -    // prefix) even if we are in a taproot descriptor. We just want some kind of unique identifier
    -    // for a key, so it doesn't really matter how the identifier is computed.
    -    match key {
    -        DescriptorPublicKey::Single(SinglePub {
    -            key: SinglePubKey::FullKey(pk),
    +fn signer_id(key: &DescriptorPublicKey, secp: &SecpCtx) -> SignerId {
    +    // For consistency we always compute the key hash in "ecdsa" form (with the leading sign
    +    // prefix) even if we are in a taproot descriptor. We just want some kind of unique identifier
    +    // for a key, so it doesn't really matter how the identifier is computed.
    +    match key {
    +        DescriptorPublicKey::Single(SinglePub {
    +            key: SinglePubKey::FullKey(pk),
                 ..
    -        }) => pk.to_pubkeyhash(SigType::Ecdsa).into(),
    -        DescriptorPublicKey::Single(SinglePub {
    -            key: SinglePubKey::XOnly(pk),
    +        }) => pk.to_pubkeyhash(SigType::Ecdsa).into(),
    +        DescriptorPublicKey::Single(SinglePub {
    +            key: SinglePubKey::XOnly(pk),
                 ..
    -        }) => pk.to_pubkeyhash(SigType::Ecdsa).into(),
    -        DescriptorPublicKey::XPub(xpub) => xpub.root_fingerprint(secp).into(),
    +        }) => pk.to_pubkeyhash(SigType::Ecdsa).into(),
    +        DescriptorPublicKey::XPub(xpub) => xpub.root_fingerprint(secp).into(),
         }
     }
     
    -fn make_generic_signature<M: Fn() -> SatisfiableItem, F: Fn(&Psbt) -> bool>(
    -    key: &DescriptorPublicKey,
    -    signers: &SignersContainer,
    -    build_sat: BuildSatisfaction,
    -    secp: &SecpCtx,
    -    make_policy: M,
    -    find_sig: F,
    -) -> Policy {
    -    let mut policy: Policy = make_policy().into();
    -
    -    policy.contribution = if signers.find(signer_id(key, secp)).is_some() {
    -        Satisfaction::Complete {
    -            condition: Default::default(),
    +fn make_generic_signature<M: Fn() -> SatisfiableItem, F: Fn(&Psbt) -> bool>(
    +    key: &DescriptorPublicKey,
    +    signers: &SignersContainer,
    +    build_sat: BuildSatisfaction,
    +    secp: &SecpCtx,
    +    make_policy: M,
    +    find_sig: F,
    +) -> Policy {
    +    let mut policy: Policy = make_policy().into();
    +
    +    policy.contribution = if signers.find(signer_id(key, secp)).is_some() {
    +        Satisfaction::Complete {
    +            condition: Default::default(),
             }
    -    } else {
    -        Satisfaction::None
    +    } else {
    +        Satisfaction::None
         };
     
    -    if let Some(psbt) = build_sat.psbt() {
    -        policy.satisfaction = if find_sig(psbt) {
    -            Satisfaction::Complete {
    -                condition: Default::default(),
    +    if let Some(psbt) = build_sat.psbt() {
    +        policy.satisfaction = if find_sig(psbt) {
    +            Satisfaction::Complete {
    +                condition: Default::default(),
                 }
    -        } else {
    -            Satisfaction::None
    +        } else {
    +            Satisfaction::None
             };
         }
     
    -    policy
    +    policy
     }
     
    -fn generic_sig_in_psbt<
    -    // C is for "check", it's a closure we use to *check* if a psbt input contains the signature
    -    // for a specific key
    -    C: Fn(&PsbtInput, &SinglePubKey) -> bool,
    -    // E is for "extract", it extracts a key from the bip32 derivations found in the psbt input
    -    E: Fn(&PsbtInput, Fingerprint) -> Option<SinglePubKey>,
    ->(
    -    psbt: &Psbt,
    -    key: &DescriptorPublicKey,
    -    secp: &SecpCtx,
    -    check: C,
    -    extract: E,
    -) -> bool {
    -    //TODO check signature validity
    -    psbt.inputs.iter().all(|input| match key {
    -        DescriptorPublicKey::Single(SinglePub { key, .. }) => check(input, key),
    -        DescriptorPublicKey::XPub(xpub) => {
    -            //TODO check actual derivation matches
    -            match extract(input, xpub.root_fingerprint(secp)) {
    -                Some(pubkey) => check(input, &pubkey),
    -                None => false,
    +fn generic_sig_in_psbt<
    +    // C is for "check", it's a closure we use to *check* if a psbt input contains the signature
    +    // for a specific key
    +    C: Fn(&PsbtInput, &SinglePubKey) -> bool,
    +    // E is for "extract", it extracts a key from the bip32 derivations found in the psbt input
    +    E: Fn(&PsbtInput, Fingerprint) -> Option<SinglePubKey>,
    +>(
    +    psbt: &Psbt,
    +    key: &DescriptorPublicKey,
    +    secp: &SecpCtx,
    +    check: C,
    +    extract: E,
    +) -> bool {
    +    //TODO check signature validity
    +    psbt.inputs.iter().all(|input| match key {
    +        DescriptorPublicKey::Single(SinglePub { key, .. }) => check(input, key),
    +        DescriptorPublicKey::XPub(xpub) => {
    +            //TODO check actual derivation matches
    +            match extract(input, xpub.root_fingerprint(secp)) {
    +                Some(pubkey) => check(input, &pubkey),
    +                None => false,
                 }
             }
         })
     }
     
    -trait SigExt: ScriptContext {
    -    fn make_signature(
    -        key: &DescriptorPublicKey,
    -        signers: &SignersContainer,
    -        build_sat: BuildSatisfaction,
    -        secp: &SecpCtx,
    -    ) -> Policy;
    +trait SigExt: ScriptContext {
    +    fn make_signature(
    +        key: &DescriptorPublicKey,
    +        signers: &SignersContainer,
    +        build_sat: BuildSatisfaction,
    +        secp: &SecpCtx,
    +    ) -> Policy;
     
    -    fn find_signature(psbt: &Psbt, key: &DescriptorPublicKey, secp: &SecpCtx) -> bool;
    +    fn find_signature(psbt: &Psbt, key: &DescriptorPublicKey, secp: &SecpCtx) -> bool;
     }
     
    -impl<T: ScriptContext + 'static> SigExt for T {
    -    fn make_signature(
    -        key: &DescriptorPublicKey,
    -        signers: &SignersContainer,
    -        build_sat: BuildSatisfaction,
    -        secp: &SecpCtx,
    -    ) -> Policy {
    -        if T::as_enum().is_taproot() {
    -            make_generic_signature(
    -                key,
    -                signers,
    -                build_sat,
    -                secp,
    -                || SatisfiableItem::SchnorrSignature(PkOrF::from_key(key, secp)),
    -                |psbt| Self::find_signature(psbt, key, secp),
    +impl<T: ScriptContext + 'static> SigExt for T {
    +    fn make_signature(
    +        key: &DescriptorPublicKey,
    +        signers: &SignersContainer,
    +        build_sat: BuildSatisfaction,
    +        secp: &SecpCtx,
    +    ) -> Policy {
    +        if T::as_enum().is_taproot() {
    +            make_generic_signature(
    +                key,
    +                signers,
    +                build_sat,
    +                secp,
    +                || SatisfiableItem::SchnorrSignature(PkOrF::from_key(key, secp)),
    +                |psbt| Self::find_signature(psbt, key, secp),
                 )
    -        } else {
    -            make_generic_signature(
    -                key,
    -                signers,
    -                build_sat,
    -                secp,
    -                || SatisfiableItem::EcdsaSignature(PkOrF::from_key(key, secp)),
    -                |psbt| Self::find_signature(psbt, key, secp),
    +        } else {
    +            make_generic_signature(
    +                key,
    +                signers,
    +                build_sat,
    +                secp,
    +                || SatisfiableItem::EcdsaSignature(PkOrF::from_key(key, secp)),
    +                |psbt| Self::find_signature(psbt, key, secp),
                 )
             }
         }
     
    -    fn find_signature(psbt: &Psbt, key: &DescriptorPublicKey, secp: &SecpCtx) -> bool {
    -        if T::as_enum().is_taproot() {
    -            generic_sig_in_psbt(
    -                psbt,
    -                key,
    -                secp,
    -                |input, pk| {
    -                    let pk = match pk {
    -                        SinglePubKey::XOnly(pk) => pk,
    -                        _ => return false,
    +    fn find_signature(psbt: &Psbt, key: &DescriptorPublicKey, secp: &SecpCtx) -> bool {
    +        if T::as_enum().is_taproot() {
    +            generic_sig_in_psbt(
    +                psbt,
    +                key,
    +                secp,
    +                |input, pk| {
    +                    let pk = match pk {
    +                        SinglePubKey::XOnly(pk) => pk,
    +                        _ => return false,
                         };
     
    -                    if input.tap_internal_key == Some(*pk) && input.tap_key_sig.is_some() {
    -                        true
    -                    } else {
    -                        input.tap_script_sigs.keys().any(|(sk, _)| sk == pk)
    +                    if input.tap_internal_key == Some(*pk) && input.tap_key_sig.is_some() {
    +                        true
    +                    } else {
    +                        input.tap_script_sigs.keys().any(|(sk, _)| sk == pk)
                         }
                     },
    -                |input, fing| {
    -                    input
    -                        .tap_key_origins
    -                        .iter()
    -                        .find(|(_, (_, (f, _)))| f == &fing)
    -                        .map(|(pk, _)| SinglePubKey::XOnly(*pk))
    +                |input, fing| {
    +                    input
    +                        .tap_key_origins
    +                        .iter()
    +                        .find(|(_, (_, (f, _)))| f == &fing)
    +                        .map(|(pk, _)| SinglePubKey::XOnly(*pk))
                     },
                 )
    -        } else {
    -            generic_sig_in_psbt(
    -                psbt,
    -                key,
    -                secp,
    -                |input, pk| match pk {
    -                    SinglePubKey::FullKey(pk) => input.partial_sigs.contains_key(pk),
    -                    _ => false,
    +        } else {
    +            generic_sig_in_psbt(
    +                psbt,
    +                key,
    +                secp,
    +                |input, pk| match pk {
    +                    SinglePubKey::FullKey(pk) => input.partial_sigs.contains_key(pk),
    +                    _ => false,
                     },
    -                |input, fing| {
    -                    input
    -                        .bip32_derivation
    -                        .iter()
    -                        .find(|(_, (f, _))| f == &fing)
    -                        .map(|(pk, _)| SinglePubKey::FullKey(PublicKey::new(*pk)))
    +                |input, fing| {
    +                    input
    +                        .bip32_derivation
    +                        .iter()
    +                        .find(|(_, (f, _))| f == &fing)
    +                        .map(|(pk, _)| SinglePubKey::FullKey(PublicKey::new(*pk)))
                     },
                 )
             }
         }
     }
     
    -impl<Ctx: ScriptContext + 'static> ExtractPolicy for Miniscript<DescriptorPublicKey, Ctx> {
    -    fn extract_policy(
    +impl<Ctx: ScriptContext + 'static> ExtractPolicy for Miniscript<DescriptorPublicKey, Ctx> {
    +    fn extract_policy(
             &self,
    -        signers: &SignersContainer,
    -        build_sat: BuildSatisfaction,
    -        secp: &SecpCtx,
    -    ) -> Result<Option<Policy>, Error> {
    -        Ok(match &self.node {
    -            // Leaves
    -            Terminal::True | Terminal::False => None,
    -            Terminal::PkK(pubkey) => Some(Ctx::make_signature(pubkey, signers, build_sat, secp)),
    -            Terminal::PkH(pubkey_hash) => {
    -                Some(Ctx::make_signature(pubkey_hash, signers, build_sat, secp))
    +        signers: &SignersContainer,
    +        build_sat: BuildSatisfaction,
    +        secp: &SecpCtx,
    +    ) -> Result<Option<Policy>, Error> {
    +        Ok(match &self.node {
    +            // Leaves
    +            Terminal::True | Terminal::False => None,
    +            Terminal::PkK(pubkey) => Some(Ctx::make_signature(pubkey, signers, build_sat, secp)),
    +            Terminal::PkH(pubkey_hash) => {
    +                Some(Ctx::make_signature(pubkey_hash, signers, build_sat, secp))
                 }
    -            Terminal::After(value) => {
    -                let mut policy: Policy = SatisfiableItem::AbsoluteTimelock {
    -                    value: value.into(),
    +            Terminal::After(value) => {
    +                let mut policy: Policy = SatisfiableItem::AbsoluteTimelock {
    +                    value: value.into(),
                     }
    -                .into();
    -                policy.contribution = Satisfaction::Complete {
    -                    condition: Condition {
    -                        timelock: Some(value.into()),
    -                        csv: None,
    +                .into();
    +                policy.contribution = Satisfaction::Complete {
    +                    condition: Condition {
    +                        timelock: Some(value.into()),
    +                        csv: None,
                         },
                     };
    -                if let BuildSatisfaction::PsbtTimelocks {
    -                    current_height,
    -                    psbt,
    +                if let BuildSatisfaction::PsbtTimelocks {
    +                    current_height,
    +                    psbt,
                         ..
    -                } = build_sat
    +                } = build_sat
                     {
    -                    let after = After::new(Some(current_height), false);
    -                    let after_sat =
    -                        Satisfier::<bitcoin::PublicKey>::check_after(&after, value.into());
    -                    let inputs_sat = psbt_inputs_sat(psbt).all(|sat| {
    -                        Satisfier::<bitcoin::PublicKey>::check_after(&sat, value.into())
    +                    let after = After::new(Some(current_height), false);
    +                    let after_sat =
    +                        Satisfier::<bitcoin::PublicKey>::check_after(&after, value.into());
    +                    let inputs_sat = psbt_inputs_sat(psbt).all(|sat| {
    +                        Satisfier::<bitcoin::PublicKey>::check_after(&sat, value.into())
                         });
    -                    if after_sat && inputs_sat {
    -                        policy.satisfaction = policy.contribution.clone();
    +                    if after_sat && inputs_sat {
    +                        policy.satisfaction = policy.contribution.clone();
                         }
                     }
     
    -                Some(policy)
    +                Some(policy)
                 }
    -            Terminal::Older(value) => {
    -                let mut policy: Policy = SatisfiableItem::RelativeTimelock { value: *value }.into();
    -                policy.contribution = Satisfaction::Complete {
    -                    condition: Condition {
    -                        timelock: None,
    -                        csv: Some(*value),
    +            Terminal::Older(value) => {
    +                let mut policy: Policy = SatisfiableItem::RelativeTimelock { value: *value }.into();
    +                policy.contribution = Satisfaction::Complete {
    +                    condition: Condition {
    +                        timelock: None,
    +                        csv: Some(*value),
                         },
                     };
    -                if let BuildSatisfaction::PsbtTimelocks {
    -                    current_height,
    -                    input_max_height,
    -                    psbt,
    -                } = build_sat
    +                if let BuildSatisfaction::PsbtTimelocks {
    +                    current_height,
    +                    input_max_height,
    +                    psbt,
    +                } = build_sat
                     {
    -                    let older = Older::new(Some(current_height), Some(input_max_height), false);
    -                    let older_sat = Satisfier::<bitcoin::PublicKey>::check_older(&older, *value);
    -                    let inputs_sat = psbt_inputs_sat(psbt)
    -                        .all(|sat| Satisfier::<bitcoin::PublicKey>::check_older(&sat, *value));
    -                    if older_sat && inputs_sat {
    -                        policy.satisfaction = policy.contribution.clone();
    +                    let older = Older::new(Some(current_height), Some(input_max_height), false);
    +                    let older_sat = Satisfier::<bitcoin::PublicKey>::check_older(&older, *value);
    +                    let inputs_sat = psbt_inputs_sat(psbt)
    +                        .all(|sat| Satisfier::<bitcoin::PublicKey>::check_older(&sat, *value));
    +                    if older_sat && inputs_sat {
    +                        policy.satisfaction = policy.contribution.clone();
                         }
                     }
     
    -                Some(policy)
    +                Some(policy)
                 }
    -            Terminal::Sha256(hash) => Some(SatisfiableItem::Sha256Preimage { hash: *hash }.into()),
    -            Terminal::Hash256(hash) => {
    -                Some(SatisfiableItem::Hash256Preimage { hash: *hash }.into())
    +            Terminal::Sha256(hash) => Some(SatisfiableItem::Sha256Preimage { hash: *hash }.into()),
    +            Terminal::Hash256(hash) => {
    +                Some(SatisfiableItem::Hash256Preimage { hash: *hash }.into())
                 }
    -            Terminal::Ripemd160(hash) => {
    -                Some(SatisfiableItem::Ripemd160Preimage { hash: *hash }.into())
    +            Terminal::Ripemd160(hash) => {
    +                Some(SatisfiableItem::Ripemd160Preimage { hash: *hash }.into())
                 }
    -            Terminal::Hash160(hash) => {
    -                Some(SatisfiableItem::Hash160Preimage { hash: *hash }.into())
    +            Terminal::Hash160(hash) => {
    +                Some(SatisfiableItem::Hash160Preimage { hash: *hash }.into())
                 }
    -            Terminal::Multi(k, pks) | Terminal::MultiA(k, pks) => {
    -                Policy::make_multisig::<Ctx>(pks, signers, build_sat, *k, false, secp)?
    -            }
    -            // Identities
    -            Terminal::Alt(inner)
    -            | Terminal::Swap(inner)
    -            | Terminal::Check(inner)
    -            | Terminal::DupIf(inner)
    -            | Terminal::Verify(inner)
    -            | Terminal::NonZero(inner)
    -            | Terminal::ZeroNotEqual(inner) => inner.extract_policy(signers, build_sat, secp)?,
    -            // Complex policies
    -            Terminal::AndV(a, b) | Terminal::AndB(a, b) => Policy::make_and(
    -                a.extract_policy(signers, build_sat, secp)?,
    -                b.extract_policy(signers, build_sat, secp)?,
    +            Terminal::Multi(k, pks) | Terminal::MultiA(k, pks) => {
    +                Policy::make_multisig::<Ctx>(pks, signers, build_sat, *k, false, secp)?
    +            }
    +            // Identities
    +            Terminal::Alt(inner)
    +            | Terminal::Swap(inner)
    +            | Terminal::Check(inner)
    +            | Terminal::DupIf(inner)
    +            | Terminal::Verify(inner)
    +            | Terminal::NonZero(inner)
    +            | Terminal::ZeroNotEqual(inner) => inner.extract_policy(signers, build_sat, secp)?,
    +            // Complex policies
    +            Terminal::AndV(a, b) | Terminal::AndB(a, b) => Policy::make_and(
    +                a.extract_policy(signers, build_sat, secp)?,
    +                b.extract_policy(signers, build_sat, secp)?,
                 )?,
    -            Terminal::AndOr(x, y, z) => Policy::make_or(
    -                Policy::make_and(
    -                    x.extract_policy(signers, build_sat, secp)?,
    -                    y.extract_policy(signers, build_sat, secp)?,
    +            Terminal::AndOr(x, y, z) => Policy::make_or(
    +                Policy::make_and(
    +                    x.extract_policy(signers, build_sat, secp)?,
    +                    y.extract_policy(signers, build_sat, secp)?,
                     )?,
    -                z.extract_policy(signers, build_sat, secp)?,
    +                z.extract_policy(signers, build_sat, secp)?,
                 )?,
    -            Terminal::OrB(a, b)
    -            | Terminal::OrD(a, b)
    -            | Terminal::OrC(a, b)
    -            | Terminal::OrI(a, b) => Policy::make_or(
    -                a.extract_policy(signers, build_sat, secp)?,
    -                b.extract_policy(signers, build_sat, secp)?,
    +            Terminal::OrB(a, b)
    +            | Terminal::OrD(a, b)
    +            | Terminal::OrC(a, b)
    +            | Terminal::OrI(a, b) => Policy::make_or(
    +                a.extract_policy(signers, build_sat, secp)?,
    +                b.extract_policy(signers, build_sat, secp)?,
                 )?,
    -            Terminal::Thresh(k, nodes) => {
    -                let mut threshold = *k;
    -                let mapped: Vec<_> = nodes
    -                    .iter()
    -                    .map(|n| n.extract_policy(signers, build_sat, secp))
    -                    .collect::<Result<Vec<_>, _>>()?
    -                    .into_iter()
    -                    .flatten()
    -                    .collect();
    -
    -                if mapped.len() < nodes.len() {
    -                    threshold = match threshold.checked_sub(nodes.len() - mapped.len()) {
    -                        None => return Ok(None),
    -                        Some(x) => x,
    +            Terminal::Thresh(k, nodes) => {
    +                let mut threshold = *k;
    +                let mapped: Vec<_> = nodes
    +                    .iter()
    +                    .map(|n| n.extract_policy(signers, build_sat, secp))
    +                    .collect::<Result<Vec<_>, _>>()?
    +                    .into_iter()
    +                    .flatten()
    +                    .collect();
    +
    +                if mapped.len() < nodes.len() {
    +                    threshold = match threshold.checked_sub(nodes.len() - mapped.len()) {
    +                        None => return Ok(None),
    +                        Some(x) => x,
                         };
                     }
     
    -                Policy::make_thresh(mapped, threshold)?
    -            }
    +                Policy::make_thresh(mapped, threshold)?
    +            }
     
    -            // Unsupported
    -            Terminal::RawPkH(_) => None,
    +            // Unsupported
    +            Terminal::RawPkH(_) => None,
             })
         }
     }
     
    -fn psbt_inputs_sat(psbt: &Psbt) -> impl Iterator<Item = PsbtInputSatisfier> {
    -    (0..psbt.inputs.len()).map(move |i| PsbtInputSatisfier::new(psbt, i))
    +fn psbt_inputs_sat(psbt: &Psbt) -> impl Iterator<Item = PsbtInputSatisfier> {
    +    (0..psbt.inputs.len()).map(move |i| PsbtInputSatisfier::new(psbt, i))
     }
     
    -/// Options to build the satisfaction field in the policy
    -#[derive(Debug, Clone, Copy)]
    -pub enum BuildSatisfaction<'a> {
    -    /// Don't generate `satisfaction` field
    -    None,
    -    /// Analyze the given PSBT to check for existing signatures
    -    Psbt(&'a Psbt),
    -    /// Like `Psbt` variant and also check for expired timelocks
    -    PsbtTimelocks {
    -        /// Given PSBT
    -        psbt: &'a Psbt,
    -        /// Current blockchain height
    -        current_height: u32,
    -        /// The highest confirmation height between the inputs
    -        /// CSV should consider different inputs, but we consider the worst condition for the tx as whole
    -        input_max_height: u32,
    +/// Options to build the satisfaction field in the policy
    +#[derive(Debug, Clone, Copy)]
    +pub enum BuildSatisfaction<'a> {
    +    /// Don't generate `satisfaction` field
    +    None,
    +    /// Analyze the given PSBT to check for existing signatures
    +    Psbt(&'a Psbt),
    +    /// Like `Psbt` variant and also check for expired timelocks
    +    PsbtTimelocks {
    +        /// Given PSBT
    +        psbt: &'a Psbt,
    +        /// Current blockchain height
    +        current_height: u32,
    +        /// The highest confirmation height between the inputs
    +        /// CSV should consider different inputs, but we consider the worst condition for the tx as whole
    +        input_max_height: u32,
         },
     }
    -impl<'a> BuildSatisfaction<'a> {
    -    fn psbt(&self) -> Option<&'a Psbt> {
    -        match self {
    -            BuildSatisfaction::None => None,
    -            BuildSatisfaction::Psbt(psbt) => Some(psbt),
    -            BuildSatisfaction::PsbtTimelocks { psbt, .. } => Some(psbt),
    +impl<'a> BuildSatisfaction<'a> {
    +    fn psbt(&self) -> Option<&'a Psbt> {
    +        match self {
    +            BuildSatisfaction::None => None,
    +            BuildSatisfaction::Psbt(psbt) => Some(psbt),
    +            BuildSatisfaction::PsbtTimelocks { psbt, .. } => Some(psbt),
             }
         }
     }
     
    -impl ExtractPolicy for Descriptor<DescriptorPublicKey> {
    -    fn extract_policy(
    +impl ExtractPolicy for Descriptor<DescriptorPublicKey> {
    +    fn extract_policy(
             &self,
    -        signers: &SignersContainer,
    -        build_sat: BuildSatisfaction,
    -        secp: &SecpCtx,
    -    ) -> Result<Option<Policy>, Error> {
    -        fn make_sortedmulti<Ctx: ScriptContext + 'static>(
    -            keys: &SortedMultiVec<DescriptorPublicKey, Ctx>,
    -            signers: &SignersContainer,
    -            build_sat: BuildSatisfaction,
    -            secp: &SecpCtx,
    -        ) -> Result<Option<Policy>, Error> {
    -            Ok(Policy::make_multisig::<Ctx>(
    -                keys.pks.as_ref(),
    -                signers,
    -                build_sat,
    -                keys.k,
    +        signers: &SignersContainer,
    +        build_sat: BuildSatisfaction,
    +        secp: &SecpCtx,
    +    ) -> Result<Option<Policy>, Error> {
    +        fn make_sortedmulti<Ctx: ScriptContext + 'static>(
    +            keys: &SortedMultiVec<DescriptorPublicKey, Ctx>,
    +            signers: &SignersContainer,
    +            build_sat: BuildSatisfaction,
    +            secp: &SecpCtx,
    +        ) -> Result<Option<Policy>, Error> {
    +            Ok(Policy::make_multisig::<Ctx>(
    +                keys.pks.as_ref(),
    +                signers,
    +                build_sat,
    +                keys.k,
                     true,
    -                secp,
    +                secp,
                 )?)
             }
     
    -        match self {
    -            Descriptor::Pkh(pk) => Ok(Some(miniscript::Legacy::make_signature(
    -                pk.as_inner(),
    -                signers,
    -                build_sat,
    -                secp,
    +        match self {
    +            Descriptor::Pkh(pk) => Ok(Some(miniscript::Legacy::make_signature(
    +                pk.as_inner(),
    +                signers,
    +                build_sat,
    +                secp,
                 ))),
    -            Descriptor::Wpkh(pk) => Ok(Some(miniscript::Segwitv0::make_signature(
    -                pk.as_inner(),
    -                signers,
    -                build_sat,
    -                secp,
    +            Descriptor::Wpkh(pk) => Ok(Some(miniscript::Segwitv0::make_signature(
    +                pk.as_inner(),
    +                signers,
    +                build_sat,
    +                secp,
                 ))),
    -            Descriptor::Sh(sh) => match sh.as_inner() {
    -                ShInner::Wpkh(pk) => Ok(Some(miniscript::Segwitv0::make_signature(
    -                    pk.as_inner(),
    -                    signers,
    -                    build_sat,
    -                    secp,
    +            Descriptor::Sh(sh) => match sh.as_inner() {
    +                ShInner::Wpkh(pk) => Ok(Some(miniscript::Segwitv0::make_signature(
    +                    pk.as_inner(),
    +                    signers,
    +                    build_sat,
    +                    secp,
                     ))),
    -                ShInner::Ms(ms) => Ok(ms.extract_policy(signers, build_sat, secp)?),
    -                ShInner::SortedMulti(ref keys) => make_sortedmulti(keys, signers, build_sat, secp),
    -                ShInner::Wsh(wsh) => match wsh.as_inner() {
    -                    WshInner::Ms(ms) => Ok(ms.extract_policy(signers, build_sat, secp)?),
    -                    WshInner::SortedMulti(ref keys) => {
    -                        make_sortedmulti(keys, signers, build_sat, secp)
    +                ShInner::Ms(ms) => Ok(ms.extract_policy(signers, build_sat, secp)?),
    +                ShInner::SortedMulti(ref keys) => make_sortedmulti(keys, signers, build_sat, secp),
    +                ShInner::Wsh(wsh) => match wsh.as_inner() {
    +                    WshInner::Ms(ms) => Ok(ms.extract_policy(signers, build_sat, secp)?),
    +                    WshInner::SortedMulti(ref keys) => {
    +                        make_sortedmulti(keys, signers, build_sat, secp)
                         }
                     },
                 },
    -            Descriptor::Wsh(wsh) => match wsh.as_inner() {
    -                WshInner::Ms(ms) => Ok(ms.extract_policy(signers, build_sat, secp)?),
    -                WshInner::SortedMulti(ref keys) => make_sortedmulti(keys, signers, build_sat, secp),
    +            Descriptor::Wsh(wsh) => match wsh.as_inner() {
    +                WshInner::Ms(ms) => Ok(ms.extract_policy(signers, build_sat, secp)?),
    +                WshInner::SortedMulti(ref keys) => make_sortedmulti(keys, signers, build_sat, secp),
                 },
    -            Descriptor::Bare(ms) => Ok(ms.as_inner().extract_policy(signers, build_sat, secp)?),
    -            Descriptor::Tr(tr) => {
    -                // If there's no tap tree, treat this as a single sig, otherwise build a `Thresh`
    -                // node with threshold = 1 and the key spend signature plus all the tree leaves
    -                let key_spend_sig =
    -                    miniscript::Tap::make_signature(tr.internal_key(), signers, build_sat, secp);
    -
    -                if tr.taptree().is_none() {
    -                    Ok(Some(key_spend_sig))
    -                } else {
    -                    let mut items = vec![key_spend_sig];
    -                    items.append(
    -                        &mut tr
    -                            .iter_scripts()
    -                            .filter_map(|(_, ms)| {
    -                                ms.extract_policy(signers, build_sat, secp).transpose()
    +            Descriptor::Bare(ms) => Ok(ms.as_inner().extract_policy(signers, build_sat, secp)?),
    +            Descriptor::Tr(tr) => {
    +                // If there's no tap tree, treat this as a single sig, otherwise build a `Thresh`
    +                // node with threshold = 1 and the key spend signature plus all the tree leaves
    +                let key_spend_sig =
    +                    miniscript::Tap::make_signature(tr.internal_key(), signers, build_sat, secp);
    +
    +                if tr.taptree().is_none() {
    +                    Ok(Some(key_spend_sig))
    +                } else {
    +                    let mut items = vec![key_spend_sig];
    +                    items.append(
    +                        &mut tr
    +                            .iter_scripts()
    +                            .filter_map(|(_, ms)| {
    +                                ms.extract_policy(signers, build_sat, secp).transpose()
                                 })
    -                            .collect::<Result<Vec<_>, _>>()?,
    +                            .collect::<Result<Vec<_>, _>>()?,
                         );
     
    -                    Ok(Policy::make_thresh(items, 1)?)
    +                    Ok(Policy::make_thresh(items, 1)?)
                     }
                 }
             }
         }
     }
     
    -#[cfg(test)]
    -mod test {
    -    use crate::descriptor;
    -    use crate::descriptor::{ExtractPolicy, IntoWalletDescriptor};
    -
    -    use super::*;
    -    use crate::descriptor::policy::SatisfiableItem::{EcdsaSignature, Multisig, Thresh};
    -    use crate::keys::{DescriptorKey, IntoDescriptorKey};
    -    use crate::wallet::signer::SignersContainer;
    -    use bitcoin::secp256k1::Secp256k1;
    -    use bitcoin::util::bip32;
    -    use bitcoin::Network;
    -    use std::str::FromStr;
    -    use std::sync::Arc;
    -
    -    const TPRV0_STR:&str = "tprv8ZgxMBicQKsPdZXrcHNLf5JAJWFAoJ2TrstMRdSKtEggz6PddbuSkvHKM9oKJyFgZV1B7rw8oChspxyYbtmEXYyg1AjfWbL3ho3XHDpHRZf";
    -    const TPRV1_STR:&str = "tprv8ZgxMBicQKsPdpkqS7Eair4YxjcuuvDPNYmKX3sCniCf16tHEVrjjiSXEkFRnUH77yXc6ZcwHHcLNfjdi5qUvw3VDfgYiH5mNsj5izuiu2N";
    -
    -    const PATH: &str = "m/44'/1'/0'/0";
    -
    -    fn setup_keys<Ctx: ScriptContext>(
    -        tprv: &str,
    -        path: &str,
    -        secp: &SecpCtx,
    -    ) -> (DescriptorKey<Ctx>, DescriptorKey<Ctx>, Fingerprint) {
    -        let path = bip32::DerivationPath::from_str(path).unwrap();
    -        let tprv = bip32::ExtendedPrivKey::from_str(tprv).unwrap();
    -        let tpub = bip32::ExtendedPubKey::from_priv(secp, &tprv);
    -        let fingerprint = tprv.fingerprint(secp);
    -        let prvkey = (tprv, path.clone()).into_descriptor_key().unwrap();
    -        let pubkey = (tpub, path).into_descriptor_key().unwrap();
    -
    -        (prvkey, pubkey, fingerprint)
    +#[cfg(test)]
    +mod test {
    +    use crate::descriptor;
    +    use crate::descriptor::{ExtractPolicy, IntoWalletDescriptor};
    +
    +    use super::*;
    +    use crate::descriptor::policy::SatisfiableItem::{EcdsaSignature, Multisig, Thresh};
    +    use crate::keys::{DescriptorKey, IntoDescriptorKey};
    +    use crate::wallet::signer::SignersContainer;
    +    use bitcoin::secp256k1::Secp256k1;
    +    use bitcoin::util::bip32;
    +    use bitcoin::Network;
    +    use std::str::FromStr;
    +    use std::sync::Arc;
    +
    +    const TPRV0_STR:&str = "tprv8ZgxMBicQKsPdZXrcHNLf5JAJWFAoJ2TrstMRdSKtEggz6PddbuSkvHKM9oKJyFgZV1B7rw8oChspxyYbtmEXYyg1AjfWbL3ho3XHDpHRZf";
    +    const TPRV1_STR:&str = "tprv8ZgxMBicQKsPdpkqS7Eair4YxjcuuvDPNYmKX3sCniCf16tHEVrjjiSXEkFRnUH77yXc6ZcwHHcLNfjdi5qUvw3VDfgYiH5mNsj5izuiu2N";
    +
    +    const PATH: &str = "m/44'/1'/0'/0";
    +
    +    fn setup_keys<Ctx: ScriptContext>(
    +        tprv: &str,
    +        path: &str,
    +        secp: &SecpCtx,
    +    ) -> (DescriptorKey<Ctx>, DescriptorKey<Ctx>, Fingerprint) {
    +        let path = bip32::DerivationPath::from_str(path).unwrap();
    +        let tprv = bip32::ExtendedPrivKey::from_str(tprv).unwrap();
    +        let tpub = bip32::ExtendedPubKey::from_priv(secp, &tprv);
    +        let fingerprint = tprv.fingerprint(secp);
    +        let prvkey = (tprv, path.clone()).into_descriptor_key().unwrap();
    +        let pubkey = (tpub, path).into_descriptor_key().unwrap();
    +
    +        (prvkey, pubkey, fingerprint)
         }
     
    -    // test ExtractPolicy trait for simple descriptors; wpkh(), sh(multi())
    -
    -    #[test]
    -    fn test_extract_policy_for_wpkh() {
    -        let secp = Secp256k1::new();
    -
    -        let (prvkey, pubkey, fingerprint) = setup_keys(TPRV0_STR, PATH, &secp);
    -        let desc = descriptor!(wpkh(pubkey)).unwrap();
    -        let (wallet_desc, keymap) = desc
    -            .into_wallet_descriptor(&secp, Network::Testnet)
    -            .unwrap();
    -        let signers_container = Arc::new(SignersContainer::build(keymap, &wallet_desc, &secp));
    -        let policy = wallet_desc
    -            .extract_policy(&signers_container, BuildSatisfaction::None, &secp)
    -            .unwrap()
    -            .unwrap();
    -
    -        assert!(matches!(&policy.item, EcdsaSignature(PkOrF::Fingerprint(f)) if f == &fingerprint));
    -        assert!(matches!(&policy.contribution, Satisfaction::None));
    -
    -        let desc = descriptor!(wpkh(prvkey)).unwrap();
    -        let (wallet_desc, keymap) = desc
    -            .into_wallet_descriptor(&secp, Network::Testnet)
    -            .unwrap();
    -        let signers_container = Arc::new(SignersContainer::build(keymap, &wallet_desc, &secp));
    -        let policy = wallet_desc
    -            .extract_policy(&signers_container, BuildSatisfaction::None, &secp)
    -            .unwrap()
    -            .unwrap();
    -
    -        assert!(matches!(&policy.item, EcdsaSignature(PkOrF::Fingerprint(f)) if f == &fingerprint));
    +    // test ExtractPolicy trait for simple descriptors; wpkh(), sh(multi())
    +
    +    #[test]
    +    fn test_extract_policy_for_wpkh() {
    +        let secp = Secp256k1::new();
    +
    +        let (prvkey, pubkey, fingerprint) = setup_keys(TPRV0_STR, PATH, &secp);
    +        let desc = descriptor!(wpkh(pubkey)).unwrap();
    +        let (wallet_desc, keymap) = desc
    +            .into_wallet_descriptor(&secp, Network::Testnet)
    +            .unwrap();
    +        let signers_container = Arc::new(SignersContainer::build(keymap, &wallet_desc, &secp));
    +        let policy = wallet_desc
    +            .extract_policy(&signers_container, BuildSatisfaction::None, &secp)
    +            .unwrap()
    +            .unwrap();
    +
    +        assert!(matches!(&policy.item, EcdsaSignature(PkOrF::Fingerprint(f)) if f == &fingerprint));
    +        assert!(matches!(&policy.contribution, Satisfaction::None));
    +
    +        let desc = descriptor!(wpkh(prvkey)).unwrap();
    +        let (wallet_desc, keymap) = desc
    +            .into_wallet_descriptor(&secp, Network::Testnet)
    +            .unwrap();
    +        let signers_container = Arc::new(SignersContainer::build(keymap, &wallet_desc, &secp));
    +        let policy = wallet_desc
    +            .extract_policy(&signers_container, BuildSatisfaction::None, &secp)
    +            .unwrap()
    +            .unwrap();
    +
    +        assert!(matches!(&policy.item, EcdsaSignature(PkOrF::Fingerprint(f)) if f == &fingerprint));
             assert!(
    -            matches!(&policy.contribution, Satisfaction::Complete {condition} if condition.csv == None && condition.timelock == None)
    +            matches!(&policy.contribution, Satisfaction::Complete {condition} if condition.csv == None && condition.timelock == None)
             );
         }
     
    -    // 2 pub keys descriptor, required 2 prv keys
    -    #[test]
    -    fn test_extract_policy_for_sh_multi_partial_0of2() {
    -        let secp = Secp256k1::new();
    -        let (_prvkey0, pubkey0, fingerprint0) = setup_keys(TPRV0_STR, PATH, &secp);
    -        let (_prvkey1, pubkey1, fingerprint1) = setup_keys(TPRV1_STR, PATH, &secp);
    -        let desc = descriptor!(sh(multi(2, pubkey0, pubkey1))).unwrap();
    -        let (wallet_desc, keymap) = desc
    -            .into_wallet_descriptor(&secp, Network::Testnet)
    -            .unwrap();
    -        let signers_container = Arc::new(SignersContainer::build(keymap, &wallet_desc, &secp));
    -        let policy = wallet_desc
    -            .extract_policy(&signers_container, BuildSatisfaction::None, &secp)
    -            .unwrap()
    -            .unwrap();
    +    // 2 pub keys descriptor, required 2 prv keys
    +    #[test]
    +    fn test_extract_policy_for_sh_multi_partial_0of2() {
    +        let secp = Secp256k1::new();
    +        let (_prvkey0, pubkey0, fingerprint0) = setup_keys(TPRV0_STR, PATH, &secp);
    +        let (_prvkey1, pubkey1, fingerprint1) = setup_keys(TPRV1_STR, PATH, &secp);
    +        let desc = descriptor!(sh(multi(2, pubkey0, pubkey1))).unwrap();
    +        let (wallet_desc, keymap) = desc
    +            .into_wallet_descriptor(&secp, Network::Testnet)
    +            .unwrap();
    +        let signers_container = Arc::new(SignersContainer::build(keymap, &wallet_desc, &secp));
    +        let policy = wallet_desc
    +            .extract_policy(&signers_container, BuildSatisfaction::None, &secp)
    +            .unwrap()
    +            .unwrap();
     
             assert!(
    -            matches!(&policy.item, Multisig { keys, threshold } if threshold == &2usize
    -            && keys[0] == PkOrF::Fingerprint(fingerprint0)
    -            && keys[1] == PkOrF::Fingerprint(fingerprint1))
    +            matches!(&policy.item, Multisig { keys, threshold } if threshold == &2usize
    +            && keys[0] == PkOrF::Fingerprint(fingerprint0)
    +            && keys[1] == PkOrF::Fingerprint(fingerprint1))
             );
    -        // TODO should this be "Satisfaction::None" since we have no prv keys?
    -        // TODO should items and conditions not be empty?
    -        assert!(
    -            matches!(&policy.contribution, Satisfaction::Partial { n, m, items, conditions, ..} if n == &2usize
    -            && m == &2usize
    -            && items.is_empty()
    -            && conditions.is_empty()
    +        // TODO should this be "Satisfaction::None" since we have no prv keys?
    +        // TODO should items and conditions not be empty?
    +        assert!(
    +            matches!(&policy.contribution, Satisfaction::Partial { n, m, items, conditions, ..} if n == &2usize
    +            && m == &2usize
    +            && items.is_empty()
    +            && conditions.is_empty()
                 )
             );
         }
     
    -    // 1 prv and 1 pub key descriptor, required 2 prv keys
    -    #[test]
    -    fn test_extract_policy_for_sh_multi_partial_1of2() {
    -        let secp = Secp256k1::new();
    -        let (prvkey0, _pubkey0, fingerprint0) = setup_keys(TPRV0_STR, PATH, &secp);
    -        let (_prvkey1, pubkey1, fingerprint1) = setup_keys(TPRV1_STR, PATH, &secp);
    -        let desc = descriptor!(sh(multi(2, prvkey0, pubkey1))).unwrap();
    -        let (wallet_desc, keymap) = desc
    -            .into_wallet_descriptor(&secp, Network::Testnet)
    -            .unwrap();
    -        let signers_container = Arc::new(SignersContainer::build(keymap, &wallet_desc, &secp));
    -        let policy = wallet_desc
    -            .extract_policy(&signers_container, BuildSatisfaction::None, &secp)
    -            .unwrap()
    -            .unwrap();
    +    // 1 prv and 1 pub key descriptor, required 2 prv keys
    +    #[test]
    +    fn test_extract_policy_for_sh_multi_partial_1of2() {
    +        let secp = Secp256k1::new();
    +        let (prvkey0, _pubkey0, fingerprint0) = setup_keys(TPRV0_STR, PATH, &secp);
    +        let (_prvkey1, pubkey1, fingerprint1) = setup_keys(TPRV1_STR, PATH, &secp);
    +        let desc = descriptor!(sh(multi(2, prvkey0, pubkey1))).unwrap();
    +        let (wallet_desc, keymap) = desc
    +            .into_wallet_descriptor(&secp, Network::Testnet)
    +            .unwrap();
    +        let signers_container = Arc::new(SignersContainer::build(keymap, &wallet_desc, &secp));
    +        let policy = wallet_desc
    +            .extract_policy(&signers_container, BuildSatisfaction::None, &secp)
    +            .unwrap()
    +            .unwrap();
             assert!(
    -            matches!(&policy.item, Multisig { keys, threshold } if threshold == &2usize
    -            && keys[0] == PkOrF::Fingerprint(fingerprint0)
    -            && keys[1] == PkOrF::Fingerprint(fingerprint1))
    +            matches!(&policy.item, Multisig { keys, threshold } if threshold == &2usize
    +            && keys[0] == PkOrF::Fingerprint(fingerprint0)
    +            && keys[1] == PkOrF::Fingerprint(fingerprint1))
             );
     
             assert!(
    -            matches!(&policy.contribution, Satisfaction::Partial { n, m, items, conditions, ..} if n == &2usize
    -             && m == &2usize
    -             && items.len() == 1
    -             && conditions.contains_key(&0)
    +            matches!(&policy.contribution, Satisfaction::Partial { n, m, items, conditions, ..} if n == &2usize
    +             && m == &2usize
    +             && items.len() == 1
    +             && conditions.contains_key(&0)
                 )
             );
         }
     
    -    // 1 prv and 1 pub key descriptor, required 1 prv keys
    -    #[test]
    -    #[ignore] // see https://github.com/bitcoindevkit/bdk/issues/225
    -    fn test_extract_policy_for_sh_multi_complete_1of2() {
    -        let secp = Secp256k1::new();
    -
    -        let (_prvkey0, pubkey0, fingerprint0) = setup_keys(TPRV0_STR, PATH, &secp);
    -        let (prvkey1, _pubkey1, fingerprint1) = setup_keys(TPRV1_STR, PATH, &secp);
    -        let desc = descriptor!(sh(multi(1, pubkey0, prvkey1))).unwrap();
    -        let (wallet_desc, keymap) = desc
    -            .into_wallet_descriptor(&secp, Network::Testnet)
    -            .unwrap();
    -        let signers_container = Arc::new(SignersContainer::build(keymap, &wallet_desc, &secp));
    -        let policy = wallet_desc
    -            .extract_policy(&signers_container, BuildSatisfaction::None, &secp)
    -            .unwrap()
    -            .unwrap();
    +    // 1 prv and 1 pub key descriptor, required 1 prv keys
    +    #[test]
    +    #[ignore] // see https://github.com/bitcoindevkit/bdk/issues/225
    +    fn test_extract_policy_for_sh_multi_complete_1of2() {
    +        let secp = Secp256k1::new();
    +
    +        let (_prvkey0, pubkey0, fingerprint0) = setup_keys(TPRV0_STR, PATH, &secp);
    +        let (prvkey1, _pubkey1, fingerprint1) = setup_keys(TPRV1_STR, PATH, &secp);
    +        let desc = descriptor!(sh(multi(1, pubkey0, prvkey1))).unwrap();
    +        let (wallet_desc, keymap) = desc
    +            .into_wallet_descriptor(&secp, Network::Testnet)
    +            .unwrap();
    +        let signers_container = Arc::new(SignersContainer::build(keymap, &wallet_desc, &secp));
    +        let policy = wallet_desc
    +            .extract_policy(&signers_container, BuildSatisfaction::None, &secp)
    +            .unwrap()
    +            .unwrap();
     
             assert!(
    -            matches!(&policy.item, Multisig { keys, threshold } if threshold == &1
    -            && keys[0] == PkOrF::Fingerprint(fingerprint0)
    -            && keys[1] == PkOrF::Fingerprint(fingerprint1))
    +            matches!(&policy.item, Multisig { keys, threshold } if threshold == &1
    +            && keys[0] == PkOrF::Fingerprint(fingerprint0)
    +            && keys[1] == PkOrF::Fingerprint(fingerprint1))
             );
             assert!(
    -            matches!(&policy.contribution, Satisfaction::PartialComplete { n, m, items, conditions, .. } if n == &2
    -             && m == &1
    -             && items.len() == 2
    -             && conditions.contains_key(&vec![0])
    -             && conditions.contains_key(&vec![1])
    +            matches!(&policy.contribution, Satisfaction::PartialComplete { n, m, items, conditions, .. } if n == &2
    +             && m == &1
    +             && items.len() == 2
    +             && conditions.contains_key(&vec![0])
    +             && conditions.contains_key(&vec![1])
                 )
             );
         }
     
    -    // 2 prv keys descriptor, required 2 prv keys
    -    #[test]
    -    fn test_extract_policy_for_sh_multi_complete_2of2() {
    -        let secp = Secp256k1::new();
    -
    -        let (prvkey0, _pubkey0, fingerprint0) = setup_keys(TPRV0_STR, PATH, &secp);
    -        let (prvkey1, _pubkey1, fingerprint1) = setup_keys(TPRV1_STR, PATH, &secp);
    -        let desc = descriptor!(sh(multi(2, prvkey0, prvkey1))).unwrap();
    -        let (wallet_desc, keymap) = desc
    -            .into_wallet_descriptor(&secp, Network::Testnet)
    -            .unwrap();
    -        let signers_container = Arc::new(SignersContainer::build(keymap, &wallet_desc, &secp));
    -        let policy = wallet_desc
    -            .extract_policy(&signers_container, BuildSatisfaction::None, &secp)
    -            .unwrap()
    -            .unwrap();
    +    // 2 prv keys descriptor, required 2 prv keys
    +    #[test]
    +    fn test_extract_policy_for_sh_multi_complete_2of2() {
    +        let secp = Secp256k1::new();
    +
    +        let (prvkey0, _pubkey0, fingerprint0) = setup_keys(TPRV0_STR, PATH, &secp);
    +        let (prvkey1, _pubkey1, fingerprint1) = setup_keys(TPRV1_STR, PATH, &secp);
    +        let desc = descriptor!(sh(multi(2, prvkey0, prvkey1))).unwrap();
    +        let (wallet_desc, keymap) = desc
    +            .into_wallet_descriptor(&secp, Network::Testnet)
    +            .unwrap();
    +        let signers_container = Arc::new(SignersContainer::build(keymap, &wallet_desc, &secp));
    +        let policy = wallet_desc
    +            .extract_policy(&signers_container, BuildSatisfaction::None, &secp)
    +            .unwrap()
    +            .unwrap();
     
             assert!(
    -            matches!(&policy.item, Multisig { keys, threshold } if threshold == &2
    -            && keys[0] == PkOrF::Fingerprint(fingerprint0)
    -            && keys[1] == PkOrF::Fingerprint(fingerprint1))
    +            matches!(&policy.item, Multisig { keys, threshold } if threshold == &2
    +            && keys[0] == PkOrF::Fingerprint(fingerprint0)
    +            && keys[1] == PkOrF::Fingerprint(fingerprint1))
             );
     
             assert!(
    -            matches!(&policy.contribution, Satisfaction::PartialComplete { n, m, items, conditions, .. } if n == &2
    -             && m == &2
    -             && items.len() == 2
    -             && conditions.contains_key(&vec![0,1])
    +            matches!(&policy.contribution, Satisfaction::PartialComplete { n, m, items, conditions, .. } if n == &2
    +             && m == &2
    +             && items.len() == 2
    +             && conditions.contains_key(&vec![0,1])
                 )
             );
         }
     
    -    // test ExtractPolicy trait with extended and single keys
    -
    -    #[test]
    -    fn test_extract_policy_for_single_wpkh() {
    -        let secp = Secp256k1::new();
    -
    -        let (prvkey, pubkey, fingerprint) = setup_keys(TPRV0_STR, PATH, &secp);
    -        let desc = descriptor!(wpkh(pubkey)).unwrap();
    -        let (wallet_desc, keymap) = desc
    -            .into_wallet_descriptor(&secp, Network::Testnet)
    -            .unwrap();
    -        let signers_container = Arc::new(SignersContainer::build(keymap, &wallet_desc, &secp));
    -        let policy = wallet_desc
    -            .extract_policy(&signers_container, BuildSatisfaction::None, &secp)
    -            .unwrap()
    -            .unwrap();
    -
    -        assert!(matches!(&policy.item, EcdsaSignature(PkOrF::Fingerprint(f)) if f == &fingerprint));
    -        assert!(matches!(&policy.contribution, Satisfaction::None));
    -
    -        let desc = descriptor!(wpkh(prvkey)).unwrap();
    -        let (wallet_desc, keymap) = desc
    -            .into_wallet_descriptor(&secp, Network::Testnet)
    -            .unwrap();
    -        let signers_container = Arc::new(SignersContainer::build(keymap, &wallet_desc, &secp));
    -        let policy = wallet_desc
    -            .extract_policy(&signers_container, BuildSatisfaction::None, &secp)
    -            .unwrap()
    -            .unwrap();
    -
    -        assert!(matches!(policy.item, EcdsaSignature(PkOrF::Fingerprint(f)) if f == fingerprint));
    +    // test ExtractPolicy trait with extended and single keys
    +
    +    #[test]
    +    fn test_extract_policy_for_single_wpkh() {
    +        let secp = Secp256k1::new();
    +
    +        let (prvkey, pubkey, fingerprint) = setup_keys(TPRV0_STR, PATH, &secp);
    +        let desc = descriptor!(wpkh(pubkey)).unwrap();
    +        let (wallet_desc, keymap) = desc
    +            .into_wallet_descriptor(&secp, Network::Testnet)
    +            .unwrap();
    +        let signers_container = Arc::new(SignersContainer::build(keymap, &wallet_desc, &secp));
    +        let policy = wallet_desc
    +            .extract_policy(&signers_container, BuildSatisfaction::None, &secp)
    +            .unwrap()
    +            .unwrap();
    +
    +        assert!(matches!(&policy.item, EcdsaSignature(PkOrF::Fingerprint(f)) if f == &fingerprint));
    +        assert!(matches!(&policy.contribution, Satisfaction::None));
    +
    +        let desc = descriptor!(wpkh(prvkey)).unwrap();
    +        let (wallet_desc, keymap) = desc
    +            .into_wallet_descriptor(&secp, Network::Testnet)
    +            .unwrap();
    +        let signers_container = Arc::new(SignersContainer::build(keymap, &wallet_desc, &secp));
    +        let policy = wallet_desc
    +            .extract_policy(&signers_container, BuildSatisfaction::None, &secp)
    +            .unwrap()
    +            .unwrap();
    +
    +        assert!(matches!(policy.item, EcdsaSignature(PkOrF::Fingerprint(f)) if f == fingerprint));
             assert!(
    -            matches!(policy.contribution, Satisfaction::Complete {condition} if condition.csv == None && condition.timelock == None)
    +            matches!(policy.contribution, Satisfaction::Complete {condition} if condition.csv == None && condition.timelock == None)
             );
         }
     
    -    // single key, 1 prv and 1 pub key descriptor, required 1 prv keys
    -    #[test]
    -    #[ignore] // see https://github.com/bitcoindevkit/bdk/issues/225
    -    fn test_extract_policy_for_single_wsh_multi_complete_1of2() {
    -        let secp = Secp256k1::new();
    -
    -        let (_prvkey0, pubkey0, fingerprint0) = setup_keys(TPRV0_STR, PATH, &secp);
    -        let (prvkey1, _pubkey1, fingerprint1) = setup_keys(TPRV1_STR, PATH, &secp);
    -        let desc = descriptor!(sh(multi(1, pubkey0, prvkey1))).unwrap();
    -        let (wallet_desc, keymap) = desc
    -            .into_wallet_descriptor(&secp, Network::Testnet)
    -            .unwrap();
    -        let signers_container = Arc::new(SignersContainer::build(keymap, &wallet_desc, &secp));
    -        let policy = wallet_desc
    -            .extract_policy(&signers_container, BuildSatisfaction::None, &secp)
    -            .unwrap()
    -            .unwrap();
    +    // single key, 1 prv and 1 pub key descriptor, required 1 prv keys
    +    #[test]
    +    #[ignore] // see https://github.com/bitcoindevkit/bdk/issues/225
    +    fn test_extract_policy_for_single_wsh_multi_complete_1of2() {
    +        let secp = Secp256k1::new();
    +
    +        let (_prvkey0, pubkey0, fingerprint0) = setup_keys(TPRV0_STR, PATH, &secp);
    +        let (prvkey1, _pubkey1, fingerprint1) = setup_keys(TPRV1_STR, PATH, &secp);
    +        let desc = descriptor!(sh(multi(1, pubkey0, prvkey1))).unwrap();
    +        let (wallet_desc, keymap) = desc
    +            .into_wallet_descriptor(&secp, Network::Testnet)
    +            .unwrap();
    +        let signers_container = Arc::new(SignersContainer::build(keymap, &wallet_desc, &secp));
    +        let policy = wallet_desc
    +            .extract_policy(&signers_container, BuildSatisfaction::None, &secp)
    +            .unwrap()
    +            .unwrap();
     
             assert!(
    -            matches!(policy.item, Multisig { keys, threshold } if threshold == 1
    -            && keys[0] == PkOrF::Fingerprint(fingerprint0)
    -            && keys[1] == PkOrF::Fingerprint(fingerprint1))
    +            matches!(policy.item, Multisig { keys, threshold } if threshold == 1
    +            && keys[0] == PkOrF::Fingerprint(fingerprint0)
    +            && keys[1] == PkOrF::Fingerprint(fingerprint1))
             );
             assert!(
    -            matches!(policy.contribution, Satisfaction::PartialComplete { n, m, items, conditions, .. } if n == 2
    -             && m == 1
    -             && items.len() == 2
    -             && conditions.contains_key(&vec![0])
    -             && conditions.contains_key(&vec![1])
    +            matches!(policy.contribution, Satisfaction::PartialComplete { n, m, items, conditions, .. } if n == 2
    +             && m == 1
    +             && items.len() == 2
    +             && conditions.contains_key(&vec![0])
    +             && conditions.contains_key(&vec![1])
                 )
             );
         }
     
    -    // test ExtractPolicy trait with descriptors containing timelocks in a thresh()
    +    // test ExtractPolicy trait with descriptors containing timelocks in a thresh()
     
    -    #[test]
    -    #[ignore] // see https://github.com/bitcoindevkit/bdk/issues/225
    -    fn test_extract_policy_for_wsh_multi_timelock() {
    -        let secp = Secp256k1::new();
    +    #[test]
    +    #[ignore] // see https://github.com/bitcoindevkit/bdk/issues/225
    +    fn test_extract_policy_for_wsh_multi_timelock() {
    +        let secp = Secp256k1::new();
     
    -        let (prvkey0, _pubkey0, _fingerprint0) = setup_keys(TPRV0_STR, PATH, &secp);
    -        let (_prvkey1, pubkey1, _fingerprint1) = setup_keys(TPRV1_STR, PATH, &secp);
    -        let sequence = 50;
    -        #[rustfmt::skip]
    -        let desc = descriptor!(wsh(thresh(
    +        let (prvkey0, _pubkey0, _fingerprint0) = setup_keys(TPRV0_STR, PATH, &secp);
    +        let (_prvkey1, pubkey1, _fingerprint1) = setup_keys(TPRV1_STR, PATH, &secp);
    +        let sequence = 50;
    +        #[rustfmt::skip]
    +        let desc = descriptor!(wsh(thresh(
                 2,
    -            pk(prvkey0),
    -            s:pk(pubkey1),
    -            s:d:v:older(sequence)
    +            pk(prvkey0),
    +            s:pk(pubkey1),
    +            s:d:v:older(sequence)
             )))
    -        .unwrap();
    +        .unwrap();
     
    -        let (wallet_desc, keymap) = desc
    -            .into_wallet_descriptor(&secp, Network::Testnet)
    -            .unwrap();
    -        let signers_container = Arc::new(SignersContainer::build(keymap, &wallet_desc, &secp));
    -        let policy = wallet_desc
    -            .extract_policy(&signers_container, BuildSatisfaction::None, &secp)
    -            .unwrap()
    -            .unwrap();
    +        let (wallet_desc, keymap) = desc
    +            .into_wallet_descriptor(&secp, Network::Testnet)
    +            .unwrap();
    +        let signers_container = Arc::new(SignersContainer::build(keymap, &wallet_desc, &secp));
    +        let policy = wallet_desc
    +            .extract_policy(&signers_container, BuildSatisfaction::None, &secp)
    +            .unwrap()
    +            .unwrap();
     
             assert!(
    -            matches!(&policy.item, Thresh { items, threshold } if items.len() == 3 && threshold == &2)
    +            matches!(&policy.item, Thresh { items, threshold } if items.len() == 3 && threshold == &2)
             );
     
             assert!(
    -            matches!(&policy.contribution, Satisfaction::PartialComplete { n, m, items, conditions, .. } if n == &3
    -             && m == &2
    -             && items.len() == 3
    -             && conditions.get(&vec![0,1]).unwrap().iter().next().unwrap().csv.is_none()
    -             && conditions.get(&vec![0,2]).unwrap().iter().next().unwrap().csv == Some(Sequence(sequence))
    -             && conditions.get(&vec![1,2]).unwrap().iter().next().unwrap().csv == Some(Sequence(sequence))
    +            matches!(&policy.contribution, Satisfaction::PartialComplete { n, m, items, conditions, .. } if n == &3
    +             && m == &2
    +             && items.len() == 3
    +             && conditions.get(&vec![0,1]).unwrap().iter().next().unwrap().csv.is_none()
    +             && conditions.get(&vec![0,2]).unwrap().iter().next().unwrap().csv == Some(Sequence(sequence))
    +             && conditions.get(&vec![1,2]).unwrap().iter().next().unwrap().csv == Some(Sequence(sequence))
                 )
             );
         }
     
    -    // - mixed timelocks should fail
    -
    -    #[test]
    -    #[ignore]
    -    fn test_extract_policy_for_wsh_mixed_timelocks() {
    -        let secp = Secp256k1::new();
    -        let (prvkey0, _pubkey0, _fingerprint0) = setup_keys(TPRV0_STR, PATH, &secp);
    -        let locktime_threshold = 500000000; // if less than this means block number, else block time in seconds
    -        let locktime_blocks = 100;
    -        let locktime_seconds = locktime_blocks + locktime_threshold;
    -        let desc = descriptor!(sh(and_v(
    -            v: pk(prvkey0),
    -            and_v(v: after(locktime_seconds), after(locktime_blocks))
    +    // - mixed timelocks should fail
    +
    +    #[test]
    +    #[ignore]
    +    fn test_extract_policy_for_wsh_mixed_timelocks() {
    +        let secp = Secp256k1::new();
    +        let (prvkey0, _pubkey0, _fingerprint0) = setup_keys(TPRV0_STR, PATH, &secp);
    +        let locktime_threshold = 500000000; // if less than this means block number, else block time in seconds
    +        let locktime_blocks = 100;
    +        let locktime_seconds = locktime_blocks + locktime_threshold;
    +        let desc = descriptor!(sh(and_v(
    +            v: pk(prvkey0),
    +            and_v(v: after(locktime_seconds), after(locktime_blocks))
             )))
    -        .unwrap();
    -        let (wallet_desc, keymap) = desc
    -            .into_wallet_descriptor(&secp, Network::Testnet)
    -            .unwrap();
    -        let signers_container = Arc::new(SignersContainer::build(keymap, &wallet_desc, &secp));
    -        let policy = wallet_desc
    -            .extract_policy(&signers_container, BuildSatisfaction::None, &secp)
    -            .unwrap()
    -            .unwrap();
    -        println!("desc policy = {:?}", policy); // TODO remove
    -                                                // TODO how should this fail with mixed timelocks?
    -    }
    -
    -    // - multiple timelocks of the same type should be correctly merged together
    -    #[test]
    -    #[ignore]
    -    fn test_extract_policy_for_multiple_same_timelocks() {
    -        let secp = Secp256k1::new();
    -        let (prvkey0, _pubkey0, _fingerprint0) = setup_keys(TPRV0_STR, PATH, &secp);
    -        let locktime_blocks0 = 100;
    -        let locktime_blocks1 = 200;
    -        let desc = descriptor!(sh(and_v(
    -            v: pk(prvkey0),
    -            and_v(v: after(locktime_blocks0), after(locktime_blocks1))
    +        .unwrap();
    +        let (wallet_desc, keymap) = desc
    +            .into_wallet_descriptor(&secp, Network::Testnet)
    +            .unwrap();
    +        let signers_container = Arc::new(SignersContainer::build(keymap, &wallet_desc, &secp));
    +        let policy = wallet_desc
    +            .extract_policy(&signers_container, BuildSatisfaction::None, &secp)
    +            .unwrap()
    +            .unwrap();
    +        println!("desc policy = {:?}", policy); // TODO remove
    +                                                // TODO how should this fail with mixed timelocks?
    +    }
    +
    +    // - multiple timelocks of the same type should be correctly merged together
    +    #[test]
    +    #[ignore]
    +    fn test_extract_policy_for_multiple_same_timelocks() {
    +        let secp = Secp256k1::new();
    +        let (prvkey0, _pubkey0, _fingerprint0) = setup_keys(TPRV0_STR, PATH, &secp);
    +        let locktime_blocks0 = 100;
    +        let locktime_blocks1 = 200;
    +        let desc = descriptor!(sh(and_v(
    +            v: pk(prvkey0),
    +            and_v(v: after(locktime_blocks0), after(locktime_blocks1))
             )))
    -        .unwrap();
    -        let (wallet_desc, keymap) = desc
    -            .into_wallet_descriptor(&secp, Network::Testnet)
    -            .unwrap();
    -        let signers_container = Arc::new(SignersContainer::build(keymap, &wallet_desc, &secp));
    -        let policy = wallet_desc
    -            .extract_policy(&signers_container, BuildSatisfaction::None, &secp)
    -            .unwrap()
    -            .unwrap();
    -        println!("desc policy = {:?}", policy); // TODO remove
    -                                                // TODO how should this merge timelocks?
    -        let (prvkey1, _pubkey1, _fingerprint1) = setup_keys(TPRV0_STR, PATH, &secp);
    -        let locktime_seconds0 = 500000100;
    -        let locktime_seconds1 = 500000200;
    -        let desc = descriptor!(sh(and_v(
    -            v: pk(prvkey1),
    -            and_v(v: after(locktime_seconds0), after(locktime_seconds1))
    +        .unwrap();
    +        let (wallet_desc, keymap) = desc
    +            .into_wallet_descriptor(&secp, Network::Testnet)
    +            .unwrap();
    +        let signers_container = Arc::new(SignersContainer::build(keymap, &wallet_desc, &secp));
    +        let policy = wallet_desc
    +            .extract_policy(&signers_container, BuildSatisfaction::None, &secp)
    +            .unwrap()
    +            .unwrap();
    +        println!("desc policy = {:?}", policy); // TODO remove
    +                                                // TODO how should this merge timelocks?
    +        let (prvkey1, _pubkey1, _fingerprint1) = setup_keys(TPRV0_STR, PATH, &secp);
    +        let locktime_seconds0 = 500000100;
    +        let locktime_seconds1 = 500000200;
    +        let desc = descriptor!(sh(and_v(
    +            v: pk(prvkey1),
    +            and_v(v: after(locktime_seconds0), after(locktime_seconds1))
             )))
    -        .unwrap();
    -        let (wallet_desc, keymap) = desc
    -            .into_wallet_descriptor(&secp, Network::Testnet)
    -            .unwrap();
    -        let signers_container = Arc::new(SignersContainer::build(keymap, &wallet_desc, &secp));
    -        let policy = wallet_desc
    -            .extract_policy(&signers_container, BuildSatisfaction::None, &secp)
    -            .unwrap()
    -            .unwrap();
    -
    -        println!("desc policy = {:?}", policy); // TODO remove
    -
    -        // TODO how should this merge timelocks?
    -    }
    -
    -    #[test]
    -    fn test_get_condition_multisig() {
    -        let secp = Secp256k1::new();
    -
    -        let (_, pk0, _) = setup_keys(TPRV0_STR, PATH, &secp);
    -        let (_, pk1, _) = setup_keys(TPRV1_STR, PATH, &secp);
    -
    -        let desc = descriptor!(wsh(multi(1, pk0, pk1))).unwrap();
    -        let (wallet_desc, keymap) = desc
    -            .into_wallet_descriptor(&secp, Network::Testnet)
    -            .unwrap();
    -        let signers_container = Arc::new(SignersContainer::build(keymap, &wallet_desc, &secp));
    -
    -        let policy = wallet_desc
    -            .extract_policy(&signers_container, BuildSatisfaction::None, &secp)
    -            .unwrap()
    -            .unwrap();
    -
    -        // no args, choose the default
    -        let no_args = policy.get_condition(&vec![].into_iter().collect());
    -        assert_eq!(no_args, Ok(Condition::default()));
    -
    -        // enough args
    -        let eq_thresh =
    -            policy.get_condition(&vec![(policy.id.clone(), vec![0])].into_iter().collect());
    -        assert_eq!(eq_thresh, Ok(Condition::default()));
    -
    -        // more args, it doesn't really change anything
    -        let gt_thresh =
    -            policy.get_condition(&vec![(policy.id.clone(), vec![0, 1])].into_iter().collect());
    -        assert_eq!(gt_thresh, Ok(Condition::default()));
    -
    -        // not enough args, error
    -        let lt_thresh =
    -            policy.get_condition(&vec![(policy.id.clone(), vec![])].into_iter().collect());
    +        .unwrap();
    +        let (wallet_desc, keymap) = desc
    +            .into_wallet_descriptor(&secp, Network::Testnet)
    +            .unwrap();
    +        let signers_container = Arc::new(SignersContainer::build(keymap, &wallet_desc, &secp));
    +        let policy = wallet_desc
    +            .extract_policy(&signers_container, BuildSatisfaction::None, &secp)
    +            .unwrap()
    +            .unwrap();
    +
    +        println!("desc policy = {:?}", policy); // TODO remove
    +
    +        // TODO how should this merge timelocks?
    +    }
    +
    +    #[test]
    +    fn test_get_condition_multisig() {
    +        let secp = Secp256k1::new();
    +
    +        let (_, pk0, _) = setup_keys(TPRV0_STR, PATH, &secp);
    +        let (_, pk1, _) = setup_keys(TPRV1_STR, PATH, &secp);
    +
    +        let desc = descriptor!(wsh(multi(1, pk0, pk1))).unwrap();
    +        let (wallet_desc, keymap) = desc
    +            .into_wallet_descriptor(&secp, Network::Testnet)
    +            .unwrap();
    +        let signers_container = Arc::new(SignersContainer::build(keymap, &wallet_desc, &secp));
    +
    +        let policy = wallet_desc
    +            .extract_policy(&signers_container, BuildSatisfaction::None, &secp)
    +            .unwrap()
    +            .unwrap();
    +
    +        // no args, choose the default
    +        let no_args = policy.get_condition(&vec![].into_iter().collect());
    +        assert_eq!(no_args, Ok(Condition::default()));
    +
    +        // enough args
    +        let eq_thresh =
    +            policy.get_condition(&vec![(policy.id.clone(), vec![0])].into_iter().collect());
    +        assert_eq!(eq_thresh, Ok(Condition::default()));
    +
    +        // more args, it doesn't really change anything
    +        let gt_thresh =
    +            policy.get_condition(&vec![(policy.id.clone(), vec![0, 1])].into_iter().collect());
    +        assert_eq!(gt_thresh, Ok(Condition::default()));
    +
    +        // not enough args, error
    +        let lt_thresh =
    +            policy.get_condition(&vec![(policy.id.clone(), vec![])].into_iter().collect());
             assert_eq!(
    -            lt_thresh,
    -            Err(PolicyError::NotEnoughItemsSelected(policy.id.clone()))
    +            lt_thresh,
    +            Err(PolicyError::NotEnoughItemsSelected(policy.id.clone()))
             );
     
    -        // index out of range
    -        let out_of_range =
    -            policy.get_condition(&vec![(policy.id.clone(), vec![5])].into_iter().collect());
    -        assert_eq!(out_of_range, Err(PolicyError::IndexOutOfRange(5)));
    +        // index out of range
    +        let out_of_range =
    +            policy.get_condition(&vec![(policy.id.clone(), vec![5])].into_iter().collect());
    +        assert_eq!(out_of_range, Err(PolicyError::IndexOutOfRange(5)));
         }
     
    -    const ALICE_TPRV_STR:&str = "tprv8ZgxMBicQKsPf6T5X327efHnvJDr45Xnb8W4JifNWtEoqXu9MRYS4v1oYe6DFcMVETxy5w3bqpubYRqvcVTqovG1LifFcVUuJcbwJwrhYzP";
    -    const BOB_TPRV_STR:&str = "tprv8ZgxMBicQKsPeinZ155cJAn117KYhbaN6MV3WeG6sWhxWzcvX1eg1awd4C9GpUN1ncLEM2rzEvunAg3GizdZD4QPPCkisTz99tXXB4wZArp";
    -    const CAROL_TPRV_STR:&str = "tprv8ZgxMBicQKsPdC3CicFifuLCEyVVdXVUNYorxUWj3iGZ6nimnLAYAY9SYB7ib8rKzRxrCKFcEytCt6szwd2GHnGPRCBLAEAoSVDefSNk4Bt";
    -    const ALICE_BOB_PATH: &str = "m/0'";
    +    const ALICE_TPRV_STR:&str = "tprv8ZgxMBicQKsPf6T5X327efHnvJDr45Xnb8W4JifNWtEoqXu9MRYS4v1oYe6DFcMVETxy5w3bqpubYRqvcVTqovG1LifFcVUuJcbwJwrhYzP";
    +    const BOB_TPRV_STR:&str = "tprv8ZgxMBicQKsPeinZ155cJAn117KYhbaN6MV3WeG6sWhxWzcvX1eg1awd4C9GpUN1ncLEM2rzEvunAg3GizdZD4QPPCkisTz99tXXB4wZArp";
    +    const CAROL_TPRV_STR:&str = "tprv8ZgxMBicQKsPdC3CicFifuLCEyVVdXVUNYorxUWj3iGZ6nimnLAYAY9SYB7ib8rKzRxrCKFcEytCt6szwd2GHnGPRCBLAEAoSVDefSNk4Bt";
    +    const ALICE_BOB_PATH: &str = "m/0'";
     
    -    #[test]
    -    fn test_extract_satisfaction() {
    -        const ALICE_SIGNED_PSBT: &str = "cHNidP8BAFMBAAAAAZb0njwT2wRS3AumaaP3yb7T4MxOePpSWih4Nq+jWChMAQAAAAD/////Af4lAAAAAAAAF6kUXv2Fn+YemPP4PUpNR1ZbU16/eRCHAAAAAAABASuJJgAAAAAAACIAIERw5kTLo9DUH9QDJSClHQwPpC7VGJ+ZMDpa8U+2fzcYIgIDeAtjYQk/Vfu4db2+68hyMKjc38+kWl5sP5QH8L42ZstHMEQCIBj0jLjUeVYXNQ6cqB+gbtvuKMjV54wSgWlm1cfcgpHVAiBa3DtC9l/1Mt4IDCvR7mmwQd3eAP/m5++81euhJNSrgQEBBUdSIQN4C2NhCT9V+7h1vb7ryHIwqNzfz6RaXmw/lAfwvjZmyyEC+GE/y+LptI8xmiR6sOe998IGzybox0Qfz4+BQl1nmYhSriIGAvhhP8vi6bSPMZokerDnvffCBs8m6MdEH8+PgUJdZ5mIDBwu7j4AAACAAAAAACIGA3gLY2EJP1X7uHW9vuvIcjCo3N/PpFpebD+UB/C+NmbLDMkRfC4AAACAAAAAAAAA";
    -        const BOB_SIGNED_PSBT: &str =   "cHNidP8BAFMBAAAAAZb0njwT2wRS3AumaaP3yb7T4MxOePpSWih4Nq+jWChMAQAAAAD/////Af4lAAAAAAAAF6kUXv2Fn+YemPP4PUpNR1ZbU16/eRCHAAAAAAABASuJJgAAAAAAACIAIERw5kTLo9DUH9QDJSClHQwPpC7VGJ+ZMDpa8U+2fzcYIgIC+GE/y+LptI8xmiR6sOe998IGzybox0Qfz4+BQl1nmYhIMEUCIQD5zDtM5MwklurwJ5aW76RsO36Iqyu+6uMdVlhL6ws2GQIgesAiz4dbKS7UmhDsC/c1ezu0o6hp00UUtsCMfUZ4anYBAQVHUiEDeAtjYQk/Vfu4db2+68hyMKjc38+kWl5sP5QH8L42ZsshAvhhP8vi6bSPMZokerDnvffCBs8m6MdEH8+PgUJdZ5mIUq4iBgL4YT/L4um0jzGaJHqw5733wgbPJujHRB/Pj4FCXWeZiAwcLu4+AAAAgAAAAAAiBgN4C2NhCT9V+7h1vb7ryHIwqNzfz6RaXmw/lAfwvjZmywzJEXwuAAAAgAAAAAAAAA==";
    -        const ALICE_BOB_SIGNED_PSBT: &str =   "cHNidP8BAFMBAAAAAZb0njwT2wRS3AumaaP3yb7T4MxOePpSWih4Nq+jWChMAQAAAAD/////Af4lAAAAAAAAF6kUXv2Fn+YemPP4PUpNR1ZbU16/eRCHAAAAAAABASuJJgAAAAAAACIAIERw5kTLo9DUH9QDJSClHQwPpC7VGJ+ZMDpa8U+2fzcYIgIC+GE/y+LptI8xmiR6sOe998IGzybox0Qfz4+BQl1nmYhIMEUCIQD5zDtM5MwklurwJ5aW76RsO36Iqyu+6uMdVlhL6ws2GQIgesAiz4dbKS7UmhDsC/c1ezu0o6hp00UUtsCMfUZ4anYBIgIDeAtjYQk/Vfu4db2+68hyMKjc38+kWl5sP5QH8L42ZstHMEQCIBj0jLjUeVYXNQ6cqB+gbtvuKMjV54wSgWlm1cfcgpHVAiBa3DtC9l/1Mt4IDCvR7mmwQd3eAP/m5++81euhJNSrgQEBBUdSIQN4C2NhCT9V+7h1vb7ryHIwqNzfz6RaXmw/lAfwvjZmyyEC+GE/y+LptI8xmiR6sOe998IGzybox0Qfz4+BQl1nmYhSriIGAvhhP8vi6bSPMZokerDnvffCBs8m6MdEH8+PgUJdZ5mIDBwu7j4AAACAAAAAACIGA3gLY2EJP1X7uHW9vuvIcjCo3N/PpFpebD+UB/C+NmbLDMkRfC4AAACAAAAAAAEHAAEI2wQARzBEAiAY9Iy41HlWFzUOnKgfoG7b7ijI1eeMEoFpZtXH3IKR1QIgWtw7QvZf9TLeCAwr0e5psEHd3gD/5ufvvNXroSTUq4EBSDBFAiEA+cw7TOTMJJbq8CeWlu+kbDt+iKsrvurjHVZYS+sLNhkCIHrAIs+HWyku1JoQ7Av3NXs7tKOoadNFFLbAjH1GeGp2AUdSIQN4C2NhCT9V+7h1vb7ryHIwqNzfz6RaXmw/lAfwvjZmyyEC+GE/y+LptI8xmiR6sOe998IGzybox0Qfz4+BQl1nmYhSrgAA";
    +    #[test]
    +    fn test_extract_satisfaction() {
    +        const ALICE_SIGNED_PSBT: &str = "cHNidP8BAFMBAAAAAZb0njwT2wRS3AumaaP3yb7T4MxOePpSWih4Nq+jWChMAQAAAAD/////Af4lAAAAAAAAF6kUXv2Fn+YemPP4PUpNR1ZbU16/eRCHAAAAAAABASuJJgAAAAAAACIAIERw5kTLo9DUH9QDJSClHQwPpC7VGJ+ZMDpa8U+2fzcYIgIDeAtjYQk/Vfu4db2+68hyMKjc38+kWl5sP5QH8L42ZstHMEQCIBj0jLjUeVYXNQ6cqB+gbtvuKMjV54wSgWlm1cfcgpHVAiBa3DtC9l/1Mt4IDCvR7mmwQd3eAP/m5++81euhJNSrgQEBBUdSIQN4C2NhCT9V+7h1vb7ryHIwqNzfz6RaXmw/lAfwvjZmyyEC+GE/y+LptI8xmiR6sOe998IGzybox0Qfz4+BQl1nmYhSriIGAvhhP8vi6bSPMZokerDnvffCBs8m6MdEH8+PgUJdZ5mIDBwu7j4AAACAAAAAACIGA3gLY2EJP1X7uHW9vuvIcjCo3N/PpFpebD+UB/C+NmbLDMkRfC4AAACAAAAAAAAA";
    +        const BOB_SIGNED_PSBT: &str =   "cHNidP8BAFMBAAAAAZb0njwT2wRS3AumaaP3yb7T4MxOePpSWih4Nq+jWChMAQAAAAD/////Af4lAAAAAAAAF6kUXv2Fn+YemPP4PUpNR1ZbU16/eRCHAAAAAAABASuJJgAAAAAAACIAIERw5kTLo9DUH9QDJSClHQwPpC7VGJ+ZMDpa8U+2fzcYIgIC+GE/y+LptI8xmiR6sOe998IGzybox0Qfz4+BQl1nmYhIMEUCIQD5zDtM5MwklurwJ5aW76RsO36Iqyu+6uMdVlhL6ws2GQIgesAiz4dbKS7UmhDsC/c1ezu0o6hp00UUtsCMfUZ4anYBAQVHUiEDeAtjYQk/Vfu4db2+68hyMKjc38+kWl5sP5QH8L42ZsshAvhhP8vi6bSPMZokerDnvffCBs8m6MdEH8+PgUJdZ5mIUq4iBgL4YT/L4um0jzGaJHqw5733wgbPJujHRB/Pj4FCXWeZiAwcLu4+AAAAgAAAAAAiBgN4C2NhCT9V+7h1vb7ryHIwqNzfz6RaXmw/lAfwvjZmywzJEXwuAAAAgAAAAAAAAA==";
    +        const ALICE_BOB_SIGNED_PSBT: &str =   "cHNidP8BAFMBAAAAAZb0njwT2wRS3AumaaP3yb7T4MxOePpSWih4Nq+jWChMAQAAAAD/////Af4lAAAAAAAAF6kUXv2Fn+YemPP4PUpNR1ZbU16/eRCHAAAAAAABASuJJgAAAAAAACIAIERw5kTLo9DUH9QDJSClHQwPpC7VGJ+ZMDpa8U+2fzcYIgIC+GE/y+LptI8xmiR6sOe998IGzybox0Qfz4+BQl1nmYhIMEUCIQD5zDtM5MwklurwJ5aW76RsO36Iqyu+6uMdVlhL6ws2GQIgesAiz4dbKS7UmhDsC/c1ezu0o6hp00UUtsCMfUZ4anYBIgIDeAtjYQk/Vfu4db2+68hyMKjc38+kWl5sP5QH8L42ZstHMEQCIBj0jLjUeVYXNQ6cqB+gbtvuKMjV54wSgWlm1cfcgpHVAiBa3DtC9l/1Mt4IDCvR7mmwQd3eAP/m5++81euhJNSrgQEBBUdSIQN4C2NhCT9V+7h1vb7ryHIwqNzfz6RaXmw/lAfwvjZmyyEC+GE/y+LptI8xmiR6sOe998IGzybox0Qfz4+BQl1nmYhSriIGAvhhP8vi6bSPMZokerDnvffCBs8m6MdEH8+PgUJdZ5mIDBwu7j4AAACAAAAAACIGA3gLY2EJP1X7uHW9vuvIcjCo3N/PpFpebD+UB/C+NmbLDMkRfC4AAACAAAAAAAEHAAEI2wQARzBEAiAY9Iy41HlWFzUOnKgfoG7b7ijI1eeMEoFpZtXH3IKR1QIgWtw7QvZf9TLeCAwr0e5psEHd3gD/5ufvvNXroSTUq4EBSDBFAiEA+cw7TOTMJJbq8CeWlu+kbDt+iKsrvurjHVZYS+sLNhkCIHrAIs+HWyku1JoQ7Av3NXs7tKOoadNFFLbAjH1GeGp2AUdSIQN4C2NhCT9V+7h1vb7ryHIwqNzfz6RaXmw/lAfwvjZmyyEC+GE/y+LptI8xmiR6sOe998IGzybox0Qfz4+BQl1nmYhSrgAA";
     
    -        let secp = Secp256k1::new();
    +        let secp = Secp256k1::new();
     
    -        let (prvkey_alice, _, _) = setup_keys(ALICE_TPRV_STR, ALICE_BOB_PATH, &secp);
    -        let (prvkey_bob, _, _) = setup_keys(BOB_TPRV_STR, ALICE_BOB_PATH, &secp);
    +        let (prvkey_alice, _, _) = setup_keys(ALICE_TPRV_STR, ALICE_BOB_PATH, &secp);
    +        let (prvkey_bob, _, _) = setup_keys(BOB_TPRV_STR, ALICE_BOB_PATH, &secp);
     
    -        let desc = descriptor!(wsh(multi(2, prvkey_alice, prvkey_bob))).unwrap();
    +        let desc = descriptor!(wsh(multi(2, prvkey_alice, prvkey_bob))).unwrap();
     
    -        let (wallet_desc, keymap) = desc
    -            .into_wallet_descriptor(&secp, Network::Testnet)
    -            .unwrap();
    +        let (wallet_desc, keymap) = desc
    +            .into_wallet_descriptor(&secp, Network::Testnet)
    +            .unwrap();
     
    -        let addr = wallet_desc
    -            .at_derivation_index(0)
    -            .address(Network::Testnet)
    -            .unwrap();
    +        let addr = wallet_desc
    +            .at_derivation_index(0)
    +            .address(Network::Testnet)
    +            .unwrap();
             assert_eq!(
                 "tb1qg3cwv3xt50gdg875qvjjpfgaps86gtk4rz0ejvp6ttc5ldnlxuvqlcn0xk",
    -            addr.to_string()
    +            addr.to_string()
             );
     
    -        let signers_container = Arc::new(SignersContainer::build(keymap, &wallet_desc, &secp));
    +        let signers_container = Arc::new(SignersContainer::build(keymap, &wallet_desc, &secp));
     
    -        let psbt = Psbt::from_str(ALICE_SIGNED_PSBT).unwrap();
    +        let psbt = Psbt::from_str(ALICE_SIGNED_PSBT).unwrap();
     
    -        let policy_alice_psbt = wallet_desc
    -            .extract_policy(&signers_container, BuildSatisfaction::Psbt(&psbt), &secp)
    -            .unwrap()
    -            .unwrap();
    -        //println!("{}", serde_json::to_string(&policy_alice_psbt).unwrap());
    +        let policy_alice_psbt = wallet_desc
    +            .extract_policy(&signers_container, BuildSatisfaction::Psbt(&psbt), &secp)
    +            .unwrap()
    +            .unwrap();
    +        //println!("{}", serde_json::to_string(&policy_alice_psbt).unwrap());
     
    -        assert!(
    -            matches!(&policy_alice_psbt.satisfaction, Satisfaction::Partial { n, m, items, .. } if n == &2
    -             && m == &2
    -             && items == &vec![0]
    +        assert!(
    +            matches!(&policy_alice_psbt.satisfaction, Satisfaction::Partial { n, m, items, .. } if n == &2
    +             && m == &2
    +             && items == &vec![0]
                 )
             );
     
    -        let psbt = Psbt::from_str(BOB_SIGNED_PSBT).unwrap();
    -        let policy_bob_psbt = wallet_desc
    -            .extract_policy(&signers_container, BuildSatisfaction::Psbt(&psbt), &secp)
    -            .unwrap()
    -            .unwrap();
    -        //println!("{}", serde_json::to_string(&policy_bob_psbt).unwrap());
    -
    -        assert!(
    -            matches!(&policy_bob_psbt.satisfaction, Satisfaction::Partial { n, m, items, .. } if n == &2
    -             && m == &2
    -             && items == &vec![1]
    +        let psbt = Psbt::from_str(BOB_SIGNED_PSBT).unwrap();
    +        let policy_bob_psbt = wallet_desc
    +            .extract_policy(&signers_container, BuildSatisfaction::Psbt(&psbt), &secp)
    +            .unwrap()
    +            .unwrap();
    +        //println!("{}", serde_json::to_string(&policy_bob_psbt).unwrap());
    +
    +        assert!(
    +            matches!(&policy_bob_psbt.satisfaction, Satisfaction::Partial { n, m, items, .. } if n == &2
    +             && m == &2
    +             && items == &vec![1]
                 )
             );
     
    -        let psbt = Psbt::from_str(ALICE_BOB_SIGNED_PSBT).unwrap();
    -        let policy_alice_bob_psbt = wallet_desc
    -            .extract_policy(&signers_container, BuildSatisfaction::Psbt(&psbt), &secp)
    -            .unwrap()
    -            .unwrap();
    +        let psbt = Psbt::from_str(ALICE_BOB_SIGNED_PSBT).unwrap();
    +        let policy_alice_bob_psbt = wallet_desc
    +            .extract_policy(&signers_container, BuildSatisfaction::Psbt(&psbt), &secp)
    +            .unwrap()
    +            .unwrap();
             assert!(
    -            matches!(&policy_alice_bob_psbt.satisfaction, Satisfaction::PartialComplete { n, m, items, .. } if n == &2
    -             && m == &2
    -             && items == &vec![0, 1]
    +            matches!(&policy_alice_bob_psbt.satisfaction, Satisfaction::PartialComplete { n, m, items, .. } if n == &2
    +             && m == &2
    +             && items == &vec![0, 1]
                 )
             );
         }
     
    -    #[test]
    -    fn test_extract_satisfaction_timelock() {
    -        //const PSBT_POLICY_CONSIDER_TIMELOCK_NOT_EXPIRED: &str = "cHNidP8BAFMBAAAAAdld52uJFGT7Yde0YZdSVh2vL020Zm2exadH5R4GSNScAAAAAAD/////ATrcAAAAAAAAF6kUXv2Fn+YemPP4PUpNR1ZbU16/eRCHAAAAAAABASvI3AAAAAAAACIAILhzvvcBzw/Zfnc9ispRK0PCahxn1F6RHXTZAmw5tqNPAQVSdmNSsmlofCEDeAtjYQk/Vfu4db2+68hyMKjc38+kWl5sP5QH8L42Zsusk3whAvhhP8vi6bSPMZokerDnvffCBs8m6MdEH8+PgUJdZ5mIrJNShyIGAvhhP8vi6bSPMZokerDnvffCBs8m6MdEH8+PgUJdZ5mIDBwu7j4AAACAAAAAACIGA3gLY2EJP1X7uHW9vuvIcjCo3N/PpFpebD+UB/C+NmbLDMkRfC4AAACAAAAAAAAA";
    -        const PSBT_POLICY_CONSIDER_TIMELOCK_EXPIRED:     &str = "cHNidP8BAFMCAAAAAdld52uJFGT7Yde0YZdSVh2vL020Zm2exadH5R4GSNScAAAAAAACAAAAATrcAAAAAAAAF6kUXv2Fn+YemPP4PUpNR1ZbU16/eRCHAAAAAAABASvI3AAAAAAAACIAILhzvvcBzw/Zfnc9ispRK0PCahxn1F6RHXTZAmw5tqNPAQVSdmNSsmlofCEDeAtjYQk/Vfu4db2+68hyMKjc38+kWl5sP5QH8L42Zsusk3whAvhhP8vi6bSPMZokerDnvffCBs8m6MdEH8+PgUJdZ5mIrJNShyIGAvhhP8vi6bSPMZokerDnvffCBs8m6MdEH8+PgUJdZ5mIDBwu7j4AAACAAAAAACIGA3gLY2EJP1X7uHW9vuvIcjCo3N/PpFpebD+UB/C+NmbLDMkRfC4AAACAAAAAAAAA";
    -        const PSBT_POLICY_CONSIDER_TIMELOCK_EXPIRED_SIGNED: &str ="cHNidP8BAFMCAAAAAdld52uJFGT7Yde0YZdSVh2vL020Zm2exadH5R4GSNScAAAAAAACAAAAATrcAAAAAAAAF6kUXv2Fn+YemPP4PUpNR1ZbU16/eRCHAAAAAAABASvI3AAAAAAAACIAILhzvvcBzw/Zfnc9ispRK0PCahxn1F6RHXTZAmw5tqNPIgIDeAtjYQk/Vfu4db2+68hyMKjc38+kWl5sP5QH8L42ZstIMEUCIQCtZxNm6H3Ux3pnc64DSpgohMdBj+57xhFHcURYt2BpPAIgG3OnI7bcj/3GtWX1HHyYGSI7QGa/zq5YnsmK1Cw29NABAQVSdmNSsmlofCEDeAtjYQk/Vfu4db2+68hyMKjc38+kWl5sP5QH8L42Zsusk3whAvhhP8vi6bSPMZokerDnvffCBs8m6MdEH8+PgUJdZ5mIrJNShyIGAvhhP8vi6bSPMZokerDnvffCBs8m6MdEH8+PgUJdZ5mIDBwu7j4AAACAAAAAACIGA3gLY2EJP1X7uHW9vuvIcjCo3N/PpFpebD+UB/C+NmbLDMkRfC4AAACAAAAAAAEHAAEIoAQASDBFAiEArWcTZuh91Md6Z3OuA0qYKITHQY/ue8YRR3FEWLdgaTwCIBtzpyO23I/9xrVl9Rx8mBkiO0Bmv86uWJ7JitQsNvTQAQEBUnZjUrJpaHwhA3gLY2EJP1X7uHW9vuvIcjCo3N/PpFpebD+UB/C+NmbLrJN8IQL4YT/L4um0jzGaJHqw5733wgbPJujHRB/Pj4FCXWeZiKyTUocAAA==";
    +    #[test]
    +    fn test_extract_satisfaction_timelock() {
    +        //const PSBT_POLICY_CONSIDER_TIMELOCK_NOT_EXPIRED: &str = "cHNidP8BAFMBAAAAAdld52uJFGT7Yde0YZdSVh2vL020Zm2exadH5R4GSNScAAAAAAD/////ATrcAAAAAAAAF6kUXv2Fn+YemPP4PUpNR1ZbU16/eRCHAAAAAAABASvI3AAAAAAAACIAILhzvvcBzw/Zfnc9ispRK0PCahxn1F6RHXTZAmw5tqNPAQVSdmNSsmlofCEDeAtjYQk/Vfu4db2+68hyMKjc38+kWl5sP5QH8L42Zsusk3whAvhhP8vi6bSPMZokerDnvffCBs8m6MdEH8+PgUJdZ5mIrJNShyIGAvhhP8vi6bSPMZokerDnvffCBs8m6MdEH8+PgUJdZ5mIDBwu7j4AAACAAAAAACIGA3gLY2EJP1X7uHW9vuvIcjCo3N/PpFpebD+UB/C+NmbLDMkRfC4AAACAAAAAAAAA";
    +        const PSBT_POLICY_CONSIDER_TIMELOCK_EXPIRED:     &str = "cHNidP8BAFMCAAAAAdld52uJFGT7Yde0YZdSVh2vL020Zm2exadH5R4GSNScAAAAAAACAAAAATrcAAAAAAAAF6kUXv2Fn+YemPP4PUpNR1ZbU16/eRCHAAAAAAABASvI3AAAAAAAACIAILhzvvcBzw/Zfnc9ispRK0PCahxn1F6RHXTZAmw5tqNPAQVSdmNSsmlofCEDeAtjYQk/Vfu4db2+68hyMKjc38+kWl5sP5QH8L42Zsusk3whAvhhP8vi6bSPMZokerDnvffCBs8m6MdEH8+PgUJdZ5mIrJNShyIGAvhhP8vi6bSPMZokerDnvffCBs8m6MdEH8+PgUJdZ5mIDBwu7j4AAACAAAAAACIGA3gLY2EJP1X7uHW9vuvIcjCo3N/PpFpebD+UB/C+NmbLDMkRfC4AAACAAAAAAAAA";
    +        const PSBT_POLICY_CONSIDER_TIMELOCK_EXPIRED_SIGNED: &str ="cHNidP8BAFMCAAAAAdld52uJFGT7Yde0YZdSVh2vL020Zm2exadH5R4GSNScAAAAAAACAAAAATrcAAAAAAAAF6kUXv2Fn+YemPP4PUpNR1ZbU16/eRCHAAAAAAABASvI3AAAAAAAACIAILhzvvcBzw/Zfnc9ispRK0PCahxn1F6RHXTZAmw5tqNPIgIDeAtjYQk/Vfu4db2+68hyMKjc38+kWl5sP5QH8L42ZstIMEUCIQCtZxNm6H3Ux3pnc64DSpgohMdBj+57xhFHcURYt2BpPAIgG3OnI7bcj/3GtWX1HHyYGSI7QGa/zq5YnsmK1Cw29NABAQVSdmNSsmlofCEDeAtjYQk/Vfu4db2+68hyMKjc38+kWl5sP5QH8L42Zsusk3whAvhhP8vi6bSPMZokerDnvffCBs8m6MdEH8+PgUJdZ5mIrJNShyIGAvhhP8vi6bSPMZokerDnvffCBs8m6MdEH8+PgUJdZ5mIDBwu7j4AAACAAAAAACIGA3gLY2EJP1X7uHW9vuvIcjCo3N/PpFpebD+UB/C+NmbLDMkRfC4AAACAAAAAAAEHAAEIoAQASDBFAiEArWcTZuh91Md6Z3OuA0qYKITHQY/ue8YRR3FEWLdgaTwCIBtzpyO23I/9xrVl9Rx8mBkiO0Bmv86uWJ7JitQsNvTQAQEBUnZjUrJpaHwhA3gLY2EJP1X7uHW9vuvIcjCo3N/PpFpebD+UB/C+NmbLrJN8IQL4YT/L4um0jzGaJHqw5733wgbPJujHRB/Pj4FCXWeZiKyTUocAAA==";
     
    -        let secp = Secp256k1::new();
    +        let secp = Secp256k1::new();
     
    -        let (prvkey_alice, _, _) = setup_keys(ALICE_TPRV_STR, ALICE_BOB_PATH, &secp);
    -        let (prvkey_bob, _, _) = setup_keys(BOB_TPRV_STR, ALICE_BOB_PATH, &secp);
    +        let (prvkey_alice, _, _) = setup_keys(ALICE_TPRV_STR, ALICE_BOB_PATH, &secp);
    +        let (prvkey_bob, _, _) = setup_keys(BOB_TPRV_STR, ALICE_BOB_PATH, &secp);
     
    -        let desc =
    -            descriptor!(wsh(thresh(2,n:d:v:older(2),s:pk(prvkey_alice),s:pk(prvkey_bob)))).unwrap();
    +        let desc =
    +            descriptor!(wsh(thresh(2,n:d:v:older(2),s:pk(prvkey_alice),s:pk(prvkey_bob)))).unwrap();
     
    -        let (wallet_desc, keymap) = desc
    -            .into_wallet_descriptor(&secp, Network::Testnet)
    -            .unwrap();
    -        let signers_container = Arc::new(SignersContainer::build(keymap, &wallet_desc, &secp));
    +        let (wallet_desc, keymap) = desc
    +            .into_wallet_descriptor(&secp, Network::Testnet)
    +            .unwrap();
    +        let signers_container = Arc::new(SignersContainer::build(keymap, &wallet_desc, &secp));
     
    -        let addr = wallet_desc
    -            .at_derivation_index(0)
    -            .address(Network::Testnet)
    -            .unwrap();
    +        let addr = wallet_desc
    +            .at_derivation_index(0)
    +            .address(Network::Testnet)
    +            .unwrap();
             assert_eq!(
                 "tb1qsydsey4hexagwkvercqsmes6yet0ndkyt6uzcphtqnygjd8hmzmsfxrv58",
    -            addr.to_string()
    +            addr.to_string()
             );
     
    -        let psbt = Psbt::from_str(PSBT_POLICY_CONSIDER_TIMELOCK_EXPIRED).unwrap();
    +        let psbt = Psbt::from_str(PSBT_POLICY_CONSIDER_TIMELOCK_EXPIRED).unwrap();
     
    -        let build_sat = BuildSatisfaction::PsbtTimelocks {
    -            psbt: &psbt,
    -            current_height: 10,
    -            input_max_height: 9,
    +        let build_sat = BuildSatisfaction::PsbtTimelocks {
    +            psbt: &psbt,
    +            current_height: 10,
    +            input_max_height: 9,
             };
     
    -        let policy = wallet_desc
    -            .extract_policy(&signers_container, build_sat, &secp)
    -            .unwrap()
    -            .unwrap();
    +        let policy = wallet_desc
    +            .extract_policy(&signers_container, build_sat, &secp)
    +            .unwrap()
    +            .unwrap();
             assert!(
    -            matches!(&policy.satisfaction, Satisfaction::Partial { n, m, items, .. } if n == &3
    -             && m == &2
    -             && items.is_empty()
    +            matches!(&policy.satisfaction, Satisfaction::Partial { n, m, items, .. } if n == &3
    +             && m == &2
    +             && items.is_empty()
                 )
             );
    -        //println!("{}", serde_json::to_string(&policy).unwrap());
    +        //println!("{}", serde_json::to_string(&policy).unwrap());
     
    -        let build_sat_expired = BuildSatisfaction::PsbtTimelocks {
    -            psbt: &psbt,
    -            current_height: 12,
    -            input_max_height: 9,
    +        let build_sat_expired = BuildSatisfaction::PsbtTimelocks {
    +            psbt: &psbt,
    +            current_height: 12,
    +            input_max_height: 9,
             };
     
    -        let policy_expired = wallet_desc
    -            .extract_policy(&signers_container, build_sat_expired, &secp)
    -            .unwrap()
    -            .unwrap();
    +        let policy_expired = wallet_desc
    +            .extract_policy(&signers_container, build_sat_expired, &secp)
    +            .unwrap()
    +            .unwrap();
             assert!(
    -            matches!(&policy_expired.satisfaction, Satisfaction::Partial { n, m, items, .. } if n == &3
    -             && m == &2
    -             && items == &vec![0]
    +            matches!(&policy_expired.satisfaction, Satisfaction::Partial { n, m, items, .. } if n == &3
    +             && m == &2
    +             && items == &vec![0]
                 )
             );
    -        //println!("{}", serde_json::to_string(&policy_expired).unwrap());
    +        //println!("{}", serde_json::to_string(&policy_expired).unwrap());
     
    -        let psbt_signed = Psbt::from_str(PSBT_POLICY_CONSIDER_TIMELOCK_EXPIRED_SIGNED).unwrap();
    +        let psbt_signed = Psbt::from_str(PSBT_POLICY_CONSIDER_TIMELOCK_EXPIRED_SIGNED).unwrap();
     
    -        let build_sat_expired_signed = BuildSatisfaction::PsbtTimelocks {
    -            psbt: &psbt_signed,
    -            current_height: 12,
    -            input_max_height: 9,
    +        let build_sat_expired_signed = BuildSatisfaction::PsbtTimelocks {
    +            psbt: &psbt_signed,
    +            current_height: 12,
    +            input_max_height: 9,
             };
     
    -        let policy_expired_signed = wallet_desc
    -            .extract_policy(&signers_container, build_sat_expired_signed, &secp)
    -            .unwrap()
    -            .unwrap();
    +        let policy_expired_signed = wallet_desc
    +            .extract_policy(&signers_container, build_sat_expired_signed, &secp)
    +            .unwrap()
    +            .unwrap();
             assert!(
    -            matches!(&policy_expired_signed.satisfaction, Satisfaction::PartialComplete { n, m, items, .. } if n == &3
    -             && m == &2
    -             && items == &vec![0, 1]
    +            matches!(&policy_expired_signed.satisfaction, Satisfaction::PartialComplete { n, m, items, .. } if n == &3
    +             && m == &2
    +             && items == &vec![0, 1]
                 )
             );
    -        //println!("{}", serde_json::to_string(&policy_expired_signed).unwrap());
    -    }
    +        //println!("{}", serde_json::to_string(&policy_expired_signed).unwrap());
    +    }
     
    -    #[test]
    -    fn test_extract_pkh() {
    -        let secp = Secp256k1::new();
    +    #[test]
    +    fn test_extract_pkh() {
    +        let secp = Secp256k1::new();
     
    -        let (prvkey_alice, _, _) = setup_keys(ALICE_TPRV_STR, ALICE_BOB_PATH, &secp);
    -        let (prvkey_bob, _, _) = setup_keys(BOB_TPRV_STR, ALICE_BOB_PATH, &secp);
    -        let (prvkey_carol, _, _) = setup_keys(CAROL_TPRV_STR, ALICE_BOB_PATH, &secp);
    +        let (prvkey_alice, _, _) = setup_keys(ALICE_TPRV_STR, ALICE_BOB_PATH, &secp);
    +        let (prvkey_bob, _, _) = setup_keys(BOB_TPRV_STR, ALICE_BOB_PATH, &secp);
    +        let (prvkey_carol, _, _) = setup_keys(CAROL_TPRV_STR, ALICE_BOB_PATH, &secp);
     
    -        let desc = descriptor!(wsh(c: andor(
    -            pk(prvkey_alice),
    -            pk_k(prvkey_bob),
    -            pk_h(prvkey_carol),
    +        let desc = descriptor!(wsh(c: andor(
    +            pk(prvkey_alice),
    +            pk_k(prvkey_bob),
    +            pk_h(prvkey_carol),
             )))
    -        .unwrap();
    +        .unwrap();
     
    -        let (wallet_desc, keymap) = desc
    -            .into_wallet_descriptor(&secp, Network::Testnet)
    -            .unwrap();
    -        let signers_container = Arc::new(SignersContainer::build(keymap, &wallet_desc, &secp));
    +        let (wallet_desc, keymap) = desc
    +            .into_wallet_descriptor(&secp, Network::Testnet)
    +            .unwrap();
    +        let signers_container = Arc::new(SignersContainer::build(keymap, &wallet_desc, &secp));
     
    -        let policy = wallet_desc.extract_policy(&signers_container, BuildSatisfaction::None, &secp);
    -        assert!(policy.is_ok());
    +        let policy = wallet_desc.extract_policy(&signers_container, BuildSatisfaction::None, &secp);
    +        assert!(policy.is_ok());
         }
     
    -    #[test]
    -    fn test_extract_tr_key_spend() {
    -        let secp = Secp256k1::new();
    +    #[test]
    +    fn test_extract_tr_key_spend() {
    +        let secp = Secp256k1::new();
     
    -        let (prvkey, _, fingerprint) = setup_keys(ALICE_TPRV_STR, ALICE_BOB_PATH, &secp);
    +        let (prvkey, _, fingerprint) = setup_keys(ALICE_TPRV_STR, ALICE_BOB_PATH, &secp);
     
    -        let desc = descriptor!(tr(prvkey)).unwrap();
    -        let (wallet_desc, keymap) = desc
    -            .into_wallet_descriptor(&secp, Network::Testnet)
    -            .unwrap();
    -        let signers_container = Arc::new(SignersContainer::build(keymap, &wallet_desc, &secp));
    +        let desc = descriptor!(tr(prvkey)).unwrap();
    +        let (wallet_desc, keymap) = desc
    +            .into_wallet_descriptor(&secp, Network::Testnet)
    +            .unwrap();
    +        let signers_container = Arc::new(SignersContainer::build(keymap, &wallet_desc, &secp));
     
    -        let policy = wallet_desc
    -            .extract_policy(&signers_container, BuildSatisfaction::None, &secp)
    -            .unwrap();
    +        let policy = wallet_desc
    +            .extract_policy(&signers_container, BuildSatisfaction::None, &secp)
    +            .unwrap();
             assert_eq!(
    -            policy,
    -            Some(Policy {
    -                id: "48u0tz0n".to_string(),
    -                item: SatisfiableItem::SchnorrSignature(PkOrF::Fingerprint(fingerprint)),
    -                satisfaction: Satisfaction::None,
    -                contribution: Satisfaction::Complete {
    -                    condition: Condition::default()
    +            policy,
    +            Some(Policy {
    +                id: "48u0tz0n".to_string(),
    +                item: SatisfiableItem::SchnorrSignature(PkOrF::Fingerprint(fingerprint)),
    +                satisfaction: Satisfaction::None,
    +                contribution: Satisfaction::Complete {
    +                    condition: Condition::default()
                     }
                 })
             );
         }
     
    -    #[test]
    -    fn test_extract_tr_script_spend() {
    -        let secp = Secp256k1::new();
    +    #[test]
    +    fn test_extract_tr_script_spend() {
    +        let secp = Secp256k1::new();
     
    -        let (alice_prv, _, alice_fing) = setup_keys(ALICE_TPRV_STR, ALICE_BOB_PATH, &secp);
    -        let (_, bob_pub, bob_fing) = setup_keys(BOB_TPRV_STR, ALICE_BOB_PATH, &secp);
    +        let (alice_prv, _, alice_fing) = setup_keys(ALICE_TPRV_STR, ALICE_BOB_PATH, &secp);
    +        let (_, bob_pub, bob_fing) = setup_keys(BOB_TPRV_STR, ALICE_BOB_PATH, &secp);
     
    -        let desc = descriptor!(tr(bob_pub, pk(alice_prv))).unwrap();
    -        let (wallet_desc, keymap) = desc
    -            .into_wallet_descriptor(&secp, Network::Testnet)
    -            .unwrap();
    -        let signers_container = Arc::new(SignersContainer::build(keymap, &wallet_desc, &secp));
    +        let desc = descriptor!(tr(bob_pub, pk(alice_prv))).unwrap();
    +        let (wallet_desc, keymap) = desc
    +            .into_wallet_descriptor(&secp, Network::Testnet)
    +            .unwrap();
    +        let signers_container = Arc::new(SignersContainer::build(keymap, &wallet_desc, &secp));
     
    -        let policy = wallet_desc
    -            .extract_policy(&signers_container, BuildSatisfaction::None, &secp)
    -            .unwrap()
    -            .unwrap();
    +        let policy = wallet_desc
    +            .extract_policy(&signers_container, BuildSatisfaction::None, &secp)
    +            .unwrap()
    +            .unwrap();
     
             assert!(
    -            matches!(policy.item, SatisfiableItem::Thresh { ref items, threshold: 1 } if items.len() == 2)
    +            matches!(policy.item, SatisfiableItem::Thresh { ref items, threshold: 1 } if items.len() == 2)
             );
             assert!(
    -            matches!(policy.contribution, Satisfaction::PartialComplete { n: 2, m: 1, items, .. } if items == vec![1])
    +            matches!(policy.contribution, Satisfaction::PartialComplete { n: 2, m: 1, items, .. } if items == vec![1])
             );
     
    -        let alice_sig = SatisfiableItem::SchnorrSignature(PkOrF::Fingerprint(alice_fing));
    -        let bob_sig = SatisfiableItem::SchnorrSignature(PkOrF::Fingerprint(bob_fing));
    +        let alice_sig = SatisfiableItem::SchnorrSignature(PkOrF::Fingerprint(alice_fing));
    +        let bob_sig = SatisfiableItem::SchnorrSignature(PkOrF::Fingerprint(bob_fing));
     
    -        let thresh_items = match policy.item {
    -            SatisfiableItem::Thresh { items, .. } => items,
    -            _ => unreachable!(),
    +        let thresh_items = match policy.item {
    +            SatisfiableItem::Thresh { items, .. } => items,
    +            _ => unreachable!(),
             };
     
    -        assert_eq!(thresh_items[0].item, bob_sig);
    -        assert_eq!(thresh_items[1].item, alice_sig);
    +        assert_eq!(thresh_items[0].item, bob_sig);
    +        assert_eq!(thresh_items[1].item, alice_sig);
         }
     
    -    #[test]
    -    fn test_extract_tr_satisfaction_key_spend() {
    -        const UNSIGNED_PSBT: &str = "cHNidP8BAFMBAAAAAUKgMCqtGLSiGYhsTols2UJ/VQQgQi/SXO38uXs2SahdAQAAAAD/////ARyWmAAAAAAAF6kU4R3W8CnGzZcSsaovTYu0X8vHt3WHAAAAAAABASuAlpgAAAAAACJRIEiEBFjbZa1xdjLfFjrKzuC1F1LeRyI/gL6IuGKNmUuSIRYnkGTDxwXMHP32fkDFoGJY28trxbkkVgR2z7jZa2pOJA0AyRF8LgAAAIADAAAAARcgJ5Bkw8cFzBz99n5AxaBiWNvLa8W5JFYEds+42WtqTiQAAA==";
    -        const SIGNED_PSBT: &str = "cHNidP8BAFMBAAAAAUKgMCqtGLSiGYhsTols2UJ/VQQgQi/SXO38uXs2SahdAQAAAAD/////ARyWmAAAAAAAF6kU4R3W8CnGzZcSsaovTYu0X8vHt3WHAAAAAAABASuAlpgAAAAAACJRIEiEBFjbZa1xdjLfFjrKzuC1F1LeRyI/gL6IuGKNmUuSARNAIsRvARpRxuyQosVA7guRQT9vXr+S25W2tnP2xOGBsSgq7A4RL8yrbvwDmNlWw9R0Nc/6t+IsyCyy7dD/lbUGgyEWJ5Bkw8cFzBz99n5AxaBiWNvLa8W5JFYEds+42WtqTiQNAMkRfC4AAACAAwAAAAEXICeQZMPHBcwc/fZ+QMWgYljby2vFuSRWBHbPuNlrak4kAAA=";
    +    #[test]
    +    fn test_extract_tr_satisfaction_key_spend() {
    +        const UNSIGNED_PSBT: &str = "cHNidP8BAFMBAAAAAUKgMCqtGLSiGYhsTols2UJ/VQQgQi/SXO38uXs2SahdAQAAAAD/////ARyWmAAAAAAAF6kU4R3W8CnGzZcSsaovTYu0X8vHt3WHAAAAAAABASuAlpgAAAAAACJRIEiEBFjbZa1xdjLfFjrKzuC1F1LeRyI/gL6IuGKNmUuSIRYnkGTDxwXMHP32fkDFoGJY28trxbkkVgR2z7jZa2pOJA0AyRF8LgAAAIADAAAAARcgJ5Bkw8cFzBz99n5AxaBiWNvLa8W5JFYEds+42WtqTiQAAA==";
    +        const SIGNED_PSBT: &str = "cHNidP8BAFMBAAAAAUKgMCqtGLSiGYhsTols2UJ/VQQgQi/SXO38uXs2SahdAQAAAAD/////ARyWmAAAAAAAF6kU4R3W8CnGzZcSsaovTYu0X8vHt3WHAAAAAAABASuAlpgAAAAAACJRIEiEBFjbZa1xdjLfFjrKzuC1F1LeRyI/gL6IuGKNmUuSARNAIsRvARpRxuyQosVA7guRQT9vXr+S25W2tnP2xOGBsSgq7A4RL8yrbvwDmNlWw9R0Nc/6t+IsyCyy7dD/lbUGgyEWJ5Bkw8cFzBz99n5AxaBiWNvLa8W5JFYEds+42WtqTiQNAMkRfC4AAACAAwAAAAEXICeQZMPHBcwc/fZ+QMWgYljby2vFuSRWBHbPuNlrak4kAAA=";
     
    -        let unsigned_psbt = Psbt::from_str(UNSIGNED_PSBT).unwrap();
    -        let signed_psbt = Psbt::from_str(SIGNED_PSBT).unwrap();
    +        let unsigned_psbt = Psbt::from_str(UNSIGNED_PSBT).unwrap();
    +        let signed_psbt = Psbt::from_str(SIGNED_PSBT).unwrap();
     
    -        let secp = Secp256k1::new();
    +        let secp = Secp256k1::new();
     
    -        let (_, pubkey, _) = setup_keys(ALICE_TPRV_STR, ALICE_BOB_PATH, &secp);
    +        let (_, pubkey, _) = setup_keys(ALICE_TPRV_STR, ALICE_BOB_PATH, &secp);
     
    -        let desc = descriptor!(tr(pubkey)).unwrap();
    -        let (wallet_desc, _) = desc
    -            .into_wallet_descriptor(&secp, Network::Testnet)
    -            .unwrap();
    +        let desc = descriptor!(tr(pubkey)).unwrap();
    +        let (wallet_desc, _) = desc
    +            .into_wallet_descriptor(&secp, Network::Testnet)
    +            .unwrap();
     
    -        let policy_unsigned = wallet_desc
    -            .extract_policy(
    -                &SignersContainer::default(),
    -                BuildSatisfaction::Psbt(&unsigned_psbt),
    -                &secp,
    +        let policy_unsigned = wallet_desc
    +            .extract_policy(
    +                &SignersContainer::default(),
    +                BuildSatisfaction::Psbt(&unsigned_psbt),
    +                &secp,
                 )
    -            .unwrap()
    -            .unwrap();
    -        let policy_signed = wallet_desc
    -            .extract_policy(
    -                &SignersContainer::default(),
    -                BuildSatisfaction::Psbt(&signed_psbt),
    -                &secp,
    +            .unwrap()
    +            .unwrap();
    +        let policy_signed = wallet_desc
    +            .extract_policy(
    +                &SignersContainer::default(),
    +                BuildSatisfaction::Psbt(&signed_psbt),
    +                &secp,
                 )
    -            .unwrap()
    -            .unwrap();
    +            .unwrap()
    +            .unwrap();
     
    -        assert_eq!(policy_unsigned.satisfaction, Satisfaction::None);
    +        assert_eq!(policy_unsigned.satisfaction, Satisfaction::None);
             assert_eq!(
    -            policy_signed.satisfaction,
    -            Satisfaction::Complete {
    -                condition: Default::default()
    +            policy_signed.satisfaction,
    +            Satisfaction::Complete {
    +                condition: Default::default()
                 }
             );
         }
     
    -    #[test]
    -    fn test_extract_tr_satisfaction_script_spend() {
    -        const UNSIGNED_PSBT: &str = "cHNidP8BAFMBAAAAAWZalxaErOL7P3WPIUc8DsjgE68S+ww+uqiqEI2SAwlPAAAAAAD/////AQiWmAAAAAAAF6kU4R3W8CnGzZcSsaovTYu0X8vHt3WHAAAAAAABASuAlpgAAAAAACJRINa6bLPZwp3/CYWoxyI3mLYcSC5f9LInAMUng94nspa2IhXBgiPY+kcolS1Hp0niOK/+7VHz6F+nsz8JVxnzWzkgToYjIHhGyuexxtRVKevRx4YwWR/W0r7LPHt6oS6DLlzyuYQarMAhFnhGyuexxtRVKevRx4YwWR/W0r7LPHt6oS6DLlzyuYQaLQH2onWFc3UR6I9ZhuHVeJCi5LNAf4APVd7mHn4BhdViHRwu7j4AAACAAgAAACEWgiPY+kcolS1Hp0niOK/+7VHz6F+nsz8JVxnzWzkgToYNAMkRfC4AAACAAgAAAAEXIIIj2PpHKJUtR6dJ4jiv/u1R8+hfp7M/CVcZ81s5IE6GARgg9qJ1hXN1EeiPWYbh1XiQouSzQH+AD1Xe5h5+AYXVYh0AAA==";
    -        const SIGNED_PSBT: &str = "cHNidP8BAFMBAAAAAWZalxaErOL7P3WPIUc8DsjgE68S+ww+uqiqEI2SAwlPAAAAAAD/////AQiWmAAAAAAAF6kU4R3W8CnGzZcSsaovTYu0X8vHt3WHAAAAAAABASuAlpgAAAAAACJRINa6bLPZwp3/CYWoxyI3mLYcSC5f9LInAMUng94nspa2AQcAAQhCAUALcP9w/+Ddly9DWdhHTnQ9uCDWLPZjR6vKbKePswW2Ee6W5KNfrklus/8z98n7BQ1U4vADHk0FbadeeL8rrbHlARNAC3D/cP/g3ZcvQ1nYR050Pbgg1iz2Y0erymynj7MFthHuluSjX65JbrP/M/fJ+wUNVOLwAx5NBW2nXni/K62x5UEUeEbK57HG1FUp69HHhjBZH9bSvss8e3qhLoMuXPK5hBr2onWFc3UR6I9ZhuHVeJCi5LNAf4APVd7mHn4BhdViHUAXNmWieJ80Fs+PMa2C186YOBPZbYG/ieEUkagMwzJ788SoCucNdp5wnxfpuJVygFhglDrXGzujFtC82PrMohwuIhXBgiPY+kcolS1Hp0niOK/+7VHz6F+nsz8JVxnzWzkgToYjIHhGyuexxtRVKevRx4YwWR/W0r7LPHt6oS6DLlzyuYQarMAhFnhGyuexxtRVKevRx4YwWR/W0r7LPHt6oS6DLlzyuYQaLQH2onWFc3UR6I9ZhuHVeJCi5LNAf4APVd7mHn4BhdViHRwu7j4AAACAAgAAACEWgiPY+kcolS1Hp0niOK/+7VHz6F+nsz8JVxnzWzkgToYNAMkRfC4AAACAAgAAAAEXIIIj2PpHKJUtR6dJ4jiv/u1R8+hfp7M/CVcZ81s5IE6GARgg9qJ1hXN1EeiPWYbh1XiQouSzQH+AD1Xe5h5+AYXVYh0AAA==";
    +    #[test]
    +    fn test_extract_tr_satisfaction_script_spend() {
    +        const UNSIGNED_PSBT: &str = "cHNidP8BAFMBAAAAAWZalxaErOL7P3WPIUc8DsjgE68S+ww+uqiqEI2SAwlPAAAAAAD/////AQiWmAAAAAAAF6kU4R3W8CnGzZcSsaovTYu0X8vHt3WHAAAAAAABASuAlpgAAAAAACJRINa6bLPZwp3/CYWoxyI3mLYcSC5f9LInAMUng94nspa2IhXBgiPY+kcolS1Hp0niOK/+7VHz6F+nsz8JVxnzWzkgToYjIHhGyuexxtRVKevRx4YwWR/W0r7LPHt6oS6DLlzyuYQarMAhFnhGyuexxtRVKevRx4YwWR/W0r7LPHt6oS6DLlzyuYQaLQH2onWFc3UR6I9ZhuHVeJCi5LNAf4APVd7mHn4BhdViHRwu7j4AAACAAgAAACEWgiPY+kcolS1Hp0niOK/+7VHz6F+nsz8JVxnzWzkgToYNAMkRfC4AAACAAgAAAAEXIIIj2PpHKJUtR6dJ4jiv/u1R8+hfp7M/CVcZ81s5IE6GARgg9qJ1hXN1EeiPWYbh1XiQouSzQH+AD1Xe5h5+AYXVYh0AAA==";
    +        const SIGNED_PSBT: &str = "cHNidP8BAFMBAAAAAWZalxaErOL7P3WPIUc8DsjgE68S+ww+uqiqEI2SAwlPAAAAAAD/////AQiWmAAAAAAAF6kU4R3W8CnGzZcSsaovTYu0X8vHt3WHAAAAAAABASuAlpgAAAAAACJRINa6bLPZwp3/CYWoxyI3mLYcSC5f9LInAMUng94nspa2AQcAAQhCAUALcP9w/+Ddly9DWdhHTnQ9uCDWLPZjR6vKbKePswW2Ee6W5KNfrklus/8z98n7BQ1U4vADHk0FbadeeL8rrbHlARNAC3D/cP/g3ZcvQ1nYR050Pbgg1iz2Y0erymynj7MFthHuluSjX65JbrP/M/fJ+wUNVOLwAx5NBW2nXni/K62x5UEUeEbK57HG1FUp69HHhjBZH9bSvss8e3qhLoMuXPK5hBr2onWFc3UR6I9ZhuHVeJCi5LNAf4APVd7mHn4BhdViHUAXNmWieJ80Fs+PMa2C186YOBPZbYG/ieEUkagMwzJ788SoCucNdp5wnxfpuJVygFhglDrXGzujFtC82PrMohwuIhXBgiPY+kcolS1Hp0niOK/+7VHz6F+nsz8JVxnzWzkgToYjIHhGyuexxtRVKevRx4YwWR/W0r7LPHt6oS6DLlzyuYQarMAhFnhGyuexxtRVKevRx4YwWR/W0r7LPHt6oS6DLlzyuYQaLQH2onWFc3UR6I9ZhuHVeJCi5LNAf4APVd7mHn4BhdViHRwu7j4AAACAAgAAACEWgiPY+kcolS1Hp0niOK/+7VHz6F+nsz8JVxnzWzkgToYNAMkRfC4AAACAAgAAAAEXIIIj2PpHKJUtR6dJ4jiv/u1R8+hfp7M/CVcZ81s5IE6GARgg9qJ1hXN1EeiPWYbh1XiQouSzQH+AD1Xe5h5+AYXVYh0AAA==";
     
    -        let unsigned_psbt = Psbt::from_str(UNSIGNED_PSBT).unwrap();
    -        let signed_psbt = Psbt::from_str(SIGNED_PSBT).unwrap();
    +        let unsigned_psbt = Psbt::from_str(UNSIGNED_PSBT).unwrap();
    +        let signed_psbt = Psbt::from_str(SIGNED_PSBT).unwrap();
     
    -        let secp = Secp256k1::new();
    +        let secp = Secp256k1::new();
     
    -        let (_, alice_pub, _) = setup_keys(ALICE_TPRV_STR, ALICE_BOB_PATH, &secp);
    -        let (_, bob_pub, _) = setup_keys(BOB_TPRV_STR, ALICE_BOB_PATH, &secp);
    +        let (_, alice_pub, _) = setup_keys(ALICE_TPRV_STR, ALICE_BOB_PATH, &secp);
    +        let (_, bob_pub, _) = setup_keys(BOB_TPRV_STR, ALICE_BOB_PATH, &secp);
     
    -        let desc = descriptor!(tr(bob_pub, pk(alice_pub))).unwrap();
    -        let (wallet_desc, _) = desc
    -            .into_wallet_descriptor(&secp, Network::Testnet)
    -            .unwrap();
    +        let desc = descriptor!(tr(bob_pub, pk(alice_pub))).unwrap();
    +        let (wallet_desc, _) = desc
    +            .into_wallet_descriptor(&secp, Network::Testnet)
    +            .unwrap();
     
    -        let policy_unsigned = wallet_desc
    -            .extract_policy(
    -                &SignersContainer::default(),
    -                BuildSatisfaction::Psbt(&unsigned_psbt),
    -                &secp,
    +        let policy_unsigned = wallet_desc
    +            .extract_policy(
    +                &SignersContainer::default(),
    +                BuildSatisfaction::Psbt(&unsigned_psbt),
    +                &secp,
                 )
    -            .unwrap()
    -            .unwrap();
    -        let policy_signed = wallet_desc
    -            .extract_policy(
    -                &SignersContainer::default(),
    -                BuildSatisfaction::Psbt(&signed_psbt),
    -                &secp,
    +            .unwrap()
    +            .unwrap();
    +        let policy_signed = wallet_desc
    +            .extract_policy(
    +                &SignersContainer::default(),
    +                BuildSatisfaction::Psbt(&signed_psbt),
    +                &secp,
                 )
    -            .unwrap()
    -            .unwrap();
    +            .unwrap()
    +            .unwrap();
     
             assert!(
    -            matches!(policy_unsigned.item, SatisfiableItem::Thresh { ref items, threshold: 1 } if items.len() == 2)
    +            matches!(policy_unsigned.item, SatisfiableItem::Thresh { ref items, threshold: 1 } if items.len() == 2)
             );
             assert!(
    -            matches!(policy_unsigned.satisfaction, Satisfaction::Partial { n: 2, m: 1, items, .. } if items.is_empty())
    +            matches!(policy_unsigned.satisfaction, Satisfaction::Partial { n: 2, m: 1, items, .. } if items.is_empty())
             );
     
             assert!(
    -            matches!(policy_signed.item, SatisfiableItem::Thresh { ref items, threshold: 1 } if items.len() == 2)
    +            matches!(policy_signed.item, SatisfiableItem::Thresh { ref items, threshold: 1 } if items.len() == 2)
             );
             assert!(
    -            matches!(policy_signed.satisfaction, Satisfaction::PartialComplete { n: 2, m: 1, items, .. } if items == vec![0, 1])
    +            matches!(policy_signed.satisfaction, Satisfaction::PartialComplete { n: 2, m: 1, items, .. } if items == vec![0, 1])
             );
     
    -        let satisfied_items = match policy_signed.item {
    -            SatisfiableItem::Thresh { items, .. } => items,
    -            _ => unreachable!(),
    +        let satisfied_items = match policy_signed.item {
    +            SatisfiableItem::Thresh { items, .. } => items,
    +            _ => unreachable!(),
             };
     
             assert_eq!(
    -            satisfied_items[0].satisfaction,
    -            Satisfaction::Complete {
    -                condition: Default::default()
    +            satisfied_items[0].satisfaction,
    +            Satisfaction::Complete {
    +                condition: Default::default()
                 }
             );
             assert_eq!(
    -            satisfied_items[1].satisfaction,
    -            Satisfaction::Complete {
    -                condition: Default::default()
    +            satisfied_items[1].satisfaction,
    +            Satisfaction::Complete {
    +                condition: Default::default()
                 }
             );
         }
     }
     
    -
    - \ No newline at end of file +
    \ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/src/bdk/descriptor/template.rs.html b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/src/bdk/descriptor/template.rs.html index 8ed57c2e46..0555c4adc1 100644 --- a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/src/bdk/descriptor/template.rs.html +++ b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/src/bdk/descriptor/template.rs.html @@ -1,1389 +1,1383 @@ -template.rs - source - -
      1
    -  2
    -  3
    -  4
    -  5
    -  6
    -  7
    -  8
    -  9
    - 10
    - 11
    - 12
    - 13
    - 14
    - 15
    - 16
    - 17
    - 18
    - 19
    - 20
    - 21
    - 22
    - 23
    - 24
    - 25
    - 26
    - 27
    - 28
    - 29
    - 30
    - 31
    - 32
    - 33
    - 34
    - 35
    - 36
    - 37
    - 38
    - 39
    - 40
    - 41
    - 42
    - 43
    - 44
    - 45
    - 46
    - 47
    - 48
    - 49
    - 50
    - 51
    - 52
    - 53
    - 54
    - 55
    - 56
    - 57
    - 58
    - 59
    - 60
    - 61
    - 62
    - 63
    - 64
    - 65
    - 66
    - 67
    - 68
    - 69
    - 70
    - 71
    - 72
    - 73
    - 74
    - 75
    - 76
    - 77
    - 78
    - 79
    - 80
    - 81
    - 82
    - 83
    - 84
    - 85
    - 86
    - 87
    - 88
    - 89
    - 90
    - 91
    - 92
    - 93
    - 94
    - 95
    - 96
    - 97
    - 98
    - 99
    -100
    -101
    -102
    -103
    -104
    -105
    -106
    -107
    -108
    -109
    -110
    -111
    -112
    -113
    -114
    -115
    -116
    -117
    -118
    -119
    -120
    -121
    -122
    -123
    -124
    -125
    -126
    -127
    -128
    -129
    -130
    -131
    -132
    -133
    -134
    -135
    -136
    -137
    -138
    -139
    -140
    -141
    -142
    -143
    -144
    -145
    -146
    -147
    -148
    -149
    -150
    -151
    -152
    -153
    -154
    -155
    -156
    -157
    -158
    -159
    -160
    -161
    -162
    -163
    -164
    -165
    -166
    -167
    -168
    -169
    -170
    -171
    -172
    -173
    -174
    -175
    -176
    -177
    -178
    -179
    -180
    -181
    -182
    -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
    -245
    -246
    -247
    -248
    -249
    -250
    -251
    -252
    -253
    -254
    -255
    -256
    -257
    -258
    -259
    -260
    -261
    -262
    -263
    -264
    -265
    -266
    -267
    -268
    -269
    -270
    -271
    -272
    -273
    -274
    -275
    -276
    -277
    -278
    -279
    -280
    -281
    -282
    -283
    -284
    -285
    -286
    -287
    -288
    -289
    -290
    -291
    -292
    -293
    -294
    -295
    -296
    -297
    -298
    -299
    -300
    -301
    -302
    -303
    -304
    -305
    -306
    -307
    -308
    -309
    -310
    -311
    -312
    -313
    -314
    -315
    -316
    -317
    -318
    -319
    -320
    -321
    -322
    -323
    -324
    -325
    -326
    -327
    -328
    -329
    -330
    -331
    -332
    -333
    -334
    -335
    -336
    -337
    -338
    -339
    -340
    -341
    -342
    -343
    -344
    -345
    -346
    -347
    -348
    -349
    -350
    -351
    -352
    -353
    -354
    -355
    -356
    -357
    -358
    -359
    -360
    -361
    -362
    -363
    -364
    -365
    -366
    -367
    -368
    -369
    -370
    -371
    -372
    -373
    -374
    -375
    -376
    -377
    -378
    -379
    -380
    -381
    -382
    -383
    -384
    -385
    -386
    -387
    -388
    -389
    -390
    -391
    -392
    -393
    -394
    -395
    -396
    -397
    -398
    -399
    -400
    -401
    -402
    -403
    -404
    -405
    -406
    -407
    -408
    -409
    -410
    -411
    -412
    -413
    -414
    -415
    -416
    -417
    -418
    -419
    -420
    -421
    -422
    -423
    -424
    -425
    -426
    -427
    -428
    -429
    -430
    -431
    -432
    -433
    -434
    -435
    -436
    -437
    -438
    -439
    -440
    -441
    -442
    -443
    -444
    -445
    -446
    -447
    -448
    -449
    -450
    -451
    -452
    -453
    -454
    -455
    -456
    -457
    -458
    -459
    -460
    -461
    -462
    -463
    -464
    -465
    -466
    -467
    -468
    -469
    -470
    -471
    -472
    -473
    -474
    -475
    -476
    -477
    -478
    -479
    -480
    -481
    -482
    -483
    -484
    -485
    -486
    -487
    -488
    -489
    -490
    -491
    -492
    -493
    -494
    -495
    -496
    -497
    -498
    -499
    -500
    -501
    -502
    -503
    -504
    -505
    -506
    -507
    -508
    -509
    -510
    -511
    -512
    -513
    -514
    -515
    -516
    -517
    -518
    -519
    -520
    -521
    -522
    -523
    -524
    -525
    -526
    -527
    -528
    -529
    -530
    -531
    -532
    -533
    -534
    -535
    -536
    -537
    -538
    -539
    -540
    -541
    -542
    -543
    -544
    -545
    -546
    -547
    -548
    -549
    -550
    -551
    -552
    -553
    -554
    -555
    -556
    -557
    -558
    -559
    -560
    -561
    -562
    -563
    -564
    -565
    -566
    -567
    -568
    -569
    -570
    -571
    -572
    -573
    -574
    -575
    -576
    -577
    -578
    -579
    -580
    -581
    -582
    -583
    -584
    -585
    -586
    -587
    -588
    -589
    -590
    -591
    -592
    -593
    -594
    -595
    -596
    -597
    -598
    -599
    -600
    -601
    -602
    -603
    -604
    -605
    -606
    -607
    -608
    -609
    -610
    -611
    -612
    -613
    -614
    -615
    -616
    -617
    -618
    -619
    -620
    -621
    -622
    -623
    -624
    -625
    -626
    -627
    -628
    -629
    -630
    -631
    -632
    -633
    -634
    -635
    -636
    -637
    -638
    -639
    -640
    -641
    -642
    -643
    -644
    -645
    -646
    -647
    -648
    -649
    -650
    -651
    -652
    -653
    -654
    -655
    -656
    -657
    -658
    -659
    -660
    -661
    -662
    -663
    -664
    -665
    -666
    -667
    -668
    -669
    -670
    -671
    -672
    -673
    -674
    -675
    -676
    -677
    -678
    -679
    -680
    -681
    -682
    -683
    -684
    -685
    -686
    -687
    -688
    -689
    -690
    -691
    -692
    -693
    -694
    -695
    -696
    -697
    -698
    -699
    -700
    -701
    -702
    -703
    -704
    -705
    -706
    -707
    -708
    -709
    -710
    -711
    -712
    -713
    -714
    -715
    -716
    -717
    -718
    -719
    -720
    -721
    -722
    -723
    -724
    -725
    -726
    -727
    -728
    -729
    -730
    -731
    -732
    -733
    -734
    -735
    -736
    -737
    -738
    -739
    -740
    -741
    -742
    -743
    -744
    -745
    -746
    -747
    -748
    -749
    -750
    -751
    -752
    -753
    -754
    -755
    -756
    -757
    -758
    -759
    -760
    -761
    -762
    -763
    -764
    -765
    -766
    -
    // Bitcoin Dev Kit
    -// Written in 2020 by Alekos Filini <alekos.filini@gmail.com>
    -//
    -// Copyright (c) 2020-2021 Bitcoin Dev Kit Developers
    -//
    -// This file is licensed under the Apache License, Version 2.0 <LICENSE-APACHE
    -// or http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
    -// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your option.
    -// You may not use this file except in accordance with one or both of these
    -// licenses.
    +template.rs - source
    1
    +2
    +3
    +4
    +5
    +6
    +7
    +8
    +9
    +10
    +11
    +12
    +13
    +14
    +15
    +16
    +17
    +18
    +19
    +20
    +21
    +22
    +23
    +24
    +25
    +26
    +27
    +28
    +29
    +30
    +31
    +32
    +33
    +34
    +35
    +36
    +37
    +38
    +39
    +40
    +41
    +42
    +43
    +44
    +45
    +46
    +47
    +48
    +49
    +50
    +51
    +52
    +53
    +54
    +55
    +56
    +57
    +58
    +59
    +60
    +61
    +62
    +63
    +64
    +65
    +66
    +67
    +68
    +69
    +70
    +71
    +72
    +73
    +74
    +75
    +76
    +77
    +78
    +79
    +80
    +81
    +82
    +83
    +84
    +85
    +86
    +87
    +88
    +89
    +90
    +91
    +92
    +93
    +94
    +95
    +96
    +97
    +98
    +99
    +100
    +101
    +102
    +103
    +104
    +105
    +106
    +107
    +108
    +109
    +110
    +111
    +112
    +113
    +114
    +115
    +116
    +117
    +118
    +119
    +120
    +121
    +122
    +123
    +124
    +125
    +126
    +127
    +128
    +129
    +130
    +131
    +132
    +133
    +134
    +135
    +136
    +137
    +138
    +139
    +140
    +141
    +142
    +143
    +144
    +145
    +146
    +147
    +148
    +149
    +150
    +151
    +152
    +153
    +154
    +155
    +156
    +157
    +158
    +159
    +160
    +161
    +162
    +163
    +164
    +165
    +166
    +167
    +168
    +169
    +170
    +171
    +172
    +173
    +174
    +175
    +176
    +177
    +178
    +179
    +180
    +181
    +182
    +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
    +245
    +246
    +247
    +248
    +249
    +250
    +251
    +252
    +253
    +254
    +255
    +256
    +257
    +258
    +259
    +260
    +261
    +262
    +263
    +264
    +265
    +266
    +267
    +268
    +269
    +270
    +271
    +272
    +273
    +274
    +275
    +276
    +277
    +278
    +279
    +280
    +281
    +282
    +283
    +284
    +285
    +286
    +287
    +288
    +289
    +290
    +291
    +292
    +293
    +294
    +295
    +296
    +297
    +298
    +299
    +300
    +301
    +302
    +303
    +304
    +305
    +306
    +307
    +308
    +309
    +310
    +311
    +312
    +313
    +314
    +315
    +316
    +317
    +318
    +319
    +320
    +321
    +322
    +323
    +324
    +325
    +326
    +327
    +328
    +329
    +330
    +331
    +332
    +333
    +334
    +335
    +336
    +337
    +338
    +339
    +340
    +341
    +342
    +343
    +344
    +345
    +346
    +347
    +348
    +349
    +350
    +351
    +352
    +353
    +354
    +355
    +356
    +357
    +358
    +359
    +360
    +361
    +362
    +363
    +364
    +365
    +366
    +367
    +368
    +369
    +370
    +371
    +372
    +373
    +374
    +375
    +376
    +377
    +378
    +379
    +380
    +381
    +382
    +383
    +384
    +385
    +386
    +387
    +388
    +389
    +390
    +391
    +392
    +393
    +394
    +395
    +396
    +397
    +398
    +399
    +400
    +401
    +402
    +403
    +404
    +405
    +406
    +407
    +408
    +409
    +410
    +411
    +412
    +413
    +414
    +415
    +416
    +417
    +418
    +419
    +420
    +421
    +422
    +423
    +424
    +425
    +426
    +427
    +428
    +429
    +430
    +431
    +432
    +433
    +434
    +435
    +436
    +437
    +438
    +439
    +440
    +441
    +442
    +443
    +444
    +445
    +446
    +447
    +448
    +449
    +450
    +451
    +452
    +453
    +454
    +455
    +456
    +457
    +458
    +459
    +460
    +461
    +462
    +463
    +464
    +465
    +466
    +467
    +468
    +469
    +470
    +471
    +472
    +473
    +474
    +475
    +476
    +477
    +478
    +479
    +480
    +481
    +482
    +483
    +484
    +485
    +486
    +487
    +488
    +489
    +490
    +491
    +492
    +493
    +494
    +495
    +496
    +497
    +498
    +499
    +500
    +501
    +502
    +503
    +504
    +505
    +506
    +507
    +508
    +509
    +510
    +511
    +512
    +513
    +514
    +515
    +516
    +517
    +518
    +519
    +520
    +521
    +522
    +523
    +524
    +525
    +526
    +527
    +528
    +529
    +530
    +531
    +532
    +533
    +534
    +535
    +536
    +537
    +538
    +539
    +540
    +541
    +542
    +543
    +544
    +545
    +546
    +547
    +548
    +549
    +550
    +551
    +552
    +553
    +554
    +555
    +556
    +557
    +558
    +559
    +560
    +561
    +562
    +563
    +564
    +565
    +566
    +567
    +568
    +569
    +570
    +571
    +572
    +573
    +574
    +575
    +576
    +577
    +578
    +579
    +580
    +581
    +582
    +583
    +584
    +585
    +586
    +587
    +588
    +589
    +590
    +591
    +592
    +593
    +594
    +595
    +596
    +597
    +598
    +599
    +600
    +601
    +602
    +603
    +604
    +605
    +606
    +607
    +608
    +609
    +610
    +611
    +612
    +613
    +614
    +615
    +616
    +617
    +618
    +619
    +620
    +621
    +622
    +623
    +624
    +625
    +626
    +627
    +628
    +629
    +630
    +631
    +632
    +633
    +634
    +635
    +636
    +637
    +638
    +639
    +640
    +641
    +642
    +643
    +644
    +645
    +646
    +647
    +648
    +649
    +650
    +651
    +652
    +653
    +654
    +655
    +656
    +657
    +658
    +659
    +660
    +661
    +662
    +663
    +664
    +665
    +666
    +667
    +668
    +669
    +670
    +671
    +672
    +673
    +674
    +675
    +676
    +677
    +678
    +679
    +680
    +681
    +682
    +683
    +684
    +685
    +686
    +687
    +688
    +689
    +690
    +691
    +692
    +693
    +694
    +695
    +696
    +697
    +698
    +699
    +700
    +701
    +702
    +703
    +704
    +705
    +706
    +707
    +708
    +709
    +710
    +711
    +712
    +713
    +714
    +715
    +716
    +717
    +718
    +719
    +720
    +721
    +722
    +723
    +724
    +725
    +726
    +727
    +728
    +729
    +730
    +731
    +732
    +733
    +734
    +735
    +736
    +737
    +738
    +739
    +740
    +741
    +742
    +743
    +744
    +745
    +746
    +747
    +748
    +749
    +750
    +751
    +752
    +753
    +754
    +755
    +756
    +757
    +758
    +759
    +760
    +761
    +762
    +763
    +764
    +765
    +766
    +
    // Bitcoin Dev Kit
    +// Written in 2020 by Alekos Filini <alekos.filini@gmail.com>
    +//
    +// Copyright (c) 2020-2021 Bitcoin Dev Kit Developers
    +//
    +// This file is licensed under the Apache License, Version 2.0 <LICENSE-APACHE
    +// or http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
    +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your option.
    +// You may not use this file except in accordance with one or both of these
    +// licenses.
     
    -//! Descriptor templates
    -//!
    -//! This module contains the definition of various common script templates that are ready to be
    -//! used. See the documentation of each template for an example.
    +//! Descriptor templates
    +//!
    +//! This module contains the definition of various common script templates that are ready to be
    +//! used. See the documentation of each template for an example.
     
    -use bitcoin::util::bip32;
    -use bitcoin::Network;
    +use bitcoin::util::bip32;
    +use bitcoin::Network;
     
    -use miniscript::{Legacy, Segwitv0};
    +use miniscript::{Legacy, Segwitv0};
     
    -use super::{ExtendedDescriptor, IntoWalletDescriptor, KeyMap};
    -use crate::descriptor::DescriptorError;
    -use crate::keys::{DerivableKey, IntoDescriptorKey, ValidNetworks};
    -use crate::wallet::utils::SecpCtx;
    -use crate::{descriptor, KeychainKind};
    +use super::{ExtendedDescriptor, IntoWalletDescriptor, KeyMap};
    +use crate::descriptor::DescriptorError;
    +use crate::keys::{DerivableKey, IntoDescriptorKey, ValidNetworks};
    +use crate::wallet::utils::SecpCtx;
    +use crate::{descriptor, KeychainKind};
     
    -/// Type alias for the return type of [`DescriptorTemplate`], [`descriptor!`](crate::descriptor!) and others
    -pub type DescriptorTemplateOut = (ExtendedDescriptor, KeyMap, ValidNetworks);
    +/// Type alias for the return type of [`DescriptorTemplate`], [`descriptor!`](crate::descriptor!) and others
    +pub type DescriptorTemplateOut = (ExtendedDescriptor, KeyMap, ValidNetworks);
     
    -/// Trait for descriptor templates that can be built into a full descriptor
    -///
    -/// Since [`IntoWalletDescriptor`] is implemented for any [`DescriptorTemplate`], they can also be
    -/// passed directly to the [`Wallet`](crate::Wallet) constructor.
    -///
    -/// ## Example
    -///
    -/// ```
    -/// use bdk::descriptor::error::Error as DescriptorError;
    -/// use bdk::keys::{IntoDescriptorKey, KeyError};
    -/// use bdk::miniscript::Legacy;
    -/// use bdk::template::{DescriptorTemplate, DescriptorTemplateOut};
    -/// use bitcoin::Network;
    -///
    -/// struct MyP2PKH<K: IntoDescriptorKey<Legacy>>(K);
    -///
    -/// impl<K: IntoDescriptorKey<Legacy>> DescriptorTemplate for MyP2PKH<K> {
    -///     fn build(self, network: Network) -> Result<DescriptorTemplateOut, DescriptorError> {
    -///         Ok(bdk::descriptor!(pkh(self.0))?)
    -///     }
    -/// }
    -/// ```
    -pub trait DescriptorTemplate {
    -    /// Build the complete descriptor
    -    fn build(self, network: Network) -> Result<DescriptorTemplateOut, DescriptorError>;
    +/// Trait for descriptor templates that can be built into a full descriptor
    +///
    +/// Since [`IntoWalletDescriptor`] is implemented for any [`DescriptorTemplate`], they can also be
    +/// passed directly to the [`Wallet`](crate::Wallet) constructor.
    +///
    +/// ## Example
    +///
    +/// ```
    +/// use bdk::descriptor::error::Error as DescriptorError;
    +/// use bdk::keys::{IntoDescriptorKey, KeyError};
    +/// use bdk::miniscript::Legacy;
    +/// use bdk::template::{DescriptorTemplate, DescriptorTemplateOut};
    +/// use bitcoin::Network;
    +///
    +/// struct MyP2PKH<K: IntoDescriptorKey<Legacy>>(K);
    +///
    +/// impl<K: IntoDescriptorKey<Legacy>> DescriptorTemplate for MyP2PKH<K> {
    +///     fn build(self, network: Network) -> Result<DescriptorTemplateOut, DescriptorError> {
    +///         Ok(bdk::descriptor!(pkh(self.0))?)
    +///     }
    +/// }
    +/// ```
    +pub trait DescriptorTemplate {
    +    /// Build the complete descriptor
    +    fn build(self, network: Network) -> Result<DescriptorTemplateOut, DescriptorError>;
     }
     
    -/// Turns a [`DescriptorTemplate`] into a valid wallet descriptor by calling its
    -/// [`build`](DescriptorTemplate::build) method
    -impl<T: DescriptorTemplate> IntoWalletDescriptor for T {
    -    fn into_wallet_descriptor(
    +/// Turns a [`DescriptorTemplate`] into a valid wallet descriptor by calling its
    +/// [`build`](DescriptorTemplate::build) method
    +impl<T: DescriptorTemplate> IntoWalletDescriptor for T {
    +    fn into_wallet_descriptor(
             self,
    -        secp: &SecpCtx,
    -        network: Network,
    -    ) -> Result<(ExtendedDescriptor, KeyMap), DescriptorError> {
    -        self.build(network)?.into_wallet_descriptor(secp, network)
    +        secp: &SecpCtx,
    +        network: Network,
    +    ) -> Result<(ExtendedDescriptor, KeyMap), DescriptorError> {
    +        self.build(network)?.into_wallet_descriptor(secp, network)
         }
     }
     
    -/// P2PKH template. Expands to a descriptor `pkh(key)`
    -///
    -/// ## Example
    -///
    -/// ```
    -/// # use bdk::bitcoin::{PrivateKey, Network};
    -/// # use bdk::{Wallet};
    -/// # use bdk::database::MemoryDatabase;
    -/// # use bdk::wallet::AddressIndex::New;
    -/// use bdk::template::P2Pkh;
    -///
    -/// let key =
    -///     bitcoin::PrivateKey::from_wif("cTc4vURSzdx6QE6KVynWGomDbLaA75dNALMNyfjh3p8DRRar84Um")?;
    -/// let wallet = Wallet::new(
    -///     P2Pkh(key),
    -///     None,
    -///     Network::Testnet,
    -///     MemoryDatabase::default(),
    -/// )?;
    -///
    -/// assert_eq!(
    -///     wallet.get_address(New)?.to_string(),
    -///     "mwJ8hxFYW19JLuc65RCTaP4v1rzVU8cVMT"
    -/// );
    -/// # Ok::<_, Box<dyn std::error::Error>>(())
    -/// ```
    -pub struct P2Pkh<K: IntoDescriptorKey<Legacy>>(pub K);
    +/// P2PKH template. Expands to a descriptor `pkh(key)`
    +///
    +/// ## Example
    +///
    +/// ```
    +/// # use bdk::bitcoin::{PrivateKey, Network};
    +/// # use bdk::{Wallet};
    +/// # use bdk::database::MemoryDatabase;
    +/// # use bdk::wallet::AddressIndex::New;
    +/// use bdk::template::P2Pkh;
    +///
    +/// let key =
    +///     bitcoin::PrivateKey::from_wif("cTc4vURSzdx6QE6KVynWGomDbLaA75dNALMNyfjh3p8DRRar84Um")?;
    +/// let wallet = Wallet::new(
    +///     P2Pkh(key),
    +///     None,
    +///     Network::Testnet,
    +///     MemoryDatabase::default(),
    +/// )?;
    +///
    +/// assert_eq!(
    +///     wallet.get_address(New)?.to_string(),
    +///     "mwJ8hxFYW19JLuc65RCTaP4v1rzVU8cVMT"
    +/// );
    +/// # Ok::<_, Box<dyn std::error::Error>>(())
    +/// ```
    +pub struct P2Pkh<K: IntoDescriptorKey<Legacy>>(pub K);
     
    -impl<K: IntoDescriptorKey<Legacy>> DescriptorTemplate for P2Pkh<K> {
    -    fn build(self, _network: Network) -> Result<DescriptorTemplateOut, DescriptorError> {
    -        descriptor!(pkh(self.0))
    +impl<K: IntoDescriptorKey<Legacy>> DescriptorTemplate for P2Pkh<K> {
    +    fn build(self, _network: Network) -> Result<DescriptorTemplateOut, DescriptorError> {
    +        descriptor!(pkh(self.0))
         }
     }
     
    -/// P2WPKH-P2SH template. Expands to a descriptor `sh(wpkh(key))`
    -///
    -/// ## Example
    -///
    -/// ```
    -/// # use bdk::bitcoin::{PrivateKey, Network};
    -/// # use bdk::{Wallet};
    -/// # use bdk::database::MemoryDatabase;
    -/// # use bdk::wallet::AddressIndex::New;
    -/// use bdk::template::P2Wpkh_P2Sh;
    -///
    -/// let key =
    -///     bitcoin::PrivateKey::from_wif("cTc4vURSzdx6QE6KVynWGomDbLaA75dNALMNyfjh3p8DRRar84Um")?;
    -/// let wallet = Wallet::new(
    -///     P2Wpkh_P2Sh(key),
    -///     None,
    -///     Network::Testnet,
    -///     MemoryDatabase::default(),
    -/// )?;
    -///
    -/// assert_eq!(
    -///     wallet.get_address(New)?.to_string(),
    -///     "2NB4ox5VDRw1ecUv6SnT3VQHPXveYztRqk5"
    -/// );
    -/// # Ok::<_, Box<dyn std::error::Error>>(())
    -/// ```
    -#[allow(non_camel_case_types)]
    -pub struct P2Wpkh_P2Sh<K: IntoDescriptorKey<Segwitv0>>(pub K);
    +/// P2WPKH-P2SH template. Expands to a descriptor `sh(wpkh(key))`
    +///
    +/// ## Example
    +///
    +/// ```
    +/// # use bdk::bitcoin::{PrivateKey, Network};
    +/// # use bdk::{Wallet};
    +/// # use bdk::database::MemoryDatabase;
    +/// # use bdk::wallet::AddressIndex::New;
    +/// use bdk::template::P2Wpkh_P2Sh;
    +///
    +/// let key =
    +///     bitcoin::PrivateKey::from_wif("cTc4vURSzdx6QE6KVynWGomDbLaA75dNALMNyfjh3p8DRRar84Um")?;
    +/// let wallet = Wallet::new(
    +///     P2Wpkh_P2Sh(key),
    +///     None,
    +///     Network::Testnet,
    +///     MemoryDatabase::default(),
    +/// )?;
    +///
    +/// assert_eq!(
    +///     wallet.get_address(New)?.to_string(),
    +///     "2NB4ox5VDRw1ecUv6SnT3VQHPXveYztRqk5"
    +/// );
    +/// # Ok::<_, Box<dyn std::error::Error>>(())
    +/// ```
    +#[allow(non_camel_case_types)]
    +pub struct P2Wpkh_P2Sh<K: IntoDescriptorKey<Segwitv0>>(pub K);
     
    -impl<K: IntoDescriptorKey<Segwitv0>> DescriptorTemplate for P2Wpkh_P2Sh<K> {
    -    fn build(self, _network: Network) -> Result<DescriptorTemplateOut, DescriptorError> {
    -        descriptor!(sh(wpkh(self.0)))
    +impl<K: IntoDescriptorKey<Segwitv0>> DescriptorTemplate for P2Wpkh_P2Sh<K> {
    +    fn build(self, _network: Network) -> Result<DescriptorTemplateOut, DescriptorError> {
    +        descriptor!(sh(wpkh(self.0)))
         }
     }
     
    -/// P2WPKH template. Expands to a descriptor `wpkh(key)`
    -///
    -/// ## Example
    -///
    -/// ```
    -/// # use bdk::bitcoin::{PrivateKey, Network};
    -/// # use bdk::{Wallet};
    -/// # use bdk::database::MemoryDatabase;
    -/// # use bdk::wallet::AddressIndex::New;
    -/// use bdk::template::P2Wpkh;
    -///
    -/// let key =
    -///     bitcoin::PrivateKey::from_wif("cTc4vURSzdx6QE6KVynWGomDbLaA75dNALMNyfjh3p8DRRar84Um")?;
    -/// let wallet = Wallet::new(
    -///     P2Wpkh(key),
    -///     None,
    -///     Network::Testnet,
    -///     MemoryDatabase::default(),
    -/// )?;
    -///
    -/// assert_eq!(
    -///     wallet.get_address(New)?.to_string(),
    -///     "tb1q4525hmgw265tl3drrl8jjta7ayffu6jf68ltjd"
    -/// );
    -/// # Ok::<_, Box<dyn std::error::Error>>(())
    -/// ```
    -pub struct P2Wpkh<K: IntoDescriptorKey<Segwitv0>>(pub K);
    +/// P2WPKH template. Expands to a descriptor `wpkh(key)`
    +///
    +/// ## Example
    +///
    +/// ```
    +/// # use bdk::bitcoin::{PrivateKey, Network};
    +/// # use bdk::{Wallet};
    +/// # use bdk::database::MemoryDatabase;
    +/// # use bdk::wallet::AddressIndex::New;
    +/// use bdk::template::P2Wpkh;
    +///
    +/// let key =
    +///     bitcoin::PrivateKey::from_wif("cTc4vURSzdx6QE6KVynWGomDbLaA75dNALMNyfjh3p8DRRar84Um")?;
    +/// let wallet = Wallet::new(
    +///     P2Wpkh(key),
    +///     None,
    +///     Network::Testnet,
    +///     MemoryDatabase::default(),
    +/// )?;
    +///
    +/// assert_eq!(
    +///     wallet.get_address(New)?.to_string(),
    +///     "tb1q4525hmgw265tl3drrl8jjta7ayffu6jf68ltjd"
    +/// );
    +/// # Ok::<_, Box<dyn std::error::Error>>(())
    +/// ```
    +pub struct P2Wpkh<K: IntoDescriptorKey<Segwitv0>>(pub K);
     
    -impl<K: IntoDescriptorKey<Segwitv0>> DescriptorTemplate for P2Wpkh<K> {
    -    fn build(self, _network: Network) -> Result<DescriptorTemplateOut, DescriptorError> {
    -        descriptor!(wpkh(self.0))
    +impl<K: IntoDescriptorKey<Segwitv0>> DescriptorTemplate for P2Wpkh<K> {
    +    fn build(self, _network: Network) -> Result<DescriptorTemplateOut, DescriptorError> {
    +        descriptor!(wpkh(self.0))
         }
     }
     
    -/// BIP44 template. Expands to `pkh(key/44'/{0,1}'/0'/{0,1}/*)`
    -///
    -/// Since there are hardened derivation steps, this template requires a private derivable key (generally a `xprv`/`tprv`).
    -///
    -/// See [`Bip44Public`] for a template that can work with a `xpub`/`tpub`.
    -///
    -/// ## Example
    -///
    -/// ```
    -/// # use std::str::FromStr;
    -/// # use bdk::bitcoin::{PrivateKey, Network};
    -/// # use bdk::{Wallet,  KeychainKind};
    -/// # use bdk::database::MemoryDatabase;
    -/// # use bdk::wallet::AddressIndex::New;
    -/// use bdk::template::Bip44;
    -///
    -/// let key = bitcoin::util::bip32::ExtendedPrivKey::from_str("tprv8ZgxMBicQKsPeZRHk4rTG6orPS2CRNFX3njhUXx5vj9qGog5ZMH4uGReDWN5kCkY3jmWEtWause41CDvBRXD1shKknAMKxT99o9qUTRVC6m")?;
    -/// let wallet = Wallet::new(
    -///     Bip44(key.clone(), KeychainKind::External),
    -///     Some(Bip44(key, KeychainKind::Internal)),
    -///     Network::Testnet,
    -///     MemoryDatabase::default()
    -/// )?;
    -///
    -/// assert_eq!(wallet.get_address(New)?.to_string(), "mmogjc7HJEZkrLqyQYqJmxUqFaC7i4uf89");
    -/// assert_eq!(wallet.public_descriptor(KeychainKind::External)?.unwrap().to_string(), "pkh([c55b303f/44'/1'/0']tpubDCuorCpzvYS2LCD75BR46KHE8GdDeg1wsAgNZeNr6DaB5gQK1o14uErKwKLuFmeemkQ6N2m3rNgvctdJLyr7nwu2yia7413Hhg8WWE44cgT/0/*)#5wrnv0xt");
    -/// # Ok::<_, Box<dyn std::error::Error>>(())
    -/// ```
    -pub struct Bip44<K: DerivableKey<Legacy>>(pub K, pub KeychainKind);
    +/// BIP44 template. Expands to `pkh(key/44'/{0,1}'/0'/{0,1}/*)`
    +///
    +/// Since there are hardened derivation steps, this template requires a private derivable key (generally a `xprv`/`tprv`).
    +///
    +/// See [`Bip44Public`] for a template that can work with a `xpub`/`tpub`.
    +///
    +/// ## Example
    +///
    +/// ```
    +/// # use std::str::FromStr;
    +/// # use bdk::bitcoin::{PrivateKey, Network};
    +/// # use bdk::{Wallet,  KeychainKind};
    +/// # use bdk::database::MemoryDatabase;
    +/// # use bdk::wallet::AddressIndex::New;
    +/// use bdk::template::Bip44;
    +///
    +/// let key = bitcoin::util::bip32::ExtendedPrivKey::from_str("tprv8ZgxMBicQKsPeZRHk4rTG6orPS2CRNFX3njhUXx5vj9qGog5ZMH4uGReDWN5kCkY3jmWEtWause41CDvBRXD1shKknAMKxT99o9qUTRVC6m")?;
    +/// let wallet = Wallet::new(
    +///     Bip44(key.clone(), KeychainKind::External),
    +///     Some(Bip44(key, KeychainKind::Internal)),
    +///     Network::Testnet,
    +///     MemoryDatabase::default()
    +/// )?;
    +///
    +/// assert_eq!(wallet.get_address(New)?.to_string(), "mmogjc7HJEZkrLqyQYqJmxUqFaC7i4uf89");
    +/// assert_eq!(wallet.public_descriptor(KeychainKind::External)?.unwrap().to_string(), "pkh([c55b303f/44'/1'/0']tpubDCuorCpzvYS2LCD75BR46KHE8GdDeg1wsAgNZeNr6DaB5gQK1o14uErKwKLuFmeemkQ6N2m3rNgvctdJLyr7nwu2yia7413Hhg8WWE44cgT/0/*)#5wrnv0xt");
    +/// # Ok::<_, Box<dyn std::error::Error>>(())
    +/// ```
    +pub struct Bip44<K: DerivableKey<Legacy>>(pub K, pub KeychainKind);
     
    -impl<K: DerivableKey<Legacy>> DescriptorTemplate for Bip44<K> {
    -    fn build(self, network: Network) -> Result<DescriptorTemplateOut, DescriptorError> {
    -        P2Pkh(legacy::make_bipxx_private(44, self.0, self.1, network)?).build(network)
    +impl<K: DerivableKey<Legacy>> DescriptorTemplate for Bip44<K> {
    +    fn build(self, network: Network) -> Result<DescriptorTemplateOut, DescriptorError> {
    +        P2Pkh(legacy::make_bipxx_private(44, self.0, self.1, network)?).build(network)
         }
     }
     
    -/// BIP44 public template. Expands to `pkh(key/{0,1}/*)`
    -///
    -/// This assumes that the key used has already been derived with `m/44'/0'/0'` for Mainnet or `m/44'/1'/0'` for Testnet.
    -///
    -/// This template requires the parent fingerprint to populate correctly the metadata of PSBTs.
    -///
    -/// See [`Bip44`] for a template that does the full derivation, but requires private data
    -/// for the key.
    -///
    -/// ## Example
    -///
    -/// ```
    -/// # use std::str::FromStr;
    -/// # use bdk::bitcoin::{PrivateKey, Network};
    -/// # use bdk::{Wallet,  KeychainKind};
    -/// # use bdk::database::MemoryDatabase;
    -/// # use bdk::wallet::AddressIndex::New;
    -/// use bdk::template::Bip44Public;
    -///
    -/// let key = bitcoin::util::bip32::ExtendedPubKey::from_str("tpubDDDzQ31JkZB7VxUr9bjvBivDdqoFLrDPyLWtLapArAi51ftfmCb2DPxwLQzX65iNcXz1DGaVvyvo6JQ6rTU73r2gqdEo8uov9QKRb7nKCSU")?;
    -/// let fingerprint = bitcoin::util::bip32::Fingerprint::from_str("c55b303f")?;
    -/// let wallet = Wallet::new(
    -///     Bip44Public(key.clone(), fingerprint, KeychainKind::External),
    -///     Some(Bip44Public(key, fingerprint, KeychainKind::Internal)),
    -///     Network::Testnet,
    -///     MemoryDatabase::default()
    -/// )?;
    -///
    -/// assert_eq!(wallet.get_address(New)?.to_string(), "miNG7dJTzJqNbFS19svRdTCisC65dsubtR");
    -/// assert_eq!(wallet.public_descriptor(KeychainKind::External)?.unwrap().to_string(), "pkh([c55b303f/44'/0'/0']tpubDDDzQ31JkZB7VxUr9bjvBivDdqoFLrDPyLWtLapArAi51ftfmCb2DPxwLQzX65iNcXz1DGaVvyvo6JQ6rTU73r2gqdEo8uov9QKRb7nKCSU/0/*)#xgaaevjx");
    -/// # Ok::<_, Box<dyn std::error::Error>>(())
    -/// ```
    -pub struct Bip44Public<K: DerivableKey<Legacy>>(pub K, pub bip32::Fingerprint, pub KeychainKind);
    +/// BIP44 public template. Expands to `pkh(key/{0,1}/*)`
    +///
    +/// This assumes that the key used has already been derived with `m/44'/0'/0'` for Mainnet or `m/44'/1'/0'` for Testnet.
    +///
    +/// This template requires the parent fingerprint to populate correctly the metadata of PSBTs.
    +///
    +/// See [`Bip44`] for a template that does the full derivation, but requires private data
    +/// for the key.
    +///
    +/// ## Example
    +///
    +/// ```
    +/// # use std::str::FromStr;
    +/// # use bdk::bitcoin::{PrivateKey, Network};
    +/// # use bdk::{Wallet,  KeychainKind};
    +/// # use bdk::database::MemoryDatabase;
    +/// # use bdk::wallet::AddressIndex::New;
    +/// use bdk::template::Bip44Public;
    +///
    +/// let key = bitcoin::util::bip32::ExtendedPubKey::from_str("tpubDDDzQ31JkZB7VxUr9bjvBivDdqoFLrDPyLWtLapArAi51ftfmCb2DPxwLQzX65iNcXz1DGaVvyvo6JQ6rTU73r2gqdEo8uov9QKRb7nKCSU")?;
    +/// let fingerprint = bitcoin::util::bip32::Fingerprint::from_str("c55b303f")?;
    +/// let wallet = Wallet::new(
    +///     Bip44Public(key.clone(), fingerprint, KeychainKind::External),
    +///     Some(Bip44Public(key, fingerprint, KeychainKind::Internal)),
    +///     Network::Testnet,
    +///     MemoryDatabase::default()
    +/// )?;
    +///
    +/// assert_eq!(wallet.get_address(New)?.to_string(), "miNG7dJTzJqNbFS19svRdTCisC65dsubtR");
    +/// assert_eq!(wallet.public_descriptor(KeychainKind::External)?.unwrap().to_string(), "pkh([c55b303f/44'/0'/0']tpubDDDzQ31JkZB7VxUr9bjvBivDdqoFLrDPyLWtLapArAi51ftfmCb2DPxwLQzX65iNcXz1DGaVvyvo6JQ6rTU73r2gqdEo8uov9QKRb7nKCSU/0/*)#xgaaevjx");
    +/// # Ok::<_, Box<dyn std::error::Error>>(())
    +/// ```
    +pub struct Bip44Public<K: DerivableKey<Legacy>>(pub K, pub bip32::Fingerprint, pub KeychainKind);
     
    -impl<K: DerivableKey<Legacy>> DescriptorTemplate for Bip44Public<K> {
    -    fn build(self, network: Network) -> Result<DescriptorTemplateOut, DescriptorError> {
    -        P2Pkh(legacy::make_bipxx_public(44, self.0, self.1, self.2)?).build(network)
    +impl<K: DerivableKey<Legacy>> DescriptorTemplate for Bip44Public<K> {
    +    fn build(self, network: Network) -> Result<DescriptorTemplateOut, DescriptorError> {
    +        P2Pkh(legacy::make_bipxx_public(44, self.0, self.1, self.2)?).build(network)
         }
     }
     
    -/// BIP49 template. Expands to `sh(wpkh(key/49'/{0,1}'/0'/{0,1}/*))`
    -///
    -/// Since there are hardened derivation steps, this template requires a private derivable key (generally a `xprv`/`tprv`).
    -///
    -/// See [`Bip49Public`] for a template that can work with a `xpub`/`tpub`.
    -///
    -/// ## Example
    -///
    -/// ```
    -/// # use std::str::FromStr;
    -/// # use bdk::bitcoin::{PrivateKey, Network};
    -/// # use bdk::{Wallet,  KeychainKind};
    -/// # use bdk::database::MemoryDatabase;
    -/// # use bdk::wallet::AddressIndex::New;
    -/// use bdk::template::Bip49;
    -///
    -/// let key = bitcoin::util::bip32::ExtendedPrivKey::from_str("tprv8ZgxMBicQKsPeZRHk4rTG6orPS2CRNFX3njhUXx5vj9qGog5ZMH4uGReDWN5kCkY3jmWEtWause41CDvBRXD1shKknAMKxT99o9qUTRVC6m")?;
    -/// let wallet = Wallet::new(
    -///     Bip49(key.clone(), KeychainKind::External),
    -///     Some(Bip49(key, KeychainKind::Internal)),
    -///     Network::Testnet,
    -///     MemoryDatabase::default()
    -/// )?;
    -///
    -/// assert_eq!(wallet.get_address(New)?.to_string(), "2N4zkWAoGdUv4NXhSsU8DvS5MB36T8nKHEB");
    -/// assert_eq!(wallet.public_descriptor(KeychainKind::External)?.unwrap().to_string(), "sh(wpkh([c55b303f/49'/1'/0']tpubDDYr4kdnZgjjShzYNjZUZXUUtpXaofdkMaipyS8ThEh45qFmhT4hKYways7UXmg6V7het1QiFo9kf4kYUXyDvV4rHEyvSpys9pjCB3pukxi/0/*))#s9vxlc8e");
    -/// # Ok::<_, Box<dyn std::error::Error>>(())
    -/// ```
    -pub struct Bip49<K: DerivableKey<Segwitv0>>(pub K, pub KeychainKind);
    +/// BIP49 template. Expands to `sh(wpkh(key/49'/{0,1}'/0'/{0,1}/*))`
    +///
    +/// Since there are hardened derivation steps, this template requires a private derivable key (generally a `xprv`/`tprv`).
    +///
    +/// See [`Bip49Public`] for a template that can work with a `xpub`/`tpub`.
    +///
    +/// ## Example
    +///
    +/// ```
    +/// # use std::str::FromStr;
    +/// # use bdk::bitcoin::{PrivateKey, Network};
    +/// # use bdk::{Wallet,  KeychainKind};
    +/// # use bdk::database::MemoryDatabase;
    +/// # use bdk::wallet::AddressIndex::New;
    +/// use bdk::template::Bip49;
    +///
    +/// let key = bitcoin::util::bip32::ExtendedPrivKey::from_str("tprv8ZgxMBicQKsPeZRHk4rTG6orPS2CRNFX3njhUXx5vj9qGog5ZMH4uGReDWN5kCkY3jmWEtWause41CDvBRXD1shKknAMKxT99o9qUTRVC6m")?;
    +/// let wallet = Wallet::new(
    +///     Bip49(key.clone(), KeychainKind::External),
    +///     Some(Bip49(key, KeychainKind::Internal)),
    +///     Network::Testnet,
    +///     MemoryDatabase::default()
    +/// )?;
    +///
    +/// assert_eq!(wallet.get_address(New)?.to_string(), "2N4zkWAoGdUv4NXhSsU8DvS5MB36T8nKHEB");
    +/// assert_eq!(wallet.public_descriptor(KeychainKind::External)?.unwrap().to_string(), "sh(wpkh([c55b303f/49'/1'/0']tpubDDYr4kdnZgjjShzYNjZUZXUUtpXaofdkMaipyS8ThEh45qFmhT4hKYways7UXmg6V7het1QiFo9kf4kYUXyDvV4rHEyvSpys9pjCB3pukxi/0/*))#s9vxlc8e");
    +/// # Ok::<_, Box<dyn std::error::Error>>(())
    +/// ```
    +pub struct Bip49<K: DerivableKey<Segwitv0>>(pub K, pub KeychainKind);
     
    -impl<K: DerivableKey<Segwitv0>> DescriptorTemplate for Bip49<K> {
    -    fn build(self, network: Network) -> Result<DescriptorTemplateOut, DescriptorError> {
    -        P2Wpkh_P2Sh(segwit_v0::make_bipxx_private(49, self.0, self.1, network)?).build(network)
    +impl<K: DerivableKey<Segwitv0>> DescriptorTemplate for Bip49<K> {
    +    fn build(self, network: Network) -> Result<DescriptorTemplateOut, DescriptorError> {
    +        P2Wpkh_P2Sh(segwit_v0::make_bipxx_private(49, self.0, self.1, network)?).build(network)
         }
     }
     
    -/// BIP49 public template. Expands to `sh(wpkh(key/{0,1}/*))`
    -///
    -/// This assumes that the key used has already been derived with `m/49'/0'/0'`.
    -///
    -/// This template requires the parent fingerprint to populate correctly the metadata of PSBTs.
    -///
    -/// See [`Bip49`] for a template that does the full derivation, but requires private data
    -/// for the key.
    -///
    -/// ## Example
    -///
    -/// ```
    -/// # use std::str::FromStr;
    -/// # use bdk::bitcoin::{PrivateKey, Network};
    -/// # use bdk::{Wallet,  KeychainKind};
    -/// # use bdk::database::MemoryDatabase;
    -/// # use bdk::wallet::AddressIndex::New;
    -/// use bdk::template::Bip49Public;
    -///
    -/// let key = bitcoin::util::bip32::ExtendedPubKey::from_str("tpubDC49r947KGK52X5rBWS4BLs5m9SRY3pYHnvRrm7HcybZ3BfdEsGFyzCMzayi1u58eT82ZeyFZwH7DD6Q83E3fM9CpfMtmnTygnLfP59jL9L")?;
    -/// let fingerprint = bitcoin::util::bip32::Fingerprint::from_str("c55b303f")?;
    -/// let wallet = Wallet::new(
    -///     Bip49Public(key.clone(), fingerprint, KeychainKind::External),
    -///     Some(Bip49Public(key, fingerprint, KeychainKind::Internal)),
    -///     Network::Testnet,
    -///     MemoryDatabase::default()
    -/// )?;
    -///
    -/// assert_eq!(wallet.get_address(New)?.to_string(), "2N3K4xbVAHoiTQSwxkZjWDfKoNC27pLkYnt");
    -/// assert_eq!(wallet.public_descriptor(KeychainKind::External)?.unwrap().to_string(), "sh(wpkh([c55b303f/49'/0'/0']tpubDC49r947KGK52X5rBWS4BLs5m9SRY3pYHnvRrm7HcybZ3BfdEsGFyzCMzayi1u58eT82ZeyFZwH7DD6Q83E3fM9CpfMtmnTygnLfP59jL9L/0/*))#gsmdv4xr");
    -/// # Ok::<_, Box<dyn std::error::Error>>(())
    -/// ```
    -pub struct Bip49Public<K: DerivableKey<Segwitv0>>(pub K, pub bip32::Fingerprint, pub KeychainKind);
    +/// BIP49 public template. Expands to `sh(wpkh(key/{0,1}/*))`
    +///
    +/// This assumes that the key used has already been derived with `m/49'/0'/0'`.
    +///
    +/// This template requires the parent fingerprint to populate correctly the metadata of PSBTs.
    +///
    +/// See [`Bip49`] for a template that does the full derivation, but requires private data
    +/// for the key.
    +///
    +/// ## Example
    +///
    +/// ```
    +/// # use std::str::FromStr;
    +/// # use bdk::bitcoin::{PrivateKey, Network};
    +/// # use bdk::{Wallet,  KeychainKind};
    +/// # use bdk::database::MemoryDatabase;
    +/// # use bdk::wallet::AddressIndex::New;
    +/// use bdk::template::Bip49Public;
    +///
    +/// let key = bitcoin::util::bip32::ExtendedPubKey::from_str("tpubDC49r947KGK52X5rBWS4BLs5m9SRY3pYHnvRrm7HcybZ3BfdEsGFyzCMzayi1u58eT82ZeyFZwH7DD6Q83E3fM9CpfMtmnTygnLfP59jL9L")?;
    +/// let fingerprint = bitcoin::util::bip32::Fingerprint::from_str("c55b303f")?;
    +/// let wallet = Wallet::new(
    +///     Bip49Public(key.clone(), fingerprint, KeychainKind::External),
    +///     Some(Bip49Public(key, fingerprint, KeychainKind::Internal)),
    +///     Network::Testnet,
    +///     MemoryDatabase::default()
    +/// )?;
    +///
    +/// assert_eq!(wallet.get_address(New)?.to_string(), "2N3K4xbVAHoiTQSwxkZjWDfKoNC27pLkYnt");
    +/// assert_eq!(wallet.public_descriptor(KeychainKind::External)?.unwrap().to_string(), "sh(wpkh([c55b303f/49'/0'/0']tpubDC49r947KGK52X5rBWS4BLs5m9SRY3pYHnvRrm7HcybZ3BfdEsGFyzCMzayi1u58eT82ZeyFZwH7DD6Q83E3fM9CpfMtmnTygnLfP59jL9L/0/*))#gsmdv4xr");
    +/// # Ok::<_, Box<dyn std::error::Error>>(())
    +/// ```
    +pub struct Bip49Public<K: DerivableKey<Segwitv0>>(pub K, pub bip32::Fingerprint, pub KeychainKind);
     
    -impl<K: DerivableKey<Segwitv0>> DescriptorTemplate for Bip49Public<K> {
    -    fn build(self, network: Network) -> Result<DescriptorTemplateOut, DescriptorError> {
    -        P2Wpkh_P2Sh(segwit_v0::make_bipxx_public(49, self.0, self.1, self.2)?).build(network)
    +impl<K: DerivableKey<Segwitv0>> DescriptorTemplate for Bip49Public<K> {
    +    fn build(self, network: Network) -> Result<DescriptorTemplateOut, DescriptorError> {
    +        P2Wpkh_P2Sh(segwit_v0::make_bipxx_public(49, self.0, self.1, self.2)?).build(network)
         }
     }
     
    -/// BIP84 template. Expands to `wpkh(key/84'/{0,1}'/0'/{0,1}/*)`
    -///
    -/// Since there are hardened derivation steps, this template requires a private derivable key (generally a `xprv`/`tprv`).
    -///
    -/// See [`Bip84Public`] for a template that can work with a `xpub`/`tpub`.
    -///
    -/// ## Example
    -///
    -/// ```
    -/// # use std::str::FromStr;
    -/// # use bdk::bitcoin::{PrivateKey, Network};
    -/// # use bdk::{Wallet,  KeychainKind};
    -/// # use bdk::database::MemoryDatabase;
    -/// # use bdk::wallet::AddressIndex::New;
    -/// use bdk::template::Bip84;
    -///
    -/// let key = bitcoin::util::bip32::ExtendedPrivKey::from_str("tprv8ZgxMBicQKsPeZRHk4rTG6orPS2CRNFX3njhUXx5vj9qGog5ZMH4uGReDWN5kCkY3jmWEtWause41CDvBRXD1shKknAMKxT99o9qUTRVC6m")?;
    -/// let wallet = Wallet::new(
    -///     Bip84(key.clone(), KeychainKind::External),
    -///     Some(Bip84(key, KeychainKind::Internal)),
    -///     Network::Testnet,
    -///     MemoryDatabase::default()
    -/// )?;
    -///
    -/// assert_eq!(wallet.get_address(New)?.to_string(), "tb1qhl85z42h7r4su5u37rvvw0gk8j2t3n9y7zsg4n");
    -/// assert_eq!(wallet.public_descriptor(KeychainKind::External)?.unwrap().to_string(), "wpkh([c55b303f/84'/1'/0']tpubDDc5mum24DekpNw92t6fHGp8Gr2JjF9J7i4TZBtN6Vp8xpAULG5CFaKsfugWa5imhrQQUZKXe261asP5koDHo5bs3qNTmf3U3o4v9SaB8gg/0/*)#6kfecsmr");
    -/// # Ok::<_, Box<dyn std::error::Error>>(())
    -/// ```
    -pub struct Bip84<K: DerivableKey<Segwitv0>>(pub K, pub KeychainKind);
    +/// BIP84 template. Expands to `wpkh(key/84'/{0,1}'/0'/{0,1}/*)`
    +///
    +/// Since there are hardened derivation steps, this template requires a private derivable key (generally a `xprv`/`tprv`).
    +///
    +/// See [`Bip84Public`] for a template that can work with a `xpub`/`tpub`.
    +///
    +/// ## Example
    +///
    +/// ```
    +/// # use std::str::FromStr;
    +/// # use bdk::bitcoin::{PrivateKey, Network};
    +/// # use bdk::{Wallet,  KeychainKind};
    +/// # use bdk::database::MemoryDatabase;
    +/// # use bdk::wallet::AddressIndex::New;
    +/// use bdk::template::Bip84;
    +///
    +/// let key = bitcoin::util::bip32::ExtendedPrivKey::from_str("tprv8ZgxMBicQKsPeZRHk4rTG6orPS2CRNFX3njhUXx5vj9qGog5ZMH4uGReDWN5kCkY3jmWEtWause41CDvBRXD1shKknAMKxT99o9qUTRVC6m")?;
    +/// let wallet = Wallet::new(
    +///     Bip84(key.clone(), KeychainKind::External),
    +///     Some(Bip84(key, KeychainKind::Internal)),
    +///     Network::Testnet,
    +///     MemoryDatabase::default()
    +/// )?;
    +///
    +/// assert_eq!(wallet.get_address(New)?.to_string(), "tb1qhl85z42h7r4su5u37rvvw0gk8j2t3n9y7zsg4n");
    +/// assert_eq!(wallet.public_descriptor(KeychainKind::External)?.unwrap().to_string(), "wpkh([c55b303f/84'/1'/0']tpubDDc5mum24DekpNw92t6fHGp8Gr2JjF9J7i4TZBtN6Vp8xpAULG5CFaKsfugWa5imhrQQUZKXe261asP5koDHo5bs3qNTmf3U3o4v9SaB8gg/0/*)#6kfecsmr");
    +/// # Ok::<_, Box<dyn std::error::Error>>(())
    +/// ```
    +pub struct Bip84<K: DerivableKey<Segwitv0>>(pub K, pub KeychainKind);
     
    -impl<K: DerivableKey<Segwitv0>> DescriptorTemplate for Bip84<K> {
    -    fn build(self, network: Network) -> Result<DescriptorTemplateOut, DescriptorError> {
    -        P2Wpkh(segwit_v0::make_bipxx_private(84, self.0, self.1, network)?).build(network)
    +impl<K: DerivableKey<Segwitv0>> DescriptorTemplate for Bip84<K> {
    +    fn build(self, network: Network) -> Result<DescriptorTemplateOut, DescriptorError> {
    +        P2Wpkh(segwit_v0::make_bipxx_private(84, self.0, self.1, network)?).build(network)
         }
     }
     
    -/// BIP84 public template. Expands to `wpkh(key/{0,1}/*)`
    -///
    -/// This assumes that the key used has already been derived with `m/84'/0'/0'`.
    -///
    -/// This template requires the parent fingerprint to populate correctly the metadata of PSBTs.
    -///
    -/// See [`Bip84`] for a template that does the full derivation, but requires private data
    -/// for the key.
    -///
    -/// ## Example
    -///
    -/// ```
    -/// # use std::str::FromStr;
    -/// # use bdk::bitcoin::{PrivateKey, Network};
    -/// # use bdk::{Wallet,  KeychainKind};
    -/// # use bdk::database::MemoryDatabase;
    -/// # use bdk::wallet::AddressIndex::New;
    -/// use bdk::template::Bip84Public;
    -///
    -/// let key = bitcoin::util::bip32::ExtendedPubKey::from_str("tpubDC2Qwo2TFsaNC4ju8nrUJ9mqVT3eSgdmy1yPqhgkjwmke3PRXutNGRYAUo6RCHTcVQaDR3ohNU9we59brGHuEKPvH1ags2nevW5opEE9Z5Q")?;
    -/// let fingerprint = bitcoin::util::bip32::Fingerprint::from_str("c55b303f")?;
    -/// let wallet = Wallet::new(
    -///     Bip84Public(key.clone(), fingerprint, KeychainKind::External),
    -///     Some(Bip84Public(key, fingerprint, KeychainKind::Internal)),
    -///     Network::Testnet,
    -///     MemoryDatabase::default()
    -/// )?;
    -///
    -/// assert_eq!(wallet.get_address(New)?.to_string(), "tb1qedg9fdlf8cnnqfd5mks6uz5w4kgpk2pr6y4qc7");
    -/// assert_eq!(wallet.public_descriptor(KeychainKind::External)?.unwrap().to_string(), "wpkh([c55b303f/84\'/0\'/0\']tpubDC2Qwo2TFsaNC4ju8nrUJ9mqVT3eSgdmy1yPqhgkjwmke3PRXutNGRYAUo6RCHTcVQaDR3ohNU9we59brGHuEKPvH1ags2nevW5opEE9Z5Q/0/*)#nkk5dtkg");
    -/// # Ok::<_, Box<dyn std::error::Error>>(())
    -/// ```
    -pub struct Bip84Public<K: DerivableKey<Segwitv0>>(pub K, pub bip32::Fingerprint, pub KeychainKind);
    +/// BIP84 public template. Expands to `wpkh(key/{0,1}/*)`
    +///
    +/// This assumes that the key used has already been derived with `m/84'/0'/0'`.
    +///
    +/// This template requires the parent fingerprint to populate correctly the metadata of PSBTs.
    +///
    +/// See [`Bip84`] for a template that does the full derivation, but requires private data
    +/// for the key.
    +///
    +/// ## Example
    +///
    +/// ```
    +/// # use std::str::FromStr;
    +/// # use bdk::bitcoin::{PrivateKey, Network};
    +/// # use bdk::{Wallet,  KeychainKind};
    +/// # use bdk::database::MemoryDatabase;
    +/// # use bdk::wallet::AddressIndex::New;
    +/// use bdk::template::Bip84Public;
    +///
    +/// let key = bitcoin::util::bip32::ExtendedPubKey::from_str("tpubDC2Qwo2TFsaNC4ju8nrUJ9mqVT3eSgdmy1yPqhgkjwmke3PRXutNGRYAUo6RCHTcVQaDR3ohNU9we59brGHuEKPvH1ags2nevW5opEE9Z5Q")?;
    +/// let fingerprint = bitcoin::util::bip32::Fingerprint::from_str("c55b303f")?;
    +/// let wallet = Wallet::new(
    +///     Bip84Public(key.clone(), fingerprint, KeychainKind::External),
    +///     Some(Bip84Public(key, fingerprint, KeychainKind::Internal)),
    +///     Network::Testnet,
    +///     MemoryDatabase::default()
    +/// )?;
    +///
    +/// assert_eq!(wallet.get_address(New)?.to_string(), "tb1qedg9fdlf8cnnqfd5mks6uz5w4kgpk2pr6y4qc7");
    +/// assert_eq!(wallet.public_descriptor(KeychainKind::External)?.unwrap().to_string(), "wpkh([c55b303f/84\'/0\'/0\']tpubDC2Qwo2TFsaNC4ju8nrUJ9mqVT3eSgdmy1yPqhgkjwmke3PRXutNGRYAUo6RCHTcVQaDR3ohNU9we59brGHuEKPvH1ags2nevW5opEE9Z5Q/0/*)#nkk5dtkg");
    +/// # Ok::<_, Box<dyn std::error::Error>>(())
    +/// ```
    +pub struct Bip84Public<K: DerivableKey<Segwitv0>>(pub K, pub bip32::Fingerprint, pub KeychainKind);
     
    -impl<K: DerivableKey<Segwitv0>> DescriptorTemplate for Bip84Public<K> {
    -    fn build(self, network: Network) -> Result<DescriptorTemplateOut, DescriptorError> {
    -        P2Wpkh(segwit_v0::make_bipxx_public(84, self.0, self.1, self.2)?).build(network)
    +impl<K: DerivableKey<Segwitv0>> DescriptorTemplate for Bip84Public<K> {
    +    fn build(self, network: Network) -> Result<DescriptorTemplateOut, DescriptorError> {
    +        P2Wpkh(segwit_v0::make_bipxx_public(84, self.0, self.1, self.2)?).build(network)
         }
     }
     
    -macro_rules! expand_make_bipxx {
    -    ( $mod_name:ident, $ctx:ty ) => {
    -        mod $mod_name {
    -            use super::*;
    +macro_rules! expand_make_bipxx {
    +    ( $mod_name:ident, $ctx:ty ) => {
    +        mod $mod_name {
    +            use super::*;
     
    -            pub(super) fn make_bipxx_private<K: DerivableKey<$ctx>>(
    -                bip: u32,
    -                key: K,
    -                keychain: KeychainKind,
    -                network: Network,
    -            ) -> Result<impl IntoDescriptorKey<$ctx>, DescriptorError> {
    -                let mut derivation_path = Vec::with_capacity(4);
    -                derivation_path.push(bip32::ChildNumber::from_hardened_idx(bip)?);
    +            pub(super) fn make_bipxx_private<K: DerivableKey<$ctx>>(
    +                bip: u32,
    +                key: K,
    +                keychain: KeychainKind,
    +                network: Network,
    +            ) -> Result<impl IntoDescriptorKey<$ctx>, DescriptorError> {
    +                let mut derivation_path = Vec::with_capacity(4);
    +                derivation_path.push(bip32::ChildNumber::from_hardened_idx(bip)?);
     
    -                match network {
    -                    Network::Bitcoin => {
    -                        derivation_path.push(bip32::ChildNumber::from_hardened_idx(0)?);
    +                match network {
    +                    Network::Bitcoin => {
    +                        derivation_path.push(bip32::ChildNumber::from_hardened_idx(0)?);
                         }
    -                    _ => {
    -                        derivation_path.push(bip32::ChildNumber::from_hardened_idx(1)?);
    +                    _ => {
    +                        derivation_path.push(bip32::ChildNumber::from_hardened_idx(1)?);
                         }
                     }
    -                derivation_path.push(bip32::ChildNumber::from_hardened_idx(0)?);
    +                derivation_path.push(bip32::ChildNumber::from_hardened_idx(0)?);
     
    -                match keychain {
    -                    KeychainKind::External => {
    -                        derivation_path.push(bip32::ChildNumber::from_normal_idx(0)?)
    +                match keychain {
    +                    KeychainKind::External => {
    +                        derivation_path.push(bip32::ChildNumber::from_normal_idx(0)?)
                         }
    -                    KeychainKind::Internal => {
    -                        derivation_path.push(bip32::ChildNumber::from_normal_idx(1)?)
    +                    KeychainKind::Internal => {
    +                        derivation_path.push(bip32::ChildNumber::from_normal_idx(1)?)
                         }
                     };
     
    -                let derivation_path: bip32::DerivationPath = derivation_path.into();
    +                let derivation_path: bip32::DerivationPath = derivation_path.into();
     
    -                Ok((key, derivation_path))
    +                Ok((key, derivation_path))
                 }
    -            pub(super) fn make_bipxx_public<K: DerivableKey<$ctx>>(
    -                bip: u32,
    -                key: K,
    -                parent_fingerprint: bip32::Fingerprint,
    -                keychain: KeychainKind,
    -            ) -> Result<impl IntoDescriptorKey<$ctx>, DescriptorError> {
    -                let derivation_path: bip32::DerivationPath = match keychain {
    -                    KeychainKind::External => vec![bip32::ChildNumber::from_normal_idx(0)?].into(),
    -                    KeychainKind::Internal => vec![bip32::ChildNumber::from_normal_idx(1)?].into(),
    +            pub(super) fn make_bipxx_public<K: DerivableKey<$ctx>>(
    +                bip: u32,
    +                key: K,
    +                parent_fingerprint: bip32::Fingerprint,
    +                keychain: KeychainKind,
    +            ) -> Result<impl IntoDescriptorKey<$ctx>, DescriptorError> {
    +                let derivation_path: bip32::DerivationPath = match keychain {
    +                    KeychainKind::External => vec![bip32::ChildNumber::from_normal_idx(0)?].into(),
    +                    KeychainKind::Internal => vec![bip32::ChildNumber::from_normal_idx(1)?].into(),
                     };
     
    -                let source_path = bip32::DerivationPath::from(vec![
    -                    bip32::ChildNumber::from_hardened_idx(bip)?,
    -                    bip32::ChildNumber::from_hardened_idx(0)?,
    -                    bip32::ChildNumber::from_hardened_idx(0)?,
    +                let source_path = bip32::DerivationPath::from(vec![
    +                    bip32::ChildNumber::from_hardened_idx(bip)?,
    +                    bip32::ChildNumber::from_hardened_idx(0)?,
    +                    bip32::ChildNumber::from_hardened_idx(0)?,
                     ]);
     
    -                Ok((key, (parent_fingerprint, source_path), derivation_path))
    +                Ok((key, (parent_fingerprint, source_path), derivation_path))
                 }
             }
         };
     }
     
    -expand_make_bipxx!(legacy, Legacy);
    -expand_make_bipxx!(segwit_v0, Segwitv0);
    +expand_make_bipxx!(legacy, Legacy);
    +expand_make_bipxx!(segwit_v0, Segwitv0);
     
    -#[cfg(test)]
    -mod test {
    -    // test existing descriptor templates, make sure they are expanded to the right descriptors
    +#[cfg(test)]
    +mod test {
    +    // test existing descriptor templates, make sure they are expanded to the right descriptors
     
    -    use std::str::FromStr;
    +    use std::str::FromStr;
     
    -    use super::*;
    -    use crate::descriptor::{DescriptorError, DescriptorMeta};
    -    use crate::keys::ValidNetworks;
    -    use bitcoin::network::constants::Network::Regtest;
    -    use miniscript::descriptor::{DescriptorPublicKey, KeyMap};
    -    use miniscript::Descriptor;
    +    use super::*;
    +    use crate::descriptor::{DescriptorError, DescriptorMeta};
    +    use crate::keys::ValidNetworks;
    +    use bitcoin::network::constants::Network::Regtest;
    +    use miniscript::descriptor::{DescriptorPublicKey, KeyMap};
    +    use miniscript::Descriptor;
     
    -    // BIP44 `pkh(key/44'/{0,1}'/0'/{0,1}/*)`
    -    #[test]
    -    fn test_bip44_template_cointype() {
    -        use bitcoin::util::bip32::ChildNumber::{self, Hardened};
    +    // BIP44 `pkh(key/44'/{0,1}'/0'/{0,1}/*)`
    +    #[test]
    +    fn test_bip44_template_cointype() {
    +        use bitcoin::util::bip32::ChildNumber::{self, Hardened};
     
    -        let xprvkey = bitcoin::util::bip32::ExtendedPrivKey::from_str("xprv9s21ZrQH143K2fpbqApQL69a4oKdGVnVN52R82Ft7d1pSqgKmajF62acJo3aMszZb6qQ22QsVECSFxvf9uyxFUvFYQMq3QbtwtRSMjLAhMf").unwrap();
    -        assert_eq!(Network::Bitcoin, xprvkey.network);
    -        let xdesc = Bip44(xprvkey, KeychainKind::Internal)
    -            .build(Network::Bitcoin)
    -            .unwrap();
    +        let xprvkey = bitcoin::util::bip32::ExtendedPrivKey::from_str("xprv9s21ZrQH143K2fpbqApQL69a4oKdGVnVN52R82Ft7d1pSqgKmajF62acJo3aMszZb6qQ22QsVECSFxvf9uyxFUvFYQMq3QbtwtRSMjLAhMf").unwrap();
    +        assert_eq!(Network::Bitcoin, xprvkey.network);
    +        let xdesc = Bip44(xprvkey, KeychainKind::Internal)
    +            .build(Network::Bitcoin)
    +            .unwrap();
     
    -        if let ExtendedDescriptor::Pkh(pkh) = xdesc.0 {
    -            let path: Vec<ChildNumber> = pkh.into_inner().full_derivation_path().into();
    -            let purpose = path.get(0).unwrap();
    -            assert!(matches!(purpose, Hardened { index: 44 }));
    -            let coin_type = path.get(1).unwrap();
    -            assert!(matches!(coin_type, Hardened { index: 0 }));
    +        if let ExtendedDescriptor::Pkh(pkh) = xdesc.0 {
    +            let path: Vec<ChildNumber> = pkh.into_inner().full_derivation_path().into();
    +            let purpose = path.get(0).unwrap();
    +            assert!(matches!(purpose, Hardened { index: 44 }));
    +            let coin_type = path.get(1).unwrap();
    +            assert!(matches!(coin_type, Hardened { index: 0 }));
             }
     
    -        let tprvkey = bitcoin::util::bip32::ExtendedPrivKey::from_str("tprv8ZgxMBicQKsPcx5nBGsR63Pe8KnRUqmbJNENAfGftF3yuXoMMoVJJcYeUw5eVkm9WBPjWYt6HMWYJNesB5HaNVBaFc1M6dRjWSYnmewUMYy").unwrap();
    -        assert_eq!(Network::Testnet, tprvkey.network);
    -        let tdesc = Bip44(tprvkey, KeychainKind::Internal)
    -            .build(Network::Testnet)
    -            .unwrap();
    +        let tprvkey = bitcoin::util::bip32::ExtendedPrivKey::from_str("tprv8ZgxMBicQKsPcx5nBGsR63Pe8KnRUqmbJNENAfGftF3yuXoMMoVJJcYeUw5eVkm9WBPjWYt6HMWYJNesB5HaNVBaFc1M6dRjWSYnmewUMYy").unwrap();
    +        assert_eq!(Network::Testnet, tprvkey.network);
    +        let tdesc = Bip44(tprvkey, KeychainKind::Internal)
    +            .build(Network::Testnet)
    +            .unwrap();
     
    -        if let ExtendedDescriptor::Pkh(pkh) = tdesc.0 {
    -            let path: Vec<ChildNumber> = pkh.into_inner().full_derivation_path().into();
    -            let purpose = path.get(0).unwrap();
    -            assert!(matches!(purpose, Hardened { index: 44 }));
    -            let coin_type = path.get(1).unwrap();
    -            assert!(matches!(coin_type, Hardened { index: 1 }));
    +        if let ExtendedDescriptor::Pkh(pkh) = tdesc.0 {
    +            let path: Vec<ChildNumber> = pkh.into_inner().full_derivation_path().into();
    +            let purpose = path.get(0).unwrap();
    +            assert!(matches!(purpose, Hardened { index: 44 }));
    +            let coin_type = path.get(1).unwrap();
    +            assert!(matches!(coin_type, Hardened { index: 1 }));
             }
         }
     
    -    // verify template descriptor generates expected address(es)
    -    fn check(
    -        desc: Result<(Descriptor<DescriptorPublicKey>, KeyMap, ValidNetworks), DescriptorError>,
    -        is_witness: bool,
    -        is_fixed: bool,
    -        expected: &[&str],
    +    // verify template descriptor generates expected address(es)
    +    fn check(
    +        desc: Result<(Descriptor<DescriptorPublicKey>, KeyMap, ValidNetworks), DescriptorError>,
    +        is_witness: bool,
    +        is_fixed: bool,
    +        expected: &[&str],
         ) {
    -        let (desc, _key_map, _networks) = desc.unwrap();
    -        assert_eq!(desc.is_witness(), is_witness);
    -        assert_eq!(!desc.has_wildcard(), is_fixed);
    -        for i in 0..expected.len() {
    -            let index = i as u32;
    -            let child_desc = if !desc.has_wildcard() {
    -                desc.at_derivation_index(0)
    -            } else {
    -                desc.at_derivation_index(index)
    +        let (desc, _key_map, _networks) = desc.unwrap();
    +        assert_eq!(desc.is_witness(), is_witness);
    +        assert_eq!(!desc.has_wildcard(), is_fixed);
    +        for i in 0..expected.len() {
    +            let index = i as u32;
    +            let child_desc = if !desc.has_wildcard() {
    +                desc.at_derivation_index(0)
    +            } else {
    +                desc.at_derivation_index(index)
                 };
    -            let address = child_desc.address(Regtest).unwrap();
    -            assert_eq!(address.to_string(), *expected.get(i).unwrap());
    +            let address = child_desc.address(Regtest).unwrap();
    +            assert_eq!(address.to_string(), *expected.get(i).unwrap());
             }
         }
     
    -    // P2PKH
    -    #[test]
    -    fn test_p2ph_template() {
    -        let prvkey =
    -            bitcoin::PrivateKey::from_wif("cTc4vURSzdx6QE6KVynWGomDbLaA75dNALMNyfjh3p8DRRar84Um")
    -                .unwrap();
    -        check(
    -            P2Pkh(prvkey).build(Network::Bitcoin),
    +    // P2PKH
    +    #[test]
    +    fn test_p2ph_template() {
    +        let prvkey =
    +            bitcoin::PrivateKey::from_wif("cTc4vURSzdx6QE6KVynWGomDbLaA75dNALMNyfjh3p8DRRar84Um")
    +                .unwrap();
    +        check(
    +            P2Pkh(prvkey).build(Network::Bitcoin),
                 false,
                 true,
                 &["mwJ8hxFYW19JLuc65RCTaP4v1rzVU8cVMT"],
             );
     
    -        let pubkey = bitcoin::PublicKey::from_str(
    +        let pubkey = bitcoin::PublicKey::from_str(
                 "03a34b99f22c790c4e36b2b3c2c35a36db06226e41c692fc82b8b56ac1c540c5bd",
             )
    -        .unwrap();
    -        check(
    -            P2Pkh(pubkey).build(Network::Bitcoin),
    +        .unwrap();
    +        check(
    +            P2Pkh(pubkey).build(Network::Bitcoin),
                 false,
                 true,
                 &["muZpTpBYhxmRFuCjLc7C6BBDF32C8XVJUi"],
             );
         }
     
    -    // P2WPKH-P2SH `sh(wpkh(key))`
    -    #[test]
    -    fn test_p2wphp2sh_template() {
    -        let prvkey =
    -            bitcoin::PrivateKey::from_wif("cTc4vURSzdx6QE6KVynWGomDbLaA75dNALMNyfjh3p8DRRar84Um")
    -                .unwrap();
    -        check(
    -            P2Wpkh_P2Sh(prvkey).build(Network::Bitcoin),
    +    // P2WPKH-P2SH `sh(wpkh(key))`
    +    #[test]
    +    fn test_p2wphp2sh_template() {
    +        let prvkey =
    +            bitcoin::PrivateKey::from_wif("cTc4vURSzdx6QE6KVynWGomDbLaA75dNALMNyfjh3p8DRRar84Um")
    +                .unwrap();
    +        check(
    +            P2Wpkh_P2Sh(prvkey).build(Network::Bitcoin),
                 true,
                 true,
                 &["2NB4ox5VDRw1ecUv6SnT3VQHPXveYztRqk5"],
             );
     
    -        let pubkey = bitcoin::PublicKey::from_str(
    +        let pubkey = bitcoin::PublicKey::from_str(
                 "03a34b99f22c790c4e36b2b3c2c35a36db06226e41c692fc82b8b56ac1c540c5bd",
             )
    -        .unwrap();
    -        check(
    -            P2Wpkh_P2Sh(pubkey).build(Network::Bitcoin),
    +        .unwrap();
    +        check(
    +            P2Wpkh_P2Sh(pubkey).build(Network::Bitcoin),
                 true,
                 true,
                 &["2N5LiC3CqzxDamRTPG1kiNv1FpNJQ7x28sb"],
             );
         }
     
    -    // P2WPKH `wpkh(key)`
    -    #[test]
    -    fn test_p2wph_template() {
    -        let prvkey =
    -            bitcoin::PrivateKey::from_wif("cTc4vURSzdx6QE6KVynWGomDbLaA75dNALMNyfjh3p8DRRar84Um")
    -                .unwrap();
    -        check(
    -            P2Wpkh(prvkey).build(Network::Bitcoin),
    +    // P2WPKH `wpkh(key)`
    +    #[test]
    +    fn test_p2wph_template() {
    +        let prvkey =
    +            bitcoin::PrivateKey::from_wif("cTc4vURSzdx6QE6KVynWGomDbLaA75dNALMNyfjh3p8DRRar84Um")
    +                .unwrap();
    +        check(
    +            P2Wpkh(prvkey).build(Network::Bitcoin),
                 true,
                 true,
                 &["bcrt1q4525hmgw265tl3drrl8jjta7ayffu6jfcwxx9y"],
             );
     
    -        let pubkey = bitcoin::PublicKey::from_str(
    +        let pubkey = bitcoin::PublicKey::from_str(
                 "03a34b99f22c790c4e36b2b3c2c35a36db06226e41c692fc82b8b56ac1c540c5bd",
             )
    -        .unwrap();
    -        check(
    -            P2Wpkh(pubkey).build(Network::Bitcoin),
    +        .unwrap();
    +        check(
    +            P2Wpkh(pubkey).build(Network::Bitcoin),
                 true,
                 true,
                 &["bcrt1qngw83fg8dz0k749cg7k3emc7v98wy0c7azaa6h"],
             );
         }
     
    -    // BIP44 `pkh(key/44'/0'/0'/{0,1}/*)`
    -    #[test]
    -    fn test_bip44_template() {
    -        let prvkey = bitcoin::util::bip32::ExtendedPrivKey::from_str("tprv8ZgxMBicQKsPcx5nBGsR63Pe8KnRUqmbJNENAfGftF3yuXoMMoVJJcYeUw5eVkm9WBPjWYt6HMWYJNesB5HaNVBaFc1M6dRjWSYnmewUMYy").unwrap();
    -        check(
    -            Bip44(prvkey, KeychainKind::External).build(Network::Bitcoin),
    +    // BIP44 `pkh(key/44'/0'/0'/{0,1}/*)`
    +    #[test]
    +    fn test_bip44_template() {
    +        let prvkey = bitcoin::util::bip32::ExtendedPrivKey::from_str("tprv8ZgxMBicQKsPcx5nBGsR63Pe8KnRUqmbJNENAfGftF3yuXoMMoVJJcYeUw5eVkm9WBPjWYt6HMWYJNesB5HaNVBaFc1M6dRjWSYnmewUMYy").unwrap();
    +        check(
    +            Bip44(prvkey, KeychainKind::External).build(Network::Bitcoin),
                 false,
                 false,
                 &[
    @@ -1392,8 +1386,8 @@
                     "mzYvhRAuQqbdSKMVVzXNYyqihgNdRadAUQ",
                 ],
             );
    -        check(
    -            Bip44(prvkey, KeychainKind::Internal).build(Network::Bitcoin),
    +        check(
    +            Bip44(prvkey, KeychainKind::Internal).build(Network::Bitcoin),
                 false,
                 false,
                 &[
    @@ -1404,13 +1398,13 @@
             );
         }
     
    -    // BIP44 public `pkh(key/{0,1}/*)`
    -    #[test]
    -    fn test_bip44_public_template() {
    -        let pubkey = bitcoin::util::bip32::ExtendedPubKey::from_str("tpubDDDzQ31JkZB7VxUr9bjvBivDdqoFLrDPyLWtLapArAi51ftfmCb2DPxwLQzX65iNcXz1DGaVvyvo6JQ6rTU73r2gqdEo8uov9QKRb7nKCSU").unwrap();
    -        let fingerprint = bitcoin::util::bip32::Fingerprint::from_str("c55b303f").unwrap();
    -        check(
    -            Bip44Public(pubkey, fingerprint, KeychainKind::External).build(Network::Bitcoin),
    +    // BIP44 public `pkh(key/{0,1}/*)`
    +    #[test]
    +    fn test_bip44_public_template() {
    +        let pubkey = bitcoin::util::bip32::ExtendedPubKey::from_str("tpubDDDzQ31JkZB7VxUr9bjvBivDdqoFLrDPyLWtLapArAi51ftfmCb2DPxwLQzX65iNcXz1DGaVvyvo6JQ6rTU73r2gqdEo8uov9QKRb7nKCSU").unwrap();
    +        let fingerprint = bitcoin::util::bip32::Fingerprint::from_str("c55b303f").unwrap();
    +        check(
    +            Bip44Public(pubkey, fingerprint, KeychainKind::External).build(Network::Bitcoin),
                 false,
                 false,
                 &[
    @@ -1419,8 +1413,8 @@
                     "muCPpS6Ue7nkzeJMWDViw7Lkwr92Yc4K8g",
                 ],
             );
    -        check(
    -            Bip44Public(pubkey, fingerprint, KeychainKind::Internal).build(Network::Bitcoin),
    +        check(
    +            Bip44Public(pubkey, fingerprint, KeychainKind::Internal).build(Network::Bitcoin),
                 false,
                 false,
                 &[
    @@ -1431,12 +1425,12 @@
             );
         }
     
    -    // BIP49 `sh(wpkh(key/49'/0'/0'/{0,1}/*))`
    -    #[test]
    -    fn test_bip49_template() {
    -        let prvkey = bitcoin::util::bip32::ExtendedPrivKey::from_str("tprv8ZgxMBicQKsPcx5nBGsR63Pe8KnRUqmbJNENAfGftF3yuXoMMoVJJcYeUw5eVkm9WBPjWYt6HMWYJNesB5HaNVBaFc1M6dRjWSYnmewUMYy").unwrap();
    -        check(
    -            Bip49(prvkey, KeychainKind::External).build(Network::Bitcoin),
    +    // BIP49 `sh(wpkh(key/49'/0'/0'/{0,1}/*))`
    +    #[test]
    +    fn test_bip49_template() {
    +        let prvkey = bitcoin::util::bip32::ExtendedPrivKey::from_str("tprv8ZgxMBicQKsPcx5nBGsR63Pe8KnRUqmbJNENAfGftF3yuXoMMoVJJcYeUw5eVkm9WBPjWYt6HMWYJNesB5HaNVBaFc1M6dRjWSYnmewUMYy").unwrap();
    +        check(
    +            Bip49(prvkey, KeychainKind::External).build(Network::Bitcoin),
                 true,
                 false,
                 &[
    @@ -1445,8 +1439,8 @@
                     "2NAFTVtksF9T4a97M7nyCjwUBD24QevZ5Z4",
                 ],
             );
    -        check(
    -            Bip49(prvkey, KeychainKind::Internal).build(Network::Bitcoin),
    +        check(
    +            Bip49(prvkey, KeychainKind::Internal).build(Network::Bitcoin),
                 true,
                 false,
                 &[
    @@ -1457,13 +1451,13 @@
             );
         }
     
    -    // BIP49 public `sh(wpkh(key/{0,1}/*))`
    -    #[test]
    -    fn test_bip49_public_template() {
    -        let pubkey = bitcoin::util::bip32::ExtendedPubKey::from_str("tpubDC49r947KGK52X5rBWS4BLs5m9SRY3pYHnvRrm7HcybZ3BfdEsGFyzCMzayi1u58eT82ZeyFZwH7DD6Q83E3fM9CpfMtmnTygnLfP59jL9L").unwrap();
    -        let fingerprint = bitcoin::util::bip32::Fingerprint::from_str("c55b303f").unwrap();
    -        check(
    -            Bip49Public(pubkey, fingerprint, KeychainKind::External).build(Network::Bitcoin),
    +    // BIP49 public `sh(wpkh(key/{0,1}/*))`
    +    #[test]
    +    fn test_bip49_public_template() {
    +        let pubkey = bitcoin::util::bip32::ExtendedPubKey::from_str("tpubDC49r947KGK52X5rBWS4BLs5m9SRY3pYHnvRrm7HcybZ3BfdEsGFyzCMzayi1u58eT82ZeyFZwH7DD6Q83E3fM9CpfMtmnTygnLfP59jL9L").unwrap();
    +        let fingerprint = bitcoin::util::bip32::Fingerprint::from_str("c55b303f").unwrap();
    +        check(
    +            Bip49Public(pubkey, fingerprint, KeychainKind::External).build(Network::Bitcoin),
                 true,
                 false,
                 &[
    @@ -1472,8 +1466,8 @@
                     "2MveFxAuC8BYPzTybx7FxSzW8HSd8ATT4z7",
                 ],
             );
    -        check(
    -            Bip49Public(pubkey, fingerprint, KeychainKind::Internal).build(Network::Bitcoin),
    +        check(
    +            Bip49Public(pubkey, fingerprint, KeychainKind::Internal).build(Network::Bitcoin),
                 true,
                 false,
                 &[
    @@ -1484,12 +1478,12 @@
             );
         }
     
    -    // BIP84 `wpkh(key/84'/0'/0'/{0,1}/*)`
    -    #[test]
    -    fn test_bip84_template() {
    -        let prvkey = bitcoin::util::bip32::ExtendedPrivKey::from_str("tprv8ZgxMBicQKsPcx5nBGsR63Pe8KnRUqmbJNENAfGftF3yuXoMMoVJJcYeUw5eVkm9WBPjWYt6HMWYJNesB5HaNVBaFc1M6dRjWSYnmewUMYy").unwrap();
    -        check(
    -            Bip84(prvkey, KeychainKind::External).build(Network::Bitcoin),
    +    // BIP84 `wpkh(key/84'/0'/0'/{0,1}/*)`
    +    #[test]
    +    fn test_bip84_template() {
    +        let prvkey = bitcoin::util::bip32::ExtendedPrivKey::from_str("tprv8ZgxMBicQKsPcx5nBGsR63Pe8KnRUqmbJNENAfGftF3yuXoMMoVJJcYeUw5eVkm9WBPjWYt6HMWYJNesB5HaNVBaFc1M6dRjWSYnmewUMYy").unwrap();
    +        check(
    +            Bip84(prvkey, KeychainKind::External).build(Network::Bitcoin),
                 true,
                 false,
                 &[
    @@ -1498,8 +1492,8 @@
                     "bcrt1q4h7fq9zhxst6e69p3n882nfj649l7w9g3zccfp",
                 ],
             );
    -        check(
    -            Bip84(prvkey, KeychainKind::Internal).build(Network::Bitcoin),
    +        check(
    +            Bip84(prvkey, KeychainKind::Internal).build(Network::Bitcoin),
                 true,
                 false,
                 &[
    @@ -1510,13 +1504,13 @@
             );
         }
     
    -    // BIP84 public `wpkh(key/{0,1}/*)`
    -    #[test]
    -    fn test_bip84_public_template() {
    -        let pubkey = bitcoin::util::bip32::ExtendedPubKey::from_str("tpubDC2Qwo2TFsaNC4ju8nrUJ9mqVT3eSgdmy1yPqhgkjwmke3PRXutNGRYAUo6RCHTcVQaDR3ohNU9we59brGHuEKPvH1ags2nevW5opEE9Z5Q").unwrap();
    -        let fingerprint = bitcoin::util::bip32::Fingerprint::from_str("c55b303f").unwrap();
    -        check(
    -            Bip84Public(pubkey, fingerprint, KeychainKind::External).build(Network::Bitcoin),
    +    // BIP84 public `wpkh(key/{0,1}/*)`
    +    #[test]
    +    fn test_bip84_public_template() {
    +        let pubkey = bitcoin::util::bip32::ExtendedPubKey::from_str("tpubDC2Qwo2TFsaNC4ju8nrUJ9mqVT3eSgdmy1yPqhgkjwmke3PRXutNGRYAUo6RCHTcVQaDR3ohNU9we59brGHuEKPvH1ags2nevW5opEE9Z5Q").unwrap();
    +        let fingerprint = bitcoin::util::bip32::Fingerprint::from_str("c55b303f").unwrap();
    +        check(
    +            Bip84Public(pubkey, fingerprint, KeychainKind::External).build(Network::Bitcoin),
                 true,
                 false,
                 &[
    @@ -1525,8 +1519,8 @@
                     "bcrt1qt9800y6xl3922jy3uyl0z33jh5wfpycyhcylr9",
                 ],
             );
    -        check(
    -            Bip84Public(pubkey, fingerprint, KeychainKind::Internal).build(Network::Bitcoin),
    +        check(
    +            Bip84Public(pubkey, fingerprint, KeychainKind::Internal).build(Network::Bitcoin),
                 true,
                 false,
                 &[
    @@ -1538,5 +1532,4 @@
         }
     }
     
    -
    - \ No newline at end of file +
    \ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/src/bdk/error.rs.html b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/src/bdk/error.rs.html index 487e0606ae..4f192cf773 100644 --- a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/src/bdk/error.rs.html +++ b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/src/bdk/error.rs.html @@ -1,510 +1,503 @@ -error.rs - source - -
      1
    -  2
    -  3
    -  4
    -  5
    -  6
    -  7
    -  8
    -  9
    - 10
    - 11
    - 12
    - 13
    - 14
    - 15
    - 16
    - 17
    - 18
    - 19
    - 20
    - 21
    - 22
    - 23
    - 24
    - 25
    - 26
    - 27
    - 28
    - 29
    - 30
    - 31
    - 32
    - 33
    - 34
    - 35
    - 36
    - 37
    - 38
    - 39
    - 40
    - 41
    - 42
    - 43
    - 44
    - 45
    - 46
    - 47
    - 48
    - 49
    - 50
    - 51
    - 52
    - 53
    - 54
    - 55
    - 56
    - 57
    - 58
    - 59
    - 60
    - 61
    - 62
    - 63
    - 64
    - 65
    - 66
    - 67
    - 68
    - 69
    - 70
    - 71
    - 72
    - 73
    - 74
    - 75
    - 76
    - 77
    - 78
    - 79
    - 80
    - 81
    - 82
    - 83
    - 84
    - 85
    - 86
    - 87
    - 88
    - 89
    - 90
    - 91
    - 92
    - 93
    - 94
    - 95
    - 96
    - 97
    - 98
    - 99
    -100
    -101
    -102
    -103
    -104
    -105
    -106
    -107
    -108
    -109
    -110
    -111
    -112
    -113
    -114
    -115
    -116
    -117
    -118
    -119
    -120
    -121
    -122
    -123
    -124
    -125
    -126
    -127
    -128
    -129
    -130
    -131
    -132
    -133
    -134
    -135
    -136
    -137
    -138
    -139
    -140
    -141
    -142
    -143
    -144
    -145
    -146
    -147
    -148
    -149
    -150
    -151
    -152
    -153
    -154
    -155
    -156
    -157
    -158
    -159
    -160
    -161
    -162
    -163
    -164
    -165
    -166
    -167
    -168
    -169
    -170
    -171
    -172
    -173
    -174
    -175
    -176
    -177
    -178
    -179
    -180
    -181
    -182
    -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
    -245
    -246
    -247
    -248
    -249
    -250
    -
    // Bitcoin Dev Kit
    -// Written in 2020 by Alekos Filini <alekos.filini@gmail.com>
    -//
    -// Copyright (c) 2020-2021 Bitcoin Dev Kit Developers
    -//
    -// This file is licensed under the Apache License, Version 2.0 <LICENSE-APACHE
    -// or http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
    -// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your option.
    -// You may not use this file except in accordance with one or both of these
    -// licenses.
    +error.rs - source
    1
    +2
    +3
    +4
    +5
    +6
    +7
    +8
    +9
    +10
    +11
    +12
    +13
    +14
    +15
    +16
    +17
    +18
    +19
    +20
    +21
    +22
    +23
    +24
    +25
    +26
    +27
    +28
    +29
    +30
    +31
    +32
    +33
    +34
    +35
    +36
    +37
    +38
    +39
    +40
    +41
    +42
    +43
    +44
    +45
    +46
    +47
    +48
    +49
    +50
    +51
    +52
    +53
    +54
    +55
    +56
    +57
    +58
    +59
    +60
    +61
    +62
    +63
    +64
    +65
    +66
    +67
    +68
    +69
    +70
    +71
    +72
    +73
    +74
    +75
    +76
    +77
    +78
    +79
    +80
    +81
    +82
    +83
    +84
    +85
    +86
    +87
    +88
    +89
    +90
    +91
    +92
    +93
    +94
    +95
    +96
    +97
    +98
    +99
    +100
    +101
    +102
    +103
    +104
    +105
    +106
    +107
    +108
    +109
    +110
    +111
    +112
    +113
    +114
    +115
    +116
    +117
    +118
    +119
    +120
    +121
    +122
    +123
    +124
    +125
    +126
    +127
    +128
    +129
    +130
    +131
    +132
    +133
    +134
    +135
    +136
    +137
    +138
    +139
    +140
    +141
    +142
    +143
    +144
    +145
    +146
    +147
    +148
    +149
    +150
    +151
    +152
    +153
    +154
    +155
    +156
    +157
    +158
    +159
    +160
    +161
    +162
    +163
    +164
    +165
    +166
    +167
    +168
    +169
    +170
    +171
    +172
    +173
    +174
    +175
    +176
    +177
    +178
    +179
    +180
    +181
    +182
    +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
    +245
    +246
    +247
    +248
    +249
    +250
    +
    // Bitcoin Dev Kit
    +// Written in 2020 by Alekos Filini <alekos.filini@gmail.com>
    +//
    +// Copyright (c) 2020-2021 Bitcoin Dev Kit Developers
    +//
    +// This file is licensed under the Apache License, Version 2.0 <LICENSE-APACHE
    +// or http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
    +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your option.
    +// You may not use this file except in accordance with one or both of these
    +// licenses.
     
    -use std::fmt;
    +use std::fmt;
     
    -use crate::bitcoin::Network;
    -use crate::{descriptor, wallet};
    -use bitcoin::{OutPoint, Txid};
    +use crate::bitcoin::Network;
    +use crate::{descriptor, wallet};
    +use bitcoin::{OutPoint, Txid};
     
    -/// Errors that can be thrown by the [`Wallet`](crate::wallet::Wallet)
    -#[derive(Debug)]
    -pub enum Error {
    -    /// Wrong number of bytes found when trying to convert to u32
    -    InvalidU32Bytes(Vec<u8>),
    -    /// Generic error
    -    Generic(String),
    -    /// This error is thrown when trying to convert Bare and Public key script to address
    -    ScriptDoesntHaveAddressForm,
    -    /// Cannot build a tx without recipients
    -    NoRecipients,
    -    /// `manually_selected_only` option is selected but no utxo has been passed
    -    NoUtxosSelected,
    -    /// Output created is under the dust limit, 546 satoshis
    -    OutputBelowDustLimit(usize),
    -    /// Wallet's UTXO set is not enough to cover recipient's requested plus fee
    -    InsufficientFunds {
    -        /// Sats needed for some transaction
    -        needed: u64,
    -        /// Sats available for spending
    -        available: u64,
    +/// Errors that can be thrown by the [`Wallet`](crate::wallet::Wallet)
    +#[derive(Debug)]
    +pub enum Error {
    +    /// Wrong number of bytes found when trying to convert to u32
    +    InvalidU32Bytes(Vec<u8>),
    +    /// Generic error
    +    Generic(String),
    +    /// This error is thrown when trying to convert Bare and Public key script to address
    +    ScriptDoesntHaveAddressForm,
    +    /// Cannot build a tx without recipients
    +    NoRecipients,
    +    /// `manually_selected_only` option is selected but no utxo has been passed
    +    NoUtxosSelected,
    +    /// Output created is under the dust limit, 546 satoshis
    +    OutputBelowDustLimit(usize),
    +    /// Wallet's UTXO set is not enough to cover recipient's requested plus fee
    +    InsufficientFunds {
    +        /// Sats needed for some transaction
    +        needed: u64,
    +        /// Sats available for spending
    +        available: u64,
         },
    -    /// 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
    -    BnBTotalTriesExceeded,
    -    /// Branch and bound coin selection tries to avoid needing a change by finding the right inputs for
    -    /// the desired outputs plus fee, if there is not such combination this error is thrown
    -    BnBNoExactMatch,
    -    /// Happens when trying to spend an UTXO that is not in the internal database
    -    UnknownUtxo,
    -    /// Thrown when a tx is not found in the internal database
    -    TransactionNotFound,
    -    /// Happens when trying to bump a transaction that is already confirmed
    -    TransactionConfirmed,
    -    /// Trying to replace a tx that has a sequence >= `0xFFFFFFFE`
    -    IrreplaceableTransaction,
    -    /// When bumping a tx the fee rate requested is lower than required
    -    FeeRateTooLow {
    -        /// Required fee rate (satoshi/vbyte)
    -        required: crate::types::FeeRate,
    +    /// 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
    +    BnBTotalTriesExceeded,
    +    /// Branch and bound coin selection tries to avoid needing a change by finding the right inputs for
    +    /// the desired outputs plus fee, if there is not such combination this error is thrown
    +    BnBNoExactMatch,
    +    /// Happens when trying to spend an UTXO that is not in the internal database
    +    UnknownUtxo,
    +    /// Thrown when a tx is not found in the internal database
    +    TransactionNotFound,
    +    /// Happens when trying to bump a transaction that is already confirmed
    +    TransactionConfirmed,
    +    /// Trying to replace a tx that has a sequence >= `0xFFFFFFFE`
    +    IrreplaceableTransaction,
    +    /// When bumping a tx the fee rate requested is lower than required
    +    FeeRateTooLow {
    +        /// Required fee rate (satoshi/vbyte)
    +        required: crate::types::FeeRate,
         },
    -    /// When bumping a tx the absolute fee requested is lower than replaced tx absolute fee
    -    FeeTooLow {
    -        /// Required fee absolute value (satoshi)
    -        required: u64,
    +    /// When bumping a tx the absolute fee requested is lower than replaced tx absolute fee
    +    FeeTooLow {
    +        /// Required fee absolute value (satoshi)
    +        required: u64,
         },
    -    /// Node doesn't have data to estimate a fee rate
    -    FeeRateUnavailable,
    -    /// In order to use the [`TxBuilder::add_global_xpubs`] option every extended
    -    /// key in the descriptor must either be a master key itself (having depth = 0) or have an
    -    /// explicit origin provided
    -    ///
    -    /// [`TxBuilder::add_global_xpubs`]: crate::wallet::tx_builder::TxBuilder::add_global_xpubs
    -    MissingKeyOrigin(String),
    -    /// Error while working with [`keys`](crate::keys)
    -    Key(crate::keys::KeyError),
    -    /// Descriptor checksum mismatch
    -    ChecksumMismatch,
    -    /// Spending policy is not compatible with this [`KeychainKind`](crate::types::KeychainKind)
    -    SpendingPolicyRequired(crate::types::KeychainKind),
    -    /// Error while extracting and manipulating policies
    -    InvalidPolicyPathError(crate::descriptor::policy::PolicyError),
    -    /// Signing error
    -    Signer(crate::wallet::signer::SignerError),
    -    /// Invalid network
    -    InvalidNetwork {
    -        /// requested network, for example what is given as bdk-cli option
    -        requested: Network,
    -        /// found network, for example the network of the bitcoin node
    -        found: Network,
    +    /// Node doesn't have data to estimate a fee rate
    +    FeeRateUnavailable,
    +    /// In order to use the [`TxBuilder::add_global_xpubs`] option every extended
    +    /// key in the descriptor must either be a master key itself (having depth = 0) or have an
    +    /// explicit origin provided
    +    ///
    +    /// [`TxBuilder::add_global_xpubs`]: crate::wallet::tx_builder::TxBuilder::add_global_xpubs
    +    MissingKeyOrigin(String),
    +    /// Error while working with [`keys`](crate::keys)
    +    Key(crate::keys::KeyError),
    +    /// Descriptor checksum mismatch
    +    ChecksumMismatch,
    +    /// Spending policy is not compatible with this [`KeychainKind`](crate::types::KeychainKind)
    +    SpendingPolicyRequired(crate::types::KeychainKind),
    +    /// Error while extracting and manipulating policies
    +    InvalidPolicyPathError(crate::descriptor::policy::PolicyError),
    +    /// Signing error
    +    Signer(crate::wallet::signer::SignerError),
    +    /// Invalid network
    +    InvalidNetwork {
    +        /// requested network, for example what is given as bdk-cli option
    +        requested: Network,
    +        /// found network, for example the network of the bitcoin node
    +        found: Network,
         },
    -    #[cfg(feature = "verify")]
    -    /// Transaction verification error
    -    Verification(crate::wallet::verify::VerifyError),
    +    #[cfg(feature = "verify")]
    +    /// Transaction verification error
    +    Verification(crate::wallet::verify::VerifyError),
     
    -    /// Progress value must be between `0.0` (included) and `100.0` (included)
    -    InvalidProgressValue(f32),
    -    /// Progress update error (maybe the channel has been closed)
    -    ProgressUpdateError,
    -    /// Requested outpoint doesn't exist in the tx (vout greater than available outputs)
    -    InvalidOutpoint(OutPoint),
    +    /// Progress value must be between `0.0` (included) and `100.0` (included)
    +    InvalidProgressValue(f32),
    +    /// Progress update error (maybe the channel has been closed)
    +    ProgressUpdateError,
    +    /// Requested outpoint doesn't exist in the tx (vout greater than available outputs)
    +    InvalidOutpoint(OutPoint),
     
    -    /// Error related to the parsing and usage of descriptors
    -    Descriptor(crate::descriptor::error::Error),
    -    /// Encoding error
    -    Encode(bitcoin::consensus::encode::Error),
    -    /// Miniscript error
    -    Miniscript(miniscript::Error),
    -    /// Miniscript PSBT error
    -    MiniscriptPsbt(MiniscriptPsbtError),
    -    /// BIP32 error
    -    Bip32(bitcoin::util::bip32::Error),
    -    /// An ECDSA error
    -    Secp256k1(bitcoin::secp256k1::Error),
    -    /// Error serializing or deserializing JSON data
    -    Json(serde_json::Error),
    -    /// Hex decoding error
    -    Hex(bitcoin::hashes::hex::Error),
    -    /// Partially signed bitcoin transaction error
    -    Psbt(bitcoin::util::psbt::Error),
    -    /// Partially signed bitcoin transaction parse error
    -    PsbtParse(bitcoin::util::psbt::PsbtParseError),
    +    /// Error related to the parsing and usage of descriptors
    +    Descriptor(crate::descriptor::error::Error),
    +    /// Encoding error
    +    Encode(bitcoin::consensus::encode::Error),
    +    /// Miniscript error
    +    Miniscript(miniscript::Error),
    +    /// Miniscript PSBT error
    +    MiniscriptPsbt(MiniscriptPsbtError),
    +    /// BIP32 error
    +    Bip32(bitcoin::util::bip32::Error),
    +    /// An ECDSA error
    +    Secp256k1(bitcoin::secp256k1::Error),
    +    /// Error serializing or deserializing JSON data
    +    Json(serde_json::Error),
    +    /// Hex decoding error
    +    Hex(bitcoin::hashes::hex::Error),
    +    /// Partially signed bitcoin transaction error
    +    Psbt(bitcoin::util::psbt::Error),
    +    /// Partially signed bitcoin transaction parse error
    +    PsbtParse(bitcoin::util::psbt::PsbtParseError),
     
    -    //KeyMismatch(bitcoin::secp256k1::PublicKey, bitcoin::secp256k1::PublicKey),
    -    //MissingInputUTXO(usize),
    -    //InvalidAddressNetwork(Address),
    -    //DifferentTransactions,
    -    //DifferentDescriptorStructure,
    -    //Uncapable(crate::blockchain::Capability),
    -    //MissingCachedAddresses,
    -    /// [`crate::blockchain::WalletSync`] sync attempt failed due to missing scripts in cache which
    -    /// are needed to satisfy `stop_gap`.
    -    MissingCachedScripts(MissingCachedScripts),
    +    //KeyMismatch(bitcoin::secp256k1::PublicKey, bitcoin::secp256k1::PublicKey),
    +    //MissingInputUTXO(usize),
    +    //InvalidAddressNetwork(Address),
    +    //DifferentTransactions,
    +    //DifferentDescriptorStructure,
    +    //Uncapable(crate::blockchain::Capability),
    +    //MissingCachedAddresses,
    +    /// [`crate::blockchain::WalletSync`] sync attempt failed due to missing scripts in cache which
    +    /// are needed to satisfy `stop_gap`.
    +    MissingCachedScripts(MissingCachedScripts),
     
    -    #[cfg(feature = "electrum")]
    -    /// Electrum client error
    -    Electrum(electrum_client::Error),
    -    #[cfg(feature = "esplora")]
    -    /// Esplora client error
    -    Esplora(Box<crate::blockchain::esplora::EsploraError>),
    -    #[cfg(feature = "compact_filters")]
    -    /// Compact filters client error)
    -    CompactFilters(crate::blockchain::compact_filters::CompactFiltersError),
    -    #[cfg(feature = "key-value-db")]
    -    /// Sled database error
    -    Sled(sled::Error),
    -    #[cfg(feature = "rpc")]
    -    /// Rpc client error
    -    Rpc(bitcoincore_rpc::Error),
    -    #[cfg(feature = "sqlite")]
    -    /// Rusqlite client error
    -    Rusqlite(rusqlite::Error),
    +    #[cfg(feature = "electrum")]
    +    /// Electrum client error
    +    Electrum(electrum_client::Error),
    +    #[cfg(feature = "esplora")]
    +    /// Esplora client error
    +    Esplora(Box<crate::blockchain::esplora::EsploraError>),
    +    #[cfg(feature = "compact_filters")]
    +    /// Compact filters client error)
    +    CompactFilters(crate::blockchain::compact_filters::CompactFiltersError),
    +    #[cfg(feature = "key-value-db")]
    +    /// Sled database error
    +    Sled(sled::Error),
    +    #[cfg(feature = "rpc")]
    +    /// Rpc client error
    +    Rpc(bitcoincore_rpc::Error),
    +    #[cfg(feature = "sqlite")]
    +    /// Rusqlite client error
    +    Rusqlite(rusqlite::Error),
     }
     
    -/// Errors returned by miniscript when updating inconsistent PSBTs
    -#[derive(Debug, Clone)]
    -pub enum MiniscriptPsbtError {
    -    Conversion(miniscript::descriptor::ConversionError),
    -    UtxoUpdate(miniscript::psbt::UtxoUpdateError),
    -    OutputUpdate(miniscript::psbt::OutputUpdateError),
    +/// Errors returned by miniscript when updating inconsistent PSBTs
    +#[derive(Debug, Clone)]
    +pub enum MiniscriptPsbtError {
    +    Conversion(miniscript::descriptor::ConversionError),
    +    UtxoUpdate(miniscript::psbt::UtxoUpdateError),
    +    OutputUpdate(miniscript::psbt::OutputUpdateError),
     }
     
    -/// Represents the last failed [`crate::blockchain::WalletSync`] sync attempt in which we were short
    -/// on cached `scriptPubKey`s.
    -#[derive(Debug)]
    -pub struct MissingCachedScripts {
    -    /// Number of scripts in which txs were requested during last request.
    -    pub last_count: usize,
    -    /// Minimum number of scripts to cache more of in order to satisfy `stop_gap`.
    -    pub missing_count: usize,
    +/// Represents the last failed [`crate::blockchain::WalletSync`] sync attempt in which we were short
    +/// on cached `scriptPubKey`s.
    +#[derive(Debug)]
    +pub struct MissingCachedScripts {
    +    /// Number of scripts in which txs were requested during last request.
    +    pub last_count: usize,
    +    /// Minimum number of scripts to cache more of in order to satisfy `stop_gap`.
    +    pub missing_count: usize,
     }
     
    -impl fmt::Display for Error {
    -    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
    -        write!(f, "{:?}", self)
    +impl fmt::Display for Error {
    +    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
    +        write!(f, "{:?}", self)
         }
     }
     
    -impl std::error::Error for Error {}
    +impl std::error::Error for Error {}
     
    -macro_rules! impl_error {
    -    ( $from:ty, $to:ident ) => {
    -        impl_error!($from, $to, Error);
    +macro_rules! impl_error {
    +    ( $from:ty, $to:ident ) => {
    +        impl_error!($from, $to, Error);
         };
    -    ( $from:ty, $to:ident, $impl_for:ty ) => {
    -        impl std::convert::From<$from> for $impl_for {
    -            fn from(err: $from) -> Self {
    -                <$impl_for>::$to(err)
    +    ( $from:ty, $to:ident, $impl_for:ty ) => {
    +        impl std::convert::From<$from> for $impl_for {
    +            fn from(err: $from) -> Self {
    +                <$impl_for>::$to(err)
                 }
             }
         };
     }
     
    -impl_error!(descriptor::error::Error, Descriptor);
    -impl_error!(descriptor::policy::PolicyError, InvalidPolicyPathError);
    -impl_error!(wallet::signer::SignerError, Signer);
    +impl_error!(descriptor::error::Error, Descriptor);
    +impl_error!(descriptor::policy::PolicyError, InvalidPolicyPathError);
    +impl_error!(wallet::signer::SignerError, Signer);
     
    -impl From<crate::keys::KeyError> for Error {
    -    fn from(key_error: crate::keys::KeyError) -> Error {
    -        match key_error {
    -            crate::keys::KeyError::Miniscript(inner) => Error::Miniscript(inner),
    -            crate::keys::KeyError::Bip32(inner) => Error::Bip32(inner),
    -            crate::keys::KeyError::InvalidChecksum => Error::ChecksumMismatch,
    -            e => Error::Key(e),
    +impl From<crate::keys::KeyError> for Error {
    +    fn from(key_error: crate::keys::KeyError) -> Error {
    +        match key_error {
    +            crate::keys::KeyError::Miniscript(inner) => Error::Miniscript(inner),
    +            crate::keys::KeyError::Bip32(inner) => Error::Bip32(inner),
    +            crate::keys::KeyError::InvalidChecksum => Error::ChecksumMismatch,
    +            e => Error::Key(e),
             }
         }
     }
     
    -impl_error!(bitcoin::consensus::encode::Error, Encode);
    -impl_error!(miniscript::Error, Miniscript);
    -impl_error!(MiniscriptPsbtError, MiniscriptPsbt);
    -impl_error!(bitcoin::util::bip32::Error, Bip32);
    -impl_error!(bitcoin::secp256k1::Error, Secp256k1);
    -impl_error!(serde_json::Error, Json);
    -impl_error!(bitcoin::hashes::hex::Error, Hex);
    -impl_error!(bitcoin::util::psbt::Error, Psbt);
    -impl_error!(bitcoin::util::psbt::PsbtParseError, PsbtParse);
    +impl_error!(bitcoin::consensus::encode::Error, Encode);
    +impl_error!(miniscript::Error, Miniscript);
    +impl_error!(MiniscriptPsbtError, MiniscriptPsbt);
    +impl_error!(bitcoin::util::bip32::Error, Bip32);
    +impl_error!(bitcoin::secp256k1::Error, Secp256k1);
    +impl_error!(serde_json::Error, Json);
    +impl_error!(bitcoin::hashes::hex::Error, Hex);
    +impl_error!(bitcoin::util::psbt::Error, Psbt);
    +impl_error!(bitcoin::util::psbt::PsbtParseError, PsbtParse);
     
    -#[cfg(feature = "electrum")]
    -impl_error!(electrum_client::Error, Electrum);
    -#[cfg(feature = "key-value-db")]
    -impl_error!(sled::Error, Sled);
    -#[cfg(feature = "rpc")]
    -impl_error!(bitcoincore_rpc::Error, Rpc);
    -#[cfg(feature = "sqlite")]
    -impl_error!(rusqlite::Error, Rusqlite);
    +#[cfg(feature = "electrum")]
    +impl_error!(electrum_client::Error, Electrum);
    +#[cfg(feature = "key-value-db")]
    +impl_error!(sled::Error, Sled);
    +#[cfg(feature = "rpc")]
    +impl_error!(bitcoincore_rpc::Error, Rpc);
    +#[cfg(feature = "sqlite")]
    +impl_error!(rusqlite::Error, Rusqlite);
     
    -#[cfg(feature = "compact_filters")]
    -impl From<crate::blockchain::compact_filters::CompactFiltersError> for Error {
    -    fn from(other: crate::blockchain::compact_filters::CompactFiltersError) -> Self {
    -        match other {
    -            crate::blockchain::compact_filters::CompactFiltersError::Global(e) => *e,
    -            err => Error::CompactFilters(err),
    +#[cfg(feature = "compact_filters")]
    +impl From<crate::blockchain::compact_filters::CompactFiltersError> for Error {
    +    fn from(other: crate::blockchain::compact_filters::CompactFiltersError) -> Self {
    +        match other {
    +            crate::blockchain::compact_filters::CompactFiltersError::Global(e) => *e,
    +            err => Error::CompactFilters(err),
             }
         }
     }
     
    -#[cfg(feature = "verify")]
    -impl From<crate::wallet::verify::VerifyError> for Error {
    -    fn from(other: crate::wallet::verify::VerifyError) -> Self {
    -        match other {
    -            crate::wallet::verify::VerifyError::Global(inner) => *inner,
    -            err => Error::Verification(err),
    +#[cfg(feature = "verify")]
    +impl From<crate::wallet::verify::VerifyError> for Error {
    +    fn from(other: crate::wallet::verify::VerifyError) -> Self {
    +        match other {
    +            crate::wallet::verify::VerifyError::Global(inner) => *inner,
    +            err => Error::Verification(err),
             }
         }
     }
     
    -#[cfg(feature = "esplora")]
    -impl From<crate::blockchain::esplora::EsploraError> for Error {
    -    fn from(other: crate::blockchain::esplora::EsploraError) -> Self {
    -        Error::Esplora(Box::new(other))
    +#[cfg(feature = "esplora")]
    +impl From<crate::blockchain::esplora::EsploraError> for Error {
    +    fn from(other: crate::blockchain::esplora::EsploraError) -> Self {
    +        Error::Esplora(Box::new(other))
         }
     }
     
    -
    - \ No newline at end of file +
    \ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/src/bdk/keys/bip39.rs.html b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/src/bdk/keys/bip39.rs.html index 6bfa6b6950..85ba29060d 100644 --- a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/src/bdk/keys/bip39.rs.html +++ b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/src/bdk/keys/bip39.rs.html @@ -1,460 +1,453 @@ -bip39.rs - source - -
      1
    -  2
    -  3
    -  4
    -  5
    -  6
    -  7
    -  8
    -  9
    - 10
    - 11
    - 12
    - 13
    - 14
    - 15
    - 16
    - 17
    - 18
    - 19
    - 20
    - 21
    - 22
    - 23
    - 24
    - 25
    - 26
    - 27
    - 28
    - 29
    - 30
    - 31
    - 32
    - 33
    - 34
    - 35
    - 36
    - 37
    - 38
    - 39
    - 40
    - 41
    - 42
    - 43
    - 44
    - 45
    - 46
    - 47
    - 48
    - 49
    - 50
    - 51
    - 52
    - 53
    - 54
    - 55
    - 56
    - 57
    - 58
    - 59
    - 60
    - 61
    - 62
    - 63
    - 64
    - 65
    - 66
    - 67
    - 68
    - 69
    - 70
    - 71
    - 72
    - 73
    - 74
    - 75
    - 76
    - 77
    - 78
    - 79
    - 80
    - 81
    - 82
    - 83
    - 84
    - 85
    - 86
    - 87
    - 88
    - 89
    - 90
    - 91
    - 92
    - 93
    - 94
    - 95
    - 96
    - 97
    - 98
    - 99
    -100
    -101
    -102
    -103
    -104
    -105
    -106
    -107
    -108
    -109
    -110
    -111
    -112
    -113
    -114
    -115
    -116
    -117
    -118
    -119
    -120
    -121
    -122
    -123
    -124
    -125
    -126
    -127
    -128
    -129
    -130
    -131
    -132
    -133
    -134
    -135
    -136
    -137
    -138
    -139
    -140
    -141
    -142
    -143
    -144
    -145
    -146
    -147
    -148
    -149
    -150
    -151
    -152
    -153
    -154
    -155
    -156
    -157
    -158
    -159
    -160
    -161
    -162
    -163
    -164
    -165
    -166
    -167
    -168
    -169
    -170
    -171
    -172
    -173
    -174
    -175
    -176
    -177
    -178
    -179
    -180
    -181
    -182
    -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
    -
    // Bitcoin Dev Kit
    -// Written in 2020 by Alekos Filini <alekos.filini@gmail.com>
    -//
    -// Copyright (c) 2020-2021 Bitcoin Dev Kit Developers
    -//
    -// This file is licensed under the Apache License, Version 2.0 <LICENSE-APACHE
    -// or http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
    -// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your option.
    -// You may not use this file except in accordance with one or both of these
    -// licenses.
    -
    -//! BIP-0039
    -
    -// TODO: maybe write our own implementation of bip39? Seems stupid to have an extra dependency for
    -// something that should be fairly simple to re-implement.
    -
    -use bitcoin::util::bip32;
    -use bitcoin::Network;
    -
    -use miniscript::ScriptContext;
    -
    -pub use bip39::{Error, Language, Mnemonic};
    -
    -type Seed = [u8; 64];
    -
    -/// Type describing entropy length (aka word count) in the mnemonic
    -pub enum WordCount {
    -    /// 12 words mnemonic (128 bits entropy)
    -    Words12 = 128,
    -    /// 15 words mnemonic (160 bits entropy)
    -    Words15 = 160,
    -    /// 18 words mnemonic (192 bits entropy)
    -    Words18 = 192,
    -    /// 21 words mnemonic (224 bits entropy)
    -    Words21 = 224,
    -    /// 24 words mnemonic (256 bits entropy)
    -    Words24 = 256,
    +bip39.rs - source
    1
    +2
    +3
    +4
    +5
    +6
    +7
    +8
    +9
    +10
    +11
    +12
    +13
    +14
    +15
    +16
    +17
    +18
    +19
    +20
    +21
    +22
    +23
    +24
    +25
    +26
    +27
    +28
    +29
    +30
    +31
    +32
    +33
    +34
    +35
    +36
    +37
    +38
    +39
    +40
    +41
    +42
    +43
    +44
    +45
    +46
    +47
    +48
    +49
    +50
    +51
    +52
    +53
    +54
    +55
    +56
    +57
    +58
    +59
    +60
    +61
    +62
    +63
    +64
    +65
    +66
    +67
    +68
    +69
    +70
    +71
    +72
    +73
    +74
    +75
    +76
    +77
    +78
    +79
    +80
    +81
    +82
    +83
    +84
    +85
    +86
    +87
    +88
    +89
    +90
    +91
    +92
    +93
    +94
    +95
    +96
    +97
    +98
    +99
    +100
    +101
    +102
    +103
    +104
    +105
    +106
    +107
    +108
    +109
    +110
    +111
    +112
    +113
    +114
    +115
    +116
    +117
    +118
    +119
    +120
    +121
    +122
    +123
    +124
    +125
    +126
    +127
    +128
    +129
    +130
    +131
    +132
    +133
    +134
    +135
    +136
    +137
    +138
    +139
    +140
    +141
    +142
    +143
    +144
    +145
    +146
    +147
    +148
    +149
    +150
    +151
    +152
    +153
    +154
    +155
    +156
    +157
    +158
    +159
    +160
    +161
    +162
    +163
    +164
    +165
    +166
    +167
    +168
    +169
    +170
    +171
    +172
    +173
    +174
    +175
    +176
    +177
    +178
    +179
    +180
    +181
    +182
    +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
    +
    // Bitcoin Dev Kit
    +// Written in 2020 by Alekos Filini <alekos.filini@gmail.com>
    +//
    +// Copyright (c) 2020-2021 Bitcoin Dev Kit Developers
    +//
    +// This file is licensed under the Apache License, Version 2.0 <LICENSE-APACHE
    +// or http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
    +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your option.
    +// You may not use this file except in accordance with one or both of these
    +// licenses.
    +
    +//! BIP-0039
    +
    +// TODO: maybe write our own implementation of bip39? Seems stupid to have an extra dependency for
    +// something that should be fairly simple to re-implement.
    +
    +use bitcoin::util::bip32;
    +use bitcoin::Network;
    +
    +use miniscript::ScriptContext;
    +
    +pub use bip39::{Error, Language, Mnemonic};
    +
    +type Seed = [u8; 64];
    +
    +/// Type describing entropy length (aka word count) in the mnemonic
    +pub enum WordCount {
    +    /// 12 words mnemonic (128 bits entropy)
    +    Words12 = 128,
    +    /// 15 words mnemonic (160 bits entropy)
    +    Words15 = 160,
    +    /// 18 words mnemonic (192 bits entropy)
    +    Words18 = 192,
    +    /// 21 words mnemonic (224 bits entropy)
    +    Words21 = 224,
    +    /// 24 words mnemonic (256 bits entropy)
    +    Words24 = 256,
     }
     
    -use super::{
    -    any_network, DerivableKey, DescriptorKey, ExtendedKey, GeneratableKey, GeneratedKey, KeyError,
    +use super::{
    +    any_network, DerivableKey, DescriptorKey, ExtendedKey, GeneratableKey, GeneratedKey, KeyError,
     };
     
    -fn set_valid_on_any_network<Ctx: ScriptContext>(
    -    descriptor_key: DescriptorKey<Ctx>,
    -) -> DescriptorKey<Ctx> {
    -    // We have to pick one network to build the xprv, but since the bip39 standard doesn't
    -    // encode the network, the xprv we create is actually valid everywhere. So we override the
    -    // valid networks with `any_network()`.
    -    descriptor_key.override_valid_networks(any_network())
    +fn set_valid_on_any_network<Ctx: ScriptContext>(
    +    descriptor_key: DescriptorKey<Ctx>,
    +) -> DescriptorKey<Ctx> {
    +    // We have to pick one network to build the xprv, but since the bip39 standard doesn't
    +    // encode the network, the xprv we create is actually valid everywhere. So we override the
    +    // valid networks with `any_network()`.
    +    descriptor_key.override_valid_networks(any_network())
     }
     
    -/// Type for a BIP39 mnemonic with an optional passphrase
    -pub type MnemonicWithPassphrase = (Mnemonic, Option<String>);
    +/// Type for a BIP39 mnemonic with an optional passphrase
    +pub type MnemonicWithPassphrase = (Mnemonic, Option<String>);
     
    -#[cfg_attr(docsrs, doc(cfg(feature = "keys-bip39")))]
    -impl<Ctx: ScriptContext> DerivableKey<Ctx> for Seed {
    -    fn into_extended_key(self) -> Result<ExtendedKey<Ctx>, KeyError> {
    -        Ok(bip32::ExtendedPrivKey::new_master(Network::Bitcoin, &self[..])?.into())
    +#[cfg_attr(docsrs, doc(cfg(feature = "keys-bip39")))]
    +impl<Ctx: ScriptContext> DerivableKey<Ctx> for Seed {
    +    fn into_extended_key(self) -> Result<ExtendedKey<Ctx>, KeyError> {
    +        Ok(bip32::ExtendedPrivKey::new_master(Network::Bitcoin, &self[..])?.into())
         }
     
    -    fn into_descriptor_key(
    +    fn into_descriptor_key(
             self,
    -        source: Option<bip32::KeySource>,
    -        derivation_path: bip32::DerivationPath,
    -    ) -> Result<DescriptorKey<Ctx>, KeyError> {
    -        let descriptor_key = self
    -            .into_extended_key()?
    -            .into_descriptor_key(source, derivation_path)?;
    -
    -        Ok(set_valid_on_any_network(descriptor_key))
    +        source: Option<bip32::KeySource>,
    +        derivation_path: bip32::DerivationPath,
    +    ) -> Result<DescriptorKey<Ctx>, KeyError> {
    +        let descriptor_key = self
    +            .into_extended_key()?
    +            .into_descriptor_key(source, derivation_path)?;
    +
    +        Ok(set_valid_on_any_network(descriptor_key))
         }
     }
     
    -#[cfg_attr(docsrs, doc(cfg(feature = "keys-bip39")))]
    -impl<Ctx: ScriptContext> DerivableKey<Ctx> for MnemonicWithPassphrase {
    -    fn into_extended_key(self) -> Result<ExtendedKey<Ctx>, KeyError> {
    -        let (mnemonic, passphrase) = self;
    -        let seed: Seed = mnemonic.to_seed(passphrase.as_deref().unwrap_or(""));
    +#[cfg_attr(docsrs, doc(cfg(feature = "keys-bip39")))]
    +impl<Ctx: ScriptContext> DerivableKey<Ctx> for MnemonicWithPassphrase {
    +    fn into_extended_key(self) -> Result<ExtendedKey<Ctx>, KeyError> {
    +        let (mnemonic, passphrase) = self;
    +        let seed: Seed = mnemonic.to_seed(passphrase.as_deref().unwrap_or(""));
     
    -        seed.into_extended_key()
    +        seed.into_extended_key()
         }
     
    -    fn into_descriptor_key(
    +    fn into_descriptor_key(
             self,
    -        source: Option<bip32::KeySource>,
    -        derivation_path: bip32::DerivationPath,
    -    ) -> Result<DescriptorKey<Ctx>, KeyError> {
    -        let descriptor_key = self
    -            .into_extended_key()?
    -            .into_descriptor_key(source, derivation_path)?;
    -
    -        Ok(set_valid_on_any_network(descriptor_key))
    +        source: Option<bip32::KeySource>,
    +        derivation_path: bip32::DerivationPath,
    +    ) -> Result<DescriptorKey<Ctx>, KeyError> {
    +        let descriptor_key = self
    +            .into_extended_key()?
    +            .into_descriptor_key(source, derivation_path)?;
    +
    +        Ok(set_valid_on_any_network(descriptor_key))
         }
     }
     
    -#[cfg_attr(docsrs, doc(cfg(feature = "keys-bip39")))]
    -impl<Ctx: ScriptContext> DerivableKey<Ctx> for (GeneratedKey<Mnemonic, Ctx>, Option<String>) {
    -    fn into_extended_key(self) -> Result<ExtendedKey<Ctx>, KeyError> {
    -        let (mnemonic, passphrase) = self;
    -        (mnemonic.into_key(), passphrase).into_extended_key()
    +#[cfg_attr(docsrs, doc(cfg(feature = "keys-bip39")))]
    +impl<Ctx: ScriptContext> DerivableKey<Ctx> for (GeneratedKey<Mnemonic, Ctx>, Option<String>) {
    +    fn into_extended_key(self) -> Result<ExtendedKey<Ctx>, KeyError> {
    +        let (mnemonic, passphrase) = self;
    +        (mnemonic.into_key(), passphrase).into_extended_key()
         }
     
    -    fn into_descriptor_key(
    +    fn into_descriptor_key(
             self,
    -        source: Option<bip32::KeySource>,
    -        derivation_path: bip32::DerivationPath,
    -    ) -> Result<DescriptorKey<Ctx>, KeyError> {
    -        let (mnemonic, passphrase) = self;
    -        (mnemonic.into_key(), passphrase).into_descriptor_key(source, derivation_path)
    +        source: Option<bip32::KeySource>,
    +        derivation_path: bip32::DerivationPath,
    +    ) -> Result<DescriptorKey<Ctx>, KeyError> {
    +        let (mnemonic, passphrase) = self;
    +        (mnemonic.into_key(), passphrase).into_descriptor_key(source, derivation_path)
         }
     }
     
    -#[cfg_attr(docsrs, doc(cfg(feature = "keys-bip39")))]
    -impl<Ctx: ScriptContext> DerivableKey<Ctx> for Mnemonic {
    -    fn into_extended_key(self) -> Result<ExtendedKey<Ctx>, KeyError> {
    -        (self, None).into_extended_key()
    +#[cfg_attr(docsrs, doc(cfg(feature = "keys-bip39")))]
    +impl<Ctx: ScriptContext> DerivableKey<Ctx> for Mnemonic {
    +    fn into_extended_key(self) -> Result<ExtendedKey<Ctx>, KeyError> {
    +        (self, None).into_extended_key()
         }
     
    -    fn into_descriptor_key(
    +    fn into_descriptor_key(
             self,
    -        source: Option<bip32::KeySource>,
    -        derivation_path: bip32::DerivationPath,
    -    ) -> Result<DescriptorKey<Ctx>, KeyError> {
    -        let descriptor_key = self
    -            .into_extended_key()?
    -            .into_descriptor_key(source, derivation_path)?;
    -
    -        Ok(set_valid_on_any_network(descriptor_key))
    +        source: Option<bip32::KeySource>,
    +        derivation_path: bip32::DerivationPath,
    +    ) -> Result<DescriptorKey<Ctx>, KeyError> {
    +        let descriptor_key = self
    +            .into_extended_key()?
    +            .into_descriptor_key(source, derivation_path)?;
    +
    +        Ok(set_valid_on_any_network(descriptor_key))
         }
     }
     
    -#[cfg_attr(docsrs, doc(cfg(feature = "keys-bip39")))]
    -impl<Ctx: ScriptContext> GeneratableKey<Ctx> for Mnemonic {
    -    type Entropy = [u8; 32];
    +#[cfg_attr(docsrs, doc(cfg(feature = "keys-bip39")))]
    +impl<Ctx: ScriptContext> GeneratableKey<Ctx> for Mnemonic {
    +    type Entropy = [u8; 32];
     
    -    type Options = (WordCount, Language);
    -    type Error = Option<bip39::Error>;
    +    type Options = (WordCount, Language);
    +    type Error = Option<bip39::Error>;
     
    -    fn generate_with_entropy(
    -        (word_count, language): Self::Options,
    -        entropy: Self::Entropy,
    -    ) -> Result<GeneratedKey<Self, Ctx>, Self::Error> {
    -        let entropy = &entropy.as_ref()[..(word_count as usize / 8)];
    -        let mnemonic = Mnemonic::from_entropy_in(language, entropy)?;
    +    fn generate_with_entropy(
    +        (word_count, language): Self::Options,
    +        entropy: Self::Entropy,
    +    ) -> Result<GeneratedKey<Self, Ctx>, Self::Error> {
    +        let entropy = &entropy.as_ref()[..(word_count as usize / 8)];
    +        let mnemonic = Mnemonic::from_entropy_in(language, entropy)?;
     
    -        Ok(GeneratedKey::new(mnemonic, any_network()))
    +        Ok(GeneratedKey::new(mnemonic, any_network()))
         }
     }
     
    -#[cfg(test)]
    -mod test {
    -    use std::str::FromStr;
    +#[cfg(test)]
    +mod test {
    +    use std::str::FromStr;
     
    -    use bitcoin::util::bip32;
    +    use bitcoin::util::bip32;
     
    -    use bip39::{Language, Mnemonic};
    +    use bip39::{Language, Mnemonic};
     
    -    use crate::keys::{any_network, GeneratableKey, GeneratedKey};
    +    use crate::keys::{any_network, GeneratableKey, GeneratedKey};
     
    -    use super::WordCount;
    +    use super::WordCount;
     
    -    #[test]
    -    fn test_keys_bip39_mnemonic() {
    -        let mnemonic =
    +    #[test]
    +    fn test_keys_bip39_mnemonic() {
    +        let mnemonic =
                 "aim bunker wash balance finish force paper analyst cabin spoon stable organ";
    -        let mnemonic = Mnemonic::parse_in(Language::English, mnemonic).unwrap();
    -        let path = bip32::DerivationPath::from_str("m/44'/0'/0'/0").unwrap();
    -
    -        let key = (mnemonic, path);
    -        let (desc, keys, networks) = crate::descriptor!(wpkh(key)).unwrap();
    -        assert_eq!(desc.to_string(), "wpkh([be83839f/44'/0'/0']xpub6DCQ1YcqvZtSwGWMrwHELPehjWV3f2MGZ69yBADTxFEUAoLwb5Mp5GniQK6tTp3AgbngVz9zEFbBJUPVnkG7LFYt8QMTfbrNqs6FNEwAPKA/0/*)#0r8v4nkv");
    -        assert_eq!(keys.len(), 1);
    -        assert_eq!(networks.len(), 4);
    +        let mnemonic = Mnemonic::parse_in(Language::English, mnemonic).unwrap();
    +        let path = bip32::DerivationPath::from_str("m/44'/0'/0'/0").unwrap();
    +
    +        let key = (mnemonic, path);
    +        let (desc, keys, networks) = crate::descriptor!(wpkh(key)).unwrap();
    +        assert_eq!(desc.to_string(), "wpkh([be83839f/44'/0'/0']xpub6DCQ1YcqvZtSwGWMrwHELPehjWV3f2MGZ69yBADTxFEUAoLwb5Mp5GniQK6tTp3AgbngVz9zEFbBJUPVnkG7LFYt8QMTfbrNqs6FNEwAPKA/0/*)#0r8v4nkv");
    +        assert_eq!(keys.len(), 1);
    +        assert_eq!(networks.len(), 4);
         }
     
    -    #[test]
    -    fn test_keys_bip39_mnemonic_passphrase() {
    -        let mnemonic =
    +    #[test]
    +    fn test_keys_bip39_mnemonic_passphrase() {
    +        let mnemonic =
                 "aim bunker wash balance finish force paper analyst cabin spoon stable organ";
    -        let mnemonic = Mnemonic::parse_in(Language::English, mnemonic).unwrap();
    -        let path = bip32::DerivationPath::from_str("m/44'/0'/0'/0").unwrap();
    -
    -        let key = ((mnemonic, Some("passphrase".into())), path);
    -        let (desc, keys, networks) = crate::descriptor!(wpkh(key)).unwrap();
    -        assert_eq!(desc.to_string(), "wpkh([8f6cb80c/44'/0'/0']xpub6DWYS8bbihFevy29M4cbw4ZR3P5E12jB8R88gBDWCTCNpYiDHhYWNywrCF9VZQYagzPmsZpxXpytzSoxynyeFr4ZyzheVjnpLKuse4fiwZw/0/*)#h0j0tg5m");
    -        assert_eq!(keys.len(), 1);
    -        assert_eq!(networks.len(), 4);
    +        let mnemonic = Mnemonic::parse_in(Language::English, mnemonic).unwrap();
    +        let path = bip32::DerivationPath::from_str("m/44'/0'/0'/0").unwrap();
    +
    +        let key = ((mnemonic, Some("passphrase".into())), path);
    +        let (desc, keys, networks) = crate::descriptor!(wpkh(key)).unwrap();
    +        assert_eq!(desc.to_string(), "wpkh([8f6cb80c/44'/0'/0']xpub6DWYS8bbihFevy29M4cbw4ZR3P5E12jB8R88gBDWCTCNpYiDHhYWNywrCF9VZQYagzPmsZpxXpytzSoxynyeFr4ZyzheVjnpLKuse4fiwZw/0/*)#h0j0tg5m");
    +        assert_eq!(keys.len(), 1);
    +        assert_eq!(networks.len(), 4);
         }
     
    -    #[test]
    -    fn test_keys_generate_bip39() {
    -        let generated_mnemonic: GeneratedKey<_, miniscript::Segwitv0> =
    -            Mnemonic::generate_with_entropy(
    -                (WordCount::Words12, Language::English),
    -                crate::keys::test::TEST_ENTROPY,
    +    #[test]
    +    fn test_keys_generate_bip39() {
    +        let generated_mnemonic: GeneratedKey<_, miniscript::Segwitv0> =
    +            Mnemonic::generate_with_entropy(
    +                (WordCount::Words12, Language::English),
    +                crate::keys::test::TEST_ENTROPY,
                 )
    -            .unwrap();
    -        assert_eq!(generated_mnemonic.valid_networks, any_network());
    +            .unwrap();
    +        assert_eq!(generated_mnemonic.valid_networks, any_network());
             assert_eq!(
    -            generated_mnemonic.to_string(),
    -            "primary fetch primary fetch primary fetch primary fetch primary fetch primary fever"
    -        );
    -
    -        let generated_mnemonic: GeneratedKey<_, miniscript::Segwitv0> =
    -            Mnemonic::generate_with_entropy(
    -                (WordCount::Words24, Language::English),
    -                crate::keys::test::TEST_ENTROPY,
    +            generated_mnemonic.to_string(),
    +            "primary fetch primary fetch primary fetch primary fetch primary fetch primary fever"
    +        );
    +
    +        let generated_mnemonic: GeneratedKey<_, miniscript::Segwitv0> =
    +            Mnemonic::generate_with_entropy(
    +                (WordCount::Words24, Language::English),
    +                crate::keys::test::TEST_ENTROPY,
                 )
    -            .unwrap();
    -        assert_eq!(generated_mnemonic.valid_networks, any_network());
    -        assert_eq!(generated_mnemonic.to_string(), "primary fetch primary fetch primary fetch primary fetch primary fetch primary fetch primary fetch primary fetch primary fetch primary fetch primary fetch primary foster");
    +            .unwrap();
    +        assert_eq!(generated_mnemonic.valid_networks, any_network());
    +        assert_eq!(generated_mnemonic.to_string(), "primary fetch primary fetch primary fetch primary fetch primary fetch primary fetch primary fetch primary fetch primary fetch primary fetch primary fetch primary foster");
         }
     
    -    #[test]
    -    fn test_keys_generate_bip39_random() {
    -        let generated_mnemonic: GeneratedKey<_, miniscript::Segwitv0> =
    -            Mnemonic::generate((WordCount::Words12, Language::English)).unwrap();
    -        assert_eq!(generated_mnemonic.valid_networks, any_network());
    +    #[test]
    +    fn test_keys_generate_bip39_random() {
    +        let generated_mnemonic: GeneratedKey<_, miniscript::Segwitv0> =
    +            Mnemonic::generate((WordCount::Words12, Language::English)).unwrap();
    +        assert_eq!(generated_mnemonic.valid_networks, any_network());
     
    -        let generated_mnemonic: GeneratedKey<_, miniscript::Segwitv0> =
    -            Mnemonic::generate((WordCount::Words24, Language::English)).unwrap();
    -        assert_eq!(generated_mnemonic.valid_networks, any_network());
    +        let generated_mnemonic: GeneratedKey<_, miniscript::Segwitv0> =
    +            Mnemonic::generate((WordCount::Words24, Language::English)).unwrap();
    +        assert_eq!(generated_mnemonic.valid_networks, any_network());
         }
     }
     
    -
    - \ No newline at end of file +
    \ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/src/bdk/keys/mod.rs.html b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/src/bdk/keys/mod.rs.html index 2aa89b2ad0..8536519a14 100644 --- a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/src/bdk/keys/mod.rs.html +++ b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/src/bdk/keys/mod.rs.html @@ -1,1465 +1,1459 @@ -mod.rs - source - -
      1
    -  2
    -  3
    -  4
    -  5
    -  6
    -  7
    -  8
    -  9
    - 10
    - 11
    - 12
    - 13
    - 14
    - 15
    - 16
    - 17
    - 18
    - 19
    - 20
    - 21
    - 22
    - 23
    - 24
    - 25
    - 26
    - 27
    - 28
    - 29
    - 30
    - 31
    - 32
    - 33
    - 34
    - 35
    - 36
    - 37
    - 38
    - 39
    - 40
    - 41
    - 42
    - 43
    - 44
    - 45
    - 46
    - 47
    - 48
    - 49
    - 50
    - 51
    - 52
    - 53
    - 54
    - 55
    - 56
    - 57
    - 58
    - 59
    - 60
    - 61
    - 62
    - 63
    - 64
    - 65
    - 66
    - 67
    - 68
    - 69
    - 70
    - 71
    - 72
    - 73
    - 74
    - 75
    - 76
    - 77
    - 78
    - 79
    - 80
    - 81
    - 82
    - 83
    - 84
    - 85
    - 86
    - 87
    - 88
    - 89
    - 90
    - 91
    - 92
    - 93
    - 94
    - 95
    - 96
    - 97
    - 98
    - 99
    -100
    -101
    -102
    -103
    -104
    -105
    -106
    -107
    -108
    -109
    -110
    -111
    -112
    -113
    -114
    -115
    -116
    -117
    -118
    -119
    -120
    -121
    -122
    -123
    -124
    -125
    -126
    -127
    -128
    -129
    -130
    -131
    -132
    -133
    -134
    -135
    -136
    -137
    -138
    -139
    -140
    -141
    -142
    -143
    -144
    -145
    -146
    -147
    -148
    -149
    -150
    -151
    -152
    -153
    -154
    -155
    -156
    -157
    -158
    -159
    -160
    -161
    -162
    -163
    -164
    -165
    -166
    -167
    -168
    -169
    -170
    -171
    -172
    -173
    -174
    -175
    -176
    -177
    -178
    -179
    -180
    -181
    -182
    -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
    -245
    -246
    -247
    -248
    -249
    -250
    -251
    -252
    -253
    -254
    -255
    -256
    -257
    -258
    -259
    -260
    -261
    -262
    -263
    -264
    -265
    -266
    -267
    -268
    -269
    -270
    -271
    -272
    -273
    -274
    -275
    -276
    -277
    -278
    -279
    -280
    -281
    -282
    -283
    -284
    -285
    -286
    -287
    -288
    -289
    -290
    -291
    -292
    -293
    -294
    -295
    -296
    -297
    -298
    -299
    -300
    -301
    -302
    -303
    -304
    -305
    -306
    -307
    -308
    -309
    -310
    -311
    -312
    -313
    -314
    -315
    -316
    -317
    -318
    -319
    -320
    -321
    -322
    -323
    -324
    -325
    -326
    -327
    -328
    -329
    -330
    -331
    -332
    -333
    -334
    -335
    -336
    -337
    -338
    -339
    -340
    -341
    -342
    -343
    -344
    -345
    -346
    -347
    -348
    -349
    -350
    -351
    -352
    -353
    -354
    -355
    -356
    -357
    -358
    -359
    -360
    -361
    -362
    -363
    -364
    -365
    -366
    -367
    -368
    -369
    -370
    -371
    -372
    -373
    -374
    -375
    -376
    -377
    -378
    -379
    -380
    -381
    -382
    -383
    -384
    -385
    -386
    -387
    -388
    -389
    -390
    -391
    -392
    -393
    -394
    -395
    -396
    -397
    -398
    -399
    -400
    -401
    -402
    -403
    -404
    -405
    -406
    -407
    -408
    -409
    -410
    -411
    -412
    -413
    -414
    -415
    -416
    -417
    -418
    -419
    -420
    -421
    -422
    -423
    -424
    -425
    -426
    -427
    -428
    -429
    -430
    -431
    -432
    -433
    -434
    -435
    -436
    -437
    -438
    -439
    -440
    -441
    -442
    -443
    -444
    -445
    -446
    -447
    -448
    -449
    -450
    -451
    -452
    -453
    -454
    -455
    -456
    -457
    -458
    -459
    -460
    -461
    -462
    -463
    -464
    -465
    -466
    -467
    -468
    -469
    -470
    -471
    -472
    -473
    -474
    -475
    -476
    -477
    -478
    -479
    -480
    -481
    -482
    -483
    -484
    -485
    -486
    -487
    -488
    -489
    -490
    -491
    -492
    -493
    -494
    -495
    -496
    -497
    -498
    -499
    -500
    -501
    -502
    -503
    -504
    -505
    -506
    -507
    -508
    -509
    -510
    -511
    -512
    -513
    -514
    -515
    -516
    -517
    -518
    -519
    -520
    -521
    -522
    -523
    -524
    -525
    -526
    -527
    -528
    -529
    -530
    -531
    -532
    -533
    -534
    -535
    -536
    -537
    -538
    -539
    -540
    -541
    -542
    -543
    -544
    -545
    -546
    -547
    -548
    -549
    -550
    -551
    -552
    -553
    -554
    -555
    -556
    -557
    -558
    -559
    -560
    -561
    -562
    -563
    -564
    -565
    -566
    -567
    -568
    -569
    -570
    -571
    -572
    -573
    -574
    -575
    -576
    -577
    -578
    -579
    -580
    -581
    -582
    -583
    -584
    -585
    -586
    -587
    -588
    -589
    -590
    -591
    -592
    -593
    -594
    -595
    -596
    -597
    -598
    -599
    -600
    -601
    -602
    -603
    -604
    -605
    -606
    -607
    -608
    -609
    -610
    -611
    -612
    -613
    -614
    -615
    -616
    -617
    -618
    -619
    -620
    -621
    -622
    -623
    -624
    -625
    -626
    -627
    -628
    -629
    -630
    -631
    -632
    -633
    -634
    -635
    -636
    -637
    -638
    -639
    -640
    -641
    -642
    -643
    -644
    -645
    -646
    -647
    -648
    -649
    -650
    -651
    -652
    -653
    -654
    -655
    -656
    -657
    -658
    -659
    -660
    -661
    -662
    -663
    -664
    -665
    -666
    -667
    -668
    -669
    -670
    -671
    -672
    -673
    -674
    -675
    -676
    -677
    -678
    -679
    -680
    -681
    -682
    -683
    -684
    -685
    -686
    -687
    -688
    -689
    -690
    -691
    -692
    -693
    -694
    -695
    -696
    -697
    -698
    -699
    -700
    -701
    -702
    -703
    -704
    -705
    -706
    -707
    -708
    -709
    -710
    -711
    -712
    -713
    -714
    -715
    -716
    -717
    -718
    -719
    -720
    -721
    -722
    -723
    -724
    -725
    -726
    -727
    -728
    -729
    -730
    -731
    -732
    -733
    -734
    -735
    -736
    -737
    -738
    -739
    -740
    -741
    -742
    -743
    -744
    -745
    -746
    -747
    -748
    -749
    -750
    -751
    -752
    -753
    -754
    -755
    -756
    -757
    -758
    -759
    -760
    -761
    -762
    -763
    -764
    -765
    -766
    -767
    -768
    -769
    -770
    -771
    -772
    -773
    -774
    -775
    -776
    -777
    -778
    -779
    -780
    -781
    -782
    -783
    -784
    -785
    -786
    -787
    -788
    -789
    -790
    -791
    -792
    -793
    -794
    -795
    -796
    -797
    -798
    -799
    -800
    -801
    -802
    -803
    -804
    -805
    -806
    -807
    -808
    -809
    -810
    -811
    -812
    -813
    -814
    -815
    -816
    -817
    -818
    -819
    -820
    -821
    -822
    -823
    -824
    -825
    -826
    -827
    -828
    -829
    -830
    -831
    -832
    -833
    -834
    -835
    -836
    -837
    -838
    -839
    -840
    -841
    -842
    -843
    -844
    -845
    -846
    -847
    -848
    -849
    -850
    -851
    -852
    -853
    -854
    -855
    -856
    -857
    -858
    -859
    -860
    -861
    -862
    -863
    -864
    -865
    -866
    -867
    -868
    -869
    -870
    -871
    -872
    -873
    -874
    -875
    -876
    -877
    -878
    -879
    -880
    -881
    -882
    -883
    -884
    -885
    -886
    -887
    -888
    -889
    -890
    -891
    -892
    -893
    -894
    -895
    -896
    -897
    -898
    -899
    -900
    -901
    -902
    -903
    -904
    -905
    -906
    -907
    -908
    -909
    -910
    -911
    -912
    -913
    -914
    -915
    -916
    -917
    -918
    -919
    -920
    -921
    -922
    -923
    -924
    -925
    -926
    -927
    -928
    -929
    -930
    -931
    -932
    -933
    -934
    -935
    -936
    -937
    -938
    -939
    -940
    -941
    -942
    -943
    -944
    -945
    -946
    -947
    -948
    -949
    -950
    -951
    -952
    -953
    -954
    -955
    -956
    -957
    -958
    -959
    -960
    -961
    -962
    -963
    -964
    -965
    -966
    -967
    -968
    -969
    -970
    -971
    -972
    -973
    -974
    -975
    -976
    -977
    -978
    -979
    -980
    -981
    -982
    -983
    -984
    -985
    -986
    -987
    -
    // Bitcoin Dev Kit
    -// Written in 2020 by Alekos Filini <alekos.filini@gmail.com>
    -//
    -// Copyright (c) 2020-2021 Bitcoin Dev Kit Developers
    -//
    -// This file is licensed under the Apache License, Version 2.0 <LICENSE-APACHE
    -// or http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
    -// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your option.
    -// You may not use this file except in accordance with one or both of these
    -// licenses.
    -
    -//! Key formats
    -
    -use std::any::TypeId;
    -use std::collections::HashSet;
    -use std::marker::PhantomData;
    -use std::ops::Deref;
    -use std::str::FromStr;
    -
    -use bitcoin::secp256k1::{self, Secp256k1, Signing};
    -
    -use bitcoin::util::bip32;
    -use bitcoin::{Network, PrivateKey, PublicKey, XOnlyPublicKey};
    -
    -use miniscript::descriptor::{Descriptor, DescriptorXKey, Wildcard};
    -pub use miniscript::descriptor::{
    -    DescriptorPublicKey, DescriptorSecretKey, KeyMap, SinglePriv, SinglePub, SinglePubKey,
    -    SortedMultiVec,
    +mod.rs - source
    1
    +2
    +3
    +4
    +5
    +6
    +7
    +8
    +9
    +10
    +11
    +12
    +13
    +14
    +15
    +16
    +17
    +18
    +19
    +20
    +21
    +22
    +23
    +24
    +25
    +26
    +27
    +28
    +29
    +30
    +31
    +32
    +33
    +34
    +35
    +36
    +37
    +38
    +39
    +40
    +41
    +42
    +43
    +44
    +45
    +46
    +47
    +48
    +49
    +50
    +51
    +52
    +53
    +54
    +55
    +56
    +57
    +58
    +59
    +60
    +61
    +62
    +63
    +64
    +65
    +66
    +67
    +68
    +69
    +70
    +71
    +72
    +73
    +74
    +75
    +76
    +77
    +78
    +79
    +80
    +81
    +82
    +83
    +84
    +85
    +86
    +87
    +88
    +89
    +90
    +91
    +92
    +93
    +94
    +95
    +96
    +97
    +98
    +99
    +100
    +101
    +102
    +103
    +104
    +105
    +106
    +107
    +108
    +109
    +110
    +111
    +112
    +113
    +114
    +115
    +116
    +117
    +118
    +119
    +120
    +121
    +122
    +123
    +124
    +125
    +126
    +127
    +128
    +129
    +130
    +131
    +132
    +133
    +134
    +135
    +136
    +137
    +138
    +139
    +140
    +141
    +142
    +143
    +144
    +145
    +146
    +147
    +148
    +149
    +150
    +151
    +152
    +153
    +154
    +155
    +156
    +157
    +158
    +159
    +160
    +161
    +162
    +163
    +164
    +165
    +166
    +167
    +168
    +169
    +170
    +171
    +172
    +173
    +174
    +175
    +176
    +177
    +178
    +179
    +180
    +181
    +182
    +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
    +245
    +246
    +247
    +248
    +249
    +250
    +251
    +252
    +253
    +254
    +255
    +256
    +257
    +258
    +259
    +260
    +261
    +262
    +263
    +264
    +265
    +266
    +267
    +268
    +269
    +270
    +271
    +272
    +273
    +274
    +275
    +276
    +277
    +278
    +279
    +280
    +281
    +282
    +283
    +284
    +285
    +286
    +287
    +288
    +289
    +290
    +291
    +292
    +293
    +294
    +295
    +296
    +297
    +298
    +299
    +300
    +301
    +302
    +303
    +304
    +305
    +306
    +307
    +308
    +309
    +310
    +311
    +312
    +313
    +314
    +315
    +316
    +317
    +318
    +319
    +320
    +321
    +322
    +323
    +324
    +325
    +326
    +327
    +328
    +329
    +330
    +331
    +332
    +333
    +334
    +335
    +336
    +337
    +338
    +339
    +340
    +341
    +342
    +343
    +344
    +345
    +346
    +347
    +348
    +349
    +350
    +351
    +352
    +353
    +354
    +355
    +356
    +357
    +358
    +359
    +360
    +361
    +362
    +363
    +364
    +365
    +366
    +367
    +368
    +369
    +370
    +371
    +372
    +373
    +374
    +375
    +376
    +377
    +378
    +379
    +380
    +381
    +382
    +383
    +384
    +385
    +386
    +387
    +388
    +389
    +390
    +391
    +392
    +393
    +394
    +395
    +396
    +397
    +398
    +399
    +400
    +401
    +402
    +403
    +404
    +405
    +406
    +407
    +408
    +409
    +410
    +411
    +412
    +413
    +414
    +415
    +416
    +417
    +418
    +419
    +420
    +421
    +422
    +423
    +424
    +425
    +426
    +427
    +428
    +429
    +430
    +431
    +432
    +433
    +434
    +435
    +436
    +437
    +438
    +439
    +440
    +441
    +442
    +443
    +444
    +445
    +446
    +447
    +448
    +449
    +450
    +451
    +452
    +453
    +454
    +455
    +456
    +457
    +458
    +459
    +460
    +461
    +462
    +463
    +464
    +465
    +466
    +467
    +468
    +469
    +470
    +471
    +472
    +473
    +474
    +475
    +476
    +477
    +478
    +479
    +480
    +481
    +482
    +483
    +484
    +485
    +486
    +487
    +488
    +489
    +490
    +491
    +492
    +493
    +494
    +495
    +496
    +497
    +498
    +499
    +500
    +501
    +502
    +503
    +504
    +505
    +506
    +507
    +508
    +509
    +510
    +511
    +512
    +513
    +514
    +515
    +516
    +517
    +518
    +519
    +520
    +521
    +522
    +523
    +524
    +525
    +526
    +527
    +528
    +529
    +530
    +531
    +532
    +533
    +534
    +535
    +536
    +537
    +538
    +539
    +540
    +541
    +542
    +543
    +544
    +545
    +546
    +547
    +548
    +549
    +550
    +551
    +552
    +553
    +554
    +555
    +556
    +557
    +558
    +559
    +560
    +561
    +562
    +563
    +564
    +565
    +566
    +567
    +568
    +569
    +570
    +571
    +572
    +573
    +574
    +575
    +576
    +577
    +578
    +579
    +580
    +581
    +582
    +583
    +584
    +585
    +586
    +587
    +588
    +589
    +590
    +591
    +592
    +593
    +594
    +595
    +596
    +597
    +598
    +599
    +600
    +601
    +602
    +603
    +604
    +605
    +606
    +607
    +608
    +609
    +610
    +611
    +612
    +613
    +614
    +615
    +616
    +617
    +618
    +619
    +620
    +621
    +622
    +623
    +624
    +625
    +626
    +627
    +628
    +629
    +630
    +631
    +632
    +633
    +634
    +635
    +636
    +637
    +638
    +639
    +640
    +641
    +642
    +643
    +644
    +645
    +646
    +647
    +648
    +649
    +650
    +651
    +652
    +653
    +654
    +655
    +656
    +657
    +658
    +659
    +660
    +661
    +662
    +663
    +664
    +665
    +666
    +667
    +668
    +669
    +670
    +671
    +672
    +673
    +674
    +675
    +676
    +677
    +678
    +679
    +680
    +681
    +682
    +683
    +684
    +685
    +686
    +687
    +688
    +689
    +690
    +691
    +692
    +693
    +694
    +695
    +696
    +697
    +698
    +699
    +700
    +701
    +702
    +703
    +704
    +705
    +706
    +707
    +708
    +709
    +710
    +711
    +712
    +713
    +714
    +715
    +716
    +717
    +718
    +719
    +720
    +721
    +722
    +723
    +724
    +725
    +726
    +727
    +728
    +729
    +730
    +731
    +732
    +733
    +734
    +735
    +736
    +737
    +738
    +739
    +740
    +741
    +742
    +743
    +744
    +745
    +746
    +747
    +748
    +749
    +750
    +751
    +752
    +753
    +754
    +755
    +756
    +757
    +758
    +759
    +760
    +761
    +762
    +763
    +764
    +765
    +766
    +767
    +768
    +769
    +770
    +771
    +772
    +773
    +774
    +775
    +776
    +777
    +778
    +779
    +780
    +781
    +782
    +783
    +784
    +785
    +786
    +787
    +788
    +789
    +790
    +791
    +792
    +793
    +794
    +795
    +796
    +797
    +798
    +799
    +800
    +801
    +802
    +803
    +804
    +805
    +806
    +807
    +808
    +809
    +810
    +811
    +812
    +813
    +814
    +815
    +816
    +817
    +818
    +819
    +820
    +821
    +822
    +823
    +824
    +825
    +826
    +827
    +828
    +829
    +830
    +831
    +832
    +833
    +834
    +835
    +836
    +837
    +838
    +839
    +840
    +841
    +842
    +843
    +844
    +845
    +846
    +847
    +848
    +849
    +850
    +851
    +852
    +853
    +854
    +855
    +856
    +857
    +858
    +859
    +860
    +861
    +862
    +863
    +864
    +865
    +866
    +867
    +868
    +869
    +870
    +871
    +872
    +873
    +874
    +875
    +876
    +877
    +878
    +879
    +880
    +881
    +882
    +883
    +884
    +885
    +886
    +887
    +888
    +889
    +890
    +891
    +892
    +893
    +894
    +895
    +896
    +897
    +898
    +899
    +900
    +901
    +902
    +903
    +904
    +905
    +906
    +907
    +908
    +909
    +910
    +911
    +912
    +913
    +914
    +915
    +916
    +917
    +918
    +919
    +920
    +921
    +922
    +923
    +924
    +925
    +926
    +927
    +928
    +929
    +930
    +931
    +932
    +933
    +934
    +935
    +936
    +937
    +938
    +939
    +940
    +941
    +942
    +943
    +944
    +945
    +946
    +947
    +948
    +949
    +950
    +951
    +952
    +953
    +954
    +955
    +956
    +957
    +958
    +959
    +960
    +961
    +962
    +963
    +964
    +965
    +966
    +967
    +968
    +969
    +970
    +971
    +972
    +973
    +974
    +975
    +976
    +977
    +978
    +979
    +980
    +981
    +982
    +983
    +984
    +985
    +986
    +987
    +
    // Bitcoin Dev Kit
    +// Written in 2020 by Alekos Filini <alekos.filini@gmail.com>
    +//
    +// Copyright (c) 2020-2021 Bitcoin Dev Kit Developers
    +//
    +// This file is licensed under the Apache License, Version 2.0 <LICENSE-APACHE
    +// or http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
    +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your option.
    +// You may not use this file except in accordance with one or both of these
    +// licenses.
    +
    +//! Key formats
    +
    +use std::any::TypeId;
    +use std::collections::HashSet;
    +use std::marker::PhantomData;
    +use std::ops::Deref;
    +use std::str::FromStr;
    +
    +use bitcoin::secp256k1::{self, Secp256k1, Signing};
    +
    +use bitcoin::util::bip32;
    +use bitcoin::{Network, PrivateKey, PublicKey, XOnlyPublicKey};
    +
    +use miniscript::descriptor::{Descriptor, DescriptorXKey, Wildcard};
    +pub use miniscript::descriptor::{
    +    DescriptorPublicKey, DescriptorSecretKey, KeyMap, SinglePriv, SinglePub, SinglePubKey,
    +    SortedMultiVec,
     };
    -pub use miniscript::ScriptContext;
    -use miniscript::{Miniscript, Terminal};
    +pub use miniscript::ScriptContext;
    +use miniscript::{Miniscript, Terminal};
     
    -use crate::descriptor::{CheckMiniscript, DescriptorError};
    -use crate::wallet::utils::SecpCtx;
    +use crate::descriptor::{CheckMiniscript, DescriptorError};
    +use crate::wallet::utils::SecpCtx;
     
    -#[cfg(feature = "keys-bip39")]
    -#[cfg_attr(docsrs, doc(cfg(feature = "keys-bip39")))]
    -pub mod bip39;
    +#[cfg(feature = "keys-bip39")]
    +#[cfg_attr(docsrs, doc(cfg(feature = "keys-bip39")))]
    +pub mod bip39;
     
    -/// Set of valid networks for a key
    -pub type ValidNetworks = HashSet<Network>;
    +/// Set of valid networks for a key
    +pub type ValidNetworks = HashSet<Network>;
     
    -/// Create a set containing mainnet, testnet and regtest
    -pub fn any_network() -> ValidNetworks {
    +/// Create a set containing mainnet, testnet and regtest
    +pub fn any_network() -> ValidNetworks {
         vec![
    -        Network::Bitcoin,
    -        Network::Testnet,
    -        Network::Regtest,
    -        Network::Signet,
    +        Network::Bitcoin,
    +        Network::Testnet,
    +        Network::Regtest,
    +        Network::Signet,
         ]
    -    .into_iter()
    -    .collect()
    +    .into_iter()
    +    .collect()
     }
    -/// Create a set only containing mainnet
    -pub fn mainnet_network() -> ValidNetworks {
    -    vec![Network::Bitcoin].into_iter().collect()
    +/// Create a set only containing mainnet
    +pub fn mainnet_network() -> ValidNetworks {
    +    vec![Network::Bitcoin].into_iter().collect()
     }
    -/// Create a set containing testnet and regtest
    -pub fn test_networks() -> ValidNetworks {
    -    vec![Network::Testnet, Network::Regtest, Network::Signet]
    -        .into_iter()
    -        .collect()
    +/// Create a set containing testnet and regtest
    +pub fn test_networks() -> ValidNetworks {
    +    vec![Network::Testnet, Network::Regtest, Network::Signet]
    +        .into_iter()
    +        .collect()
     }
    -/// Compute the intersection of two sets
    -pub fn merge_networks(a: &ValidNetworks, b: &ValidNetworks) -> ValidNetworks {
    -    a.intersection(b).cloned().collect()
    +/// Compute the intersection of two sets
    +pub fn merge_networks(a: &ValidNetworks, b: &ValidNetworks) -> ValidNetworks {
    +    a.intersection(b).cloned().collect()
     }
     
    -/// Container for public or secret keys
    -#[derive(Debug)]
    -pub enum DescriptorKey<Ctx: ScriptContext> {
    -    #[doc(hidden)]
    -    Public(DescriptorPublicKey, ValidNetworks, PhantomData<Ctx>),
    -    #[doc(hidden)]
    -    Secret(DescriptorSecretKey, ValidNetworks, PhantomData<Ctx>),
    +/// Container for public or secret keys
    +#[derive(Debug)]
    +pub enum DescriptorKey<Ctx: ScriptContext> {
    +    #[doc(hidden)]
    +    Public(DescriptorPublicKey, ValidNetworks, PhantomData<Ctx>),
    +    #[doc(hidden)]
    +    Secret(DescriptorSecretKey, ValidNetworks, PhantomData<Ctx>),
     }
     
    -impl<Ctx: ScriptContext> DescriptorKey<Ctx> {
    -    /// Create an instance given a public key and a set of valid networks
    -    pub fn from_public(public: DescriptorPublicKey, networks: ValidNetworks) -> Self {
    -        DescriptorKey::Public(public, networks, PhantomData)
    +impl<Ctx: ScriptContext> DescriptorKey<Ctx> {
    +    /// Create an instance given a public key and a set of valid networks
    +    pub fn from_public(public: DescriptorPublicKey, networks: ValidNetworks) -> Self {
    +        DescriptorKey::Public(public, networks, PhantomData)
         }
     
    -    /// Create an instance given a secret key and a set of valid networks
    -    pub fn from_secret(secret: DescriptorSecretKey, networks: ValidNetworks) -> Self {
    -        DescriptorKey::Secret(secret, networks, PhantomData)
    +    /// Create an instance given a secret key and a set of valid networks
    +    pub fn from_secret(secret: DescriptorSecretKey, networks: ValidNetworks) -> Self {
    +        DescriptorKey::Secret(secret, networks, PhantomData)
         }
     
    -    /// Override the computed set of valid networks
    -    pub fn override_valid_networks(self, networks: ValidNetworks) -> Self {
    -        match self {
    -            DescriptorKey::Public(key, _, _) => DescriptorKey::Public(key, networks, PhantomData),
    -            DescriptorKey::Secret(key, _, _) => DescriptorKey::Secret(key, networks, PhantomData),
    +    /// Override the computed set of valid networks
    +    pub fn override_valid_networks(self, networks: ValidNetworks) -> Self {
    +        match self {
    +            DescriptorKey::Public(key, _, _) => DescriptorKey::Public(key, networks, PhantomData),
    +            DescriptorKey::Secret(key, _, _) => DescriptorKey::Secret(key, networks, PhantomData),
             }
         }
     
    -    // This method is used internally by `bdk::fragment!` and `bdk::descriptor!`. It has to be
    -    // public because it is effectively called by external crates, once the macros are expanded,
    -    // but since it is not meant to be part of the public api we hide it from the docs.
    -    #[doc(hidden)]
    -    pub fn extract(
    +    // This method is used internally by `bdk::fragment!` and `bdk::descriptor!`. It has to be
    +    // public because it is effectively called by external crates, once the macros are expanded,
    +    // but since it is not meant to be part of the public api we hide it from the docs.
    +    #[doc(hidden)]
    +    pub fn extract(
             self,
    -        secp: &SecpCtx,
    -    ) -> Result<(DescriptorPublicKey, KeyMap, ValidNetworks), KeyError> {
    -        match self {
    -            DescriptorKey::Public(public, valid_networks, _) => {
    -                Ok((public, KeyMap::default(), valid_networks))
    +        secp: &SecpCtx,
    +    ) -> Result<(DescriptorPublicKey, KeyMap, ValidNetworks), KeyError> {
    +        match self {
    +            DescriptorKey::Public(public, valid_networks, _) => {
    +                Ok((public, KeyMap::default(), valid_networks))
                 }
    -            DescriptorKey::Secret(secret, valid_networks, _) => {
    -                let mut key_map = KeyMap::with_capacity(1);
    +            DescriptorKey::Secret(secret, valid_networks, _) => {
    +                let mut key_map = KeyMap::with_capacity(1);
     
    -                let public = secret
    -                    .to_public(secp)
    -                    .map_err(|e| miniscript::Error::Unexpected(e.to_string()))?;
    -                key_map.insert(public.clone(), secret);
    +                let public = secret
    +                    .to_public(secp)
    +                    .map_err(|e| miniscript::Error::Unexpected(e.to_string()))?;
    +                key_map.insert(public.clone(), secret);
     
    -                Ok((public, key_map, valid_networks))
    +                Ok((public, key_map, valid_networks))
                 }
             }
         }
     }
     
    -/// Enum representation of the known valid [`ScriptContext`]s
    -#[derive(Debug, Eq, PartialEq, Copy, Clone)]
    -pub enum ScriptContextEnum {
    -    /// Legacy scripts
    -    Legacy,
    -    /// Segwitv0 scripts
    -    Segwitv0,
    -    /// Taproot scripts
    -    Tap,
    +/// Enum representation of the known valid [`ScriptContext`]s
    +#[derive(Debug, Eq, PartialEq, Copy, Clone)]
    +pub enum ScriptContextEnum {
    +    /// Legacy scripts
    +    Legacy,
    +    /// Segwitv0 scripts
    +    Segwitv0,
    +    /// Taproot scripts
    +    Tap,
     }
     
    -impl ScriptContextEnum {
    -    /// Returns whether the script context is [`ScriptContextEnum::Legacy`]
    -    pub fn is_legacy(&self) -> bool {
    -        self == &ScriptContextEnum::Legacy
    +impl ScriptContextEnum {
    +    /// Returns whether the script context is [`ScriptContextEnum::Legacy`]
    +    pub fn is_legacy(&self) -> bool {
    +        self == &ScriptContextEnum::Legacy
         }
     
    -    /// Returns whether the script context is [`ScriptContextEnum::Segwitv0`]
    -    pub fn is_segwit_v0(&self) -> bool {
    -        self == &ScriptContextEnum::Segwitv0
    +    /// Returns whether the script context is [`ScriptContextEnum::Segwitv0`]
    +    pub fn is_segwit_v0(&self) -> bool {
    +        self == &ScriptContextEnum::Segwitv0
         }
     
    -    /// Returns whether the script context is [`ScriptContextEnum::Tap`]
    -    pub fn is_taproot(&self) -> bool {
    -        self == &ScriptContextEnum::Tap
    +    /// Returns whether the script context is [`ScriptContextEnum::Tap`]
    +    pub fn is_taproot(&self) -> bool {
    +        self == &ScriptContextEnum::Tap
         }
     }
     
    -/// Trait that adds extra useful methods to [`ScriptContext`]s
    -pub trait ExtScriptContext: ScriptContext {
    -    /// Returns the [`ScriptContext`] as a [`ScriptContextEnum`]
    -    fn as_enum() -> ScriptContextEnum;
    +/// Trait that adds extra useful methods to [`ScriptContext`]s
    +pub trait ExtScriptContext: ScriptContext {
    +    /// Returns the [`ScriptContext`] as a [`ScriptContextEnum`]
    +    fn as_enum() -> ScriptContextEnum;
     
    -    /// Returns whether the script context is [`Legacy`](miniscript::Legacy)
    -    fn is_legacy() -> bool {
    -        Self::as_enum().is_legacy()
    +    /// Returns whether the script context is [`Legacy`](miniscript::Legacy)
    +    fn is_legacy() -> bool {
    +        Self::as_enum().is_legacy()
         }
     
    -    /// Returns whether the script context is [`Segwitv0`](miniscript::Segwitv0)
    -    fn is_segwit_v0() -> bool {
    -        Self::as_enum().is_segwit_v0()
    +    /// Returns whether the script context is [`Segwitv0`](miniscript::Segwitv0)
    +    fn is_segwit_v0() -> bool {
    +        Self::as_enum().is_segwit_v0()
         }
     
    -    /// Returns whether the script context is [`Tap`](miniscript::Tap), aka Taproot or Segwit V1
    -    fn is_taproot() -> bool {
    -        Self::as_enum().is_taproot()
    +    /// Returns whether the script context is [`Tap`](miniscript::Tap), aka Taproot or Segwit V1
    +    fn is_taproot() -> bool {
    +        Self::as_enum().is_taproot()
         }
     }
     
    -impl<Ctx: ScriptContext + 'static> ExtScriptContext for Ctx {
    -    fn as_enum() -> ScriptContextEnum {
    -        match TypeId::of::<Ctx>() {
    -            t if t == TypeId::of::<miniscript::Legacy>() => ScriptContextEnum::Legacy,
    -            t if t == TypeId::of::<miniscript::Segwitv0>() => ScriptContextEnum::Segwitv0,
    -            t if t == TypeId::of::<miniscript::Tap>() => ScriptContextEnum::Tap,
    -            _ => unimplemented!("Unknown ScriptContext type"),
    +impl<Ctx: ScriptContext + 'static> ExtScriptContext for Ctx {
    +    fn as_enum() -> ScriptContextEnum {
    +        match TypeId::of::<Ctx>() {
    +            t if t == TypeId::of::<miniscript::Legacy>() => ScriptContextEnum::Legacy,
    +            t if t == TypeId::of::<miniscript::Segwitv0>() => ScriptContextEnum::Segwitv0,
    +            t if t == TypeId::of::<miniscript::Tap>() => ScriptContextEnum::Tap,
    +            _ => unimplemented!("Unknown ScriptContext type"),
             }
         }
     }
     
    -/// Trait for objects that can be turned into a public or secret [`DescriptorKey`]
    -///
    -/// The generic type `Ctx` is used to define the context in which the key is valid: some key
    -/// formats, like the mnemonics used by Electrum wallets, encode internally whether the wallet is
    -/// legacy or segwit. Thus, trying to turn a valid legacy mnemonic into a `DescriptorKey`
    -/// that would become part of a segwit descriptor should fail.
    -///
    -/// For key types that do care about this, the [`ExtScriptContext`] trait provides some useful
    -/// methods that can be used to check at runtime which `Ctx` is being used.
    -///
    -/// For key types that can do this check statically (because they can only work within a
    -/// single `Ctx`), the "specialized" trait can be implemented to make the compiler handle the type
    -/// checking.
    -///
    -/// Keys also have control over the networks they support: constructing the return object with
    -/// [`DescriptorKey::from_public`] or [`DescriptorKey::from_secret`] allows to specify a set of
    -/// [`ValidNetworks`].
    -///
    -/// ## Examples
    -///
    -/// Key type valid in any context:
    -///
    -/// ```
    -/// use bdk::bitcoin::PublicKey;
    -///
    -/// use bdk::keys::{DescriptorKey, IntoDescriptorKey, KeyError, ScriptContext};
    -///
    -/// pub struct MyKeyType {
    -///     pubkey: PublicKey,
    -/// }
    -///
    -/// impl<Ctx: ScriptContext> IntoDescriptorKey<Ctx> for MyKeyType {
    -///     fn into_descriptor_key(self) -> Result<DescriptorKey<Ctx>, KeyError> {
    -///         self.pubkey.into_descriptor_key()
    -///     }
    -/// }
    -/// ```
    -///
    -/// Key type that is only valid on mainnet:
    -///
    -/// ```
    -/// use bdk::bitcoin::PublicKey;
    -///
    -/// use bdk::keys::{
    -///     mainnet_network, DescriptorKey, DescriptorPublicKey, IntoDescriptorKey, KeyError,
    -///     ScriptContext, SinglePub, SinglePubKey,
    -/// };
    -///
    -/// pub struct MyKeyType {
    -///     pubkey: PublicKey,
    -/// }
    -///
    -/// impl<Ctx: ScriptContext> IntoDescriptorKey<Ctx> for MyKeyType {
    -///     fn into_descriptor_key(self) -> Result<DescriptorKey<Ctx>, KeyError> {
    -///         Ok(DescriptorKey::from_public(
    -///             DescriptorPublicKey::Single(SinglePub {
    -///                 origin: None,
    -///                 key: SinglePubKey::FullKey(self.pubkey),
    -///             }),
    -///             mainnet_network(),
    -///         ))
    -///     }
    -/// }
    -/// ```
    -///
    -/// Key type that internally encodes in which context it's valid. The context is checked at runtime:
    -///
    -/// ```
    -/// use bdk::bitcoin::PublicKey;
    -///
    -/// use bdk::keys::{DescriptorKey, ExtScriptContext, IntoDescriptorKey, KeyError, ScriptContext};
    -///
    -/// pub struct MyKeyType {
    -///     is_legacy: bool,
    -///     pubkey: PublicKey,
    -/// }
    -///
    -/// impl<Ctx: ScriptContext + 'static> IntoDescriptorKey<Ctx> for MyKeyType {
    -///     fn into_descriptor_key(self) -> Result<DescriptorKey<Ctx>, KeyError> {
    -///         if Ctx::is_legacy() == self.is_legacy {
    -///             self.pubkey.into_descriptor_key()
    -///         } else {
    -///             Err(KeyError::InvalidScriptContext)
    -///         }
    -///     }
    -/// }
    -/// ```
    -///
    -/// Key type that can only work within [`miniscript::Segwitv0`] context. Only the specialized version
    -/// of the trait is implemented.
    -///
    -/// This example deliberately fails to compile, to demonstrate how the compiler can catch when keys
    -/// are misused. In this case, the "segwit-only" key is used to build a `pkh()` descriptor, which
    -/// makes the compiler (correctly) fail.
    -///
    -/// ```compile_fail
    -/// use bdk::bitcoin::PublicKey;
    -/// use std::str::FromStr;
    -///
    -/// use bdk::keys::{DescriptorKey, IntoDescriptorKey, KeyError};
    -///
    -/// pub struct MySegwitOnlyKeyType {
    -///     pubkey: PublicKey,
    -/// }
    -///
    -/// impl IntoDescriptorKey<bdk::miniscript::Segwitv0> for MySegwitOnlyKeyType {
    -///     fn into_descriptor_key(self) -> Result<DescriptorKey<bdk::miniscript::Segwitv0>, KeyError> {
    -///         self.pubkey.into_descriptor_key()
    -///     }
    -/// }
    -///
    -/// let key = MySegwitOnlyKeyType {
    -///     pubkey: PublicKey::from_str("...")?,
    -/// };
    -/// let (descriptor, _, _) = bdk::descriptor!(pkh(key))?;
    -/// //                                       ^^^^^ changing this to `wpkh` would make it compile
    -///
    -/// # Ok::<_, Box<dyn std::error::Error>>(())
    -/// ```
    -pub trait IntoDescriptorKey<Ctx: ScriptContext>: Sized {
    -    /// Turn the key into a [`DescriptorKey`] within the requested [`ScriptContext`]
    -    fn into_descriptor_key(self) -> Result<DescriptorKey<Ctx>, KeyError>;
    +/// Trait for objects that can be turned into a public or secret [`DescriptorKey`]
    +///
    +/// The generic type `Ctx` is used to define the context in which the key is valid: some key
    +/// formats, like the mnemonics used by Electrum wallets, encode internally whether the wallet is
    +/// legacy or segwit. Thus, trying to turn a valid legacy mnemonic into a `DescriptorKey`
    +/// that would become part of a segwit descriptor should fail.
    +///
    +/// For key types that do care about this, the [`ExtScriptContext`] trait provides some useful
    +/// methods that can be used to check at runtime which `Ctx` is being used.
    +///
    +/// For key types that can do this check statically (because they can only work within a
    +/// single `Ctx`), the "specialized" trait can be implemented to make the compiler handle the type
    +/// checking.
    +///
    +/// Keys also have control over the networks they support: constructing the return object with
    +/// [`DescriptorKey::from_public`] or [`DescriptorKey::from_secret`] allows to specify a set of
    +/// [`ValidNetworks`].
    +///
    +/// ## Examples
    +///
    +/// Key type valid in any context:
    +///
    +/// ```
    +/// use bdk::bitcoin::PublicKey;
    +///
    +/// use bdk::keys::{DescriptorKey, IntoDescriptorKey, KeyError, ScriptContext};
    +///
    +/// pub struct MyKeyType {
    +///     pubkey: PublicKey,
    +/// }
    +///
    +/// impl<Ctx: ScriptContext> IntoDescriptorKey<Ctx> for MyKeyType {
    +///     fn into_descriptor_key(self) -> Result<DescriptorKey<Ctx>, KeyError> {
    +///         self.pubkey.into_descriptor_key()
    +///     }
    +/// }
    +/// ```
    +///
    +/// Key type that is only valid on mainnet:
    +///
    +/// ```
    +/// use bdk::bitcoin::PublicKey;
    +///
    +/// use bdk::keys::{
    +///     mainnet_network, DescriptorKey, DescriptorPublicKey, IntoDescriptorKey, KeyError,
    +///     ScriptContext, SinglePub, SinglePubKey,
    +/// };
    +///
    +/// pub struct MyKeyType {
    +///     pubkey: PublicKey,
    +/// }
    +///
    +/// impl<Ctx: ScriptContext> IntoDescriptorKey<Ctx> for MyKeyType {
    +///     fn into_descriptor_key(self) -> Result<DescriptorKey<Ctx>, KeyError> {
    +///         Ok(DescriptorKey::from_public(
    +///             DescriptorPublicKey::Single(SinglePub {
    +///                 origin: None,
    +///                 key: SinglePubKey::FullKey(self.pubkey),
    +///             }),
    +///             mainnet_network(),
    +///         ))
    +///     }
    +/// }
    +/// ```
    +///
    +/// Key type that internally encodes in which context it's valid. The context is checked at runtime:
    +///
    +/// ```
    +/// use bdk::bitcoin::PublicKey;
    +///
    +/// use bdk::keys::{DescriptorKey, ExtScriptContext, IntoDescriptorKey, KeyError, ScriptContext};
    +///
    +/// pub struct MyKeyType {
    +///     is_legacy: bool,
    +///     pubkey: PublicKey,
    +/// }
    +///
    +/// impl<Ctx: ScriptContext + 'static> IntoDescriptorKey<Ctx> for MyKeyType {
    +///     fn into_descriptor_key(self) -> Result<DescriptorKey<Ctx>, KeyError> {
    +///         if Ctx::is_legacy() == self.is_legacy {
    +///             self.pubkey.into_descriptor_key()
    +///         } else {
    +///             Err(KeyError::InvalidScriptContext)
    +///         }
    +///     }
    +/// }
    +/// ```
    +///
    +/// Key type that can only work within [`miniscript::Segwitv0`] context. Only the specialized version
    +/// of the trait is implemented.
    +///
    +/// This example deliberately fails to compile, to demonstrate how the compiler can catch when keys
    +/// are misused. In this case, the "segwit-only" key is used to build a `pkh()` descriptor, which
    +/// makes the compiler (correctly) fail.
    +///
    +/// ```compile_fail
    +/// use bdk::bitcoin::PublicKey;
    +/// use std::str::FromStr;
    +///
    +/// use bdk::keys::{DescriptorKey, IntoDescriptorKey, KeyError};
    +///
    +/// pub struct MySegwitOnlyKeyType {
    +///     pubkey: PublicKey,
    +/// }
    +///
    +/// impl IntoDescriptorKey<bdk::miniscript::Segwitv0> for MySegwitOnlyKeyType {
    +///     fn into_descriptor_key(self) -> Result<DescriptorKey<bdk::miniscript::Segwitv0>, KeyError> {
    +///         self.pubkey.into_descriptor_key()
    +///     }
    +/// }
    +///
    +/// let key = MySegwitOnlyKeyType {
    +///     pubkey: PublicKey::from_str("...")?,
    +/// };
    +/// let (descriptor, _, _) = bdk::descriptor!(pkh(key))?;
    +/// //                                       ^^^^^ changing this to `wpkh` would make it compile
    +///
    +/// # Ok::<_, Box<dyn std::error::Error>>(())
    +/// ```
    +pub trait IntoDescriptorKey<Ctx: ScriptContext>: Sized {
    +    /// Turn the key into a [`DescriptorKey`] within the requested [`ScriptContext`]
    +    fn into_descriptor_key(self) -> Result<DescriptorKey<Ctx>, KeyError>;
     }
     
    -/// Enum for extended keys that can be either `xprv` or `xpub`
    -///
    -/// An instance of [`ExtendedKey`] can be constructed from an [`ExtendedPrivKey`](bip32::ExtendedPrivKey)
    -/// or an [`ExtendedPubKey`](bip32::ExtendedPubKey) by using the `From` trait.
    -///
    -/// Defaults to the [`Legacy`](miniscript::Legacy) context.
    -pub enum ExtendedKey<Ctx: ScriptContext = miniscript::Legacy> {
    -    /// A private extended key, aka an `xprv`
    -    Private((bip32::ExtendedPrivKey, PhantomData<Ctx>)),
    -    /// A public extended key, aka an `xpub`
    -    Public((bip32::ExtendedPubKey, PhantomData<Ctx>)),
    +/// Enum for extended keys that can be either `xprv` or `xpub`
    +///
    +/// An instance of [`ExtendedKey`] can be constructed from an [`ExtendedPrivKey`](bip32::ExtendedPrivKey)
    +/// or an [`ExtendedPubKey`](bip32::ExtendedPubKey) by using the `From` trait.
    +///
    +/// Defaults to the [`Legacy`](miniscript::Legacy) context.
    +pub enum ExtendedKey<Ctx: ScriptContext = miniscript::Legacy> {
    +    /// A private extended key, aka an `xprv`
    +    Private((bip32::ExtendedPrivKey, PhantomData<Ctx>)),
    +    /// A public extended key, aka an `xpub`
    +    Public((bip32::ExtendedPubKey, PhantomData<Ctx>)),
     }
     
    -impl<Ctx: ScriptContext> ExtendedKey<Ctx> {
    -    /// Return whether or not the key contains the private data
    -    pub fn has_secret(&self) -> bool {
    -        match self {
    -            ExtendedKey::Private(_) => true,
    -            ExtendedKey::Public(_) => false,
    +impl<Ctx: ScriptContext> ExtendedKey<Ctx> {
    +    /// Return whether or not the key contains the private data
    +    pub fn has_secret(&self) -> bool {
    +        match self {
    +            ExtendedKey::Private(_) => true,
    +            ExtendedKey::Public(_) => false,
             }
         }
     
    -    /// Transform the [`ExtendedKey`] into an [`ExtendedPrivKey`](bip32::ExtendedPrivKey) for the
    -    /// given [`Network`], if the key contains the private data
    -    pub fn into_xprv(self, network: Network) -> Option<bip32::ExtendedPrivKey> {
    -        match self {
    -            ExtendedKey::Private((mut xprv, _)) => {
    -                xprv.network = network;
    -                Some(xprv)
    +    /// Transform the [`ExtendedKey`] into an [`ExtendedPrivKey`](bip32::ExtendedPrivKey) for the
    +    /// given [`Network`], if the key contains the private data
    +    pub fn into_xprv(self, network: Network) -> Option<bip32::ExtendedPrivKey> {
    +        match self {
    +            ExtendedKey::Private((mut xprv, _)) => {
    +                xprv.network = network;
    +                Some(xprv)
                 }
    -            ExtendedKey::Public(_) => None,
    +            ExtendedKey::Public(_) => None,
             }
         }
     
    -    /// Transform the [`ExtendedKey`] into an [`ExtendedPubKey`](bip32::ExtendedPubKey) for the
    -    /// given [`Network`]
    -    pub fn into_xpub<C: Signing>(
    +    /// Transform the [`ExtendedKey`] into an [`ExtendedPubKey`](bip32::ExtendedPubKey) for the
    +    /// given [`Network`]
    +    pub fn into_xpub<C: Signing>(
             self,
    -        network: bitcoin::Network,
    -        secp: &Secp256k1<C>,
    -    ) -> bip32::ExtendedPubKey {
    -        let mut xpub = match self {
    -            ExtendedKey::Private((xprv, _)) => bip32::ExtendedPubKey::from_priv(secp, &xprv),
    -            ExtendedKey::Public((xpub, _)) => xpub,
    +        network: bitcoin::Network,
    +        secp: &Secp256k1<C>,
    +    ) -> bip32::ExtendedPubKey {
    +        let mut xpub = match self {
    +            ExtendedKey::Private((xprv, _)) => bip32::ExtendedPubKey::from_priv(secp, &xprv),
    +            ExtendedKey::Public((xpub, _)) => xpub,
             };
     
    -        xpub.network = network;
    -        xpub
    +        xpub.network = network;
    +        xpub
         }
     }
     
    -impl<Ctx: ScriptContext> From<bip32::ExtendedPubKey> for ExtendedKey<Ctx> {
    -    fn from(xpub: bip32::ExtendedPubKey) -> Self {
    -        ExtendedKey::Public((xpub, PhantomData))
    +impl<Ctx: ScriptContext> From<bip32::ExtendedPubKey> for ExtendedKey<Ctx> {
    +    fn from(xpub: bip32::ExtendedPubKey) -> Self {
    +        ExtendedKey::Public((xpub, PhantomData))
         }
     }
     
    -impl<Ctx: ScriptContext> From<bip32::ExtendedPrivKey> for ExtendedKey<Ctx> {
    -    fn from(xprv: bip32::ExtendedPrivKey) -> Self {
    -        ExtendedKey::Private((xprv, PhantomData))
    +impl<Ctx: ScriptContext> From<bip32::ExtendedPrivKey> for ExtendedKey<Ctx> {
    +    fn from(xprv: bip32::ExtendedPrivKey) -> Self {
    +        ExtendedKey::Private((xprv, PhantomData))
         }
     }
     
    -/// Trait for keys that can be derived.
    -///
    -/// When extra metadata are provided, a [`DerivableKey`] can be transformed into a
    -/// [`DescriptorKey`]: the trait [`IntoDescriptorKey`] is automatically implemented
    -/// for `(DerivableKey, DerivationPath)` and
    -/// `(DerivableKey, KeySource, DerivationPath)` tuples.
    -///
    -/// For key types that don't encode any indication about the path to use (like bip39), it's
    -/// generally recommended to implemented this trait instead of [`IntoDescriptorKey`]. The same
    -/// rules regarding script context and valid networks apply.
    -///
    -/// ## Examples
    -///
    -/// Key types that can be directly converted into an [`ExtendedPrivKey`] or
    -/// an [`ExtendedPubKey`] can implement only the required `into_extended_key()` method.
    -///
    -/// ```
    -/// use bdk::bitcoin;
    -/// use bdk::bitcoin::util::bip32;
    -/// use bdk::keys::{DerivableKey, ExtendedKey, KeyError, ScriptContext};
    -///
    -/// struct MyCustomKeyType {
    -///     key_data: bitcoin::PrivateKey,
    -///     chain_code: Vec<u8>,
    -///     network: bitcoin::Network,
    -/// }
    -///
    -/// impl<Ctx: ScriptContext> DerivableKey<Ctx> for MyCustomKeyType {
    -///     fn into_extended_key(self) -> Result<ExtendedKey<Ctx>, KeyError> {
    -///         let xprv = bip32::ExtendedPrivKey {
    -///             network: self.network,
    -///             depth: 0,
    -///             parent_fingerprint: bip32::Fingerprint::default(),
    -///             private_key: self.key_data.inner,
    -///             chain_code: bip32::ChainCode::from(self.chain_code.as_ref()),
    -///             child_number: bip32::ChildNumber::Normal { index: 0 },
    -///         };
    -///
    -///         xprv.into_extended_key()
    -///     }
    -/// }
    -/// ```
    -///
    -/// Types that don't internally encode the [`Network`](bitcoin::Network) in which they are valid need some extra
    -/// steps to override the set of valid networks, otherwise only the network specified in the
    -/// [`ExtendedPrivKey`] or [`ExtendedPubKey`] will be considered valid.
    -///
    -/// ```
    -/// use bdk::bitcoin;
    -/// use bdk::bitcoin::util::bip32;
    -/// use bdk::keys::{
    -///     any_network, DerivableKey, DescriptorKey, ExtendedKey, KeyError, ScriptContext,
    -/// };
    -///
    -/// struct MyCustomKeyType {
    -///     key_data: bitcoin::PrivateKey,
    -///     chain_code: Vec<u8>,
    -/// }
    -///
    -/// impl<Ctx: ScriptContext> DerivableKey<Ctx> for MyCustomKeyType {
    -///     fn into_extended_key(self) -> Result<ExtendedKey<Ctx>, KeyError> {
    -///         let xprv = bip32::ExtendedPrivKey {
    -///             network: bitcoin::Network::Bitcoin, // pick an arbitrary network here
    -///             depth: 0,
    -///             parent_fingerprint: bip32::Fingerprint::default(),
    -///             private_key: self.key_data.inner,
    -///             chain_code: bip32::ChainCode::from(self.chain_code.as_ref()),
    -///             child_number: bip32::ChildNumber::Normal { index: 0 },
    -///         };
    -///
    -///         xprv.into_extended_key()
    -///     }
    -///
    -///     fn into_descriptor_key(
    -///         self,
    -///         source: Option<bip32::KeySource>,
    -///         derivation_path: bip32::DerivationPath,
    -///     ) -> Result<DescriptorKey<Ctx>, KeyError> {
    -///         let descriptor_key = self
    -///             .into_extended_key()?
    -///             .into_descriptor_key(source, derivation_path)?;
    -///
    -///         // Override the set of valid networks here
    -///         Ok(descriptor_key.override_valid_networks(any_network()))
    -///     }
    -/// }
    -/// ```
    -///
    -/// [`DerivationPath`]: (bip32::DerivationPath)
    -/// [`ExtendedPrivKey`]: (bip32::ExtendedPrivKey)
    -/// [`ExtendedPubKey`]: (bip32::ExtendedPubKey)
    -pub trait DerivableKey<Ctx: ScriptContext = miniscript::Legacy>: Sized {
    -    /// Consume `self` and turn it into an [`ExtendedKey`]
    -    ///
    -    /// This can be used to get direct access to `xprv`s and `xpub`s for types that implement this trait,
    -    /// like [`Mnemonic`](bip39::Mnemonic) when the `keys-bip39` feature is enabled.
    -    #[cfg_attr(
    -        feature = "keys-bip39",
    -        doc = r##"
    +/// Trait for keys that can be derived.
    +///
    +/// When extra metadata are provided, a [`DerivableKey`] can be transformed into a
    +/// [`DescriptorKey`]: the trait [`IntoDescriptorKey`] is automatically implemented
    +/// for `(DerivableKey, DerivationPath)` and
    +/// `(DerivableKey, KeySource, DerivationPath)` tuples.
    +///
    +/// For key types that don't encode any indication about the path to use (like bip39), it's
    +/// generally recommended to implemented this trait instead of [`IntoDescriptorKey`]. The same
    +/// rules regarding script context and valid networks apply.
    +///
    +/// ## Examples
    +///
    +/// Key types that can be directly converted into an [`ExtendedPrivKey`] or
    +/// an [`ExtendedPubKey`] can implement only the required `into_extended_key()` method.
    +///
    +/// ```
    +/// use bdk::bitcoin;
    +/// use bdk::bitcoin::util::bip32;
    +/// use bdk::keys::{DerivableKey, ExtendedKey, KeyError, ScriptContext};
    +///
    +/// struct MyCustomKeyType {
    +///     key_data: bitcoin::PrivateKey,
    +///     chain_code: Vec<u8>,
    +///     network: bitcoin::Network,
    +/// }
    +///
    +/// impl<Ctx: ScriptContext> DerivableKey<Ctx> for MyCustomKeyType {
    +///     fn into_extended_key(self) -> Result<ExtendedKey<Ctx>, KeyError> {
    +///         let xprv = bip32::ExtendedPrivKey {
    +///             network: self.network,
    +///             depth: 0,
    +///             parent_fingerprint: bip32::Fingerprint::default(),
    +///             private_key: self.key_data.inner,
    +///             chain_code: bip32::ChainCode::from(self.chain_code.as_ref()),
    +///             child_number: bip32::ChildNumber::Normal { index: 0 },
    +///         };
    +///
    +///         xprv.into_extended_key()
    +///     }
    +/// }
    +/// ```
    +///
    +/// Types that don't internally encode the [`Network`](bitcoin::Network) in which they are valid need some extra
    +/// steps to override the set of valid networks, otherwise only the network specified in the
    +/// [`ExtendedPrivKey`] or [`ExtendedPubKey`] will be considered valid.
    +///
    +/// ```
    +/// use bdk::bitcoin;
    +/// use bdk::bitcoin::util::bip32;
    +/// use bdk::keys::{
    +///     any_network, DerivableKey, DescriptorKey, ExtendedKey, KeyError, ScriptContext,
    +/// };
    +///
    +/// struct MyCustomKeyType {
    +///     key_data: bitcoin::PrivateKey,
    +///     chain_code: Vec<u8>,
    +/// }
    +///
    +/// impl<Ctx: ScriptContext> DerivableKey<Ctx> for MyCustomKeyType {
    +///     fn into_extended_key(self) -> Result<ExtendedKey<Ctx>, KeyError> {
    +///         let xprv = bip32::ExtendedPrivKey {
    +///             network: bitcoin::Network::Bitcoin, // pick an arbitrary network here
    +///             depth: 0,
    +///             parent_fingerprint: bip32::Fingerprint::default(),
    +///             private_key: self.key_data.inner,
    +///             chain_code: bip32::ChainCode::from(self.chain_code.as_ref()),
    +///             child_number: bip32::ChildNumber::Normal { index: 0 },
    +///         };
    +///
    +///         xprv.into_extended_key()
    +///     }
    +///
    +///     fn into_descriptor_key(
    +///         self,
    +///         source: Option<bip32::KeySource>,
    +///         derivation_path: bip32::DerivationPath,
    +///     ) -> Result<DescriptorKey<Ctx>, KeyError> {
    +///         let descriptor_key = self
    +///             .into_extended_key()?
    +///             .into_descriptor_key(source, derivation_path)?;
    +///
    +///         // Override the set of valid networks here
    +///         Ok(descriptor_key.override_valid_networks(any_network()))
    +///     }
    +/// }
    +/// ```
    +///
    +/// [`DerivationPath`]: (bip32::DerivationPath)
    +/// [`ExtendedPrivKey`]: (bip32::ExtendedPrivKey)
    +/// [`ExtendedPubKey`]: (bip32::ExtendedPubKey)
    +pub trait DerivableKey<Ctx: ScriptContext = miniscript::Legacy>: Sized {
    +    /// Consume `self` and turn it into an [`ExtendedKey`]
    +    ///
    +    /// This can be used to get direct access to `xprv`s and `xpub`s for types that implement this trait,
    +    /// like [`Mnemonic`](bip39::Mnemonic) when the `keys-bip39` feature is enabled.
    +    #[cfg_attr(
    +        feature = "keys-bip39",
    +        doc = r##"
     ```rust
     use bdk::bitcoin::Network;
     use bdk::keys::{DerivableKey, ExtendedKey};
    @@ -1475,510 +1469,509 @@ let xkey: ExtendedKey =
     let xprv = xkey.into_xprv(Network::Bitcoin).unwrap();
     # Ok(()) }
     ```
    -"##
    -    )]
    -    fn into_extended_key(self) -> Result<ExtendedKey<Ctx>, KeyError>;
    +"##
    +    )]
    +    fn into_extended_key(self) -> Result<ExtendedKey<Ctx>, KeyError>;
     
    -    /// Consume `self` and turn it into a [`DescriptorKey`] by adding the extra metadata, such as
    -    /// key origin and derivation path
    -    fn into_descriptor_key(
    +    /// Consume `self` and turn it into a [`DescriptorKey`] by adding the extra metadata, such as
    +    /// key origin and derivation path
    +    fn into_descriptor_key(
             self,
    -        origin: Option<bip32::KeySource>,
    -        derivation_path: bip32::DerivationPath,
    -    ) -> Result<DescriptorKey<Ctx>, KeyError> {
    -        match self.into_extended_key()? {
    -            ExtendedKey::Private((xprv, _)) => DescriptorSecretKey::XPrv(DescriptorXKey {
    -                origin,
    -                xkey: xprv,
    -                derivation_path,
    -                wildcard: Wildcard::Unhardened,
    +        origin: Option<bip32::KeySource>,
    +        derivation_path: bip32::DerivationPath,
    +    ) -> Result<DescriptorKey<Ctx>, KeyError> {
    +        match self.into_extended_key()? {
    +            ExtendedKey::Private((xprv, _)) => DescriptorSecretKey::XPrv(DescriptorXKey {
    +                origin,
    +                xkey: xprv,
    +                derivation_path,
    +                wildcard: Wildcard::Unhardened,
                 })
    -            .into_descriptor_key(),
    -            ExtendedKey::Public((xpub, _)) => DescriptorPublicKey::XPub(DescriptorXKey {
    -                origin,
    -                xkey: xpub,
    -                derivation_path,
    -                wildcard: Wildcard::Unhardened,
    +            .into_descriptor_key(),
    +            ExtendedKey::Public((xpub, _)) => DescriptorPublicKey::XPub(DescriptorXKey {
    +                origin,
    +                xkey: xpub,
    +                derivation_path,
    +                wildcard: Wildcard::Unhardened,
                 })
    -            .into_descriptor_key(),
    +            .into_descriptor_key(),
             }
         }
     }
     
    -/// Identity conversion
    -impl<Ctx: ScriptContext> DerivableKey<Ctx> for ExtendedKey<Ctx> {
    -    fn into_extended_key(self) -> Result<ExtendedKey<Ctx>, KeyError> {
    +/// Identity conversion
    +impl<Ctx: ScriptContext> DerivableKey<Ctx> for ExtendedKey<Ctx> {
    +    fn into_extended_key(self) -> Result<ExtendedKey<Ctx>, KeyError> {
             Ok(self)
         }
     }
     
    -impl<Ctx: ScriptContext> DerivableKey<Ctx> for bip32::ExtendedPubKey {
    -    fn into_extended_key(self) -> Result<ExtendedKey<Ctx>, KeyError> {
    -        Ok(self.into())
    +impl<Ctx: ScriptContext> DerivableKey<Ctx> for bip32::ExtendedPubKey {
    +    fn into_extended_key(self) -> Result<ExtendedKey<Ctx>, KeyError> {
    +        Ok(self.into())
         }
     }
     
    -impl<Ctx: ScriptContext> DerivableKey<Ctx> for bip32::ExtendedPrivKey {
    -    fn into_extended_key(self) -> Result<ExtendedKey<Ctx>, KeyError> {
    -        Ok(self.into())
    +impl<Ctx: ScriptContext> DerivableKey<Ctx> for bip32::ExtendedPrivKey {
    +    fn into_extended_key(self) -> Result<ExtendedKey<Ctx>, KeyError> {
    +        Ok(self.into())
         }
     }
     
    -/// Output of a [`GeneratableKey`] key generation
    -pub struct GeneratedKey<K, Ctx: ScriptContext> {
    -    key: K,
    -    valid_networks: ValidNetworks,
    -    phantom: PhantomData<Ctx>,
    +/// Output of a [`GeneratableKey`] key generation
    +pub struct GeneratedKey<K, Ctx: ScriptContext> {
    +    key: K,
    +    valid_networks: ValidNetworks,
    +    phantom: PhantomData<Ctx>,
     }
     
    -impl<K, Ctx: ScriptContext> GeneratedKey<K, Ctx> {
    -    fn new(key: K, valid_networks: ValidNetworks) -> Self {
    -        GeneratedKey {
    -            key,
    -            valid_networks,
    -            phantom: PhantomData,
    +impl<K, Ctx: ScriptContext> GeneratedKey<K, Ctx> {
    +    fn new(key: K, valid_networks: ValidNetworks) -> Self {
    +        GeneratedKey {
    +            key,
    +            valid_networks,
    +            phantom: PhantomData,
             }
         }
     
    -    /// Consumes `self` and returns the key
    -    pub fn into_key(self) -> K {
    -        self.key
    +    /// Consumes `self` and returns the key
    +    pub fn into_key(self) -> K {
    +        self.key
         }
     }
     
    -impl<K, Ctx: ScriptContext> Deref for GeneratedKey<K, Ctx> {
    -    type Target = K;
    +impl<K, Ctx: ScriptContext> Deref for GeneratedKey<K, Ctx> {
    +    type Target = K;
     
    -    fn deref(&self) -> &Self::Target {
    -        &self.key
    +    fn deref(&self) -> &Self::Target {
    +        &self.key
         }
     }
     
    -impl<K: Clone, Ctx: ScriptContext> Clone for GeneratedKey<K, Ctx> {
    -    fn clone(&self) -> GeneratedKey<K, Ctx> {
    -        GeneratedKey {
    -            key: self.key.clone(),
    -            valid_networks: self.valid_networks.clone(),
    -            phantom: self.phantom,
    +impl<K: Clone, Ctx: ScriptContext> Clone for GeneratedKey<K, Ctx> {
    +    fn clone(&self) -> GeneratedKey<K, Ctx> {
    +        GeneratedKey {
    +            key: self.key.clone(),
    +            valid_networks: self.valid_networks.clone(),
    +            phantom: self.phantom,
             }
         }
     }
     
    -// Make generated "derivable" keys themselves "derivable". Also make sure they are assigned the
    -// right `valid_networks`.
    -impl<Ctx, K> DerivableKey<Ctx> for GeneratedKey<K, Ctx>
    -where
    -    Ctx: ScriptContext,
    -    K: DerivableKey<Ctx>,
    +// Make generated "derivable" keys themselves "derivable". Also make sure they are assigned the
    +// right `valid_networks`.
    +impl<Ctx, K> DerivableKey<Ctx> for GeneratedKey<K, Ctx>
    +where
    +    Ctx: ScriptContext,
    +    K: DerivableKey<Ctx>,
     {
    -    fn into_extended_key(self) -> Result<ExtendedKey<Ctx>, KeyError> {
    -        self.key.into_extended_key()
    +    fn into_extended_key(self) -> Result<ExtendedKey<Ctx>, KeyError> {
    +        self.key.into_extended_key()
         }
     
    -    fn into_descriptor_key(
    +    fn into_descriptor_key(
             self,
    -        origin: Option<bip32::KeySource>,
    -        derivation_path: bip32::DerivationPath,
    -    ) -> Result<DescriptorKey<Ctx>, KeyError> {
    -        let descriptor_key = self.key.into_descriptor_key(origin, derivation_path)?;
    -        Ok(descriptor_key.override_valid_networks(self.valid_networks))
    +        origin: Option<bip32::KeySource>,
    +        derivation_path: bip32::DerivationPath,
    +    ) -> Result<DescriptorKey<Ctx>, KeyError> {
    +        let descriptor_key = self.key.into_descriptor_key(origin, derivation_path)?;
    +        Ok(descriptor_key.override_valid_networks(self.valid_networks))
         }
     }
     
    -// Make generated keys directly usable in descriptors, and make sure they get assigned the right
    -// `valid_networks`.
    -impl<Ctx, K> IntoDescriptorKey<Ctx> for GeneratedKey<K, Ctx>
    -where
    -    Ctx: ScriptContext,
    -    K: IntoDescriptorKey<Ctx>,
    +// Make generated keys directly usable in descriptors, and make sure they get assigned the right
    +// `valid_networks`.
    +impl<Ctx, K> IntoDescriptorKey<Ctx> for GeneratedKey<K, Ctx>
    +where
    +    Ctx: ScriptContext,
    +    K: IntoDescriptorKey<Ctx>,
     {
    -    fn into_descriptor_key(self) -> Result<DescriptorKey<Ctx>, KeyError> {
    -        let desc_key = self.key.into_descriptor_key()?;
    -        Ok(desc_key.override_valid_networks(self.valid_networks))
    +    fn into_descriptor_key(self) -> Result<DescriptorKey<Ctx>, KeyError> {
    +        let desc_key = self.key.into_descriptor_key()?;
    +        Ok(desc_key.override_valid_networks(self.valid_networks))
         }
     }
     
    -/// 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`].
    -pub trait GeneratableKey<Ctx: ScriptContext>: Sized {
    -    /// Type specifying the amount of entropy required e.g. `[u8;32]`
    -    type Entropy: AsMut<[u8]> + Default;
    -
    -    /// Extra options required by the `generate_with_entropy`
    -    type Options;
    -    /// Returned error in case of failure
    -    type Error: std::fmt::Debug;
    -
    -    /// Generate a key given the extra options and the entropy
    -    fn generate_with_entropy(
    -        options: Self::Options,
    -        entropy: Self::Entropy,
    -    ) -> Result<GeneratedKey<Self, Ctx>, Self::Error>;
    -
    -    /// Generate a key given the options with a random entropy
    -    fn generate(options: Self::Options) -> Result<GeneratedKey<Self, Ctx>, Self::Error> {
    -        use rand::{thread_rng, Rng};
    -
    -        let mut entropy = Self::Entropy::default();
    -        thread_rng().fill(entropy.as_mut());
    -        Self::generate_with_entropy(options, entropy)
    +/// 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`].
    +pub trait GeneratableKey<Ctx: ScriptContext>: Sized {
    +    /// Type specifying the amount of entropy required e.g. `[u8;32]`
    +    type Entropy: AsMut<[u8]> + Default;
    +
    +    /// Extra options required by the `generate_with_entropy`
    +    type Options;
    +    /// Returned error in case of failure
    +    type Error: std::fmt::Debug;
    +
    +    /// Generate a key given the extra options and the entropy
    +    fn generate_with_entropy(
    +        options: Self::Options,
    +        entropy: Self::Entropy,
    +    ) -> Result<GeneratedKey<Self, Ctx>, Self::Error>;
    +
    +    /// Generate a key given the options with a random entropy
    +    fn generate(options: Self::Options) -> Result<GeneratedKey<Self, Ctx>, Self::Error> {
    +        use rand::{thread_rng, Rng};
    +
    +        let mut entropy = Self::Entropy::default();
    +        thread_rng().fill(entropy.as_mut());
    +        Self::generate_with_entropy(options, entropy)
         }
     }
     
    -/// Trait that allows generating a key with the default options
    -///
    -/// This trait is automatically implemented if the [`GeneratableKey::Options`] implements [`Default`].
    -pub trait GeneratableDefaultOptions<Ctx>: GeneratableKey<Ctx>
    -where
    -    Ctx: ScriptContext,
    -    <Self as GeneratableKey<Ctx>>::Options: Default,
    +/// Trait that allows generating a key with the default options
    +///
    +/// This trait is automatically implemented if the [`GeneratableKey::Options`] implements [`Default`].
    +pub trait GeneratableDefaultOptions<Ctx>: GeneratableKey<Ctx>
    +where
    +    Ctx: ScriptContext,
    +    <Self as GeneratableKey<Ctx>>::Options: Default,
     {
    -    /// Generate a key with the default options and a given entropy
    -    fn generate_with_entropy_default(
    -        entropy: Self::Entropy,
    -    ) -> Result<GeneratedKey<Self, Ctx>, Self::Error> {
    -        Self::generate_with_entropy(Default::default(), entropy)
    +    /// Generate a key with the default options and a given entropy
    +    fn generate_with_entropy_default(
    +        entropy: Self::Entropy,
    +    ) -> Result<GeneratedKey<Self, Ctx>, Self::Error> {
    +        Self::generate_with_entropy(Default::default(), entropy)
         }
     
    -    /// Generate a key with the default options and a random entropy
    -    fn generate_default() -> Result<GeneratedKey<Self, Ctx>, Self::Error> {
    -        Self::generate(Default::default())
    +    /// Generate a key with the default options and a random entropy
    +    fn generate_default() -> Result<GeneratedKey<Self, Ctx>, Self::Error> {
    +        Self::generate(Default::default())
         }
     }
     
    -/// Automatic implementation of [`GeneratableDefaultOptions`] for [`GeneratableKey`]s where
    -/// `Options` implements `Default`
    -impl<Ctx, K> GeneratableDefaultOptions<Ctx> for K
    -where
    -    Ctx: ScriptContext,
    -    K: GeneratableKey<Ctx>,
    -    <K as GeneratableKey<Ctx>>::Options: Default,
    +/// Automatic implementation of [`GeneratableDefaultOptions`] for [`GeneratableKey`]s where
    +/// `Options` implements `Default`
    +impl<Ctx, K> GeneratableDefaultOptions<Ctx> for K
    +where
    +    Ctx: ScriptContext,
    +    K: GeneratableKey<Ctx>,
    +    <K as GeneratableKey<Ctx>>::Options: Default,
     {
     }
     
    -impl<Ctx: ScriptContext> GeneratableKey<Ctx> for bip32::ExtendedPrivKey {
    -    type Entropy = [u8; 32];
    +impl<Ctx: ScriptContext> GeneratableKey<Ctx> for bip32::ExtendedPrivKey {
    +    type Entropy = [u8; 32];
     
    -    type Options = ();
    -    type Error = bip32::Error;
    +    type Options = ();
    +    type Error = bip32::Error;
     
    -    fn generate_with_entropy(
    -        _: Self::Options,
    -        entropy: Self::Entropy,
    -    ) -> Result<GeneratedKey<Self, Ctx>, Self::Error> {
    -        // pick a arbitrary network here, but say that we support all of them
    -        let xprv = bip32::ExtendedPrivKey::new_master(Network::Bitcoin, entropy.as_ref())?;
    -        Ok(GeneratedKey::new(xprv, any_network()))
    +    fn generate_with_entropy(
    +        _: Self::Options,
    +        entropy: Self::Entropy,
    +    ) -> Result<GeneratedKey<Self, Ctx>, Self::Error> {
    +        // pick a arbitrary network here, but say that we support all of them
    +        let xprv = bip32::ExtendedPrivKey::new_master(Network::Bitcoin, entropy.as_ref())?;
    +        Ok(GeneratedKey::new(xprv, any_network()))
         }
     }
     
    -/// Options for generating a [`PrivateKey`]
    -///
    -/// Defaults to creating compressed keys, which save on-chain bytes and fees
    -#[derive(Debug, Copy, Clone)]
    -pub struct PrivateKeyGenerateOptions {
    -    /// Whether the generated key should be "compressed" or not
    -    pub compressed: bool,
    +/// Options for generating a [`PrivateKey`]
    +///
    +/// Defaults to creating compressed keys, which save on-chain bytes and fees
    +#[derive(Debug, Copy, Clone)]
    +pub struct PrivateKeyGenerateOptions {
    +    /// Whether the generated key should be "compressed" or not
    +    pub compressed: bool,
     }
     
    -impl Default for PrivateKeyGenerateOptions {
    -    fn default() -> Self {
    -        PrivateKeyGenerateOptions { compressed: true }
    +impl Default for PrivateKeyGenerateOptions {
    +    fn default() -> Self {
    +        PrivateKeyGenerateOptions { compressed: true }
         }
     }
     
    -impl<Ctx: ScriptContext> GeneratableKey<Ctx> for PrivateKey {
    -    type Entropy = [u8; secp256k1::constants::SECRET_KEY_SIZE];
    -
    -    type Options = PrivateKeyGenerateOptions;
    -    type Error = bip32::Error;
    -
    -    fn generate_with_entropy(
    -        options: Self::Options,
    -        entropy: Self::Entropy,
    -    ) -> Result<GeneratedKey<Self, Ctx>, Self::Error> {
    -        // pick a arbitrary network here, but say that we support all of them
    -        let inner = secp256k1::SecretKey::from_slice(&entropy)?;
    -        let private_key = PrivateKey {
    -            compressed: options.compressed,
    -            network: Network::Bitcoin,
    -            inner,
    +impl<Ctx: ScriptContext> GeneratableKey<Ctx> for PrivateKey {
    +    type Entropy = [u8; secp256k1::constants::SECRET_KEY_SIZE];
    +
    +    type Options = PrivateKeyGenerateOptions;
    +    type Error = bip32::Error;
    +
    +    fn generate_with_entropy(
    +        options: Self::Options,
    +        entropy: Self::Entropy,
    +    ) -> Result<GeneratedKey<Self, Ctx>, Self::Error> {
    +        // pick a arbitrary network here, but say that we support all of them
    +        let inner = secp256k1::SecretKey::from_slice(&entropy)?;
    +        let private_key = PrivateKey {
    +            compressed: options.compressed,
    +            network: Network::Bitcoin,
    +            inner,
             };
     
    -        Ok(GeneratedKey::new(private_key, any_network()))
    +        Ok(GeneratedKey::new(private_key, any_network()))
         }
     }
     
    -impl<Ctx: ScriptContext, T: DerivableKey<Ctx>> IntoDescriptorKey<Ctx>
    -    for (T, bip32::DerivationPath)
    +impl<Ctx: ScriptContext, T: DerivableKey<Ctx>> IntoDescriptorKey<Ctx>
    +    for (T, bip32::DerivationPath)
     {
    -    fn into_descriptor_key(self) -> Result<DescriptorKey<Ctx>, KeyError> {
    -        self.0.into_descriptor_key(None, self.1)
    +    fn into_descriptor_key(self) -> Result<DescriptorKey<Ctx>, KeyError> {
    +        self.0.into_descriptor_key(None, self.1)
         }
     }
     
    -impl<Ctx: ScriptContext, T: DerivableKey<Ctx>> IntoDescriptorKey<Ctx>
    -    for (T, bip32::KeySource, bip32::DerivationPath)
    +impl<Ctx: ScriptContext, T: DerivableKey<Ctx>> IntoDescriptorKey<Ctx>
    +    for (T, bip32::KeySource, bip32::DerivationPath)
     {
    -    fn into_descriptor_key(self) -> Result<DescriptorKey<Ctx>, KeyError> {
    -        self.0.into_descriptor_key(Some(self.1), self.2)
    +    fn into_descriptor_key(self) -> Result<DescriptorKey<Ctx>, KeyError> {
    +        self.0.into_descriptor_key(Some(self.1), self.2)
         }
     }
     
    -fn expand_multi_keys<Pk: IntoDescriptorKey<Ctx>, Ctx: ScriptContext>(
    -    pks: Vec<Pk>,
    -    secp: &SecpCtx,
    -) -> Result<(Vec<DescriptorPublicKey>, KeyMap, ValidNetworks), KeyError> {
    -    let (pks, key_maps_networks): (Vec<_>, Vec<_>) = pks
    -        .into_iter()
    -        .map(|key| key.into_descriptor_key()?.extract(secp))
    -        .collect::<Result<Vec<_>, _>>()?
    -        .into_iter()
    -        .map(|(a, b, c)| (a, (b, c)))
    -        .unzip();
    -
    -    let (key_map, valid_networks) = key_maps_networks.into_iter().fold(
    -        (KeyMap::default(), any_network()),
    -        |(mut keys_acc, net_acc), (key, net)| {
    -            keys_acc.extend(key.into_iter());
    -            let net_acc = merge_networks(&net_acc, &net);
    -
    -            (keys_acc, net_acc)
    +fn expand_multi_keys<Pk: IntoDescriptorKey<Ctx>, Ctx: ScriptContext>(
    +    pks: Vec<Pk>,
    +    secp: &SecpCtx,
    +) -> Result<(Vec<DescriptorPublicKey>, KeyMap, ValidNetworks), KeyError> {
    +    let (pks, key_maps_networks): (Vec<_>, Vec<_>) = pks
    +        .into_iter()
    +        .map(|key| key.into_descriptor_key()?.extract(secp))
    +        .collect::<Result<Vec<_>, _>>()?
    +        .into_iter()
    +        .map(|(a, b, c)| (a, (b, c)))
    +        .unzip();
    +
    +    let (key_map, valid_networks) = key_maps_networks.into_iter().fold(
    +        (KeyMap::default(), any_network()),
    +        |(mut keys_acc, net_acc), (key, net)| {
    +            keys_acc.extend(key.into_iter());
    +            let net_acc = merge_networks(&net_acc, &net);
    +
    +            (keys_acc, net_acc)
             },
         );
     
    -    Ok((pks, key_map, valid_networks))
    +    Ok((pks, key_map, valid_networks))
     }
     
    -// Used internally by `bdk::fragment!` to build `pk_k()` fragments
    -#[doc(hidden)]
    -pub fn make_pk<Pk: IntoDescriptorKey<Ctx>, Ctx: ScriptContext>(
    -    descriptor_key: Pk,
    -    secp: &SecpCtx,
    -) -> Result<(Miniscript<DescriptorPublicKey, Ctx>, KeyMap, ValidNetworks), DescriptorError> {
    -    let (key, key_map, valid_networks) = descriptor_key.into_descriptor_key()?.extract(secp)?;
    -    let minisc = Miniscript::from_ast(Terminal::PkK(key))?;
    +// Used internally by `bdk::fragment!` to build `pk_k()` fragments
    +#[doc(hidden)]
    +pub fn make_pk<Pk: IntoDescriptorKey<Ctx>, Ctx: ScriptContext>(
    +    descriptor_key: Pk,
    +    secp: &SecpCtx,
    +) -> Result<(Miniscript<DescriptorPublicKey, Ctx>, KeyMap, ValidNetworks), DescriptorError> {
    +    let (key, key_map, valid_networks) = descriptor_key.into_descriptor_key()?.extract(secp)?;
    +    let minisc = Miniscript::from_ast(Terminal::PkK(key))?;
     
    -    minisc.check_miniscript()?;
    +    minisc.check_miniscript()?;
     
    -    Ok((minisc, key_map, valid_networks))
    +    Ok((minisc, key_map, valid_networks))
     }
     
    -// Used internally by `bdk::fragment!` to build `pk_h()` fragments
    -#[doc(hidden)]
    -pub fn make_pkh<Pk: IntoDescriptorKey<Ctx>, Ctx: ScriptContext>(
    -    descriptor_key: Pk,
    -    secp: &SecpCtx,
    -) -> Result<(Miniscript<DescriptorPublicKey, Ctx>, KeyMap, ValidNetworks), DescriptorError> {
    -    let (key, key_map, valid_networks) = descriptor_key.into_descriptor_key()?.extract(secp)?;
    -    let minisc = Miniscript::from_ast(Terminal::PkH(key))?;
    +// Used internally by `bdk::fragment!` to build `pk_h()` fragments
    +#[doc(hidden)]
    +pub fn make_pkh<Pk: IntoDescriptorKey<Ctx>, Ctx: ScriptContext>(
    +    descriptor_key: Pk,
    +    secp: &SecpCtx,
    +) -> Result<(Miniscript<DescriptorPublicKey, Ctx>, KeyMap, ValidNetworks), DescriptorError> {
    +    let (key, key_map, valid_networks) = descriptor_key.into_descriptor_key()?.extract(secp)?;
    +    let minisc = Miniscript::from_ast(Terminal::PkH(key))?;
     
    -    minisc.check_miniscript()?;
    +    minisc.check_miniscript()?;
     
    -    Ok((minisc, key_map, valid_networks))
    +    Ok((minisc, key_map, valid_networks))
     }
     
    -// Used internally by `bdk::fragment!` to build `multi()` fragments
    -#[doc(hidden)]
    -pub fn make_multi<
    -    Pk: IntoDescriptorKey<Ctx>,
    -    Ctx: ScriptContext,
    -    V: Fn(usize, Vec<DescriptorPublicKey>) -> Terminal<DescriptorPublicKey, Ctx>,
    ->(
    -    thresh: usize,
    -    variant: V,
    -    pks: Vec<Pk>,
    -    secp: &SecpCtx,
    -) -> Result<(Miniscript<DescriptorPublicKey, Ctx>, KeyMap, ValidNetworks), DescriptorError> {
    -    let (pks, key_map, valid_networks) = expand_multi_keys(pks, secp)?;
    -    let minisc = Miniscript::from_ast(variant(thresh, pks))?;
    -
    -    minisc.check_miniscript()?;
    -
    -    Ok((minisc, key_map, valid_networks))
    +// Used internally by `bdk::fragment!` to build `multi()` fragments
    +#[doc(hidden)]
    +pub fn make_multi<
    +    Pk: IntoDescriptorKey<Ctx>,
    +    Ctx: ScriptContext,
    +    V: Fn(usize, Vec<DescriptorPublicKey>) -> Terminal<DescriptorPublicKey, Ctx>,
    +>(
    +    thresh: usize,
    +    variant: V,
    +    pks: Vec<Pk>,
    +    secp: &SecpCtx,
    +) -> Result<(Miniscript<DescriptorPublicKey, Ctx>, KeyMap, ValidNetworks), DescriptorError> {
    +    let (pks, key_map, valid_networks) = expand_multi_keys(pks, secp)?;
    +    let minisc = Miniscript::from_ast(variant(thresh, pks))?;
    +
    +    minisc.check_miniscript()?;
    +
    +    Ok((minisc, key_map, valid_networks))
     }
     
    -// Used internally by `bdk::descriptor!` to build `sortedmulti()` fragments
    -#[doc(hidden)]
    -pub fn make_sortedmulti<Pk, Ctx, F>(
    -    thresh: usize,
    -    pks: Vec<Pk>,
    -    build_desc: F,
    -    secp: &SecpCtx,
    -) -> Result<(Descriptor<DescriptorPublicKey>, KeyMap, ValidNetworks), DescriptorError>
    -where
    -    Pk: IntoDescriptorKey<Ctx>,
    -    Ctx: ScriptContext,
    -    F: Fn(
    -        usize,
    -        Vec<DescriptorPublicKey>,
    -    ) -> Result<(Descriptor<DescriptorPublicKey>, PhantomData<Ctx>), DescriptorError>,
    +// Used internally by `bdk::descriptor!` to build `sortedmulti()` fragments
    +#[doc(hidden)]
    +pub fn make_sortedmulti<Pk, Ctx, F>(
    +    thresh: usize,
    +    pks: Vec<Pk>,
    +    build_desc: F,
    +    secp: &SecpCtx,
    +) -> Result<(Descriptor<DescriptorPublicKey>, KeyMap, ValidNetworks), DescriptorError>
    +where
    +    Pk: IntoDescriptorKey<Ctx>,
    +    Ctx: ScriptContext,
    +    F: Fn(
    +        usize,
    +        Vec<DescriptorPublicKey>,
    +    ) -> Result<(Descriptor<DescriptorPublicKey>, PhantomData<Ctx>), DescriptorError>,
     {
    -    let (pks, key_map, valid_networks) = expand_multi_keys(pks, secp)?;
    -    let descriptor = build_desc(thresh, pks)?.0;
    +    let (pks, key_map, valid_networks) = expand_multi_keys(pks, secp)?;
    +    let descriptor = build_desc(thresh, pks)?.0;
     
    -    Ok((descriptor, key_map, valid_networks))
    +    Ok((descriptor, key_map, valid_networks))
     }
     
    -/// The "identity" conversion is used internally by some `bdk::fragment`s
    -impl<Ctx: ScriptContext> IntoDescriptorKey<Ctx> for DescriptorKey<Ctx> {
    -    fn into_descriptor_key(self) -> Result<DescriptorKey<Ctx>, KeyError> {
    +/// The "identity" conversion is used internally by some `bdk::fragment`s
    +impl<Ctx: ScriptContext> IntoDescriptorKey<Ctx> for DescriptorKey<Ctx> {
    +    fn into_descriptor_key(self) -> Result<DescriptorKey<Ctx>, KeyError> {
             Ok(self)
         }
     }
     
    -impl<Ctx: ScriptContext> IntoDescriptorKey<Ctx> for DescriptorPublicKey {
    -    fn into_descriptor_key(self) -> Result<DescriptorKey<Ctx>, KeyError> {
    -        let networks = match self {
    -            DescriptorPublicKey::Single(_) => any_network(),
    -            DescriptorPublicKey::XPub(DescriptorXKey { xkey, .. })
    -                if xkey.network == Network::Bitcoin =>
    +impl<Ctx: ScriptContext> IntoDescriptorKey<Ctx> for DescriptorPublicKey {
    +    fn into_descriptor_key(self) -> Result<DescriptorKey<Ctx>, KeyError> {
    +        let networks = match self {
    +            DescriptorPublicKey::Single(_) => any_network(),
    +            DescriptorPublicKey::XPub(DescriptorXKey { xkey, .. })
    +                if xkey.network == Network::Bitcoin =>
                 {
    -                mainnet_network()
    +                mainnet_network()
                 }
    -            _ => test_networks(),
    +            _ => test_networks(),
             };
     
    -        Ok(DescriptorKey::from_public(self, networks))
    +        Ok(DescriptorKey::from_public(self, networks))
         }
     }
     
    -impl<Ctx: ScriptContext> IntoDescriptorKey<Ctx> for PublicKey {
    -    fn into_descriptor_key(self) -> Result<DescriptorKey<Ctx>, KeyError> {
    -        DescriptorPublicKey::Single(SinglePub {
    -            key: SinglePubKey::FullKey(self),
    -            origin: None,
    +impl<Ctx: ScriptContext> IntoDescriptorKey<Ctx> for PublicKey {
    +    fn into_descriptor_key(self) -> Result<DescriptorKey<Ctx>, KeyError> {
    +        DescriptorPublicKey::Single(SinglePub {
    +            key: SinglePubKey::FullKey(self),
    +            origin: None,
             })
    -        .into_descriptor_key()
    +        .into_descriptor_key()
         }
     }
     
    -impl<Ctx: ScriptContext> IntoDescriptorKey<Ctx> for XOnlyPublicKey {
    -    fn into_descriptor_key(self) -> Result<DescriptorKey<Ctx>, KeyError> {
    -        DescriptorPublicKey::Single(SinglePub {
    -            key: SinglePubKey::XOnly(self),
    -            origin: None,
    +impl<Ctx: ScriptContext> IntoDescriptorKey<Ctx> for XOnlyPublicKey {
    +    fn into_descriptor_key(self) -> Result<DescriptorKey<Ctx>, KeyError> {
    +        DescriptorPublicKey::Single(SinglePub {
    +            key: SinglePubKey::XOnly(self),
    +            origin: None,
             })
    -        .into_descriptor_key()
    +        .into_descriptor_key()
         }
     }
     
    -impl<Ctx: ScriptContext> IntoDescriptorKey<Ctx> for DescriptorSecretKey {
    -    fn into_descriptor_key(self) -> Result<DescriptorKey<Ctx>, KeyError> {
    -        let networks = match &self {
    -            DescriptorSecretKey::Single(sk) if sk.key.network == Network::Bitcoin => {
    -                mainnet_network()
    +impl<Ctx: ScriptContext> IntoDescriptorKey<Ctx> for DescriptorSecretKey {
    +    fn into_descriptor_key(self) -> Result<DescriptorKey<Ctx>, KeyError> {
    +        let networks = match &self {
    +            DescriptorSecretKey::Single(sk) if sk.key.network == Network::Bitcoin => {
    +                mainnet_network()
                 }
    -            DescriptorSecretKey::XPrv(DescriptorXKey { xkey, .. })
    -                if xkey.network == Network::Bitcoin =>
    +            DescriptorSecretKey::XPrv(DescriptorXKey { xkey, .. })
    +                if xkey.network == Network::Bitcoin =>
                 {
    -                mainnet_network()
    +                mainnet_network()
                 }
    -            _ => test_networks(),
    +            _ => test_networks(),
             };
     
    -        Ok(DescriptorKey::from_secret(self, networks))
    +        Ok(DescriptorKey::from_secret(self, networks))
         }
     }
     
    -impl<Ctx: ScriptContext> IntoDescriptorKey<Ctx> for &'_ str {
    -    fn into_descriptor_key(self) -> Result<DescriptorKey<Ctx>, KeyError> {
    -        DescriptorSecretKey::from_str(self)
    -            .map_err(|e| KeyError::Message(e.to_string()))?
    -            .into_descriptor_key()
    +impl<Ctx: ScriptContext> IntoDescriptorKey<Ctx> for &'_ str {
    +    fn into_descriptor_key(self) -> Result<DescriptorKey<Ctx>, KeyError> {
    +        DescriptorSecretKey::from_str(self)
    +            .map_err(|e| KeyError::Message(e.to_string()))?
    +            .into_descriptor_key()
         }
     }
     
    -impl<Ctx: ScriptContext> IntoDescriptorKey<Ctx> for PrivateKey {
    -    fn into_descriptor_key(self) -> Result<DescriptorKey<Ctx>, KeyError> {
    -        DescriptorSecretKey::Single(SinglePriv {
    -            key: self,
    -            origin: None,
    +impl<Ctx: ScriptContext> IntoDescriptorKey<Ctx> for PrivateKey {
    +    fn into_descriptor_key(self) -> Result<DescriptorKey<Ctx>, KeyError> {
    +        DescriptorSecretKey::Single(SinglePriv {
    +            key: self,
    +            origin: None,
             })
    -        .into_descriptor_key()
    +        .into_descriptor_key()
         }
     }
     
    -/// Errors thrown while working with [`keys`](crate::keys)
    -#[derive(Debug)]
    -pub enum KeyError {
    -    /// The key cannot exist in the given script context
    -    InvalidScriptContext,
    -    /// The key is not valid for the given network
    -    InvalidNetwork,
    -    /// The key has an invalid checksum
    -    InvalidChecksum,
    -
    -    /// Custom error message
    -    Message(String),
    -
    -    /// BIP32 error
    -    Bip32(bitcoin::util::bip32::Error),
    -    /// Miniscript error
    -    Miniscript(miniscript::Error),
    +/// Errors thrown while working with [`keys`](crate::keys)
    +#[derive(Debug)]
    +pub enum KeyError {
    +    /// The key cannot exist in the given script context
    +    InvalidScriptContext,
    +    /// The key is not valid for the given network
    +    InvalidNetwork,
    +    /// The key has an invalid checksum
    +    InvalidChecksum,
    +
    +    /// Custom error message
    +    Message(String),
    +
    +    /// BIP32 error
    +    Bip32(bitcoin::util::bip32::Error),
    +    /// Miniscript error
    +    Miniscript(miniscript::Error),
     }
     
    -impl_error!(miniscript::Error, Miniscript, KeyError);
    -impl_error!(bitcoin::util::bip32::Error, Bip32, KeyError);
    +impl_error!(miniscript::Error, Miniscript, KeyError);
    +impl_error!(bitcoin::util::bip32::Error, Bip32, KeyError);
     
    -impl std::fmt::Display for KeyError {
    -    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
    -        write!(f, "{:?}", self)
    +impl std::fmt::Display for KeyError {
    +    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
    +        write!(f, "{:?}", self)
         }
     }
     
    -impl std::error::Error for KeyError {}
    +impl std::error::Error for KeyError {}
     
    -#[cfg(test)]
    -pub mod test {
    -    use bitcoin::util::bip32;
    +#[cfg(test)]
    +pub mod test {
    +    use bitcoin::util::bip32;
     
    -    use super::*;
    +    use super::*;
     
    -    pub const TEST_ENTROPY: [u8; 32] = [0xAA; 32];
    +    pub const TEST_ENTROPY: [u8; 32] = [0xAA; 32];
     
    -    #[test]
    -    fn test_keys_generate_xprv() {
    -        let generated_xprv: GeneratedKey<_, miniscript::Segwitv0> =
    -            bip32::ExtendedPrivKey::generate_with_entropy_default(TEST_ENTROPY).unwrap();
    +    #[test]
    +    fn test_keys_generate_xprv() {
    +        let generated_xprv: GeneratedKey<_, miniscript::Segwitv0> =
    +            bip32::ExtendedPrivKey::generate_with_entropy_default(TEST_ENTROPY).unwrap();
     
    -        assert_eq!(generated_xprv.valid_networks, any_network());
    -        assert_eq!(generated_xprv.to_string(), "xprv9s21ZrQH143K4Xr1cJyqTvuL2FWR8eicgY9boWqMBv8MDVUZ65AXHnzBrK1nyomu6wdcabRgmGTaAKawvhAno1V5FowGpTLVx3jxzE5uk3Q");
    +        assert_eq!(generated_xprv.valid_networks, any_network());
    +        assert_eq!(generated_xprv.to_string(), "xprv9s21ZrQH143K4Xr1cJyqTvuL2FWR8eicgY9boWqMBv8MDVUZ65AXHnzBrK1nyomu6wdcabRgmGTaAKawvhAno1V5FowGpTLVx3jxzE5uk3Q");
         }
     
    -    #[test]
    -    fn test_keys_generate_wif() {
    -        let generated_wif: GeneratedKey<_, miniscript::Segwitv0> =
    -            bitcoin::PrivateKey::generate_with_entropy_default(TEST_ENTROPY).unwrap();
    +    #[test]
    +    fn test_keys_generate_wif() {
    +        let generated_wif: GeneratedKey<_, miniscript::Segwitv0> =
    +            bitcoin::PrivateKey::generate_with_entropy_default(TEST_ENTROPY).unwrap();
     
    -        assert_eq!(generated_wif.valid_networks, any_network());
    +        assert_eq!(generated_wif.valid_networks, any_network());
             assert_eq!(
    -            generated_wif.to_string(),
    -            "L2wTu6hQrnDMiFNWA5na6jB12ErGQqtXwqpSL7aWquJaZG8Ai3ch"
    -        );
    +            generated_wif.to_string(),
    +            "L2wTu6hQrnDMiFNWA5na6jB12ErGQqtXwqpSL7aWquJaZG8Ai3ch"
    +        );
         }
     
    -    #[cfg(feature = "keys-bip39")]
    -    #[test]
    -    fn test_keys_wif_network_bip39() {
    -        let xkey: ExtendedKey = bip39::Mnemonic::parse_in(
    -            bip39::Language::English,
    +    #[cfg(feature = "keys-bip39")]
    +    #[test]
    +    fn test_keys_wif_network_bip39() {
    +        let xkey: ExtendedKey = bip39::Mnemonic::parse_in(
    +            bip39::Language::English,
                 "jelly crash boy whisper mouse ecology tuna soccer memory million news short",
             )
    -        .unwrap()
    -        .into_extended_key()
    -        .unwrap();
    -        let xprv = xkey.into_xprv(Network::Testnet).unwrap();
    +        .unwrap()
    +        .into_extended_key()
    +        .unwrap();
    +        let xprv = xkey.into_xprv(Network::Testnet).unwrap();
     
    -        assert_eq!(xprv.network, Network::Testnet);
    +        assert_eq!(xprv.network, Network::Testnet);
         }
     }
     
    -
    - \ No newline at end of file +
    \ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/src/bdk/lib.rs.html b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/src/bdk/lib.rs.html index 7bbd293572..ccb66ecff8 100644 --- a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/src/bdk/lib.rs.html +++ b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/src/bdk/lib.rs.html @@ -1,344 +1,338 @@ -lib.rs - source - -
      1
    -  2
    -  3
    -  4
    -  5
    -  6
    -  7
    -  8
    -  9
    - 10
    - 11
    - 12
    - 13
    - 14
    - 15
    - 16
    - 17
    - 18
    - 19
    - 20
    - 21
    - 22
    - 23
    - 24
    - 25
    - 26
    - 27
    - 28
    - 29
    - 30
    - 31
    - 32
    - 33
    - 34
    - 35
    - 36
    - 37
    - 38
    - 39
    - 40
    - 41
    - 42
    - 43
    - 44
    - 45
    - 46
    - 47
    - 48
    - 49
    - 50
    - 51
    - 52
    - 53
    - 54
    - 55
    - 56
    - 57
    - 58
    - 59
    - 60
    - 61
    - 62
    - 63
    - 64
    - 65
    - 66
    - 67
    - 68
    - 69
    - 70
    - 71
    - 72
    - 73
    - 74
    - 75
    - 76
    - 77
    - 78
    - 79
    - 80
    - 81
    - 82
    - 83
    - 84
    - 85
    - 86
    - 87
    - 88
    - 89
    - 90
    - 91
    - 92
    - 93
    - 94
    - 95
    - 96
    - 97
    - 98
    - 99
    -100
    -101
    -102
    -103
    -104
    -105
    -106
    -107
    -108
    -109
    -110
    -111
    -112
    -113
    -114
    -115
    -116
    -117
    -118
    -119
    -120
    -121
    -122
    -123
    -124
    -125
    -126
    -127
    -128
    -129
    -130
    -131
    -132
    -133
    -134
    -135
    -136
    -137
    -138
    -139
    -140
    -141
    -142
    -143
    -144
    -145
    -146
    -147
    -148
    -149
    -150
    -151
    -152
    -153
    -154
    -155
    -156
    -157
    -158
    -159
    -160
    -161
    -162
    -163
    -164
    -165
    -166
    -167
    -168
    -169
    -170
    -171
    -172
    -173
    -174
    -175
    -176
    -177
    -178
    -179
    -180
    -181
    -182
    -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
    -245
    -246
    -247
    -248
    -249
    -250
    -251
    -252
    -253
    -254
    -255
    -256
    -257
    -258
    -259
    -260
    -261
    -262
    -263
    -264
    -265
    -266
    -267
    -268
    -269
    -270
    -271
    -272
    -273
    -274
    -275
    -276
    -277
    -278
    -279
    -280
    -281
    -282
    -283
    -284
    -285
    -
    // Bitcoin Dev Kit
    -// Written in 2020 by Alekos Filini <alekos.filini@gmail.com>
    -//
    -// Copyright (c) 2020-2021 Bitcoin Dev Kit Developers
    -//
    -// This file is licensed under the Apache License, Version 2.0 <LICENSE-APACHE
    -// or http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
    -// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your option.
    -// You may not use this file except in accordance with one or both of these
    -// licenses.
    +lib.rs - source
    1
    +2
    +3
    +4
    +5
    +6
    +7
    +8
    +9
    +10
    +11
    +12
    +13
    +14
    +15
    +16
    +17
    +18
    +19
    +20
    +21
    +22
    +23
    +24
    +25
    +26
    +27
    +28
    +29
    +30
    +31
    +32
    +33
    +34
    +35
    +36
    +37
    +38
    +39
    +40
    +41
    +42
    +43
    +44
    +45
    +46
    +47
    +48
    +49
    +50
    +51
    +52
    +53
    +54
    +55
    +56
    +57
    +58
    +59
    +60
    +61
    +62
    +63
    +64
    +65
    +66
    +67
    +68
    +69
    +70
    +71
    +72
    +73
    +74
    +75
    +76
    +77
    +78
    +79
    +80
    +81
    +82
    +83
    +84
    +85
    +86
    +87
    +88
    +89
    +90
    +91
    +92
    +93
    +94
    +95
    +96
    +97
    +98
    +99
    +100
    +101
    +102
    +103
    +104
    +105
    +106
    +107
    +108
    +109
    +110
    +111
    +112
    +113
    +114
    +115
    +116
    +117
    +118
    +119
    +120
    +121
    +122
    +123
    +124
    +125
    +126
    +127
    +128
    +129
    +130
    +131
    +132
    +133
    +134
    +135
    +136
    +137
    +138
    +139
    +140
    +141
    +142
    +143
    +144
    +145
    +146
    +147
    +148
    +149
    +150
    +151
    +152
    +153
    +154
    +155
    +156
    +157
    +158
    +159
    +160
    +161
    +162
    +163
    +164
    +165
    +166
    +167
    +168
    +169
    +170
    +171
    +172
    +173
    +174
    +175
    +176
    +177
    +178
    +179
    +180
    +181
    +182
    +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
    +245
    +246
    +247
    +248
    +249
    +250
    +251
    +252
    +253
    +254
    +255
    +256
    +257
    +258
    +259
    +260
    +261
    +262
    +263
    +264
    +265
    +266
    +267
    +268
    +269
    +270
    +271
    +272
    +273
    +274
    +275
    +276
    +277
    +278
    +279
    +280
    +281
    +282
    +283
    +284
    +285
    +
    // Bitcoin Dev Kit
    +// Written in 2020 by Alekos Filini <alekos.filini@gmail.com>
    +//
    +// Copyright (c) 2020-2021 Bitcoin Dev Kit Developers
    +//
    +// This file is licensed under the Apache License, Version 2.0 <LICENSE-APACHE
    +// or http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
    +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your option.
    +// You may not use this file except in accordance with one or both of these
    +// licenses.
     
    -// rustdoc will warn if there are missing docs
    -#![warn(missing_docs)]
    -// only enables the `doc_cfg` feature when
    -// the `docsrs` configuration attribute is defined
    -#![cfg_attr(docsrs, feature(doc_cfg))]
    -#![cfg_attr(
    -    docsrs,
    -    doc(html_logo_url = "https://github.com/bitcoindevkit/bdk/raw/master/static/bdk.png")
    -)]
    +// rustdoc will warn if there are missing docs
    +#![warn(missing_docs)]
    +// only enables the `doc_cfg` feature when
    +// the `docsrs` configuration attribute is defined
    +#![cfg_attr(docsrs, feature(doc_cfg))]
    +#![cfg_attr(
    +    docsrs,
    +    doc(html_logo_url = "https://github.com/bitcoindevkit/bdk/raw/master/static/bdk.png")
    +)]
     
    -//! A modern, lightweight, descriptor-based wallet library written in Rust.
    -//!
    -//! # About
    -//!
    -//! The BDK library aims to be the core building block for Bitcoin wallets of any kind.
    -//!
    -//! * It uses [Miniscript](https://github.com/rust-bitcoin/rust-miniscript) to support descriptors with generalized conditions. This exact same library can be used to build
    -//!   single-sig wallets, multisigs, timelocked contracts and more.
    -//! * It supports multiple blockchain backends and databases, allowing developers to choose exactly what's right for their projects.
    -//! * It is built to be cross-platform: the core logic works on desktop, mobile, and even WebAssembly.
    -//! * It is very easy to extend: developers can implement customized logic for blockchain backends, databases, signers, coin selection, and more, without having to fork and modify this library.
    -//!
    -//! # A Tour of BDK
    -//!
    -//! BDK consists of a number of modules that provide a range of functionality
    -//! essential for implementing descriptor based Bitcoin wallet applications in Rust. In this
    -//! section, we will take a brief tour of BDK, summarizing the major APIs and
    -//! their uses.
    -//!
    -//! The easiest way to get started is to add bdk to your dependencies with the default features.
    -//! The default features include a simple key-value database ([`sled`](sled)) to cache
    -//! blockchain data and an [electrum](https://docs.rs/electrum-client/) blockchain client to
    -//! interact with the bitcoin P2P network.
    -//!
    -//! # Examples
    -#![cfg_attr(
    -    feature = "electrum",
    -    doc = r##"
    +//! A modern, lightweight, descriptor-based wallet library written in Rust.
    +//!
    +//! # About
    +//!
    +//! The BDK library aims to be the core building block for Bitcoin wallets of any kind.
    +//!
    +//! * It uses [Miniscript](https://github.com/rust-bitcoin/rust-miniscript) to support descriptors with generalized conditions. This exact same library can be used to build
    +//!   single-sig wallets, multisigs, timelocked contracts and more.
    +//! * It supports multiple blockchain backends and databases, allowing developers to choose exactly what's right for their projects.
    +//! * It is built to be cross-platform: the core logic works on desktop, mobile, and even WebAssembly.
    +//! * It is very easy to extend: developers can implement customized logic for blockchain backends, databases, signers, coin selection, and more, without having to fork and modify this library.
    +//!
    +//! # A Tour of BDK
    +//!
    +//! BDK consists of a number of modules that provide a range of functionality
    +//! essential for implementing descriptor based Bitcoin wallet applications in Rust. In this
    +//! section, we will take a brief tour of BDK, summarizing the major APIs and
    +//! their uses.
    +//!
    +//! The easiest way to get started is to add bdk to your dependencies with the default features.
    +//! The default features include a simple key-value database ([`sled`](sled)) to cache
    +//! blockchain data and an [electrum](https://docs.rs/electrum-client/) blockchain client to
    +//! interact with the bitcoin P2P network.
    +//!
    +//! # Examples
    +#![cfg_attr(
    +    feature = "electrum",
    +    doc = r##"
     ## Sync the balance of a descriptor
     
     ```no_run
    @@ -364,35 +358,35 @@ fn main() -> Result<(), bdk::Error> {
         Ok(())
     }
     ```
    -"##
    -)]
    -//!
    -//! ## Generate a few addresses
    -//!
    -//! ### Example
    -//! ```
    -//! use bdk::{Wallet};
    -//! use bdk::database::MemoryDatabase;
    -//! use bdk::wallet::AddressIndex::New;
    -//!
    -//! fn main() -> Result<(), bdk::Error> {
    -//! let wallet = Wallet::new(
    -//!         "wpkh([c258d2e4/84h/1h/0h]tpubDDYkZojQFQjht8Tm4jsS3iuEmKjTiEGjG6KnuFNKKJb5A6ZUCUZKdvLdSDWofKi4ToRCwb9poe1XdqfUnP4jaJjCB2Zwv11ZLgSbnZSNecE/0/*)",
    -//!         Some("wpkh([c258d2e4/84h/1h/0h]tpubDDYkZojQFQjht8Tm4jsS3iuEmKjTiEGjG6KnuFNKKJb5A6ZUCUZKdvLdSDWofKi4ToRCwb9poe1XdqfUnP4jaJjCB2Zwv11ZLgSbnZSNecE/1/*)"),
    -//!         bitcoin::Network::Testnet,
    -//!         MemoryDatabase::default(),
    -//!     )?;
    -//!
    -//!     println!("Address #0: {}", wallet.get_address(New)?);
    -//!     println!("Address #1: {}", wallet.get_address(New)?);
    -//!     println!("Address #2: {}", wallet.get_address(New)?);
    -//!
    -//!     Ok(())
    -//! }
    -//! ```
    -#![cfg_attr(
    -    feature = "electrum",
    -    doc = r##"
    +"##
    +)]
    +//!
    +//! ## Generate a few addresses
    +//!
    +//! ### Example
    +//! ```
    +//! use bdk::{Wallet};
    +//! use bdk::database::MemoryDatabase;
    +//! use bdk::wallet::AddressIndex::New;
    +//!
    +//! fn main() -> Result<(), bdk::Error> {
    +//! let wallet = Wallet::new(
    +//!         "wpkh([c258d2e4/84h/1h/0h]tpubDDYkZojQFQjht8Tm4jsS3iuEmKjTiEGjG6KnuFNKKJb5A6ZUCUZKdvLdSDWofKi4ToRCwb9poe1XdqfUnP4jaJjCB2Zwv11ZLgSbnZSNecE/0/*)",
    +//!         Some("wpkh([c258d2e4/84h/1h/0h]tpubDDYkZojQFQjht8Tm4jsS3iuEmKjTiEGjG6KnuFNKKJb5A6ZUCUZKdvLdSDWofKi4ToRCwb9poe1XdqfUnP4jaJjCB2Zwv11ZLgSbnZSNecE/1/*)"),
    +//!         bitcoin::Network::Testnet,
    +//!         MemoryDatabase::default(),
    +//!     )?;
    +//!
    +//!     println!("Address #0: {}", wallet.get_address(New)?);
    +//!     println!("Address #1: {}", wallet.get_address(New)?);
    +//!     println!("Address #2: {}", wallet.get_address(New)?);
    +//!
    +//!     Ok(())
    +//! }
    +//! ```
    +#![cfg_attr(
    +    feature = "electrum",
    +    doc = r##"
     ## Create a transaction
     
     ```no_run
    @@ -433,148 +427,147 @@ fn main() -> Result<(), bdk::Error> {
         Ok(())
     }
     ```
    -"##
    -)]
    -//!
    -//! ## Sign a transaction
    -//!
    -//! ```no_run
    -//! use std::str::FromStr;
    -//!
    -//! use bitcoin::util::psbt::PartiallySignedTransaction as Psbt;
    -//!
    -//! use bdk::{Wallet, SignOptions};
    -//! use bdk::database::MemoryDatabase;
    -//!
    -//! fn main() -> Result<(), bdk::Error> {
    -//!     let wallet = Wallet::new(
    -//!         "wpkh([c258d2e4/84h/1h/0h]tprv8griRPhA7342zfRyB6CqeKF8CJDXYu5pgnj1cjL1u2ngKcJha5jjTRimG82ABzJQ4MQe71CV54xfn25BbhCNfEGGJZnxvCDQCd6JkbvxW6h/0/*)",
    -//!         Some("wpkh([c258d2e4/84h/1h/0h]tprv8griRPhA7342zfRyB6CqeKF8CJDXYu5pgnj1cjL1u2ngKcJha5jjTRimG82ABzJQ4MQe71CV54xfn25BbhCNfEGGJZnxvCDQCd6JkbvxW6h/1/*)"),
    -//!         bitcoin::Network::Testnet,
    -//!         MemoryDatabase::default(),
    -//!     )?;
    -//!
    -//!     let psbt = "...";
    -//!     let mut psbt = Psbt::from_str(psbt)?;
    -//!
    -//!     let finalized = wallet.sign(&mut psbt, SignOptions::default())?;
    -//!
    -//!     Ok(())
    -//! }
    -//! ```
    -//!
    -//! # Feature flags
    -//!
    -//! BDK uses a set of [feature flags](https://doc.rust-lang.org/cargo/reference/manifest.html#the-features-section)
    -//! to reduce the amount of compiled code by allowing projects to only enable the features they need.
    -//! By default, BDK enables two internal features, `key-value-db` and `electrum`.
    -//!
    -//! If you are new to BDK we recommended that you use the default features which will enable
    -//! basic descriptor wallet functionality. More advanced users can disable the `default` features
    -//! (`--no-default-features`) and build the BDK library with only the features you need.
    +"##
    +)]
    +//!
    +//! ## Sign a transaction
    +//!
    +//! ```no_run
    +//! use std::str::FromStr;
    +//!
    +//! use bitcoin::util::psbt::PartiallySignedTransaction as Psbt;
    +//!
    +//! use bdk::{Wallet, SignOptions};
    +//! use bdk::database::MemoryDatabase;
    +//!
    +//! fn main() -> Result<(), bdk::Error> {
    +//!     let wallet = Wallet::new(
    +//!         "wpkh([c258d2e4/84h/1h/0h]tprv8griRPhA7342zfRyB6CqeKF8CJDXYu5pgnj1cjL1u2ngKcJha5jjTRimG82ABzJQ4MQe71CV54xfn25BbhCNfEGGJZnxvCDQCd6JkbvxW6h/0/*)",
    +//!         Some("wpkh([c258d2e4/84h/1h/0h]tprv8griRPhA7342zfRyB6CqeKF8CJDXYu5pgnj1cjL1u2ngKcJha5jjTRimG82ABzJQ4MQe71CV54xfn25BbhCNfEGGJZnxvCDQCd6JkbvxW6h/1/*)"),
    +//!         bitcoin::Network::Testnet,
    +//!         MemoryDatabase::default(),
    +//!     )?;
    +//!
    +//!     let psbt = "...";
    +//!     let mut psbt = Psbt::from_str(psbt)?;
    +//!
    +//!     let finalized = wallet.sign(&mut psbt, SignOptions::default())?;
    +//!
    +//!     Ok(())
    +//! }
    +//! ```
    +//!
    +//! # Feature flags
    +//!
    +//! BDK uses a set of [feature flags](https://doc.rust-lang.org/cargo/reference/manifest.html#the-features-section)
    +//! to reduce the amount of compiled code by allowing projects to only enable the features they need.
    +//! By default, BDK enables two internal features, `key-value-db` and `electrum`.
    +//!
    +//! If you are new to BDK we recommended that you use the default features which will enable
    +//! basic descriptor wallet functionality. More advanced users can disable the `default` features
    +//! (`--no-default-features`) and build the BDK library with only the features you need.
     
    -//! Below is a list of the available feature flags and the additional functionality they provide.
    -//!
    -//! * `all-keys`: all features for working with bitcoin keys
    -//! * `async-interface`: async functions in bdk traits
    -//! * `keys-bip39`: [BIP-39](https://github.com/bitcoin/bips/blob/master/bip-0039.mediawiki) mnemonic codes for generating deterministic keys
    -//!
    -//! # Internal features
    -//!
    -//! These features do not expose any new API, but influence internal implementation aspects of
    -//! BDK.
    -//!
    -//! * `compact_filters`: [`compact_filters`](crate::blockchain::compact_filters) client protocol for interacting with the bitcoin P2P network
    -//! * `electrum`: [`electrum`](crate::blockchain::electrum) client protocol for interacting with electrum servers
    -//! * `esplora`: [`esplora`](crate::blockchain::esplora) client protocol for interacting with blockstream [electrs](https://github.com/Blockstream/electrs) servers
    -//! * `key-value-db`: key value [`database`](crate::database) based on [`sled`](crate::sled) for caching blockchain data
    +//! Below is a list of the available feature flags and the additional functionality they provide.
    +//!
    +//! * `all-keys`: all features for working with bitcoin keys
    +//! * `async-interface`: async functions in bdk traits
    +//! * `keys-bip39`: [BIP-39](https://github.com/bitcoin/bips/blob/master/bip-0039.mediawiki) mnemonic codes for generating deterministic keys
    +//!
    +//! # Internal features
    +//!
    +//! These features do not expose any new API, but influence internal implementation aspects of
    +//! BDK.
    +//!
    +//! * `compact_filters`: [`compact_filters`](crate::blockchain::compact_filters) client protocol for interacting with the bitcoin P2P network
    +//! * `electrum`: [`electrum`](crate::blockchain::electrum) client protocol for interacting with electrum servers
    +//! * `esplora`: [`esplora`](crate::blockchain::esplora) client protocol for interacting with blockstream [electrs](https://github.com/Blockstream/electrs) servers
    +//! * `key-value-db`: key value [`database`](crate::database) based on [`sled`](crate::sled) for caching blockchain data
     
    -pub extern crate bitcoin;
    -extern crate log;
    -pub extern crate miniscript;
    -extern crate serde;
    -#[macro_use]
    -extern crate serde_json;
    -#[cfg(feature = "hardware-signer")]
    -pub extern crate hwi;
    +pub extern crate bitcoin;
    +extern crate log;
    +pub extern crate miniscript;
    +extern crate serde;
    +#[macro_use]
    +extern crate serde_json;
    +#[cfg(feature = "hardware-signer")]
    +pub extern crate hwi;
     
    -#[cfg(all(feature = "reqwest", feature = "ureq"))]
    -compile_error!("Features reqwest and ureq are mutually exclusive and cannot be enabled together");
    +#[cfg(all(feature = "reqwest", feature = "ureq"))]
    +compile_error!("Features reqwest and ureq are mutually exclusive and cannot be enabled together");
     
    -#[cfg(all(feature = "async-interface", feature = "electrum"))]
    -compile_error!(
    -    "Features async-interface and electrum are mutually exclusive and cannot be enabled together"
    -);
    +#[cfg(all(feature = "async-interface", feature = "electrum"))]
    +compile_error!(
    +    "Features async-interface and electrum are mutually exclusive and cannot be enabled together"
    +);
     
    -#[cfg(all(feature = "async-interface", feature = "ureq"))]
    -compile_error!(
    -    "Features async-interface and ureq are mutually exclusive and cannot be enabled together"
    -);
    +#[cfg(all(feature = "async-interface", feature = "ureq"))]
    +compile_error!(
    +    "Features async-interface and ureq are mutually exclusive and cannot be enabled together"
    +);
     
    -#[cfg(all(feature = "async-interface", feature = "compact_filters"))]
    -compile_error!(
    -    "Features async-interface and compact_filters are mutually exclusive and cannot be enabled together"
    -);
    +#[cfg(all(feature = "async-interface", feature = "compact_filters"))]
    +compile_error!(
    +    "Features async-interface and compact_filters are mutually exclusive and cannot be enabled together"
    +);
     
    -#[cfg(feature = "keys-bip39")]
    -extern crate bip39;
    +#[cfg(feature = "keys-bip39")]
    +extern crate bip39;
     
    -#[cfg(any(target_arch = "wasm32", feature = "async-interface"))]
    -#[macro_use]
    -extern crate async_trait;
    -#[macro_use]
    -extern crate bdk_macros;
    +#[cfg(any(target_arch = "wasm32", feature = "async-interface"))]
    +#[macro_use]
    +extern crate async_trait;
    +#[macro_use]
    +extern crate bdk_macros;
     
    -#[cfg(feature = "rpc")]
    -pub extern crate bitcoincore_rpc;
    +#[cfg(feature = "rpc")]
    +pub extern crate bitcoincore_rpc;
     
    -#[cfg(feature = "electrum")]
    -pub extern crate electrum_client;
    +#[cfg(feature = "electrum")]
    +pub extern crate electrum_client;
     
    -#[cfg(feature = "esplora")]
    -pub extern crate esplora_client;
    +#[cfg(feature = "esplora")]
    +pub extern crate esplora_client;
     
    -#[cfg(feature = "key-value-db")]
    -pub extern crate sled;
    +#[cfg(feature = "key-value-db")]
    +pub extern crate sled;
     
    -#[cfg(feature = "sqlite")]
    -pub extern crate rusqlite;
    +#[cfg(feature = "sqlite")]
    +pub extern crate rusqlite;
     
    -// We should consider putting this under a feature flag but we need the macro in doctests so we need
    -// to wait until https://github.com/rust-lang/rust/issues/67295 is fixed.
    -//
    -// Stuff in here is too rough to document atm
    -#[doc(hidden)]
    -#[macro_use]
    -pub mod testutils;
    +// We should consider putting this under a feature flag but we need the macro in doctests so we need
    +// to wait until https://github.com/rust-lang/rust/issues/67295 is fixed.
    +//
    +// Stuff in here is too rough to document atm
    +#[doc(hidden)]
    +#[macro_use]
    +pub mod testutils;
     
    -#[allow(unused_imports)]
    -#[macro_use]
    -pub(crate) mod error;
    -pub mod blockchain;
    -pub mod database;
    -pub mod descriptor;
    -#[cfg(feature = "test-md-docs")]
    -mod doctest;
    -pub mod keys;
    -pub mod psbt;
    -pub(crate) mod types;
    -pub mod wallet;
    +#[allow(unused_imports)]
    +#[macro_use]
    +pub(crate) mod error;
    +pub mod blockchain;
    +pub mod database;
    +pub mod descriptor;
    +#[cfg(feature = "test-md-docs")]
    +mod doctest;
    +pub mod keys;
    +pub mod psbt;
    +pub(crate) mod types;
    +pub mod wallet;
     
    -pub use descriptor::template;
    -pub use descriptor::HdKeyPaths;
    -pub use error::Error;
    -pub use types::*;
    -pub use wallet::signer;
    -pub use wallet::signer::SignOptions;
    -pub use wallet::tx_builder::TxBuilder;
    -pub use wallet::SyncOptions;
    -pub use wallet::Wallet;
    +pub use descriptor::template;
    +pub use descriptor::HdKeyPaths;
    +pub use error::Error;
    +pub use types::*;
    +pub use wallet::signer;
    +pub use wallet::signer::SignOptions;
    +pub use wallet::tx_builder::TxBuilder;
    +pub use wallet::SyncOptions;
    +pub use wallet::Wallet;
     
    -/// Get the version of BDK at runtime
    -pub fn version() -> &'static str {
    +/// Get the version of BDK at runtime
    +pub fn version() -> &'static str {
         env!("CARGO_PKG_VERSION", "unknown")
     }
     
    -
    - \ No newline at end of file +
    \ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/src/bdk/psbt/mod.rs.html b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/src/bdk/psbt/mod.rs.html index b867f2d165..3fdc63983c 100644 --- a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/src/bdk/psbt/mod.rs.html +++ b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/src/bdk/psbt/mod.rs.html @@ -1,488 +1,481 @@ -mod.rs - source - -
      1
    -  2
    -  3
    -  4
    -  5
    -  6
    -  7
    -  8
    -  9
    - 10
    - 11
    - 12
    - 13
    - 14
    - 15
    - 16
    - 17
    - 18
    - 19
    - 20
    - 21
    - 22
    - 23
    - 24
    - 25
    - 26
    - 27
    - 28
    - 29
    - 30
    - 31
    - 32
    - 33
    - 34
    - 35
    - 36
    - 37
    - 38
    - 39
    - 40
    - 41
    - 42
    - 43
    - 44
    - 45
    - 46
    - 47
    - 48
    - 49
    - 50
    - 51
    - 52
    - 53
    - 54
    - 55
    - 56
    - 57
    - 58
    - 59
    - 60
    - 61
    - 62
    - 63
    - 64
    - 65
    - 66
    - 67
    - 68
    - 69
    - 70
    - 71
    - 72
    - 73
    - 74
    - 75
    - 76
    - 77
    - 78
    - 79
    - 80
    - 81
    - 82
    - 83
    - 84
    - 85
    - 86
    - 87
    - 88
    - 89
    - 90
    - 91
    - 92
    - 93
    - 94
    - 95
    - 96
    - 97
    - 98
    - 99
    -100
    -101
    -102
    -103
    -104
    -105
    -106
    -107
    -108
    -109
    -110
    -111
    -112
    -113
    -114
    -115
    -116
    -117
    -118
    -119
    -120
    -121
    -122
    -123
    -124
    -125
    -126
    -127
    -128
    -129
    -130
    -131
    -132
    -133
    -134
    -135
    -136
    -137
    -138
    -139
    -140
    -141
    -142
    -143
    -144
    -145
    -146
    -147
    -148
    -149
    -150
    -151
    -152
    -153
    -154
    -155
    -156
    -157
    -158
    -159
    -160
    -161
    -162
    -163
    -164
    -165
    -166
    -167
    -168
    -169
    -170
    -171
    -172
    -173
    -174
    -175
    -176
    -177
    -178
    -179
    -180
    -181
    -182
    -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
    -
    // Bitcoin Dev Kit
    -// Written in 2020 by Alekos Filini <alekos.filini@gmail.com>
    -//
    -// Copyright (c) 2020-2021 Bitcoin Dev Kit Developers
    -//
    -// This file is licensed under the Apache License, Version 2.0 <LICENSE-APACHE
    -// or http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
    -// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your option.
    -// You may not use this file except in accordance with one or both of these
    -// licenses.
    -
    -//! Additional functions on the `rust-bitcoin` `PartiallySignedTransaction` structure.
    -
    -use crate::FeeRate;
    -use bitcoin::util::psbt::PartiallySignedTransaction as Psbt;
    -use bitcoin::TxOut;
    -
    -// TODO upstream the functions here to `rust-bitcoin`?
    -
    -/// Trait to add functions to extract utxos and calculate fees.
    -pub trait PsbtUtils {
    -    /// Get the `TxOut` for the specified input index, if it doesn't exist in the PSBT `None` is returned.
    -    fn get_utxo_for(&self, input_index: usize) -> Option<TxOut>;
    -
    -    /// The total transaction fee amount, sum of input amounts minus sum of output amounts, in Sats.
    -    /// If the PSBT is missing a TxOut for an input returns None.
    -    fn fee_amount(&self) -> Option<u64>;
    -
    -    /// The transaction's fee rate. This value will only be accurate if calculated AFTER the
    -    /// `PartiallySignedTransaction` is finalized and all witness/signature data is added to the
    -    /// transaction.
    -    /// If the PSBT is missing a TxOut for an input returns None.
    -    fn fee_rate(&self) -> Option<FeeRate>;
    +mod.rs - source
    1
    +2
    +3
    +4
    +5
    +6
    +7
    +8
    +9
    +10
    +11
    +12
    +13
    +14
    +15
    +16
    +17
    +18
    +19
    +20
    +21
    +22
    +23
    +24
    +25
    +26
    +27
    +28
    +29
    +30
    +31
    +32
    +33
    +34
    +35
    +36
    +37
    +38
    +39
    +40
    +41
    +42
    +43
    +44
    +45
    +46
    +47
    +48
    +49
    +50
    +51
    +52
    +53
    +54
    +55
    +56
    +57
    +58
    +59
    +60
    +61
    +62
    +63
    +64
    +65
    +66
    +67
    +68
    +69
    +70
    +71
    +72
    +73
    +74
    +75
    +76
    +77
    +78
    +79
    +80
    +81
    +82
    +83
    +84
    +85
    +86
    +87
    +88
    +89
    +90
    +91
    +92
    +93
    +94
    +95
    +96
    +97
    +98
    +99
    +100
    +101
    +102
    +103
    +104
    +105
    +106
    +107
    +108
    +109
    +110
    +111
    +112
    +113
    +114
    +115
    +116
    +117
    +118
    +119
    +120
    +121
    +122
    +123
    +124
    +125
    +126
    +127
    +128
    +129
    +130
    +131
    +132
    +133
    +134
    +135
    +136
    +137
    +138
    +139
    +140
    +141
    +142
    +143
    +144
    +145
    +146
    +147
    +148
    +149
    +150
    +151
    +152
    +153
    +154
    +155
    +156
    +157
    +158
    +159
    +160
    +161
    +162
    +163
    +164
    +165
    +166
    +167
    +168
    +169
    +170
    +171
    +172
    +173
    +174
    +175
    +176
    +177
    +178
    +179
    +180
    +181
    +182
    +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
    +
    // Bitcoin Dev Kit
    +// Written in 2020 by Alekos Filini <alekos.filini@gmail.com>
    +//
    +// Copyright (c) 2020-2021 Bitcoin Dev Kit Developers
    +//
    +// This file is licensed under the Apache License, Version 2.0 <LICENSE-APACHE
    +// or http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
    +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your option.
    +// You may not use this file except in accordance with one or both of these
    +// licenses.
    +
    +//! Additional functions on the `rust-bitcoin` `PartiallySignedTransaction` structure.
    +
    +use crate::FeeRate;
    +use bitcoin::util::psbt::PartiallySignedTransaction as Psbt;
    +use bitcoin::TxOut;
    +
    +// TODO upstream the functions here to `rust-bitcoin`?
    +
    +/// Trait to add functions to extract utxos and calculate fees.
    +pub trait PsbtUtils {
    +    /// Get the `TxOut` for the specified input index, if it doesn't exist in the PSBT `None` is returned.
    +    fn get_utxo_for(&self, input_index: usize) -> Option<TxOut>;
    +
    +    /// The total transaction fee amount, sum of input amounts minus sum of output amounts, in Sats.
    +    /// If the PSBT is missing a TxOut for an input returns None.
    +    fn fee_amount(&self) -> Option<u64>;
    +
    +    /// The transaction's fee rate. This value will only be accurate if calculated AFTER the
    +    /// `PartiallySignedTransaction` is finalized and all witness/signature data is added to the
    +    /// transaction.
    +    /// If the PSBT is missing a TxOut for an input returns None.
    +    fn fee_rate(&self) -> Option<FeeRate>;
     }
     
    -impl PsbtUtils for Psbt {
    -    #[allow(clippy::all)] // We want to allow `manual_map` but it is too new.
    -    fn get_utxo_for(&self, input_index: usize) -> Option<TxOut> {
    -        let tx = &self.unsigned_tx;
    +impl PsbtUtils for Psbt {
    +    #[allow(clippy::all)] // We want to allow `manual_map` but it is too new.
    +    fn get_utxo_for(&self, input_index: usize) -> Option<TxOut> {
    +        let tx = &self.unsigned_tx;
     
    -        if input_index >= tx.input.len() {
    -            return None;
    +        if input_index >= tx.input.len() {
    +            return None;
             }
     
    -        if let Some(input) = self.inputs.get(input_index) {
    -            if let Some(wit_utxo) = &input.witness_utxo {
    -                Some(wit_utxo.clone())
    -            } else if let Some(in_tx) = &input.non_witness_utxo {
    -                Some(in_tx.output[tx.input[input_index].previous_output.vout as usize].clone())
    -            } else {
    -                None
    -            }
    -        } else {
    -            None
    -        }
    +        if let Some(input) = self.inputs.get(input_index) {
    +            if let Some(wit_utxo) = &input.witness_utxo {
    +                Some(wit_utxo.clone())
    +            } else if let Some(in_tx) = &input.non_witness_utxo {
    +                Some(in_tx.output[tx.input[input_index].previous_output.vout as usize].clone())
    +            } else {
    +                None
    +            }
    +        } else {
    +            None
    +        }
         }
     
    -    fn fee_amount(&self) -> Option<u64> {
    -        let tx = &self.unsigned_tx;
    -        let utxos: Option<Vec<TxOut>> = (0..tx.input.len()).map(|i| self.get_utxo_for(i)).collect();
    +    fn fee_amount(&self) -> Option<u64> {
    +        let tx = &self.unsigned_tx;
    +        let utxos: Option<Vec<TxOut>> = (0..tx.input.len()).map(|i| self.get_utxo_for(i)).collect();
     
    -        utxos.map(|inputs| {
    -            let input_amount: u64 = inputs.iter().map(|i| i.value).sum();
    -            let output_amount: u64 = self.unsigned_tx.output.iter().map(|o| o.value).sum();
    -            input_amount
    -                .checked_sub(output_amount)
    -                .expect("input amount must be greater than output amount")
    +        utxos.map(|inputs| {
    +            let input_amount: u64 = inputs.iter().map(|i| i.value).sum();
    +            let output_amount: u64 = self.unsigned_tx.output.iter().map(|o| o.value).sum();
    +            input_amount
    +                .checked_sub(output_amount)
    +                .expect("input amount must be greater than output amount")
             })
         }
     
    -    fn fee_rate(&self) -> Option<FeeRate> {
    -        let fee_amount = self.fee_amount();
    -        fee_amount.map(|fee| {
    -            let weight = self.clone().extract_tx().weight();
    -            FeeRate::from_wu(fee, weight)
    +    fn fee_rate(&self) -> Option<FeeRate> {
    +        let fee_amount = self.fee_amount();
    +        fee_amount.map(|fee| {
    +            let weight = self.clone().extract_tx().weight();
    +            FeeRate::from_wu(fee, weight)
             })
         }
     }
     
    -#[cfg(test)]
    -mod test {
    -    use crate::bitcoin::TxIn;
    -    use crate::psbt::Psbt;
    -    use crate::wallet::AddressIndex;
    -    use crate::wallet::AddressIndex::New;
    -    use crate::wallet::{get_funded_wallet, test::get_test_wpkh};
    -    use crate::{psbt, FeeRate, SignOptions};
    -    use std::str::FromStr;
    -
    -    // from bip 174
    -    const PSBT_STR: &str = "cHNidP8BAKACAAAAAqsJSaCMWvfEm4IS9Bfi8Vqz9cM9zxU4IagTn4d6W3vkAAAAAAD+////qwlJoIxa98SbghL0F+LxWrP1wz3PFTghqBOfh3pbe+QBAAAAAP7///8CYDvqCwAAAAAZdqkUdopAu9dAy+gdmI5x3ipNXHE5ax2IrI4kAAAAAAAAGXapFG9GILVT+glechue4O/p+gOcykWXiKwAAAAAAAEHakcwRAIgR1lmF5fAGwNrJZKJSGhiGDR9iYZLcZ4ff89X0eURZYcCIFMJ6r9Wqk2Ikf/REf3xM286KdqGbX+EhtdVRs7tr5MZASEDXNxh/HupccC1AaZGoqg7ECy0OIEhfKaC3Ibi1z+ogpIAAQEgAOH1BQAAAAAXqRQ1RebjO4MsRwUPJNPuuTycA5SLx4cBBBYAFIXRNTfy4mVAWjTbr6nj3aAfuCMIAAAA";
    -
    -    #[test]
    -    #[should_panic(expected = "InputIndexOutOfRange")]
    -    fn test_psbt_malformed_psbt_input_legacy() {
    -        let psbt_bip = Psbt::from_str(PSBT_STR).unwrap();
    -        let (wallet, _, _) = get_funded_wallet(get_test_wpkh());
    -        let send_to = wallet.get_address(AddressIndex::New).unwrap();
    -        let mut builder = wallet.build_tx();
    -        builder.add_recipient(send_to.script_pubkey(), 10_000);
    -        let (mut psbt, _) = builder.finish().unwrap();
    -        psbt.inputs.push(psbt_bip.inputs[0].clone());
    -        let options = SignOptions {
    -            trust_witness_utxo: true,
    -            ..Default::default()
    +#[cfg(test)]
    +mod test {
    +    use crate::bitcoin::TxIn;
    +    use crate::psbt::Psbt;
    +    use crate::wallet::AddressIndex;
    +    use crate::wallet::AddressIndex::New;
    +    use crate::wallet::{get_funded_wallet, test::get_test_wpkh};
    +    use crate::{psbt, FeeRate, SignOptions};
    +    use std::str::FromStr;
    +
    +    // from bip 174
    +    const PSBT_STR: &str = "cHNidP8BAKACAAAAAqsJSaCMWvfEm4IS9Bfi8Vqz9cM9zxU4IagTn4d6W3vkAAAAAAD+////qwlJoIxa98SbghL0F+LxWrP1wz3PFTghqBOfh3pbe+QBAAAAAP7///8CYDvqCwAAAAAZdqkUdopAu9dAy+gdmI5x3ipNXHE5ax2IrI4kAAAAAAAAGXapFG9GILVT+glechue4O/p+gOcykWXiKwAAAAAAAEHakcwRAIgR1lmF5fAGwNrJZKJSGhiGDR9iYZLcZ4ff89X0eURZYcCIFMJ6r9Wqk2Ikf/REf3xM286KdqGbX+EhtdVRs7tr5MZASEDXNxh/HupccC1AaZGoqg7ECy0OIEhfKaC3Ibi1z+ogpIAAQEgAOH1BQAAAAAXqRQ1RebjO4MsRwUPJNPuuTycA5SLx4cBBBYAFIXRNTfy4mVAWjTbr6nj3aAfuCMIAAAA";
    +
    +    #[test]
    +    #[should_panic(expected = "InputIndexOutOfRange")]
    +    fn test_psbt_malformed_psbt_input_legacy() {
    +        let psbt_bip = Psbt::from_str(PSBT_STR).unwrap();
    +        let (wallet, _, _) = get_funded_wallet(get_test_wpkh());
    +        let send_to = wallet.get_address(AddressIndex::New).unwrap();
    +        let mut builder = wallet.build_tx();
    +        builder.add_recipient(send_to.script_pubkey(), 10_000);
    +        let (mut psbt, _) = builder.finish().unwrap();
    +        psbt.inputs.push(psbt_bip.inputs[0].clone());
    +        let options = SignOptions {
    +            trust_witness_utxo: true,
    +            ..Default::default()
             };
    -        let _ = wallet.sign(&mut psbt, options).unwrap();
    +        let _ = wallet.sign(&mut psbt, options).unwrap();
         }
     
    -    #[test]
    -    #[should_panic(expected = "InputIndexOutOfRange")]
    -    fn test_psbt_malformed_psbt_input_segwit() {
    -        let psbt_bip = Psbt::from_str(PSBT_STR).unwrap();
    -        let (wallet, _, _) = get_funded_wallet(get_test_wpkh());
    -        let send_to = wallet.get_address(AddressIndex::New).unwrap();
    -        let mut builder = wallet.build_tx();
    -        builder.add_recipient(send_to.script_pubkey(), 10_000);
    -        let (mut psbt, _) = builder.finish().unwrap();
    -        psbt.inputs.push(psbt_bip.inputs[1].clone());
    -        let options = SignOptions {
    -            trust_witness_utxo: true,
    -            ..Default::default()
    +    #[test]
    +    #[should_panic(expected = "InputIndexOutOfRange")]
    +    fn test_psbt_malformed_psbt_input_segwit() {
    +        let psbt_bip = Psbt::from_str(PSBT_STR).unwrap();
    +        let (wallet, _, _) = get_funded_wallet(get_test_wpkh());
    +        let send_to = wallet.get_address(AddressIndex::New).unwrap();
    +        let mut builder = wallet.build_tx();
    +        builder.add_recipient(send_to.script_pubkey(), 10_000);
    +        let (mut psbt, _) = builder.finish().unwrap();
    +        psbt.inputs.push(psbt_bip.inputs[1].clone());
    +        let options = SignOptions {
    +            trust_witness_utxo: true,
    +            ..Default::default()
             };
    -        let _ = wallet.sign(&mut psbt, options).unwrap();
    +        let _ = wallet.sign(&mut psbt, options).unwrap();
         }
     
    -    #[test]
    -    #[should_panic(expected = "InputIndexOutOfRange")]
    -    fn test_psbt_malformed_tx_input() {
    -        let (wallet, _, _) = get_funded_wallet(get_test_wpkh());
    -        let send_to = wallet.get_address(AddressIndex::New).unwrap();
    -        let mut builder = wallet.build_tx();
    -        builder.add_recipient(send_to.script_pubkey(), 10_000);
    -        let (mut psbt, _) = builder.finish().unwrap();
    -        psbt.unsigned_tx.input.push(TxIn::default());
    -        let options = SignOptions {
    -            trust_witness_utxo: true,
    -            ..Default::default()
    +    #[test]
    +    #[should_panic(expected = "InputIndexOutOfRange")]
    +    fn test_psbt_malformed_tx_input() {
    +        let (wallet, _, _) = get_funded_wallet(get_test_wpkh());
    +        let send_to = wallet.get_address(AddressIndex::New).unwrap();
    +        let mut builder = wallet.build_tx();
    +        builder.add_recipient(send_to.script_pubkey(), 10_000);
    +        let (mut psbt, _) = builder.finish().unwrap();
    +        psbt.unsigned_tx.input.push(TxIn::default());
    +        let options = SignOptions {
    +            trust_witness_utxo: true,
    +            ..Default::default()
             };
    -        let _ = wallet.sign(&mut psbt, options).unwrap();
    +        let _ = wallet.sign(&mut psbt, options).unwrap();
         }
     
    -    #[test]
    -    fn test_psbt_sign_with_finalized() {
    -        let psbt_bip = Psbt::from_str(PSBT_STR).unwrap();
    -        let (wallet, _, _) = get_funded_wallet(get_test_wpkh());
    -        let send_to = wallet.get_address(AddressIndex::New).unwrap();
    -        let mut builder = wallet.build_tx();
    -        builder.add_recipient(send_to.script_pubkey(), 10_000);
    -        let (mut psbt, _) = builder.finish().unwrap();
    -
    -        // add a finalized input
    -        psbt.inputs.push(psbt_bip.inputs[0].clone());
    -        psbt.unsigned_tx
    -            .input
    -            .push(psbt_bip.unsigned_tx.input[0].clone());
    -
    -        let _ = wallet.sign(&mut psbt, SignOptions::default()).unwrap();
    +    #[test]
    +    fn test_psbt_sign_with_finalized() {
    +        let psbt_bip = Psbt::from_str(PSBT_STR).unwrap();
    +        let (wallet, _, _) = get_funded_wallet(get_test_wpkh());
    +        let send_to = wallet.get_address(AddressIndex::New).unwrap();
    +        let mut builder = wallet.build_tx();
    +        builder.add_recipient(send_to.script_pubkey(), 10_000);
    +        let (mut psbt, _) = builder.finish().unwrap();
    +
    +        // add a finalized input
    +        psbt.inputs.push(psbt_bip.inputs[0].clone());
    +        psbt.unsigned_tx
    +            .input
    +            .push(psbt_bip.unsigned_tx.input[0].clone());
    +
    +        let _ = wallet.sign(&mut psbt, SignOptions::default()).unwrap();
         }
     
    -    #[test]
    -    fn test_psbt_fee_rate_with_witness_utxo() {
    -        use psbt::PsbtUtils;
    +    #[test]
    +    fn test_psbt_fee_rate_with_witness_utxo() {
    +        use psbt::PsbtUtils;
     
    -        let expected_fee_rate = 1.2345;
    +        let expected_fee_rate = 1.2345;
     
    -        let (wallet, _, _) = get_funded_wallet("wpkh(tprv8ZgxMBicQKsPd3EupYiPRhaMooHKUHJxNsTfYuScep13go8QFfHdtkG9nRkFGb7busX4isf6X9dURGCoKgitaApQ6MupRhZMcELAxTBRJgS/*)");
    -        let addr = wallet.get_address(New).unwrap();
    -        let mut builder = wallet.build_tx();
    -        builder.drain_to(addr.script_pubkey()).drain_wallet();
    -        builder.fee_rate(FeeRate::from_sat_per_vb(expected_fee_rate));
    -        let (mut psbt, _) = builder.finish().unwrap();
    -        let fee_amount = psbt.fee_amount();
    -        assert!(fee_amount.is_some());
    +        let (wallet, _, _) = get_funded_wallet("wpkh(tprv8ZgxMBicQKsPd3EupYiPRhaMooHKUHJxNsTfYuScep13go8QFfHdtkG9nRkFGb7busX4isf6X9dURGCoKgitaApQ6MupRhZMcELAxTBRJgS/*)");
    +        let addr = wallet.get_address(New).unwrap();
    +        let mut builder = wallet.build_tx();
    +        builder.drain_to(addr.script_pubkey()).drain_wallet();
    +        builder.fee_rate(FeeRate::from_sat_per_vb(expected_fee_rate));
    +        let (mut psbt, _) = builder.finish().unwrap();
    +        let fee_amount = psbt.fee_amount();
    +        assert!(fee_amount.is_some());
     
    -        let unfinalized_fee_rate = psbt.fee_rate().unwrap();
    +        let unfinalized_fee_rate = psbt.fee_rate().unwrap();
     
    -        let finalized = wallet.sign(&mut psbt, Default::default()).unwrap();
    -        assert!(finalized);
    +        let finalized = wallet.sign(&mut psbt, Default::default()).unwrap();
    +        assert!(finalized);
     
    -        let finalized_fee_rate = psbt.fee_rate().unwrap();
    -        assert!(finalized_fee_rate.as_sat_per_vb() >= expected_fee_rate);
    -        assert!(finalized_fee_rate.as_sat_per_vb() < unfinalized_fee_rate.as_sat_per_vb());
    +        let finalized_fee_rate = psbt.fee_rate().unwrap();
    +        assert!(finalized_fee_rate.as_sat_per_vb() >= expected_fee_rate);
    +        assert!(finalized_fee_rate.as_sat_per_vb() < unfinalized_fee_rate.as_sat_per_vb());
         }
     
    -    #[test]
    -    fn test_psbt_fee_rate_with_nonwitness_utxo() {
    -        use psbt::PsbtUtils;
    +    #[test]
    +    fn test_psbt_fee_rate_with_nonwitness_utxo() {
    +        use psbt::PsbtUtils;
     
    -        let expected_fee_rate = 1.2345;
    +        let expected_fee_rate = 1.2345;
     
    -        let (wallet, _, _) = get_funded_wallet("pkh(tprv8ZgxMBicQKsPd3EupYiPRhaMooHKUHJxNsTfYuScep13go8QFfHdtkG9nRkFGb7busX4isf6X9dURGCoKgitaApQ6MupRhZMcELAxTBRJgS/*)");
    -        let addr = wallet.get_address(New).unwrap();
    -        let mut builder = wallet.build_tx();
    -        builder.drain_to(addr.script_pubkey()).drain_wallet();
    -        builder.fee_rate(FeeRate::from_sat_per_vb(expected_fee_rate));
    -        let (mut psbt, _) = builder.finish().unwrap();
    -        let fee_amount = psbt.fee_amount();
    -        assert!(fee_amount.is_some());
    -        let unfinalized_fee_rate = psbt.fee_rate().unwrap();
    +        let (wallet, _, _) = get_funded_wallet("pkh(tprv8ZgxMBicQKsPd3EupYiPRhaMooHKUHJxNsTfYuScep13go8QFfHdtkG9nRkFGb7busX4isf6X9dURGCoKgitaApQ6MupRhZMcELAxTBRJgS/*)");
    +        let addr = wallet.get_address(New).unwrap();
    +        let mut builder = wallet.build_tx();
    +        builder.drain_to(addr.script_pubkey()).drain_wallet();
    +        builder.fee_rate(FeeRate::from_sat_per_vb(expected_fee_rate));
    +        let (mut psbt, _) = builder.finish().unwrap();
    +        let fee_amount = psbt.fee_amount();
    +        assert!(fee_amount.is_some());
    +        let unfinalized_fee_rate = psbt.fee_rate().unwrap();
     
    -        let finalized = wallet.sign(&mut psbt, Default::default()).unwrap();
    -        assert!(finalized);
    +        let finalized = wallet.sign(&mut psbt, Default::default()).unwrap();
    +        assert!(finalized);
     
    -        let finalized_fee_rate = psbt.fee_rate().unwrap();
    -        assert!(finalized_fee_rate.as_sat_per_vb() >= expected_fee_rate);
    -        assert!(finalized_fee_rate.as_sat_per_vb() < unfinalized_fee_rate.as_sat_per_vb());
    +        let finalized_fee_rate = psbt.fee_rate().unwrap();
    +        assert!(finalized_fee_rate.as_sat_per_vb() >= expected_fee_rate);
    +        assert!(finalized_fee_rate.as_sat_per_vb() < unfinalized_fee_rate.as_sat_per_vb());
         }
     
    -    #[test]
    -    fn test_psbt_fee_rate_with_missing_txout() {
    -        use psbt::PsbtUtils;
    -
    -        let expected_fee_rate = 1.2345;
    -
    -        let (wpkh_wallet, _, _) = get_funded_wallet("wpkh(tprv8ZgxMBicQKsPd3EupYiPRhaMooHKUHJxNsTfYuScep13go8QFfHdtkG9nRkFGb7busX4isf6X9dURGCoKgitaApQ6MupRhZMcELAxTBRJgS/*)");
    -        let addr = wpkh_wallet.get_address(New).unwrap();
    -        let mut builder = wpkh_wallet.build_tx();
    -        builder.drain_to(addr.script_pubkey()).drain_wallet();
    -        builder.fee_rate(FeeRate::from_sat_per_vb(expected_fee_rate));
    -        let (mut wpkh_psbt, _) = builder.finish().unwrap();
    -
    -        wpkh_psbt.inputs[0].witness_utxo = None;
    -        wpkh_psbt.inputs[0].non_witness_utxo = None;
    -        assert!(wpkh_psbt.fee_amount().is_none());
    -        assert!(wpkh_psbt.fee_rate().is_none());
    -
    -        let (pkh_wallet, _, _) = get_funded_wallet("pkh(tprv8ZgxMBicQKsPd3EupYiPRhaMooHKUHJxNsTfYuScep13go8QFfHdtkG9nRkFGb7busX4isf6X9dURGCoKgitaApQ6MupRhZMcELAxTBRJgS/*)");
    -        let addr = pkh_wallet.get_address(New).unwrap();
    -        let mut builder = pkh_wallet.build_tx();
    -        builder.drain_to(addr.script_pubkey()).drain_wallet();
    -        builder.fee_rate(FeeRate::from_sat_per_vb(expected_fee_rate));
    -        let (mut pkh_psbt, _) = builder.finish().unwrap();
    -
    -        pkh_psbt.inputs[0].non_witness_utxo = None;
    -        assert!(pkh_psbt.fee_amount().is_none());
    -        assert!(pkh_psbt.fee_rate().is_none());
    +    #[test]
    +    fn test_psbt_fee_rate_with_missing_txout() {
    +        use psbt::PsbtUtils;
    +
    +        let expected_fee_rate = 1.2345;
    +
    +        let (wpkh_wallet, _, _) = get_funded_wallet("wpkh(tprv8ZgxMBicQKsPd3EupYiPRhaMooHKUHJxNsTfYuScep13go8QFfHdtkG9nRkFGb7busX4isf6X9dURGCoKgitaApQ6MupRhZMcELAxTBRJgS/*)");
    +        let addr = wpkh_wallet.get_address(New).unwrap();
    +        let mut builder = wpkh_wallet.build_tx();
    +        builder.drain_to(addr.script_pubkey()).drain_wallet();
    +        builder.fee_rate(FeeRate::from_sat_per_vb(expected_fee_rate));
    +        let (mut wpkh_psbt, _) = builder.finish().unwrap();
    +
    +        wpkh_psbt.inputs[0].witness_utxo = None;
    +        wpkh_psbt.inputs[0].non_witness_utxo = None;
    +        assert!(wpkh_psbt.fee_amount().is_none());
    +        assert!(wpkh_psbt.fee_rate().is_none());
    +
    +        let (pkh_wallet, _, _) = get_funded_wallet("pkh(tprv8ZgxMBicQKsPd3EupYiPRhaMooHKUHJxNsTfYuScep13go8QFfHdtkG9nRkFGb7busX4isf6X9dURGCoKgitaApQ6MupRhZMcELAxTBRJgS/*)");
    +        let addr = pkh_wallet.get_address(New).unwrap();
    +        let mut builder = pkh_wallet.build_tx();
    +        builder.drain_to(addr.script_pubkey()).drain_wallet();
    +        builder.fee_rate(FeeRate::from_sat_per_vb(expected_fee_rate));
    +        let (mut pkh_psbt, _) = builder.finish().unwrap();
    +
    +        pkh_psbt.inputs[0].non_witness_utxo = None;
    +        assert!(pkh_psbt.fee_amount().is_none());
    +        assert!(pkh_psbt.fee_rate().is_none());
         }
     }
     
    -
    - \ No newline at end of file +
    \ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/src/bdk/testutils/mod.rs.html b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/src/bdk/testutils/mod.rs.html index 836b1c1f9b..34d9b190c8 100644 --- a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/src/bdk/testutils/mod.rs.html +++ b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/src/bdk/testutils/mod.rs.html @@ -1,476 +1,469 @@ -mod.rs - source - -
      1
    -  2
    -  3
    -  4
    -  5
    -  6
    -  7
    -  8
    -  9
    - 10
    - 11
    - 12
    - 13
    - 14
    - 15
    - 16
    - 17
    - 18
    - 19
    - 20
    - 21
    - 22
    - 23
    - 24
    - 25
    - 26
    - 27
    - 28
    - 29
    - 30
    - 31
    - 32
    - 33
    - 34
    - 35
    - 36
    - 37
    - 38
    - 39
    - 40
    - 41
    - 42
    - 43
    - 44
    - 45
    - 46
    - 47
    - 48
    - 49
    - 50
    - 51
    - 52
    - 53
    - 54
    - 55
    - 56
    - 57
    - 58
    - 59
    - 60
    - 61
    - 62
    - 63
    - 64
    - 65
    - 66
    - 67
    - 68
    - 69
    - 70
    - 71
    - 72
    - 73
    - 74
    - 75
    - 76
    - 77
    - 78
    - 79
    - 80
    - 81
    - 82
    - 83
    - 84
    - 85
    - 86
    - 87
    - 88
    - 89
    - 90
    - 91
    - 92
    - 93
    - 94
    - 95
    - 96
    - 97
    - 98
    - 99
    -100
    -101
    -102
    -103
    -104
    -105
    -106
    -107
    -108
    -109
    -110
    -111
    -112
    -113
    -114
    -115
    -116
    -117
    -118
    -119
    -120
    -121
    -122
    -123
    -124
    -125
    -126
    -127
    -128
    -129
    -130
    -131
    -132
    -133
    -134
    -135
    -136
    -137
    -138
    -139
    -140
    -141
    -142
    -143
    -144
    -145
    -146
    -147
    -148
    -149
    -150
    -151
    -152
    -153
    -154
    -155
    -156
    -157
    -158
    -159
    -160
    -161
    -162
    -163
    -164
    -165
    -166
    -167
    -168
    -169
    -170
    -171
    -172
    -173
    -174
    -175
    -176
    -177
    -178
    -179
    -180
    -181
    -182
    -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
    -
    // Bitcoin Dev Kit
    -// Written in 2020 by Alekos Filini <alekos.filini@gmail.com>
    -//
    -// Copyright (c) 2020-2021 Bitcoin Dev Kit Developers
    -//
    -// This file is licensed under the Apache License, Version 2.0 <LICENSE-APACHE
    -// or http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
    -// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your option.
    -// You may not use this file except in accordance with one or both of these
    -// licenses.
    -#![allow(missing_docs)]
    -
    -#[cfg(test)]
    -#[cfg(feature = "test-blockchains")]
    -pub mod blockchain_tests;
    -
    -#[cfg(test)]
    -#[cfg(feature = "test-blockchains")]
    -pub mod configurable_blockchain_tests;
    -
    -use bitcoin::{Address, Txid};
    -
    -#[derive(Clone, Debug)]
    -pub struct TestIncomingInput {
    -    pub txid: Txid,
    -    pub vout: u32,
    -    pub sequence: Option<u32>,
    +mod.rs - source
    1
    +2
    +3
    +4
    +5
    +6
    +7
    +8
    +9
    +10
    +11
    +12
    +13
    +14
    +15
    +16
    +17
    +18
    +19
    +20
    +21
    +22
    +23
    +24
    +25
    +26
    +27
    +28
    +29
    +30
    +31
    +32
    +33
    +34
    +35
    +36
    +37
    +38
    +39
    +40
    +41
    +42
    +43
    +44
    +45
    +46
    +47
    +48
    +49
    +50
    +51
    +52
    +53
    +54
    +55
    +56
    +57
    +58
    +59
    +60
    +61
    +62
    +63
    +64
    +65
    +66
    +67
    +68
    +69
    +70
    +71
    +72
    +73
    +74
    +75
    +76
    +77
    +78
    +79
    +80
    +81
    +82
    +83
    +84
    +85
    +86
    +87
    +88
    +89
    +90
    +91
    +92
    +93
    +94
    +95
    +96
    +97
    +98
    +99
    +100
    +101
    +102
    +103
    +104
    +105
    +106
    +107
    +108
    +109
    +110
    +111
    +112
    +113
    +114
    +115
    +116
    +117
    +118
    +119
    +120
    +121
    +122
    +123
    +124
    +125
    +126
    +127
    +128
    +129
    +130
    +131
    +132
    +133
    +134
    +135
    +136
    +137
    +138
    +139
    +140
    +141
    +142
    +143
    +144
    +145
    +146
    +147
    +148
    +149
    +150
    +151
    +152
    +153
    +154
    +155
    +156
    +157
    +158
    +159
    +160
    +161
    +162
    +163
    +164
    +165
    +166
    +167
    +168
    +169
    +170
    +171
    +172
    +173
    +174
    +175
    +176
    +177
    +178
    +179
    +180
    +181
    +182
    +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
    +
    // Bitcoin Dev Kit
    +// Written in 2020 by Alekos Filini <alekos.filini@gmail.com>
    +//
    +// Copyright (c) 2020-2021 Bitcoin Dev Kit Developers
    +//
    +// This file is licensed under the Apache License, Version 2.0 <LICENSE-APACHE
    +// or http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
    +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your option.
    +// You may not use this file except in accordance with one or both of these
    +// licenses.
    +#![allow(missing_docs)]
    +
    +#[cfg(test)]
    +#[cfg(feature = "test-blockchains")]
    +pub mod blockchain_tests;
    +
    +#[cfg(test)]
    +#[cfg(feature = "test-blockchains")]
    +pub mod configurable_blockchain_tests;
    +
    +use bitcoin::{Address, Txid};
    +
    +#[derive(Clone, Debug)]
    +pub struct TestIncomingInput {
    +    pub txid: Txid,
    +    pub vout: u32,
    +    pub sequence: Option<u32>,
     }
     
    -impl TestIncomingInput {
    -    pub fn new(txid: Txid, vout: u32, sequence: Option<u32>) -> Self {
    -        Self {
    -            txid,
    -            vout,
    -            sequence,
    +impl TestIncomingInput {
    +    pub fn new(txid: Txid, vout: u32, sequence: Option<u32>) -> Self {
    +        Self {
    +            txid,
    +            vout,
    +            sequence,
             }
         }
     
    -    #[cfg(feature = "test-blockchains")]
    -    pub fn into_raw_tx_input(self) -> bitcoincore_rpc::json::CreateRawTransactionInput {
    -        bitcoincore_rpc::json::CreateRawTransactionInput {
    -            txid: self.txid,
    -            vout: self.vout,
    -            sequence: self.sequence,
    +    #[cfg(feature = "test-blockchains")]
    +    pub fn into_raw_tx_input(self) -> bitcoincore_rpc::json::CreateRawTransactionInput {
    +        bitcoincore_rpc::json::CreateRawTransactionInput {
    +            txid: self.txid,
    +            vout: self.vout,
    +            sequence: self.sequence,
             }
         }
     }
     
    -#[derive(Clone, Debug)]
    -pub struct TestIncomingOutput {
    -    pub value: u64,
    -    pub to_address: String,
    +#[derive(Clone, Debug)]
    +pub struct TestIncomingOutput {
    +    pub value: u64,
    +    pub to_address: String,
     }
     
    -impl TestIncomingOutput {
    -    pub fn new(value: u64, to_address: Address) -> Self {
    -        Self {
    -            value,
    -            to_address: to_address.to_string(),
    +impl TestIncomingOutput {
    +    pub fn new(value: u64, to_address: Address) -> Self {
    +        Self {
    +            value,
    +            to_address: to_address.to_string(),
             }
         }
     }
     
    -#[derive(Clone, Debug)]
    -pub struct TestIncomingTx {
    -    pub input: Vec<TestIncomingInput>,
    -    pub output: Vec<TestIncomingOutput>,
    -    pub min_confirmations: Option<u64>,
    -    pub locktime: Option<i64>,
    -    pub replaceable: Option<bool>,
    +#[derive(Clone, Debug)]
    +pub struct TestIncomingTx {
    +    pub input: Vec<TestIncomingInput>,
    +    pub output: Vec<TestIncomingOutput>,
    +    pub min_confirmations: Option<u64>,
    +    pub locktime: Option<i64>,
    +    pub replaceable: Option<bool>,
     }
     
    -impl TestIncomingTx {
    -    pub fn new(
    -        input: Vec<TestIncomingInput>,
    -        output: Vec<TestIncomingOutput>,
    -        min_confirmations: Option<u64>,
    -        locktime: Option<i64>,
    -        replaceable: Option<bool>,
    -    ) -> Self {
    -        Self {
    -            input,
    -            output,
    -            min_confirmations,
    -            locktime,
    -            replaceable,
    +impl TestIncomingTx {
    +    pub fn new(
    +        input: Vec<TestIncomingInput>,
    +        output: Vec<TestIncomingOutput>,
    +        min_confirmations: Option<u64>,
    +        locktime: Option<i64>,
    +        replaceable: Option<bool>,
    +    ) -> Self {
    +        Self {
    +            input,
    +            output,
    +            min_confirmations,
    +            locktime,
    +            replaceable,
             }
         }
     
    -    pub fn add_input(&mut self, input: TestIncomingInput) {
    -        self.input.push(input);
    +    pub fn add_input(&mut self, input: TestIncomingInput) {
    +        self.input.push(input);
         }
     
    -    pub fn add_output(&mut self, output: TestIncomingOutput) {
    -        self.output.push(output);
    +    pub fn add_output(&mut self, output: TestIncomingOutput) {
    +        self.output.push(output);
         }
     }
     
    -#[doc(hidden)]
    -#[macro_export]
    -macro_rules! testutils {
    -    ( @external $descriptors:expr, $child:expr ) => ({
    -        use $crate::bitcoin::secp256k1::Secp256k1;
    -        use $crate::miniscript::descriptor::{Descriptor, DescriptorPublicKey};
    +#[doc(hidden)]
    +#[macro_export]
    +macro_rules! testutils {
    +    ( @external $descriptors:expr, $child:expr ) => ({
    +        use $crate::bitcoin::secp256k1::Secp256k1;
    +        use $crate::miniscript::descriptor::{Descriptor, DescriptorPublicKey};
     
    -        let secp = Secp256k1::new();
    +        let secp = Secp256k1::new();
     
    -        let parsed = Descriptor::<DescriptorPublicKey>::parse_descriptor(&secp, &$descriptors.0).expect("Failed to parse descriptor in `testutils!(@external)`").0;
    -        parsed.at_derivation_index($child).address(bitcoin::Network::Regtest).expect("No address form")
    +        let parsed = Descriptor::<DescriptorPublicKey>::parse_descriptor(&secp, &$descriptors.0).expect("Failed to parse descriptor in `testutils!(@external)`").0;
    +        parsed.at_derivation_index($child).address(bitcoin::Network::Regtest).expect("No address form")
         });
    -    ( @internal $descriptors:expr, $child:expr ) => ({
    -        use $crate::bitcoin::secp256k1::Secp256k1;
    -        use $crate::miniscript::descriptor::{Descriptor, DescriptorPublicKey};
    +    ( @internal $descriptors:expr, $child:expr ) => ({
    +        use $crate::bitcoin::secp256k1::Secp256k1;
    +        use $crate::miniscript::descriptor::{Descriptor, DescriptorPublicKey};
     
    -        let secp = Secp256k1::new();
    +        let secp = Secp256k1::new();
     
    -        let parsed = Descriptor::<DescriptorPublicKey>::parse_descriptor(&secp, &$descriptors.1.expect("Missing internal descriptor")).expect("Failed to parse descriptor in `testutils!(@internal)`").0;
    -        parsed.at_derivation_index($child).address($crate::bitcoin::Network::Regtest).expect("No address form")
    +        let parsed = Descriptor::<DescriptorPublicKey>::parse_descriptor(&secp, &$descriptors.1.expect("Missing internal descriptor")).expect("Failed to parse descriptor in `testutils!(@internal)`").0;
    +        parsed.at_derivation_index($child).address($crate::bitcoin::Network::Regtest).expect("No address form")
         });
    -    ( @e $descriptors:expr, $child:expr ) => ({ testutils!(@external $descriptors, $child) });
    -    ( @i $descriptors:expr, $child:expr ) => ({ testutils!(@internal $descriptors, $child) });
    -    ( @addr $addr:expr ) => ({ $addr });
    +    ( @e $descriptors:expr, $child:expr ) => ({ testutils!(@external $descriptors, $child) });
    +    ( @i $descriptors:expr, $child:expr ) => ({ testutils!(@internal $descriptors, $child) });
    +    ( @addr $addr:expr ) => ({ $addr });
     
    -    ( @tx ( $( ( $( $addr:tt )* ) => $amount:expr ),+ ) $( ( @inputs $( ($txid:expr, $vout:expr) ),+ ) )? $( ( @locktime $locktime:expr ) )? $( ( @confirmations $confirmations:expr ) )? $( ( @replaceable $replaceable:expr ) )? ) => ({
    -        let outs = vec![$( $crate::testutils::TestIncomingOutput::new($amount, testutils!( $($addr)* ))),+];
    -        let _ins: Vec<$crate::testutils::TestIncomingInput> = vec![];
    +    ( @tx ( $( ( $( $addr:tt )* ) => $amount:expr ),+ ) $( ( @inputs $( ($txid:expr, $vout:expr) ),+ ) )? $( ( @locktime $locktime:expr ) )? $( ( @confirmations $confirmations:expr ) )? $( ( @replaceable $replaceable:expr ) )? ) => ({
    +        let outs = vec![$( $crate::testutils::TestIncomingOutput::new($amount, testutils!( $($addr)* ))),+];
    +        let _ins: Vec<$crate::testutils::TestIncomingInput> = vec![];
             $(
    -            let _ins = vec![$( $crate::testutils::TestIncomingInput { txid: $txid, vout: $vout, sequence: None }),+];
    -        )?
    +            let _ins = vec![$( $crate::testutils::TestIncomingInput { txid: $txid, vout: $vout, sequence: None }),+];
    +        )?
     
    -        let locktime = None::<i64>$(.or(Some($locktime)))?;
    +        let locktime = None::<i64>$(.or(Some($locktime)))?;
     
    -        let min_confirmations = None::<u64>$(.or(Some($confirmations)))?;
    -        let replaceable = None::<bool>$(.or(Some($replaceable)))?;
    +        let min_confirmations = None::<u64>$(.or(Some($confirmations)))?;
    +        let replaceable = None::<bool>$(.or(Some($replaceable)))?;
     
    -        $crate::testutils::TestIncomingTx::new(_ins, outs, min_confirmations, locktime, replaceable)
    +        $crate::testutils::TestIncomingTx::new(_ins, outs, min_confirmations, locktime, replaceable)
         });
     
    -    ( @literal $key:expr ) => ({
    -        let key = $key.to_string();
    -        (key, None::<String>, None::<String>)
    +    ( @literal $key:expr ) => ({
    +        let key = $key.to_string();
    +        (key, None::<String>, None::<String>)
         });
    -    ( @generate_xprv $( $external_path:expr )? $( ,$internal_path:expr )? ) => ({
    -        use rand::Rng;
    +    ( @generate_xprv $( $external_path:expr )? $( ,$internal_path:expr )? ) => ({
    +        use rand::Rng;
     
    -        let mut seed = [0u8; 32];
    -        rand::thread_rng().fill(&mut seed[..]);
    +        let mut seed = [0u8; 32];
    +        rand::thread_rng().fill(&mut seed[..]);
     
    -        let key = $crate::bitcoin::util::bip32::ExtendedPrivKey::new_master(
    -            $crate::bitcoin::Network::Testnet,
    -            &seed,
    +        let key = $crate::bitcoin::util::bip32::ExtendedPrivKey::new_master(
    +            $crate::bitcoin::Network::Testnet,
    +            &seed,
             );
     
    -        let external_path = None::<String>$(.or(Some($external_path.to_string())))?;
    -        let internal_path = None::<String>$(.or(Some($internal_path.to_string())))?;
    +        let external_path = None::<String>$(.or(Some($external_path.to_string())))?;
    +        let internal_path = None::<String>$(.or(Some($internal_path.to_string())))?;
     
    -        (key.unwrap().to_string(), external_path, internal_path)
    +        (key.unwrap().to_string(), external_path, internal_path)
         });
    -    ( @generate_wif ) => ({
    -        use rand::Rng;
    +    ( @generate_wif ) => ({
    +        use rand::Rng;
     
    -        let mut key = [0u8; $crate::bitcoin::secp256k1::constants::SECRET_KEY_SIZE];
    -        rand::thread_rng().fill(&mut key[..]);
    +        let mut key = [0u8; $crate::bitcoin::secp256k1::constants::SECRET_KEY_SIZE];
    +        rand::thread_rng().fill(&mut key[..]);
     
    -        ($crate::bitcoin::PrivateKey {
    -            compressed: true,
    -            network: $crate::bitcoin::Network::Testnet,
    -            key: $crate::bitcoin::secp256k1::SecretKey::from_slice(&key).unwrap(),
    -        }.to_string(), None::<String>, None::<String>)
    +        ($crate::bitcoin::PrivateKey {
    +            compressed: true,
    +            network: $crate::bitcoin::Network::Testnet,
    +            key: $crate::bitcoin::secp256k1::SecretKey::from_slice(&key).unwrap(),
    +        }.to_string(), None::<String>, None::<String>)
         });
     
    -    ( @keys ( $( $alias:expr => ( $( $key_type:tt )* ) ),+ ) ) => ({
    -        let mut map = std::collections::HashMap::new();
    +    ( @keys ( $( $alias:expr => ( $( $key_type:tt )* ) ),+ ) ) => ({
    +        let mut map = std::collections::HashMap::new();
             $(
    -            let alias: &str = $alias;
    -            map.insert(alias, testutils!( $($key_type)* ));
    -        )+
    +            let alias: &str = $alias;
    +            map.insert(alias, testutils!( $($key_type)* ));
    +        )+
     
    -        map
    +        map
         });
     
    -    ( @descriptors ( $external_descriptor:expr ) $( ( $internal_descriptor:expr ) )? $( ( @keys $( $keys:tt )* ) )* ) => ({
    -        use std::str::FromStr;
    -        use std::collections::HashMap;
    -        use std::convert::Infallible;
    +    ( @descriptors ( $external_descriptor:expr ) $( ( $internal_descriptor:expr ) )? $( ( @keys $( $keys:tt )* ) )* ) => ({
    +        use std::str::FromStr;
    +        use std::collections::HashMap;
    +        use std::convert::Infallible;
     
    -        use $crate::miniscript::descriptor::Descriptor;
    -        use $crate::miniscript::TranslatePk;
    +        use $crate::miniscript::descriptor::Descriptor;
    +        use $crate::miniscript::TranslatePk;
     
    -        struct Translator {
    -            keys: HashMap<&'static str, (String, Option<String>, Option<String>)>,
    -            is_internal: bool,
    +        struct Translator {
    +            keys: HashMap<&'static str, (String, Option<String>, Option<String>)>,
    +            is_internal: bool,
             }
     
    -        impl $crate::miniscript::Translator<String, String, Infallible> for Translator {
    -            fn pk(&mut self, pk: &String) -> Result<String, Infallible> {
    -                match self.keys.get(pk.as_str()) {
    -                    Some((key, ext_path, int_path)) => {
    -                        let path = if self.is_internal { int_path } else { ext_path };
    -                        Ok(format!("{}{}", key, path.clone().unwrap_or_default()))
    +        impl $crate::miniscript::Translator<String, String, Infallible> for Translator {
    +            fn pk(&mut self, pk: &String) -> Result<String, Infallible> {
    +                match self.keys.get(pk.as_str()) {
    +                    Some((key, ext_path, int_path)) => {
    +                        let path = if self.is_internal { int_path } else { ext_path };
    +                        Ok(format!("{}{}", key, path.clone().unwrap_or_default()))
                         }
    -                    None => Ok(pk.clone()),
    +                    None => Ok(pk.clone()),
                     }
                 }
    -            fn sha256(&mut self, sha256: &String) -> Result<String, Infallible> { Ok(sha256.clone()) }
    -            fn hash256(&mut self, hash256: &String) -> Result<String, Infallible> { Ok(hash256.clone()) }
    -            fn ripemd160(&mut self, ripemd160: &String) -> Result<String, Infallible> { Ok(ripemd160.clone()) }
    -            fn hash160(&mut self, hash160: &String) -> Result<String, Infallible> { Ok(hash160.clone()) }
    +            fn sha256(&mut self, sha256: &String) -> Result<String, Infallible> { Ok(sha256.clone()) }
    +            fn hash256(&mut self, hash256: &String) -> Result<String, Infallible> { Ok(hash256.clone()) }
    +            fn ripemd160(&mut self, ripemd160: &String) -> Result<String, Infallible> { Ok(ripemd160.clone()) }
    +            fn hash160(&mut self, hash160: &String) -> Result<String, Infallible> { Ok(hash160.clone()) }
             }
     
    -        #[allow(unused_assignments, unused_mut)]
    -        let mut keys = HashMap::new();
    +        #[allow(unused_assignments, unused_mut)]
    +        let mut keys = HashMap::new();
             $(
    -            keys = testutils!{ @keys $( $keys )* };
    -        )*
    +            keys = testutils!{ @keys $( $keys )* };
    +        )*
     
    -        let mut translator = Translator { keys, is_internal: false };
    +        let mut translator = Translator { keys, is_internal: false };
     
    -        let external: Descriptor<String> = FromStr::from_str($external_descriptor).unwrap();
    -        let external = external.translate_pk(&mut translator).expect("Infallible conversion");
    -        let external = external.to_string();
    +        let external: Descriptor<String> = FromStr::from_str($external_descriptor).unwrap();
    +        let external = external.translate_pk(&mut translator).expect("Infallible conversion");
    +        let external = external.to_string();
     
    -        translator.is_internal = true;
    +        translator.is_internal = true;
     
    -        let internal = None::<String>$(.or({
    -            let internal: Descriptor<String> = FromStr::from_str($internal_descriptor).unwrap();
    -            let internal = internal.translate_pk(&mut translator).expect("Infallible conversion");
    -            Some(internal.to_string())
    +        let internal = None::<String>$(.or({
    +            let internal: Descriptor<String> = FromStr::from_str($internal_descriptor).unwrap();
    +            let internal = internal.translate_pk(&mut translator).expect("Infallible conversion");
    +            Some(internal.to_string())
             }))?;
     
    -        (external, internal)
    +        (external, internal)
         })
     }
     
    -
    - \ No newline at end of file +
    \ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/src/bdk/types.rs.html b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/src/bdk/types.rs.html index b7501081dd..235b0e08b0 100644 --- a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/src/bdk/types.rs.html +++ b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/src/bdk/types.rs.html @@ -1,628 +1,622 @@ -types.rs - source - -
      1
    -  2
    -  3
    -  4
    -  5
    -  6
    -  7
    -  8
    -  9
    - 10
    - 11
    - 12
    - 13
    - 14
    - 15
    - 16
    - 17
    - 18
    - 19
    - 20
    - 21
    - 22
    - 23
    - 24
    - 25
    - 26
    - 27
    - 28
    - 29
    - 30
    - 31
    - 32
    - 33
    - 34
    - 35
    - 36
    - 37
    - 38
    - 39
    - 40
    - 41
    - 42
    - 43
    - 44
    - 45
    - 46
    - 47
    - 48
    - 49
    - 50
    - 51
    - 52
    - 53
    - 54
    - 55
    - 56
    - 57
    - 58
    - 59
    - 60
    - 61
    - 62
    - 63
    - 64
    - 65
    - 66
    - 67
    - 68
    - 69
    - 70
    - 71
    - 72
    - 73
    - 74
    - 75
    - 76
    - 77
    - 78
    - 79
    - 80
    - 81
    - 82
    - 83
    - 84
    - 85
    - 86
    - 87
    - 88
    - 89
    - 90
    - 91
    - 92
    - 93
    - 94
    - 95
    - 96
    - 97
    - 98
    - 99
    -100
    -101
    -102
    -103
    -104
    -105
    -106
    -107
    -108
    -109
    -110
    -111
    -112
    -113
    -114
    -115
    -116
    -117
    -118
    -119
    -120
    -121
    -122
    -123
    -124
    -125
    -126
    -127
    -128
    -129
    -130
    -131
    -132
    -133
    -134
    -135
    -136
    -137
    -138
    -139
    -140
    -141
    -142
    -143
    -144
    -145
    -146
    -147
    -148
    -149
    -150
    -151
    -152
    -153
    -154
    -155
    -156
    -157
    -158
    -159
    -160
    -161
    -162
    -163
    -164
    -165
    -166
    -167
    -168
    -169
    -170
    -171
    -172
    -173
    -174
    -175
    -176
    -177
    -178
    -179
    -180
    -181
    -182
    -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
    -245
    -246
    -247
    -248
    -249
    -250
    -251
    -252
    -253
    -254
    -255
    -256
    -257
    -258
    -259
    -260
    -261
    -262
    -263
    -264
    -265
    -266
    -267
    -268
    -269
    -270
    -271
    -272
    -273
    -274
    -275
    -276
    -277
    -278
    -279
    -280
    -281
    -282
    -283
    -284
    -285
    -286
    -287
    -288
    -289
    -290
    -291
    -292
    -293
    -294
    -295
    -296
    -297
    -298
    -299
    -300
    -301
    -302
    -303
    -304
    -305
    -306
    -307
    -308
    -309
    -310
    -311
    -312
    -313
    -314
    -315
    -316
    -317
    -318
    -319
    -320
    -321
    -322
    -323
    -324
    -325
    -326
    -327
    -328
    -329
    -330
    -331
    -332
    -333
    -334
    -335
    -336
    -337
    -338
    -339
    -340
    -341
    -342
    -343
    -344
    -345
    -346
    -347
    -348
    -349
    -350
    -351
    -352
    -353
    -354
    -355
    -356
    -357
    -358
    -359
    -360
    -361
    -362
    -363
    -364
    -365
    -366
    -367
    -368
    -369
    -370
    -371
    -372
    -373
    -374
    -375
    -376
    -377
    -378
    -379
    -380
    -381
    -382
    -383
    -384
    -385
    -386
    -387
    -388
    -389
    -390
    -391
    -392
    -393
    -394
    -395
    -396
    -397
    -398
    -399
    -400
    -401
    -
    // Bitcoin Dev Kit
    -// Written in 2020 by Alekos Filini <alekos.filini@gmail.com>
    -//
    -// Copyright (c) 2020-2021 Bitcoin Dev Kit Developers
    -//
    -// This file is licensed under the Apache License, Version 2.0 <LICENSE-APACHE
    -// or http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
    -// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your option.
    -// You may not use this file except in accordance with one or both of these
    -// licenses.
    -
    -use std::convert::AsRef;
    -use std::ops::Sub;
    -
    -use bitcoin::blockdata::transaction::{OutPoint, Transaction, TxOut};
    -use bitcoin::{hash_types::Txid, util::psbt};
    -
    -use serde::{Deserialize, Serialize};
    -
    -/// Types of keychains
    -#[derive(Serialize, Deserialize, Debug, Clone, Copy, PartialEq, Eq, Hash)]
    -pub enum KeychainKind {
    -    /// External
    -    External = 0,
    -    /// Internal, usually used for change outputs
    -    Internal = 1,
    +types.rs - source
    1
    +2
    +3
    +4
    +5
    +6
    +7
    +8
    +9
    +10
    +11
    +12
    +13
    +14
    +15
    +16
    +17
    +18
    +19
    +20
    +21
    +22
    +23
    +24
    +25
    +26
    +27
    +28
    +29
    +30
    +31
    +32
    +33
    +34
    +35
    +36
    +37
    +38
    +39
    +40
    +41
    +42
    +43
    +44
    +45
    +46
    +47
    +48
    +49
    +50
    +51
    +52
    +53
    +54
    +55
    +56
    +57
    +58
    +59
    +60
    +61
    +62
    +63
    +64
    +65
    +66
    +67
    +68
    +69
    +70
    +71
    +72
    +73
    +74
    +75
    +76
    +77
    +78
    +79
    +80
    +81
    +82
    +83
    +84
    +85
    +86
    +87
    +88
    +89
    +90
    +91
    +92
    +93
    +94
    +95
    +96
    +97
    +98
    +99
    +100
    +101
    +102
    +103
    +104
    +105
    +106
    +107
    +108
    +109
    +110
    +111
    +112
    +113
    +114
    +115
    +116
    +117
    +118
    +119
    +120
    +121
    +122
    +123
    +124
    +125
    +126
    +127
    +128
    +129
    +130
    +131
    +132
    +133
    +134
    +135
    +136
    +137
    +138
    +139
    +140
    +141
    +142
    +143
    +144
    +145
    +146
    +147
    +148
    +149
    +150
    +151
    +152
    +153
    +154
    +155
    +156
    +157
    +158
    +159
    +160
    +161
    +162
    +163
    +164
    +165
    +166
    +167
    +168
    +169
    +170
    +171
    +172
    +173
    +174
    +175
    +176
    +177
    +178
    +179
    +180
    +181
    +182
    +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
    +245
    +246
    +247
    +248
    +249
    +250
    +251
    +252
    +253
    +254
    +255
    +256
    +257
    +258
    +259
    +260
    +261
    +262
    +263
    +264
    +265
    +266
    +267
    +268
    +269
    +270
    +271
    +272
    +273
    +274
    +275
    +276
    +277
    +278
    +279
    +280
    +281
    +282
    +283
    +284
    +285
    +286
    +287
    +288
    +289
    +290
    +291
    +292
    +293
    +294
    +295
    +296
    +297
    +298
    +299
    +300
    +301
    +302
    +303
    +304
    +305
    +306
    +307
    +308
    +309
    +310
    +311
    +312
    +313
    +314
    +315
    +316
    +317
    +318
    +319
    +320
    +321
    +322
    +323
    +324
    +325
    +326
    +327
    +328
    +329
    +330
    +331
    +332
    +333
    +334
    +335
    +336
    +337
    +338
    +339
    +340
    +341
    +342
    +343
    +344
    +345
    +346
    +347
    +348
    +349
    +350
    +351
    +352
    +353
    +354
    +355
    +356
    +357
    +358
    +359
    +360
    +361
    +362
    +363
    +364
    +365
    +366
    +367
    +368
    +369
    +370
    +371
    +372
    +373
    +374
    +375
    +376
    +377
    +378
    +379
    +380
    +381
    +382
    +383
    +384
    +385
    +386
    +387
    +388
    +389
    +390
    +391
    +392
    +393
    +394
    +395
    +396
    +397
    +398
    +399
    +400
    +401
    +
    // Bitcoin Dev Kit
    +// Written in 2020 by Alekos Filini <alekos.filini@gmail.com>
    +//
    +// Copyright (c) 2020-2021 Bitcoin Dev Kit Developers
    +//
    +// This file is licensed under the Apache License, Version 2.0 <LICENSE-APACHE
    +// or http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
    +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your option.
    +// You may not use this file except in accordance with one or both of these
    +// licenses.
    +
    +use std::convert::AsRef;
    +use std::ops::Sub;
    +
    +use bitcoin::blockdata::transaction::{OutPoint, Transaction, TxOut};
    +use bitcoin::{hash_types::Txid, util::psbt};
    +
    +use serde::{Deserialize, Serialize};
    +
    +/// Types of keychains
    +#[derive(Serialize, Deserialize, Debug, Clone, Copy, PartialEq, Eq, Hash)]
    +pub enum KeychainKind {
    +    /// External
    +    External = 0,
    +    /// Internal, usually used for change outputs
    +    Internal = 1,
     }
     
    -impl KeychainKind {
    -    /// Return [`KeychainKind`] as a byte
    -    pub fn as_byte(&self) -> u8 {
    -        match self {
    -            KeychainKind::External => b'e',
    -            KeychainKind::Internal => b'i',
    +impl KeychainKind {
    +    /// Return [`KeychainKind`] as a byte
    +    pub fn as_byte(&self) -> u8 {
    +        match self {
    +            KeychainKind::External => b'e',
    +            KeychainKind::Internal => b'i',
             }
         }
     }
     
    -impl AsRef<[u8]> for KeychainKind {
    -    fn as_ref(&self) -> &[u8] {
    -        match self {
    -            KeychainKind::External => b"e",
    -            KeychainKind::Internal => b"i",
    +impl AsRef<[u8]> for KeychainKind {
    +    fn as_ref(&self) -> &[u8] {
    +        match self {
    +            KeychainKind::External => b"e",
    +            KeychainKind::Internal => b"i",
             }
         }
     }
     
    -/// Fee rate
    -#[derive(Debug, Copy, Clone, PartialEq, PartialOrd)]
    -// Internally stored as satoshi/vbyte
    -pub struct FeeRate(f32);
    +/// Fee rate
    +#[derive(Debug, Copy, Clone, PartialEq, PartialOrd)]
    +// Internally stored as satoshi/vbyte
    +pub struct FeeRate(f32);
     
    -impl FeeRate {
    -    /// Create a new instance checking the value provided
    -    ///
    -    /// ## Panics
    -    ///
    -    /// Panics if the value is not [normal](https://doc.rust-lang.org/std/primitive.f32.html#method.is_normal) (except if it's a positive zero) or negative.
    -    fn new_checked(value: f32) -> Self {
    -        assert!(value.is_normal() || value == 0.0);
    -        assert!(value.is_sign_positive());
    +impl FeeRate {
    +    /// Create a new instance checking the value provided
    +    ///
    +    /// ## Panics
    +    ///
    +    /// Panics if the value is not [normal](https://doc.rust-lang.org/std/primitive.f32.html#method.is_normal) (except if it's a positive zero) or negative.
    +    fn new_checked(value: f32) -> Self {
    +        assert!(value.is_normal() || value == 0.0);
    +        assert!(value.is_sign_positive());
     
    -        FeeRate(value)
    +        FeeRate(value)
         }
     
    -    /// Create a new instance of [`FeeRate`] given a float fee rate in sats/kwu
    -    pub fn from_sat_per_kwu(sat_per_kwu: f32) -> Self {
    -        FeeRate::new_checked(sat_per_kwu / 250.0_f32)
    +    /// Create a new instance of [`FeeRate`] given a float fee rate in sats/kwu
    +    pub fn from_sat_per_kwu(sat_per_kwu: f32) -> Self {
    +        FeeRate::new_checked(sat_per_kwu / 250.0_f32)
         }
     
    -    /// Create a new instance of [`FeeRate`] given a float fee rate in sats/kvb
    -    pub fn from_sat_per_kvb(sat_per_kvb: f32) -> Self {
    -        FeeRate::new_checked(sat_per_kvb / 1000.0_f32)
    +    /// Create a new instance of [`FeeRate`] given a float fee rate in sats/kvb
    +    pub fn from_sat_per_kvb(sat_per_kvb: f32) -> Self {
    +        FeeRate::new_checked(sat_per_kvb / 1000.0_f32)
         }
     
    -    /// Create a new instance of [`FeeRate`] given a float fee rate in btc/kvbytes
    -    ///
    -    /// ## Panics
    -    ///
    -    /// Panics if the value is not [normal](https://doc.rust-lang.org/std/primitive.f32.html#method.is_normal) (except if it's a positive zero) or negative.
    -    pub fn from_btc_per_kvb(btc_per_kvb: f32) -> Self {
    -        FeeRate::new_checked(btc_per_kvb * 1e5)
    +    /// Create a new instance of [`FeeRate`] given a float fee rate in btc/kvbytes
    +    ///
    +    /// ## Panics
    +    ///
    +    /// Panics if the value is not [normal](https://doc.rust-lang.org/std/primitive.f32.html#method.is_normal) (except if it's a positive zero) or negative.
    +    pub fn from_btc_per_kvb(btc_per_kvb: f32) -> Self {
    +        FeeRate::new_checked(btc_per_kvb * 1e5)
         }
     
    -    /// Create a new instance of [`FeeRate`] given a float fee rate in satoshi/vbyte
    -    ///
    -    /// ## Panics
    -    ///
    -    /// Panics if the value is not [normal](https://doc.rust-lang.org/std/primitive.f32.html#method.is_normal) (except if it's a positive zero) or negative.
    -    pub fn from_sat_per_vb(sat_per_vb: f32) -> Self {
    -        FeeRate::new_checked(sat_per_vb)
    +    /// Create a new instance of [`FeeRate`] given a float fee rate in satoshi/vbyte
    +    ///
    +    /// ## Panics
    +    ///
    +    /// Panics if the value is not [normal](https://doc.rust-lang.org/std/primitive.f32.html#method.is_normal) (except if it's a positive zero) or negative.
    +    pub fn from_sat_per_vb(sat_per_vb: f32) -> Self {
    +        FeeRate::new_checked(sat_per_vb)
         }
     
    -    /// Create a new [`FeeRate`] with the default min relay fee value
    -    pub const fn default_min_relay_fee() -> Self {
    -        FeeRate(1.0)
    +    /// Create a new [`FeeRate`] with the default min relay fee value
    +    pub const fn default_min_relay_fee() -> Self {
    +        FeeRate(1.0)
         }
     
    -    /// Calculate fee rate from `fee` and weight units (`wu`).
    -    pub fn from_wu(fee: u64, wu: usize) -> FeeRate {
    -        Self::from_vb(fee, wu.vbytes())
    +    /// Calculate fee rate from `fee` and weight units (`wu`).
    +    pub fn from_wu(fee: u64, wu: usize) -> FeeRate {
    +        Self::from_vb(fee, wu.vbytes())
         }
     
    -    /// Calculate fee rate from `fee` and `vbytes`.
    -    pub fn from_vb(fee: u64, vbytes: usize) -> FeeRate {
    -        let rate = fee as f32 / vbytes as f32;
    -        Self::from_sat_per_vb(rate)
    +    /// Calculate fee rate from `fee` and `vbytes`.
    +    pub fn from_vb(fee: u64, vbytes: usize) -> FeeRate {
    +        let rate = fee as f32 / vbytes as f32;
    +        Self::from_sat_per_vb(rate)
         }
     
    -    /// Return the value as satoshi/vbyte
    -    pub fn as_sat_per_vb(&self) -> f32 {
    -        self.0
    -    }
    +    /// Return the value as satoshi/vbyte
    +    pub fn as_sat_per_vb(&self) -> f32 {
    +        self.0
    +    }
     
    -    /// Calculate absolute fee in Satoshis using size in weight units.
    -    pub fn fee_wu(&self, wu: usize) -> u64 {
    -        self.fee_vb(wu.vbytes())
    +    /// Calculate absolute fee in Satoshis using size in weight units.
    +    pub fn fee_wu(&self, wu: usize) -> u64 {
    +        self.fee_vb(wu.vbytes())
         }
     
    -    /// Calculate absolute fee in Satoshis using size in virtual bytes.
    -    pub fn fee_vb(&self, vbytes: usize) -> u64 {
    -        (self.as_sat_per_vb() * vbytes as f32).ceil() as u64
    +    /// Calculate absolute fee in Satoshis using size in virtual bytes.
    +    pub fn fee_vb(&self, vbytes: usize) -> u64 {
    +        (self.as_sat_per_vb() * vbytes as f32).ceil() as u64
         }
     }
     
    -impl std::default::Default for FeeRate {
    -    fn default() -> Self {
    -        FeeRate::default_min_relay_fee()
    +impl std::default::Default for FeeRate {
    +    fn default() -> Self {
    +        FeeRate::default_min_relay_fee()
         }
     }
     
    -impl Sub for FeeRate {
    -    type Output = Self;
    +impl Sub for FeeRate {
    +    type Output = Self;
     
    -    fn sub(self, other: FeeRate) -> Self::Output {
    -        FeeRate(self.0 - other.0)
    +    fn sub(self, other: FeeRate) -> Self::Output {
    +        FeeRate(self.0 - other.0)
         }
     }
     
    -/// Trait implemented by types that can be used to measure weight units.
    -pub trait Vbytes {
    -    /// Convert weight units to virtual bytes.
    -    fn vbytes(self) -> usize;
    +/// Trait implemented by types that can be used to measure weight units.
    +pub trait Vbytes {
    +    /// Convert weight units to virtual bytes.
    +    fn vbytes(self) -> usize;
     }
     
    -impl Vbytes for usize {
    -    fn vbytes(self) -> usize {
    -        // ref: https://github.com/bitcoin/bips/blob/master/bip-0141.mediawiki#transaction-size-calculations
    -        (self as f32 / 4.0).ceil() as usize
    +impl Vbytes for usize {
    +    fn vbytes(self) -> usize {
    +        // ref: https://github.com/bitcoin/bips/blob/master/bip-0141.mediawiki#transaction-size-calculations
    +        (self as f32 / 4.0).ceil() as usize
         }
     }
     
    -/// An unspent output owned by a [`Wallet`].
    -///
    -/// [`Wallet`]: crate::Wallet
    -#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, Hash)]
    -pub struct LocalUtxo {
    -    /// Reference to a transaction output
    -    pub outpoint: OutPoint,
    -    /// Transaction output
    -    pub txout: TxOut,
    -    /// Type of keychain
    -    pub keychain: KeychainKind,
    -    /// Whether this UTXO is spent or not
    -    pub is_spent: bool,
    +/// An unspent output owned by a [`Wallet`].
    +///
    +/// [`Wallet`]: crate::Wallet
    +#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, Hash)]
    +pub struct LocalUtxo {
    +    /// Reference to a transaction output
    +    pub outpoint: OutPoint,
    +    /// Transaction output
    +    pub txout: TxOut,
    +    /// Type of keychain
    +    pub keychain: KeychainKind,
    +    /// Whether this UTXO is spent or not
    +    pub is_spent: bool,
     }
     
    -/// A [`Utxo`] with its `satisfaction_weight`.
    -#[derive(Debug, Clone, PartialEq, Eq)]
    -pub struct WeightedUtxo {
    -    /// The weight of the witness data and `scriptSig` expressed in [weight units]. This is used to
    -    /// properly maintain the feerate when adding this input to a transaction during coin selection.
    -    ///
    -    /// [weight units]: https://en.bitcoin.it/wiki/Weight_units
    -    pub satisfaction_weight: usize,
    -    /// The UTXO
    -    pub utxo: Utxo,
    +/// A [`Utxo`] with its `satisfaction_weight`.
    +#[derive(Debug, Clone, PartialEq, Eq)]
    +pub struct WeightedUtxo {
    +    /// The weight of the witness data and `scriptSig` expressed in [weight units]. This is used to
    +    /// properly maintain the feerate when adding this input to a transaction during coin selection.
    +    ///
    +    /// [weight units]: https://en.bitcoin.it/wiki/Weight_units
    +    pub satisfaction_weight: usize,
    +    /// The UTXO
    +    pub utxo: Utxo,
     }
     
    -#[derive(Debug, Clone, PartialEq, Eq)]
    -/// An unspent transaction output (UTXO).
    -pub enum Utxo {
    -    /// A UTXO owned by the local wallet.
    -    Local(LocalUtxo),
    -    /// A UTXO owned by another wallet.
    -    Foreign {
    -        /// The location of the output.
    -        outpoint: OutPoint,
    -        /// The information about the input we require to add it to a PSBT.
    -        // Box it to stop the type being too big.
    -        psbt_input: Box<psbt::Input>,
    +#[derive(Debug, Clone, PartialEq, Eq)]
    +/// An unspent transaction output (UTXO).
    +pub enum Utxo {
    +    /// A UTXO owned by the local wallet.
    +    Local(LocalUtxo),
    +    /// A UTXO owned by another wallet.
    +    Foreign {
    +        /// The location of the output.
    +        outpoint: OutPoint,
    +        /// The information about the input we require to add it to a PSBT.
    +        // Box it to stop the type being too big.
    +        psbt_input: Box<psbt::Input>,
         },
     }
     
    -impl Utxo {
    -    /// Get the location of the UTXO
    -    pub fn outpoint(&self) -> OutPoint {
    -        match &self {
    -            Utxo::Local(local) => local.outpoint,
    -            Utxo::Foreign { outpoint, .. } => *outpoint,
    +impl Utxo {
    +    /// Get the location of the UTXO
    +    pub fn outpoint(&self) -> OutPoint {
    +        match &self {
    +            Utxo::Local(local) => local.outpoint,
    +            Utxo::Foreign { outpoint, .. } => *outpoint,
             }
         }
     
    -    /// Get the `TxOut` of the UTXO
    -    pub fn txout(&self) -> &TxOut {
    -        match &self {
    -            Utxo::Local(local) => &local.txout,
    -            Utxo::Foreign {
    -                outpoint,
    -                psbt_input,
    +    /// Get the `TxOut` of the UTXO
    +    pub fn txout(&self) -> &TxOut {
    +        match &self {
    +            Utxo::Local(local) => &local.txout,
    +            Utxo::Foreign {
    +                outpoint,
    +                psbt_input,
                 } => {
    -                if let Some(prev_tx) = &psbt_input.non_witness_utxo {
    -                    return &prev_tx.output[outpoint.vout as usize];
    +                if let Some(prev_tx) = &psbt_input.non_witness_utxo {
    +                    return &prev_tx.output[outpoint.vout as usize];
                     }
     
    -                if let Some(txout) = &psbt_input.witness_utxo {
    -                    return txout;
    +                if let Some(txout) = &psbt_input.witness_utxo {
    +                    return txout;
                     }
     
                     unreachable!("Foreign UTXOs will always have one of these set")
    @@ -631,182 +625,181 @@
         }
     }
     
    -/// A wallet transaction
    -#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq)]
    -pub struct TransactionDetails {
    -    /// Optional transaction
    -    pub transaction: Option<Transaction>,
    -    /// Transaction id
    -    pub txid: Txid,
    -
    -    /// Received value (sats)
    -    /// Sum of owned outputs of this transaction.
    -    pub received: u64,
    -    /// Sent value (sats)
    -    /// Sum of owned inputs of this transaction.
    -    pub sent: u64,
    -    /// Fee value (sats) if confirmed.
    -    /// The availability of the fee depends on the backend. It's never `None` with an Electrum
    -    /// Server backend, but it could be `None` with a Bitcoin RPC node without txindex that receive
    -    /// funds while offline.
    -    pub fee: Option<u64>,
    -    /// If the transaction is confirmed, contains height and timestamp of the block containing the
    -    /// transaction, unconfirmed transaction contains `None`.
    -    pub confirmation_time: Option<BlockTime>,
    +/// A wallet transaction
    +#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq)]
    +pub struct TransactionDetails {
    +    /// Optional transaction
    +    pub transaction: Option<Transaction>,
    +    /// Transaction id
    +    pub txid: Txid,
    +
    +    /// Received value (sats)
    +    /// Sum of owned outputs of this transaction.
    +    pub received: u64,
    +    /// Sent value (sats)
    +    /// Sum of owned inputs of this transaction.
    +    pub sent: u64,
    +    /// Fee value (sats) if confirmed.
    +    /// The availability of the fee depends on the backend. It's never `None` with an Electrum
    +    /// Server backend, but it could be `None` with a Bitcoin RPC node without txindex that receive
    +    /// funds while offline.
    +    pub fee: Option<u64>,
    +    /// If the transaction is confirmed, contains height and timestamp of the block containing the
    +    /// transaction, unconfirmed transaction contains `None`.
    +    pub confirmation_time: Option<BlockTime>,
     }
     
    -/// Block height and timestamp of a block
    -#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, Default)]
    -pub struct BlockTime {
    -    /// confirmation block height
    -    pub height: u32,
    -    /// confirmation block timestamp
    -    pub timestamp: u64,
    +/// Block height and timestamp of a block
    +#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, Default)]
    +pub struct BlockTime {
    +    /// confirmation block height
    +    pub height: u32,
    +    /// confirmation block timestamp
    +    pub timestamp: u64,
     }
     
    -/// **DEPRECATED**: Confirmation time of a transaction
    -///
    -/// The structure has been renamed to `BlockTime`
    -#[deprecated(note = "This structure has been renamed to `BlockTime`")]
    -pub type ConfirmationTime = BlockTime;
    -
    -impl BlockTime {
    -    /// Returns `Some` `BlockTime` if both `height` and `timestamp` are `Some`
    -    pub fn new(height: Option<u32>, timestamp: Option<u64>) -> Option<Self> {
    -        match (height, timestamp) {
    -            (Some(height), Some(timestamp)) => Some(BlockTime { height, timestamp }),
    -            _ => None,
    +/// **DEPRECATED**: Confirmation time of a transaction
    +///
    +/// The structure has been renamed to `BlockTime`
    +#[deprecated(note = "This structure has been renamed to `BlockTime`")]
    +pub type ConfirmationTime = BlockTime;
    +
    +impl BlockTime {
    +    /// Returns `Some` `BlockTime` if both `height` and `timestamp` are `Some`
    +    pub fn new(height: Option<u32>, timestamp: Option<u64>) -> Option<Self> {
    +        match (height, timestamp) {
    +            (Some(height), Some(timestamp)) => Some(BlockTime { height, timestamp }),
    +            _ => None,
             }
         }
     }
     
    -/// Balance differentiated in various categories
    -#[derive(Serialize, Deserialize, Debug, PartialEq, Eq, Clone, Default)]
    -pub struct Balance {
    -    /// All coinbase outputs not yet matured
    -    pub immature: u64,
    -    /// Unconfirmed UTXOs generated by a wallet tx
    -    pub trusted_pending: u64,
    -    /// Unconfirmed UTXOs received from an external wallet
    -    pub untrusted_pending: u64,
    -    /// Confirmed and immediately spendable balance
    -    pub confirmed: u64,
    +/// Balance differentiated in various categories
    +#[derive(Serialize, Deserialize, Debug, PartialEq, Eq, Clone, Default)]
    +pub struct Balance {
    +    /// All coinbase outputs not yet matured
    +    pub immature: u64,
    +    /// Unconfirmed UTXOs generated by a wallet tx
    +    pub trusted_pending: u64,
    +    /// Unconfirmed UTXOs received from an external wallet
    +    pub untrusted_pending: u64,
    +    /// Confirmed and immediately spendable balance
    +    pub confirmed: u64,
     }
     
    -impl Balance {
    -    /// Get sum of trusted_pending and confirmed coins
    -    pub fn get_spendable(&self) -> u64 {
    -        self.confirmed + self.trusted_pending
    +impl Balance {
    +    /// Get sum of trusted_pending and confirmed coins
    +    pub fn get_spendable(&self) -> u64 {
    +        self.confirmed + self.trusted_pending
         }
     
    -    /// Get the whole balance visible to the wallet
    -    pub fn get_total(&self) -> u64 {
    -        self.confirmed + self.trusted_pending + self.untrusted_pending + self.immature
    +    /// Get the whole balance visible to the wallet
    +    pub fn get_total(&self) -> u64 {
    +        self.confirmed + self.trusted_pending + self.untrusted_pending + self.immature
         }
     }
     
    -impl std::fmt::Display for Balance {
    -    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
    +impl std::fmt::Display for Balance {
    +    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
             write!(
    -            f,
    +            f,
                 "{{ immature: {}, trusted_pending: {}, untrusted_pending: {}, confirmed: {} }}",
    -            self.immature, self.trusted_pending, self.untrusted_pending, self.confirmed
    +            self.immature, self.trusted_pending, self.untrusted_pending, self.confirmed
             )
         }
     }
     
    -impl std::ops::Add for Balance {
    -    type Output = Self;
    +impl std::ops::Add for Balance {
    +    type Output = Self;
     
    -    fn add(self, other: Self) -> Self {
    -        Self {
    -            immature: self.immature + other.immature,
    -            trusted_pending: self.trusted_pending + other.trusted_pending,
    -            untrusted_pending: self.untrusted_pending + other.untrusted_pending,
    -            confirmed: self.confirmed + other.confirmed,
    +    fn add(self, other: Self) -> Self {
    +        Self {
    +            immature: self.immature + other.immature,
    +            trusted_pending: self.trusted_pending + other.trusted_pending,
    +            untrusted_pending: self.untrusted_pending + other.untrusted_pending,
    +            confirmed: self.confirmed + other.confirmed,
             }
         }
     }
     
    -impl std::iter::Sum for Balance {
    -    fn sum<I: Iterator<Item = Self>>(iter: I) -> Self {
    -        iter.fold(
    -            Balance {
    -                ..Default::default()
    +impl std::iter::Sum for Balance {
    +    fn sum<I: Iterator<Item = Self>>(iter: I) -> Self {
    +        iter.fold(
    +            Balance {
    +                ..Default::default()
                 },
    -            |a, b| a + b,
    +            |a, b| a + b,
             )
         }
     }
     
    -#[cfg(test)]
    -mod tests {
    -    use super::*;
    +#[cfg(test)]
    +mod tests {
    +    use super::*;
     
    -    #[test]
    -    fn can_store_feerate_in_const() {
    -        const _MIN_RELAY: FeeRate = FeeRate::default_min_relay_fee();
    +    #[test]
    +    fn can_store_feerate_in_const() {
    +        const _MIN_RELAY: FeeRate = FeeRate::default_min_relay_fee();
         }
     
    -    #[test]
    -    #[should_panic]
    -    fn test_invalid_feerate_neg_zero() {
    -        let _ = FeeRate::from_sat_per_vb(-0.0);
    +    #[test]
    +    #[should_panic]
    +    fn test_invalid_feerate_neg_zero() {
    +        let _ = FeeRate::from_sat_per_vb(-0.0);
         }
     
    -    #[test]
    -    #[should_panic]
    -    fn test_invalid_feerate_neg_value() {
    -        let _ = FeeRate::from_sat_per_vb(-5.0);
    +    #[test]
    +    #[should_panic]
    +    fn test_invalid_feerate_neg_value() {
    +        let _ = FeeRate::from_sat_per_vb(-5.0);
         }
     
    -    #[test]
    -    #[should_panic]
    -    fn test_invalid_feerate_nan() {
    -        let _ = FeeRate::from_sat_per_vb(f32::NAN);
    +    #[test]
    +    #[should_panic]
    +    fn test_invalid_feerate_nan() {
    +        let _ = FeeRate::from_sat_per_vb(f32::NAN);
         }
     
    -    #[test]
    -    #[should_panic]
    -    fn test_invalid_feerate_inf() {
    -        let _ = FeeRate::from_sat_per_vb(f32::INFINITY);
    +    #[test]
    +    #[should_panic]
    +    fn test_invalid_feerate_inf() {
    +        let _ = FeeRate::from_sat_per_vb(f32::INFINITY);
         }
     
    -    #[test]
    -    fn test_valid_feerate_pos_zero() {
    -        let _ = FeeRate::from_sat_per_vb(0.0);
    +    #[test]
    +    fn test_valid_feerate_pos_zero() {
    +        let _ = FeeRate::from_sat_per_vb(0.0);
         }
     
    -    #[test]
    -    fn test_fee_from_btc_per_kvb() {
    -        let fee = FeeRate::from_btc_per_kvb(1e-5);
    -        assert!((fee.as_sat_per_vb() - 1.0).abs() < f32::EPSILON);
    +    #[test]
    +    fn test_fee_from_btc_per_kvb() {
    +        let fee = FeeRate::from_btc_per_kvb(1e-5);
    +        assert!((fee.as_sat_per_vb() - 1.0).abs() < f32::EPSILON);
         }
     
    -    #[test]
    -    fn test_fee_from_sat_per_vbyte() {
    -        let fee = FeeRate::from_sat_per_vb(1.0);
    -        assert!((fee.as_sat_per_vb() - 1.0).abs() < f32::EPSILON);
    +    #[test]
    +    fn test_fee_from_sat_per_vbyte() {
    +        let fee = FeeRate::from_sat_per_vb(1.0);
    +        assert!((fee.as_sat_per_vb() - 1.0).abs() < f32::EPSILON);
         }
     
    -    #[test]
    -    fn test_fee_default_min_relay_fee() {
    -        let fee = FeeRate::default_min_relay_fee();
    -        assert!((fee.as_sat_per_vb() - 1.0).abs() < f32::EPSILON);
    +    #[test]
    +    fn test_fee_default_min_relay_fee() {
    +        let fee = FeeRate::default_min_relay_fee();
    +        assert!((fee.as_sat_per_vb() - 1.0).abs() < f32::EPSILON);
         }
     
    -    #[test]
    -    fn test_fee_from_sat_per_kvb() {
    -        let fee = FeeRate::from_sat_per_kvb(1000.0);
    -        assert!((fee.as_sat_per_vb() - 1.0).abs() < f32::EPSILON);
    +    #[test]
    +    fn test_fee_from_sat_per_kvb() {
    +        let fee = FeeRate::from_sat_per_kvb(1000.0);
    +        assert!((fee.as_sat_per_vb() - 1.0).abs() < f32::EPSILON);
         }
     
    -    #[test]
    -    fn test_fee_from_sat_per_kwu() {
    -        let fee = FeeRate::from_sat_per_kwu(250.0);
    -        assert!((fee.as_sat_per_vb() - 1.0).abs() < f32::EPSILON);
    +    #[test]
    +    fn test_fee_from_sat_per_kwu() {
    +        let fee = FeeRate::from_sat_per_kwu(250.0);
    +        assert!((fee.as_sat_per_vb() - 1.0).abs() < f32::EPSILON);
         }
     }
     
    -
    - \ No newline at end of file +
    \ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/src/bdk/wallet/coin_selection.rs.html b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/src/bdk/wallet/coin_selection.rs.html index 96e56095a7..253f37f6b8 100644 --- a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/src/bdk/wallet/coin_selection.rs.html +++ b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/src/bdk/wallet/coin_selection.rs.html @@ -1,3210 +1,3203 @@ -coin_selection.rs - source - -
       1
    -   2
    -   3
    -   4
    -   5
    -   6
    -   7
    -   8
    -   9
    -  10
    -  11
    -  12
    -  13
    -  14
    -  15
    -  16
    -  17
    -  18
    -  19
    -  20
    -  21
    -  22
    -  23
    -  24
    -  25
    -  26
    -  27
    -  28
    -  29
    -  30
    -  31
    -  32
    -  33
    -  34
    -  35
    -  36
    -  37
    -  38
    -  39
    -  40
    -  41
    -  42
    -  43
    -  44
    -  45
    -  46
    -  47
    -  48
    -  49
    -  50
    -  51
    -  52
    -  53
    -  54
    -  55
    -  56
    -  57
    -  58
    -  59
    -  60
    -  61
    -  62
    -  63
    -  64
    -  65
    -  66
    -  67
    -  68
    -  69
    -  70
    -  71
    -  72
    -  73
    -  74
    -  75
    -  76
    -  77
    -  78
    -  79
    -  80
    -  81
    -  82
    -  83
    -  84
    -  85
    -  86
    -  87
    -  88
    -  89
    -  90
    -  91
    -  92
    -  93
    -  94
    -  95
    -  96
    -  97
    -  98
    -  99
    - 100
    - 101
    - 102
    - 103
    - 104
    - 105
    - 106
    - 107
    - 108
    - 109
    - 110
    - 111
    - 112
    - 113
    - 114
    - 115
    - 116
    - 117
    - 118
    - 119
    - 120
    - 121
    - 122
    - 123
    - 124
    - 125
    - 126
    - 127
    - 128
    - 129
    - 130
    - 131
    - 132
    - 133
    - 134
    - 135
    - 136
    - 137
    - 138
    - 139
    - 140
    - 141
    - 142
    - 143
    - 144
    - 145
    - 146
    - 147
    - 148
    - 149
    - 150
    - 151
    - 152
    - 153
    - 154
    - 155
    - 156
    - 157
    - 158
    - 159
    - 160
    - 161
    - 162
    - 163
    - 164
    - 165
    - 166
    - 167
    - 168
    - 169
    - 170
    - 171
    - 172
    - 173
    - 174
    - 175
    - 176
    - 177
    - 178
    - 179
    - 180
    - 181
    - 182
    - 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
    - 245
    - 246
    - 247
    - 248
    - 249
    - 250
    - 251
    - 252
    - 253
    - 254
    - 255
    - 256
    - 257
    - 258
    - 259
    - 260
    - 261
    - 262
    - 263
    - 264
    - 265
    - 266
    - 267
    - 268
    - 269
    - 270
    - 271
    - 272
    - 273
    - 274
    - 275
    - 276
    - 277
    - 278
    - 279
    - 280
    - 281
    - 282
    - 283
    - 284
    - 285
    - 286
    - 287
    - 288
    - 289
    - 290
    - 291
    - 292
    - 293
    - 294
    - 295
    - 296
    - 297
    - 298
    - 299
    - 300
    - 301
    - 302
    - 303
    - 304
    - 305
    - 306
    - 307
    - 308
    - 309
    - 310
    - 311
    - 312
    - 313
    - 314
    - 315
    - 316
    - 317
    - 318
    - 319
    - 320
    - 321
    - 322
    - 323
    - 324
    - 325
    - 326
    - 327
    - 328
    - 329
    - 330
    - 331
    - 332
    - 333
    - 334
    - 335
    - 336
    - 337
    - 338
    - 339
    - 340
    - 341
    - 342
    - 343
    - 344
    - 345
    - 346
    - 347
    - 348
    - 349
    - 350
    - 351
    - 352
    - 353
    - 354
    - 355
    - 356
    - 357
    - 358
    - 359
    - 360
    - 361
    - 362
    - 363
    - 364
    - 365
    - 366
    - 367
    - 368
    - 369
    - 370
    - 371
    - 372
    - 373
    - 374
    - 375
    - 376
    - 377
    - 378
    - 379
    - 380
    - 381
    - 382
    - 383
    - 384
    - 385
    - 386
    - 387
    - 388
    - 389
    - 390
    - 391
    - 392
    - 393
    - 394
    - 395
    - 396
    - 397
    - 398
    - 399
    - 400
    - 401
    - 402
    - 403
    - 404
    - 405
    - 406
    - 407
    - 408
    - 409
    - 410
    - 411
    - 412
    - 413
    - 414
    - 415
    - 416
    - 417
    - 418
    - 419
    - 420
    - 421
    - 422
    - 423
    - 424
    - 425
    - 426
    - 427
    - 428
    - 429
    - 430
    - 431
    - 432
    - 433
    - 434
    - 435
    - 436
    - 437
    - 438
    - 439
    - 440
    - 441
    - 442
    - 443
    - 444
    - 445
    - 446
    - 447
    - 448
    - 449
    - 450
    - 451
    - 452
    - 453
    - 454
    - 455
    - 456
    - 457
    - 458
    - 459
    - 460
    - 461
    - 462
    - 463
    - 464
    - 465
    - 466
    - 467
    - 468
    - 469
    - 470
    - 471
    - 472
    - 473
    - 474
    - 475
    - 476
    - 477
    - 478
    - 479
    - 480
    - 481
    - 482
    - 483
    - 484
    - 485
    - 486
    - 487
    - 488
    - 489
    - 490
    - 491
    - 492
    - 493
    - 494
    - 495
    - 496
    - 497
    - 498
    - 499
    - 500
    - 501
    - 502
    - 503
    - 504
    - 505
    - 506
    - 507
    - 508
    - 509
    - 510
    - 511
    - 512
    - 513
    - 514
    - 515
    - 516
    - 517
    - 518
    - 519
    - 520
    - 521
    - 522
    - 523
    - 524
    - 525
    - 526
    - 527
    - 528
    - 529
    - 530
    - 531
    - 532
    - 533
    - 534
    - 535
    - 536
    - 537
    - 538
    - 539
    - 540
    - 541
    - 542
    - 543
    - 544
    - 545
    - 546
    - 547
    - 548
    - 549
    - 550
    - 551
    - 552
    - 553
    - 554
    - 555
    - 556
    - 557
    - 558
    - 559
    - 560
    - 561
    - 562
    - 563
    - 564
    - 565
    - 566
    - 567
    - 568
    - 569
    - 570
    - 571
    - 572
    - 573
    - 574
    - 575
    - 576
    - 577
    - 578
    - 579
    - 580
    - 581
    - 582
    - 583
    - 584
    - 585
    - 586
    - 587
    - 588
    - 589
    - 590
    - 591
    - 592
    - 593
    - 594
    - 595
    - 596
    - 597
    - 598
    - 599
    - 600
    - 601
    - 602
    - 603
    - 604
    - 605
    - 606
    - 607
    - 608
    - 609
    - 610
    - 611
    - 612
    - 613
    - 614
    - 615
    - 616
    - 617
    - 618
    - 619
    - 620
    - 621
    - 622
    - 623
    - 624
    - 625
    - 626
    - 627
    - 628
    - 629
    - 630
    - 631
    - 632
    - 633
    - 634
    - 635
    - 636
    - 637
    - 638
    - 639
    - 640
    - 641
    - 642
    - 643
    - 644
    - 645
    - 646
    - 647
    - 648
    - 649
    - 650
    - 651
    - 652
    - 653
    - 654
    - 655
    - 656
    - 657
    - 658
    - 659
    - 660
    - 661
    - 662
    - 663
    - 664
    - 665
    - 666
    - 667
    - 668
    - 669
    - 670
    - 671
    - 672
    - 673
    - 674
    - 675
    - 676
    - 677
    - 678
    - 679
    - 680
    - 681
    - 682
    - 683
    - 684
    - 685
    - 686
    - 687
    - 688
    - 689
    - 690
    - 691
    - 692
    - 693
    - 694
    - 695
    - 696
    - 697
    - 698
    - 699
    - 700
    - 701
    - 702
    - 703
    - 704
    - 705
    - 706
    - 707
    - 708
    - 709
    - 710
    - 711
    - 712
    - 713
    - 714
    - 715
    - 716
    - 717
    - 718
    - 719
    - 720
    - 721
    - 722
    - 723
    - 724
    - 725
    - 726
    - 727
    - 728
    - 729
    - 730
    - 731
    - 732
    - 733
    - 734
    - 735
    - 736
    - 737
    - 738
    - 739
    - 740
    - 741
    - 742
    - 743
    - 744
    - 745
    - 746
    - 747
    - 748
    - 749
    - 750
    - 751
    - 752
    - 753
    - 754
    - 755
    - 756
    - 757
    - 758
    - 759
    - 760
    - 761
    - 762
    - 763
    - 764
    - 765
    - 766
    - 767
    - 768
    - 769
    - 770
    - 771
    - 772
    - 773
    - 774
    - 775
    - 776
    - 777
    - 778
    - 779
    - 780
    - 781
    - 782
    - 783
    - 784
    - 785
    - 786
    - 787
    - 788
    - 789
    - 790
    - 791
    - 792
    - 793
    - 794
    - 795
    - 796
    - 797
    - 798
    - 799
    - 800
    - 801
    - 802
    - 803
    - 804
    - 805
    - 806
    - 807
    - 808
    - 809
    - 810
    - 811
    - 812
    - 813
    - 814
    - 815
    - 816
    - 817
    - 818
    - 819
    - 820
    - 821
    - 822
    - 823
    - 824
    - 825
    - 826
    - 827
    - 828
    - 829
    - 830
    - 831
    - 832
    - 833
    - 834
    - 835
    - 836
    - 837
    - 838
    - 839
    - 840
    - 841
    - 842
    - 843
    - 844
    - 845
    - 846
    - 847
    - 848
    - 849
    - 850
    - 851
    - 852
    - 853
    - 854
    - 855
    - 856
    - 857
    - 858
    - 859
    - 860
    - 861
    - 862
    - 863
    - 864
    - 865
    - 866
    - 867
    - 868
    - 869
    - 870
    - 871
    - 872
    - 873
    - 874
    - 875
    - 876
    - 877
    - 878
    - 879
    - 880
    - 881
    - 882
    - 883
    - 884
    - 885
    - 886
    - 887
    - 888
    - 889
    - 890
    - 891
    - 892
    - 893
    - 894
    - 895
    - 896
    - 897
    - 898
    - 899
    - 900
    - 901
    - 902
    - 903
    - 904
    - 905
    - 906
    - 907
    - 908
    - 909
    - 910
    - 911
    - 912
    - 913
    - 914
    - 915
    - 916
    - 917
    - 918
    - 919
    - 920
    - 921
    - 922
    - 923
    - 924
    - 925
    - 926
    - 927
    - 928
    - 929
    - 930
    - 931
    - 932
    - 933
    - 934
    - 935
    - 936
    - 937
    - 938
    - 939
    - 940
    - 941
    - 942
    - 943
    - 944
    - 945
    - 946
    - 947
    - 948
    - 949
    - 950
    - 951
    - 952
    - 953
    - 954
    - 955
    - 956
    - 957
    - 958
    - 959
    - 960
    - 961
    - 962
    - 963
    - 964
    - 965
    - 966
    - 967
    - 968
    - 969
    - 970
    - 971
    - 972
    - 973
    - 974
    - 975
    - 976
    - 977
    - 978
    - 979
    - 980
    - 981
    - 982
    - 983
    - 984
    - 985
    - 986
    - 987
    - 988
    - 989
    - 990
    - 991
    - 992
    - 993
    - 994
    - 995
    - 996
    - 997
    - 998
    - 999
    -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
    -1028
    -1029
    -1030
    -1031
    -1032
    -1033
    -1034
    -1035
    -1036
    -1037
    -1038
    -1039
    -1040
    -1041
    -1042
    -1043
    -1044
    -1045
    -1046
    -1047
    -1048
    -1049
    -1050
    -1051
    -1052
    -1053
    -1054
    -1055
    -1056
    -1057
    -1058
    -1059
    -1060
    -1061
    -1062
    -1063
    -1064
    -1065
    -1066
    -1067
    -1068
    -1069
    -1070
    -1071
    -1072
    -1073
    -1074
    -1075
    -1076
    -1077
    -1078
    -1079
    -1080
    -1081
    -1082
    -1083
    -1084
    -1085
    -1086
    -1087
    -1088
    -1089
    -1090
    -1091
    -1092
    -1093
    -1094
    -1095
    -1096
    -1097
    -1098
    -1099
    -1100
    -1101
    -1102
    -1103
    -1104
    -1105
    -1106
    -1107
    -1108
    -1109
    -1110
    -1111
    -1112
    -1113
    -1114
    -1115
    -1116
    -1117
    -1118
    -1119
    -1120
    -1121
    -1122
    -1123
    -1124
    -1125
    -1126
    -1127
    -1128
    -1129
    -1130
    -1131
    -1132
    -1133
    -1134
    -1135
    -1136
    -1137
    -1138
    -1139
    -1140
    -1141
    -1142
    -1143
    -1144
    -1145
    -1146
    -1147
    -1148
    -1149
    -1150
    -1151
    -1152
    -1153
    -1154
    -1155
    -1156
    -1157
    -1158
    -1159
    -1160
    -1161
    -1162
    -1163
    -1164
    -1165
    -1166
    -1167
    -1168
    -1169
    -1170
    -1171
    -1172
    -1173
    -1174
    -1175
    -1176
    -1177
    -1178
    -1179
    -1180
    -1181
    -1182
    -1183
    -1184
    -1185
    -1186
    -1187
    -1188
    -1189
    -1190
    -1191
    -1192
    -1193
    -1194
    -1195
    -1196
    -1197
    -1198
    -1199
    -1200
    -1201
    -1202
    -1203
    -1204
    -1205
    -1206
    -1207
    -1208
    -1209
    -1210
    -1211
    -1212
    -1213
    -1214
    -1215
    -1216
    -1217
    -1218
    -1219
    -1220
    -1221
    -1222
    -1223
    -1224
    -1225
    -1226
    -1227
    -1228
    -1229
    -1230
    -1231
    -1232
    -1233
    -1234
    -1235
    -1236
    -1237
    -1238
    -1239
    -1240
    -1241
    -1242
    -1243
    -1244
    -1245
    -1246
    -1247
    -1248
    -1249
    -1250
    -1251
    -1252
    -1253
    -1254
    -1255
    -1256
    -1257
    -1258
    -1259
    -1260
    -1261
    -1262
    -1263
    -1264
    -1265
    -1266
    -1267
    -1268
    -1269
    -1270
    -1271
    -1272
    -1273
    -1274
    -1275
    -1276
    -1277
    -1278
    -1279
    -1280
    -1281
    -1282
    -1283
    -1284
    -1285
    -1286
    -1287
    -1288
    -1289
    -1290
    -1291
    -1292
    -1293
    -1294
    -1295
    -1296
    -1297
    -1298
    -1299
    -1300
    -1301
    -1302
    -1303
    -1304
    -1305
    -1306
    -1307
    -1308
    -1309
    -1310
    -1311
    -1312
    -1313
    -1314
    -1315
    -1316
    -1317
    -1318
    -1319
    -1320
    -1321
    -1322
    -1323
    -1324
    -1325
    -1326
    -1327
    -1328
    -1329
    -1330
    -1331
    -1332
    -1333
    -1334
    -1335
    -1336
    -1337
    -1338
    -1339
    -1340
    -1341
    -1342
    -1343
    -1344
    -1345
    -1346
    -1347
    -1348
    -1349
    -1350
    -1351
    -1352
    -1353
    -1354
    -1355
    -1356
    -1357
    -1358
    -1359
    -1360
    -1361
    -1362
    -1363
    -1364
    -1365
    -1366
    -1367
    -1368
    -1369
    -1370
    -1371
    -1372
    -1373
    -1374
    -1375
    -1376
    -1377
    -1378
    -1379
    -1380
    -1381
    -1382
    -1383
    -1384
    -1385
    -1386
    -1387
    -1388
    -1389
    -1390
    -1391
    -1392
    -1393
    -1394
    -1395
    -1396
    -1397
    -1398
    -1399
    -1400
    -1401
    -1402
    -1403
    -1404
    -1405
    -1406
    -1407
    -1408
    -1409
    -1410
    -1411
    -1412
    -1413
    -1414
    -1415
    -1416
    -1417
    -1418
    -1419
    -1420
    -1421
    -1422
    -1423
    -1424
    -1425
    -1426
    -1427
    -1428
    -1429
    -1430
    -1431
    -1432
    -1433
    -1434
    -1435
    -1436
    -1437
    -1438
    -1439
    -1440
    -1441
    -1442
    -1443
    -1444
    -1445
    -1446
    -1447
    -1448
    -1449
    -1450
    -1451
    -1452
    -1453
    -1454
    -1455
    -1456
    -1457
    -1458
    -1459
    -1460
    -1461
    -1462
    -1463
    -1464
    -1465
    -1466
    -1467
    -1468
    -1469
    -1470
    -1471
    -1472
    -1473
    -1474
    -1475
    -1476
    -1477
    -1478
    -1479
    -1480
    -1481
    -1482
    -1483
    -1484
    -1485
    -1486
    -1487
    -1488
    -1489
    -1490
    -1491
    -1492
    -1493
    -1494
    -1495
    -1496
    -1497
    -1498
    -1499
    -1500
    -1501
    -1502
    -1503
    -1504
    -1505
    -1506
    -1507
    -1508
    -1509
    -1510
    -1511
    -1512
    -1513
    -1514
    -1515
    -1516
    -1517
    -1518
    -1519
    -1520
    -1521
    -1522
    -1523
    -1524
    -1525
    -1526
    -1527
    -1528
    -1529
    -1530
    -1531
    -1532
    -1533
    -1534
    -1535
    -1536
    -1537
    -1538
    -1539
    -1540
    -1541
    -1542
    -1543
    -1544
    -1545
    -1546
    -1547
    -1548
    -1549
    -1550
    -1551
    -1552
    -1553
    -1554
    -1555
    -1556
    -1557
    -1558
    -1559
    -1560
    -1561
    -1562
    -1563
    -1564
    -1565
    -1566
    -1567
    -1568
    -1569
    -1570
    -1571
    -1572
    -1573
    -1574
    -1575
    -1576
    -1577
    -1578
    -1579
    -1580
    -1581
    -1582
    -1583
    -1584
    -1585
    -1586
    -1587
    -1588
    -1589
    -1590
    -1591
    -1592
    -1593
    -1594
    -1595
    -1596
    -1597
    -1598
    -1599
    -1600
    -
    // Bitcoin Dev Kit
    -// Written in 2020 by Alekos Filini <alekos.filini@gmail.com>
    -//
    -// Copyright (c) 2020-2021 Bitcoin Dev Kit Developers
    -//
    -// This file is licensed under the Apache License, Version 2.0 <LICENSE-APACHE
    -// or http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
    -// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your option.
    -// You may not use this file except in accordance with one or both of these
    -// licenses.
    -
    -//! Coin selection
    -//!
    -//! This module provides the trait [`CoinSelectionAlgorithm`] that can be implemented to
    -//! define custom coin selection algorithms.
    -//!
    -//! You can specify a custom coin selection algorithm through the [`coin_selection`] method on
    -//! [`TxBuilder`]. [`DefaultCoinSelectionAlgorithm`] aliases the coin selection algorithm that will
    -//! be used if it is not explicitly set.
    -//!
    -//! [`TxBuilder`]: super::tx_builder::TxBuilder
    -//! [`coin_selection`]: super::tx_builder::TxBuilder::coin_selection
    -//!
    -//! ## Example
    -//!
    -//! ```
    -//! # use std::str::FromStr;
    -//! # use bitcoin::*;
    -//! # use bdk::wallet::{self, coin_selection::*};
    -//! # use bdk::database::Database;
    -//! # use bdk::*;
    -//! # use bdk::wallet::coin_selection::decide_change;
    -//! # const TXIN_BASE_WEIGHT: usize = (32 + 4 + 4) * 4;
    -//! #[derive(Debug)]
    -//! struct AlwaysSpendEverything;
    -//!
    -//! impl<D: Database> CoinSelectionAlgorithm<D> for AlwaysSpendEverything {
    -//!     fn coin_select(
    -//!         &self,
    -//!         database: &D,
    -//!         required_utxos: Vec<WeightedUtxo>,
    -//!         optional_utxos: Vec<WeightedUtxo>,
    -//!         fee_rate: FeeRate,
    -//!         target_amount: u64,
    -//!         drain_script: &Script,
    -//!     ) -> Result<CoinSelectionResult, bdk::Error> {
    -//!         let mut selected_amount = 0;
    -//!         let mut additional_weight = 0;
    -//!         let all_utxos_selected = required_utxos
    -//!             .into_iter()
    -//!             .chain(optional_utxos)
    -//!             .scan(
    -//!                 (&mut selected_amount, &mut additional_weight),
    -//!                 |(selected_amount, additional_weight), weighted_utxo| {
    -//!                     **selected_amount += weighted_utxo.utxo.txout().value;
    -//!                     **additional_weight += TXIN_BASE_WEIGHT + weighted_utxo.satisfaction_weight;
    -//!                     Some(weighted_utxo.utxo)
    -//!                 },
    -//!             )
    -//!             .collect::<Vec<_>>();
    -//!         let additional_fees = fee_rate.fee_wu(additional_weight);
    -//!         let amount_needed_with_fees = additional_fees + target_amount;
    -//!         if selected_amount < amount_needed_with_fees {
    -//!             return Err(bdk::Error::InsufficientFunds {
    -//!                 needed: amount_needed_with_fees,
    -//!                 available: selected_amount,
    -//!             });
    -//!         }
    -//!
    -//!         let remaining_amount = selected_amount - amount_needed_with_fees;
    -//!
    -//!         let excess = decide_change(remaining_amount, fee_rate, drain_script);
    -//!
    -//!         Ok(CoinSelectionResult {
    -//!             selected: all_utxos_selected,
    -//!             fee_amount: additional_fees,
    -//!             excess,
    -//!         })
    -//!     }
    -//! }
    -//!
    -//! # let wallet = doctest_wallet!();
    -//! // create wallet, sync, ...
    -//!
    -//! let to_address = Address::from_str("2N4eQYCbKUHCCTUjBJeHcJp9ok6J2GZsTDt").unwrap();
    -//! let (psbt, details) = {
    -//!     let mut builder = wallet.build_tx().coin_selection(AlwaysSpendEverything);
    -//!     builder.add_recipient(to_address.script_pubkey(), 50_000);
    -//!     builder.finish()?
    -//! };
    -//!
    -//! // inspect, sign, broadcast, ...
    -//!
    -//! # Ok::<(), bdk::Error>(())
    -//! ```
    -
    -use crate::types::FeeRate;
    -use crate::wallet::utils::IsDust;
    -use crate::{database::Database, WeightedUtxo};
    -use crate::{error::Error, Utxo};
    -
    -use bitcoin::consensus::encode::serialize;
    -use bitcoin::Script;
    -
    -use rand::seq::SliceRandom;
    -#[cfg(not(test))]
    -use rand::thread_rng;
    -#[cfg(test)]
    -use rand::{rngs::StdRng, SeedableRng};
    -use std::collections::HashMap;
    -use std::convert::TryInto;
    -
    -/// Default coin selection algorithm used by [`TxBuilder`](super::tx_builder::TxBuilder) if not
    -/// overridden
    -#[cfg(not(test))]
    -pub type DefaultCoinSelectionAlgorithm = BranchAndBoundCoinSelection;
    -#[cfg(test)]
    -pub type DefaultCoinSelectionAlgorithm = LargestFirstCoinSelection; // make the tests more predictable
    -
    -// Base weight of a Txin, not counting the weight needed for satisfying it.
    -// prev_txid (32 bytes) + prev_vout (4 bytes) + sequence (4 bytes)
    -pub(crate) const TXIN_BASE_WEIGHT: usize = (32 + 4 + 4) * 4;
    -
    -#[derive(Debug)]
    -/// Remaining amount after performing coin selection
    -pub enum Excess {
    -    /// It's not possible to create spendable output from excess using the current drain output
    -    NoChange {
    -        /// Threshold to consider amount as dust for this particular change script_pubkey
    -        dust_threshold: u64,
    -        /// Exceeding amount of current selection over outgoing value and fee costs
    -        remaining_amount: u64,
    -        /// The calculated fee for the drain TxOut with the selected script_pubkey
    -        change_fee: u64,
    +coin_selection.rs - source
    1
    +2
    +3
    +4
    +5
    +6
    +7
    +8
    +9
    +10
    +11
    +12
    +13
    +14
    +15
    +16
    +17
    +18
    +19
    +20
    +21
    +22
    +23
    +24
    +25
    +26
    +27
    +28
    +29
    +30
    +31
    +32
    +33
    +34
    +35
    +36
    +37
    +38
    +39
    +40
    +41
    +42
    +43
    +44
    +45
    +46
    +47
    +48
    +49
    +50
    +51
    +52
    +53
    +54
    +55
    +56
    +57
    +58
    +59
    +60
    +61
    +62
    +63
    +64
    +65
    +66
    +67
    +68
    +69
    +70
    +71
    +72
    +73
    +74
    +75
    +76
    +77
    +78
    +79
    +80
    +81
    +82
    +83
    +84
    +85
    +86
    +87
    +88
    +89
    +90
    +91
    +92
    +93
    +94
    +95
    +96
    +97
    +98
    +99
    +100
    +101
    +102
    +103
    +104
    +105
    +106
    +107
    +108
    +109
    +110
    +111
    +112
    +113
    +114
    +115
    +116
    +117
    +118
    +119
    +120
    +121
    +122
    +123
    +124
    +125
    +126
    +127
    +128
    +129
    +130
    +131
    +132
    +133
    +134
    +135
    +136
    +137
    +138
    +139
    +140
    +141
    +142
    +143
    +144
    +145
    +146
    +147
    +148
    +149
    +150
    +151
    +152
    +153
    +154
    +155
    +156
    +157
    +158
    +159
    +160
    +161
    +162
    +163
    +164
    +165
    +166
    +167
    +168
    +169
    +170
    +171
    +172
    +173
    +174
    +175
    +176
    +177
    +178
    +179
    +180
    +181
    +182
    +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
    +245
    +246
    +247
    +248
    +249
    +250
    +251
    +252
    +253
    +254
    +255
    +256
    +257
    +258
    +259
    +260
    +261
    +262
    +263
    +264
    +265
    +266
    +267
    +268
    +269
    +270
    +271
    +272
    +273
    +274
    +275
    +276
    +277
    +278
    +279
    +280
    +281
    +282
    +283
    +284
    +285
    +286
    +287
    +288
    +289
    +290
    +291
    +292
    +293
    +294
    +295
    +296
    +297
    +298
    +299
    +300
    +301
    +302
    +303
    +304
    +305
    +306
    +307
    +308
    +309
    +310
    +311
    +312
    +313
    +314
    +315
    +316
    +317
    +318
    +319
    +320
    +321
    +322
    +323
    +324
    +325
    +326
    +327
    +328
    +329
    +330
    +331
    +332
    +333
    +334
    +335
    +336
    +337
    +338
    +339
    +340
    +341
    +342
    +343
    +344
    +345
    +346
    +347
    +348
    +349
    +350
    +351
    +352
    +353
    +354
    +355
    +356
    +357
    +358
    +359
    +360
    +361
    +362
    +363
    +364
    +365
    +366
    +367
    +368
    +369
    +370
    +371
    +372
    +373
    +374
    +375
    +376
    +377
    +378
    +379
    +380
    +381
    +382
    +383
    +384
    +385
    +386
    +387
    +388
    +389
    +390
    +391
    +392
    +393
    +394
    +395
    +396
    +397
    +398
    +399
    +400
    +401
    +402
    +403
    +404
    +405
    +406
    +407
    +408
    +409
    +410
    +411
    +412
    +413
    +414
    +415
    +416
    +417
    +418
    +419
    +420
    +421
    +422
    +423
    +424
    +425
    +426
    +427
    +428
    +429
    +430
    +431
    +432
    +433
    +434
    +435
    +436
    +437
    +438
    +439
    +440
    +441
    +442
    +443
    +444
    +445
    +446
    +447
    +448
    +449
    +450
    +451
    +452
    +453
    +454
    +455
    +456
    +457
    +458
    +459
    +460
    +461
    +462
    +463
    +464
    +465
    +466
    +467
    +468
    +469
    +470
    +471
    +472
    +473
    +474
    +475
    +476
    +477
    +478
    +479
    +480
    +481
    +482
    +483
    +484
    +485
    +486
    +487
    +488
    +489
    +490
    +491
    +492
    +493
    +494
    +495
    +496
    +497
    +498
    +499
    +500
    +501
    +502
    +503
    +504
    +505
    +506
    +507
    +508
    +509
    +510
    +511
    +512
    +513
    +514
    +515
    +516
    +517
    +518
    +519
    +520
    +521
    +522
    +523
    +524
    +525
    +526
    +527
    +528
    +529
    +530
    +531
    +532
    +533
    +534
    +535
    +536
    +537
    +538
    +539
    +540
    +541
    +542
    +543
    +544
    +545
    +546
    +547
    +548
    +549
    +550
    +551
    +552
    +553
    +554
    +555
    +556
    +557
    +558
    +559
    +560
    +561
    +562
    +563
    +564
    +565
    +566
    +567
    +568
    +569
    +570
    +571
    +572
    +573
    +574
    +575
    +576
    +577
    +578
    +579
    +580
    +581
    +582
    +583
    +584
    +585
    +586
    +587
    +588
    +589
    +590
    +591
    +592
    +593
    +594
    +595
    +596
    +597
    +598
    +599
    +600
    +601
    +602
    +603
    +604
    +605
    +606
    +607
    +608
    +609
    +610
    +611
    +612
    +613
    +614
    +615
    +616
    +617
    +618
    +619
    +620
    +621
    +622
    +623
    +624
    +625
    +626
    +627
    +628
    +629
    +630
    +631
    +632
    +633
    +634
    +635
    +636
    +637
    +638
    +639
    +640
    +641
    +642
    +643
    +644
    +645
    +646
    +647
    +648
    +649
    +650
    +651
    +652
    +653
    +654
    +655
    +656
    +657
    +658
    +659
    +660
    +661
    +662
    +663
    +664
    +665
    +666
    +667
    +668
    +669
    +670
    +671
    +672
    +673
    +674
    +675
    +676
    +677
    +678
    +679
    +680
    +681
    +682
    +683
    +684
    +685
    +686
    +687
    +688
    +689
    +690
    +691
    +692
    +693
    +694
    +695
    +696
    +697
    +698
    +699
    +700
    +701
    +702
    +703
    +704
    +705
    +706
    +707
    +708
    +709
    +710
    +711
    +712
    +713
    +714
    +715
    +716
    +717
    +718
    +719
    +720
    +721
    +722
    +723
    +724
    +725
    +726
    +727
    +728
    +729
    +730
    +731
    +732
    +733
    +734
    +735
    +736
    +737
    +738
    +739
    +740
    +741
    +742
    +743
    +744
    +745
    +746
    +747
    +748
    +749
    +750
    +751
    +752
    +753
    +754
    +755
    +756
    +757
    +758
    +759
    +760
    +761
    +762
    +763
    +764
    +765
    +766
    +767
    +768
    +769
    +770
    +771
    +772
    +773
    +774
    +775
    +776
    +777
    +778
    +779
    +780
    +781
    +782
    +783
    +784
    +785
    +786
    +787
    +788
    +789
    +790
    +791
    +792
    +793
    +794
    +795
    +796
    +797
    +798
    +799
    +800
    +801
    +802
    +803
    +804
    +805
    +806
    +807
    +808
    +809
    +810
    +811
    +812
    +813
    +814
    +815
    +816
    +817
    +818
    +819
    +820
    +821
    +822
    +823
    +824
    +825
    +826
    +827
    +828
    +829
    +830
    +831
    +832
    +833
    +834
    +835
    +836
    +837
    +838
    +839
    +840
    +841
    +842
    +843
    +844
    +845
    +846
    +847
    +848
    +849
    +850
    +851
    +852
    +853
    +854
    +855
    +856
    +857
    +858
    +859
    +860
    +861
    +862
    +863
    +864
    +865
    +866
    +867
    +868
    +869
    +870
    +871
    +872
    +873
    +874
    +875
    +876
    +877
    +878
    +879
    +880
    +881
    +882
    +883
    +884
    +885
    +886
    +887
    +888
    +889
    +890
    +891
    +892
    +893
    +894
    +895
    +896
    +897
    +898
    +899
    +900
    +901
    +902
    +903
    +904
    +905
    +906
    +907
    +908
    +909
    +910
    +911
    +912
    +913
    +914
    +915
    +916
    +917
    +918
    +919
    +920
    +921
    +922
    +923
    +924
    +925
    +926
    +927
    +928
    +929
    +930
    +931
    +932
    +933
    +934
    +935
    +936
    +937
    +938
    +939
    +940
    +941
    +942
    +943
    +944
    +945
    +946
    +947
    +948
    +949
    +950
    +951
    +952
    +953
    +954
    +955
    +956
    +957
    +958
    +959
    +960
    +961
    +962
    +963
    +964
    +965
    +966
    +967
    +968
    +969
    +970
    +971
    +972
    +973
    +974
    +975
    +976
    +977
    +978
    +979
    +980
    +981
    +982
    +983
    +984
    +985
    +986
    +987
    +988
    +989
    +990
    +991
    +992
    +993
    +994
    +995
    +996
    +997
    +998
    +999
    +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
    +1028
    +1029
    +1030
    +1031
    +1032
    +1033
    +1034
    +1035
    +1036
    +1037
    +1038
    +1039
    +1040
    +1041
    +1042
    +1043
    +1044
    +1045
    +1046
    +1047
    +1048
    +1049
    +1050
    +1051
    +1052
    +1053
    +1054
    +1055
    +1056
    +1057
    +1058
    +1059
    +1060
    +1061
    +1062
    +1063
    +1064
    +1065
    +1066
    +1067
    +1068
    +1069
    +1070
    +1071
    +1072
    +1073
    +1074
    +1075
    +1076
    +1077
    +1078
    +1079
    +1080
    +1081
    +1082
    +1083
    +1084
    +1085
    +1086
    +1087
    +1088
    +1089
    +1090
    +1091
    +1092
    +1093
    +1094
    +1095
    +1096
    +1097
    +1098
    +1099
    +1100
    +1101
    +1102
    +1103
    +1104
    +1105
    +1106
    +1107
    +1108
    +1109
    +1110
    +1111
    +1112
    +1113
    +1114
    +1115
    +1116
    +1117
    +1118
    +1119
    +1120
    +1121
    +1122
    +1123
    +1124
    +1125
    +1126
    +1127
    +1128
    +1129
    +1130
    +1131
    +1132
    +1133
    +1134
    +1135
    +1136
    +1137
    +1138
    +1139
    +1140
    +1141
    +1142
    +1143
    +1144
    +1145
    +1146
    +1147
    +1148
    +1149
    +1150
    +1151
    +1152
    +1153
    +1154
    +1155
    +1156
    +1157
    +1158
    +1159
    +1160
    +1161
    +1162
    +1163
    +1164
    +1165
    +1166
    +1167
    +1168
    +1169
    +1170
    +1171
    +1172
    +1173
    +1174
    +1175
    +1176
    +1177
    +1178
    +1179
    +1180
    +1181
    +1182
    +1183
    +1184
    +1185
    +1186
    +1187
    +1188
    +1189
    +1190
    +1191
    +1192
    +1193
    +1194
    +1195
    +1196
    +1197
    +1198
    +1199
    +1200
    +1201
    +1202
    +1203
    +1204
    +1205
    +1206
    +1207
    +1208
    +1209
    +1210
    +1211
    +1212
    +1213
    +1214
    +1215
    +1216
    +1217
    +1218
    +1219
    +1220
    +1221
    +1222
    +1223
    +1224
    +1225
    +1226
    +1227
    +1228
    +1229
    +1230
    +1231
    +1232
    +1233
    +1234
    +1235
    +1236
    +1237
    +1238
    +1239
    +1240
    +1241
    +1242
    +1243
    +1244
    +1245
    +1246
    +1247
    +1248
    +1249
    +1250
    +1251
    +1252
    +1253
    +1254
    +1255
    +1256
    +1257
    +1258
    +1259
    +1260
    +1261
    +1262
    +1263
    +1264
    +1265
    +1266
    +1267
    +1268
    +1269
    +1270
    +1271
    +1272
    +1273
    +1274
    +1275
    +1276
    +1277
    +1278
    +1279
    +1280
    +1281
    +1282
    +1283
    +1284
    +1285
    +1286
    +1287
    +1288
    +1289
    +1290
    +1291
    +1292
    +1293
    +1294
    +1295
    +1296
    +1297
    +1298
    +1299
    +1300
    +1301
    +1302
    +1303
    +1304
    +1305
    +1306
    +1307
    +1308
    +1309
    +1310
    +1311
    +1312
    +1313
    +1314
    +1315
    +1316
    +1317
    +1318
    +1319
    +1320
    +1321
    +1322
    +1323
    +1324
    +1325
    +1326
    +1327
    +1328
    +1329
    +1330
    +1331
    +1332
    +1333
    +1334
    +1335
    +1336
    +1337
    +1338
    +1339
    +1340
    +1341
    +1342
    +1343
    +1344
    +1345
    +1346
    +1347
    +1348
    +1349
    +1350
    +1351
    +1352
    +1353
    +1354
    +1355
    +1356
    +1357
    +1358
    +1359
    +1360
    +1361
    +1362
    +1363
    +1364
    +1365
    +1366
    +1367
    +1368
    +1369
    +1370
    +1371
    +1372
    +1373
    +1374
    +1375
    +1376
    +1377
    +1378
    +1379
    +1380
    +1381
    +1382
    +1383
    +1384
    +1385
    +1386
    +1387
    +1388
    +1389
    +1390
    +1391
    +1392
    +1393
    +1394
    +1395
    +1396
    +1397
    +1398
    +1399
    +1400
    +1401
    +1402
    +1403
    +1404
    +1405
    +1406
    +1407
    +1408
    +1409
    +1410
    +1411
    +1412
    +1413
    +1414
    +1415
    +1416
    +1417
    +1418
    +1419
    +1420
    +1421
    +1422
    +1423
    +1424
    +1425
    +1426
    +1427
    +1428
    +1429
    +1430
    +1431
    +1432
    +1433
    +1434
    +1435
    +1436
    +1437
    +1438
    +1439
    +1440
    +1441
    +1442
    +1443
    +1444
    +1445
    +1446
    +1447
    +1448
    +1449
    +1450
    +1451
    +1452
    +1453
    +1454
    +1455
    +1456
    +1457
    +1458
    +1459
    +1460
    +1461
    +1462
    +1463
    +1464
    +1465
    +1466
    +1467
    +1468
    +1469
    +1470
    +1471
    +1472
    +1473
    +1474
    +1475
    +1476
    +1477
    +1478
    +1479
    +1480
    +1481
    +1482
    +1483
    +1484
    +1485
    +1486
    +1487
    +1488
    +1489
    +1490
    +1491
    +1492
    +1493
    +1494
    +1495
    +1496
    +1497
    +1498
    +1499
    +1500
    +1501
    +1502
    +1503
    +1504
    +1505
    +1506
    +1507
    +1508
    +1509
    +1510
    +1511
    +1512
    +1513
    +1514
    +1515
    +1516
    +1517
    +1518
    +1519
    +1520
    +1521
    +1522
    +1523
    +1524
    +1525
    +1526
    +1527
    +1528
    +1529
    +1530
    +1531
    +1532
    +1533
    +1534
    +1535
    +1536
    +1537
    +1538
    +1539
    +1540
    +1541
    +1542
    +1543
    +1544
    +1545
    +1546
    +1547
    +1548
    +1549
    +1550
    +1551
    +1552
    +1553
    +1554
    +1555
    +1556
    +1557
    +1558
    +1559
    +1560
    +1561
    +1562
    +1563
    +1564
    +1565
    +1566
    +1567
    +1568
    +1569
    +1570
    +1571
    +1572
    +1573
    +1574
    +1575
    +1576
    +1577
    +1578
    +1579
    +1580
    +1581
    +1582
    +1583
    +1584
    +1585
    +1586
    +1587
    +1588
    +1589
    +1590
    +1591
    +1592
    +1593
    +1594
    +1595
    +1596
    +1597
    +1598
    +1599
    +1600
    +
    // Bitcoin Dev Kit
    +// Written in 2020 by Alekos Filini <alekos.filini@gmail.com>
    +//
    +// Copyright (c) 2020-2021 Bitcoin Dev Kit Developers
    +//
    +// This file is licensed under the Apache License, Version 2.0 <LICENSE-APACHE
    +// or http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
    +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your option.
    +// You may not use this file except in accordance with one or both of these
    +// licenses.
    +
    +//! Coin selection
    +//!
    +//! This module provides the trait [`CoinSelectionAlgorithm`] that can be implemented to
    +//! define custom coin selection algorithms.
    +//!
    +//! You can specify a custom coin selection algorithm through the [`coin_selection`] method on
    +//! [`TxBuilder`]. [`DefaultCoinSelectionAlgorithm`] aliases the coin selection algorithm that will
    +//! be used if it is not explicitly set.
    +//!
    +//! [`TxBuilder`]: super::tx_builder::TxBuilder
    +//! [`coin_selection`]: super::tx_builder::TxBuilder::coin_selection
    +//!
    +//! ## Example
    +//!
    +//! ```
    +//! # use std::str::FromStr;
    +//! # use bitcoin::*;
    +//! # use bdk::wallet::{self, coin_selection::*};
    +//! # use bdk::database::Database;
    +//! # use bdk::*;
    +//! # use bdk::wallet::coin_selection::decide_change;
    +//! # const TXIN_BASE_WEIGHT: usize = (32 + 4 + 4) * 4;
    +//! #[derive(Debug)]
    +//! struct AlwaysSpendEverything;
    +//!
    +//! impl<D: Database> CoinSelectionAlgorithm<D> for AlwaysSpendEverything {
    +//!     fn coin_select(
    +//!         &self,
    +//!         database: &D,
    +//!         required_utxos: Vec<WeightedUtxo>,
    +//!         optional_utxos: Vec<WeightedUtxo>,
    +//!         fee_rate: FeeRate,
    +//!         target_amount: u64,
    +//!         drain_script: &Script,
    +//!     ) -> Result<CoinSelectionResult, bdk::Error> {
    +//!         let mut selected_amount = 0;
    +//!         let mut additional_weight = 0;
    +//!         let all_utxos_selected = required_utxos
    +//!             .into_iter()
    +//!             .chain(optional_utxos)
    +//!             .scan(
    +//!                 (&mut selected_amount, &mut additional_weight),
    +//!                 |(selected_amount, additional_weight), weighted_utxo| {
    +//!                     **selected_amount += weighted_utxo.utxo.txout().value;
    +//!                     **additional_weight += TXIN_BASE_WEIGHT + weighted_utxo.satisfaction_weight;
    +//!                     Some(weighted_utxo.utxo)
    +//!                 },
    +//!             )
    +//!             .collect::<Vec<_>>();
    +//!         let additional_fees = fee_rate.fee_wu(additional_weight);
    +//!         let amount_needed_with_fees = additional_fees + target_amount;
    +//!         if selected_amount < amount_needed_with_fees {
    +//!             return Err(bdk::Error::InsufficientFunds {
    +//!                 needed: amount_needed_with_fees,
    +//!                 available: selected_amount,
    +//!             });
    +//!         }
    +//!
    +//!         let remaining_amount = selected_amount - amount_needed_with_fees;
    +//!
    +//!         let excess = decide_change(remaining_amount, fee_rate, drain_script);
    +//!
    +//!         Ok(CoinSelectionResult {
    +//!             selected: all_utxos_selected,
    +//!             fee_amount: additional_fees,
    +//!             excess,
    +//!         })
    +//!     }
    +//! }
    +//!
    +//! # let wallet = doctest_wallet!();
    +//! // create wallet, sync, ...
    +//!
    +//! let to_address = Address::from_str("2N4eQYCbKUHCCTUjBJeHcJp9ok6J2GZsTDt").unwrap();
    +//! let (psbt, details) = {
    +//!     let mut builder = wallet.build_tx().coin_selection(AlwaysSpendEverything);
    +//!     builder.add_recipient(to_address.script_pubkey(), 50_000);
    +//!     builder.finish()?
    +//! };
    +//!
    +//! // inspect, sign, broadcast, ...
    +//!
    +//! # Ok::<(), bdk::Error>(())
    +//! ```
    +
    +use crate::types::FeeRate;
    +use crate::wallet::utils::IsDust;
    +use crate::{database::Database, WeightedUtxo};
    +use crate::{error::Error, Utxo};
    +
    +use bitcoin::consensus::encode::serialize;
    +use bitcoin::Script;
    +
    +use rand::seq::SliceRandom;
    +#[cfg(not(test))]
    +use rand::thread_rng;
    +#[cfg(test)]
    +use rand::{rngs::StdRng, SeedableRng};
    +use std::collections::HashMap;
    +use std::convert::TryInto;
    +
    +/// Default coin selection algorithm used by [`TxBuilder`](super::tx_builder::TxBuilder) if not
    +/// overridden
    +#[cfg(not(test))]
    +pub type DefaultCoinSelectionAlgorithm = BranchAndBoundCoinSelection;
    +#[cfg(test)]
    +pub type DefaultCoinSelectionAlgorithm = LargestFirstCoinSelection; // make the tests more predictable
    +
    +// Base weight of a Txin, not counting the weight needed for satisfying it.
    +// prev_txid (32 bytes) + prev_vout (4 bytes) + sequence (4 bytes)
    +pub(crate) const TXIN_BASE_WEIGHT: usize = (32 + 4 + 4) * 4;
    +
    +#[derive(Debug)]
    +/// Remaining amount after performing coin selection
    +pub enum Excess {
    +    /// It's not possible to create spendable output from excess using the current drain output
    +    NoChange {
    +        /// Threshold to consider amount as dust for this particular change script_pubkey
    +        dust_threshold: u64,
    +        /// Exceeding amount of current selection over outgoing value and fee costs
    +        remaining_amount: u64,
    +        /// The calculated fee for the drain TxOut with the selected script_pubkey
    +        change_fee: u64,
         },
    -    /// It's possible to create spendable output from excess using the current drain output
    -    Change {
    -        /// Effective amount available to create change after deducting the change output fee
    -        amount: u64,
    -        /// The deducted change output fee
    -        fee: u64,
    +    /// It's possible to create spendable output from excess using the current drain output
    +    Change {
    +        /// Effective amount available to create change after deducting the change output fee
    +        amount: u64,
    +        /// The deducted change output fee
    +        fee: u64,
         },
     }
     
    -/// Result of a successful coin selection
    -#[derive(Debug)]
    -pub struct CoinSelectionResult {
    -    /// List of outputs selected for use as inputs
    -    pub selected: Vec<Utxo>,
    -    /// Total fee amount for the selected utxos in satoshis
    -    pub fee_amount: u64,
    -    /// Remaining amount after deducing fees and outgoing outputs
    -    pub excess: Excess,
    +/// Result of a successful coin selection
    +#[derive(Debug)]
    +pub struct CoinSelectionResult {
    +    /// List of outputs selected for use as inputs
    +    pub selected: Vec<Utxo>,
    +    /// Total fee amount for the selected utxos in satoshis
    +    pub fee_amount: u64,
    +    /// Remaining amount after deducing fees and outgoing outputs
    +    pub excess: Excess,
     }
     
    -impl CoinSelectionResult {
    -    /// The total value of the inputs selected.
    -    pub fn selected_amount(&self) -> u64 {
    -        self.selected.iter().map(|u| u.txout().value).sum()
    +impl CoinSelectionResult {
    +    /// The total value of the inputs selected.
    +    pub fn selected_amount(&self) -> u64 {
    +        self.selected.iter().map(|u| u.txout().value).sum()
         }
     
    -    /// The total value of the inputs selected from the local wallet.
    -    pub fn local_selected_amount(&self) -> u64 {
    -        self.selected
    -            .iter()
    -            .filter_map(|u| match u {
    -                Utxo::Local(_) => Some(u.txout().value),
    -                _ => None,
    +    /// The total value of the inputs selected from the local wallet.
    +    pub fn local_selected_amount(&self) -> u64 {
    +        self.selected
    +            .iter()
    +            .filter_map(|u| match u {
    +                Utxo::Local(_) => Some(u.txout().value),
    +                _ => None,
                 })
    -            .sum()
    +            .sum()
         }
     }
     
    -/// Trait for generalized coin selection algorithms
    -///
    -/// This trait can be implemented to make the [`Wallet`](super::Wallet) use a customized coin
    -/// selection algorithm when it creates transactions.
    -///
    -/// For an example see [this module](crate::wallet::coin_selection)'s documentation.
    -pub trait CoinSelectionAlgorithm<D: Database>: std::fmt::Debug {
    -    /// Perform the coin selection
    -    ///
    -    /// - `database`: a reference to the wallet's database that can be used to lookup additional
    -    ///               details for a specific UTXO
    -    /// - `required_utxos`: the utxos that must be spent regardless of `target_amount` with their
    -    ///                     weight cost
    -    /// - `optional_utxos`: the remaining available utxos to satisfy `target_amount` with their
    -    ///                     weight cost
    -    /// - `fee_rate`: fee rate to use
    -    /// - `target_amount`: the outgoing amount in satoshis and the fees already
    -    ///                    accumulated from added outputs and transaction’s header.
    -    /// - `drain_script`: the script to use in case of change
    -    #[allow(clippy::too_many_arguments)]
    -    fn coin_select(
    +/// Trait for generalized coin selection algorithms
    +///
    +/// This trait can be implemented to make the [`Wallet`](super::Wallet) use a customized coin
    +/// selection algorithm when it creates transactions.
    +///
    +/// For an example see [this module](crate::wallet::coin_selection)'s documentation.
    +pub trait CoinSelectionAlgorithm<D: Database>: std::fmt::Debug {
    +    /// Perform the coin selection
    +    ///
    +    /// - `database`: a reference to the wallet's database that can be used to lookup additional
    +    ///               details for a specific UTXO
    +    /// - `required_utxos`: the utxos that must be spent regardless of `target_amount` with their
    +    ///                     weight cost
    +    /// - `optional_utxos`: the remaining available utxos to satisfy `target_amount` with their
    +    ///                     weight cost
    +    /// - `fee_rate`: fee rate to use
    +    /// - `target_amount`: the outgoing amount in satoshis and the fees already
    +    ///                    accumulated from added outputs and transaction’s header.
    +    /// - `drain_script`: the script to use in case of change
    +    #[allow(clippy::too_many_arguments)]
    +    fn coin_select(
             &self,
    -        database: &D,
    -        required_utxos: Vec<WeightedUtxo>,
    -        optional_utxos: Vec<WeightedUtxo>,
    -        fee_rate: FeeRate,
    -        target_amount: u64,
    -        drain_script: &Script,
    -    ) -> Result<CoinSelectionResult, Error>;
    +        database: &D,
    +        required_utxos: Vec<WeightedUtxo>,
    +        optional_utxos: Vec<WeightedUtxo>,
    +        fee_rate: FeeRate,
    +        target_amount: u64,
    +        drain_script: &Script,
    +    ) -> Result<CoinSelectionResult, Error>;
     }
     
    -/// 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.
    -#[derive(Debug, Default, Clone, Copy)]
    -pub struct LargestFirstCoinSelection;
    +/// 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.
    +#[derive(Debug, Default, Clone, Copy)]
    +pub struct LargestFirstCoinSelection;
     
    -impl<D: Database> CoinSelectionAlgorithm<D> for LargestFirstCoinSelection {
    -    fn coin_select(
    +impl<D: Database> CoinSelectionAlgorithm<D> for LargestFirstCoinSelection {
    +    fn coin_select(
             &self,
    -        _database: &D,
    -        required_utxos: Vec<WeightedUtxo>,
    -        mut optional_utxos: Vec<WeightedUtxo>,
    -        fee_rate: FeeRate,
    -        target_amount: u64,
    -        drain_script: &Script,
    -    ) -> Result<CoinSelectionResult, Error> {
    +        _database: &D,
    +        required_utxos: Vec<WeightedUtxo>,
    +        mut optional_utxos: Vec<WeightedUtxo>,
    +        fee_rate: FeeRate,
    +        target_amount: u64,
    +        drain_script: &Script,
    +    ) -> Result<CoinSelectionResult, Error> {
             log::debug!(
                 "target_amount = `{}`, fee_rate = `{:?}`",
    -            target_amount,
    -            fee_rate
    +            target_amount,
    +            fee_rate
             );
     
    -        // We put the "required UTXOs" first and make sure the optional UTXOs are sorted,
    -        // initially smallest to largest, before being reversed with `.rev()`.
    -        let utxos = {
    -            optional_utxos.sort_unstable_by_key(|wu| wu.utxo.txout().value);
    -            required_utxos
    -                .into_iter()
    -                .map(|utxo| (true, utxo))
    -                .chain(optional_utxos.into_iter().rev().map(|utxo| (false, utxo)))
    +        // We put the "required UTXOs" first and make sure the optional UTXOs are sorted,
    +        // initially smallest to largest, before being reversed with `.rev()`.
    +        let utxos = {
    +            optional_utxos.sort_unstable_by_key(|wu| wu.utxo.txout().value);
    +            required_utxos
    +                .into_iter()
    +                .map(|utxo| (true, utxo))
    +                .chain(optional_utxos.into_iter().rev().map(|utxo| (false, utxo)))
             };
     
    -        select_sorted_utxos(utxos, fee_rate, target_amount, drain_script)
    +        select_sorted_utxos(utxos, fee_rate, target_amount, drain_script)
         }
     }
     
    -/// 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.
    -#[derive(Debug, Default, Clone, Copy)]
    -pub struct OldestFirstCoinSelection;
    +/// 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.
    +#[derive(Debug, Default, Clone, Copy)]
    +pub struct OldestFirstCoinSelection;
     
    -impl<D: Database> CoinSelectionAlgorithm<D> for OldestFirstCoinSelection {
    -    fn coin_select(
    +impl<D: Database> CoinSelectionAlgorithm<D> for OldestFirstCoinSelection {
    +    fn coin_select(
             &self,
    -        database: &D,
    -        required_utxos: Vec<WeightedUtxo>,
    -        mut optional_utxos: Vec<WeightedUtxo>,
    -        fee_rate: FeeRate,
    -        target_amount: u64,
    -        drain_script: &Script,
    -    ) -> Result<CoinSelectionResult, Error> {
    -        // query db and create a blockheight lookup table
    -        let blockheights = optional_utxos
    -            .iter()
    -            .map(|wu| wu.utxo.outpoint().txid)
    -            // fold is used so we can skip db query for txid that already exist in hashmap acc
    -            .fold(Ok(HashMap::new()), |bh_result_acc, txid| {
    -                bh_result_acc.and_then(|mut bh_acc| {
    -                    if bh_acc.contains_key(&txid) {
    -                        Ok(bh_acc)
    -                    } else {
    -                        database.get_tx(&txid, false).map(|details| {
    -                            bh_acc.insert(
    -                                txid,
    -                                details.and_then(|d| d.confirmation_time.map(|ct| ct.height)),
    +        database: &D,
    +        required_utxos: Vec<WeightedUtxo>,
    +        mut optional_utxos: Vec<WeightedUtxo>,
    +        fee_rate: FeeRate,
    +        target_amount: u64,
    +        drain_script: &Script,
    +    ) -> Result<CoinSelectionResult, Error> {
    +        // query db and create a blockheight lookup table
    +        let blockheights = optional_utxos
    +            .iter()
    +            .map(|wu| wu.utxo.outpoint().txid)
    +            // fold is used so we can skip db query for txid that already exist in hashmap acc
    +            .fold(Ok(HashMap::new()), |bh_result_acc, txid| {
    +                bh_result_acc.and_then(|mut bh_acc| {
    +                    if bh_acc.contains_key(&txid) {
    +                        Ok(bh_acc)
    +                    } else {
    +                        database.get_tx(&txid, false).map(|details| {
    +                            bh_acc.insert(
    +                                txid,
    +                                details.and_then(|d| d.confirmation_time.map(|ct| ct.height)),
                                 );
    -                            bh_acc
    +                            bh_acc
                             })
                         }
                     })
                 })?;
     
    -        // We put the "required UTXOs" first and make sure the optional UTXOs are sorted from
    -        // oldest to newest according to blocktime
    -        // For utxo that doesn't exist in DB, they will have lowest priority to be selected
    -        let utxos = {
    -            optional_utxos.sort_unstable_by_key(|wu| {
    -                match blockheights.get(&wu.utxo.outpoint().txid) {
    -                    Some(Some(blockheight)) => blockheight,
    -                    _ => &u32::MAX,
    +        // We put the "required UTXOs" first and make sure the optional UTXOs are sorted from
    +        // oldest to newest according to blocktime
    +        // For utxo that doesn't exist in DB, they will have lowest priority to be selected
    +        let utxos = {
    +            optional_utxos.sort_unstable_by_key(|wu| {
    +                match blockheights.get(&wu.utxo.outpoint().txid) {
    +                    Some(Some(blockheight)) => blockheight,
    +                    _ => &u32::MAX,
                     }
                 });
     
    -            required_utxos
    -                .into_iter()
    -                .map(|utxo| (true, utxo))
    -                .chain(optional_utxos.into_iter().map(|utxo| (false, utxo)))
    +            required_utxos
    +                .into_iter()
    +                .map(|utxo| (true, utxo))
    +                .chain(optional_utxos.into_iter().map(|utxo| (false, utxo)))
             };
     
    -        select_sorted_utxos(utxos, fee_rate, target_amount, drain_script)
    +        select_sorted_utxos(utxos, fee_rate, target_amount, drain_script)
         }
     }
     
    -/// Decide if change can be created
    -///
    -/// - `remaining_amount`: the amount in which the selected coins exceed the target amount
    -/// - `fee_rate`: required fee rate for the current selection
    -/// - `drain_script`: script to consider change creation
    -pub fn decide_change(remaining_amount: u64, fee_rate: FeeRate, drain_script: &Script) -> Excess {
    -    // drain_output_len = size(len(script_pubkey)) + len(script_pubkey) + size(output_value)
    -    let drain_output_len = serialize(drain_script).len() + 8usize;
    -    let change_fee = fee_rate.fee_vb(drain_output_len);
    -    let drain_val = remaining_amount.saturating_sub(change_fee);
    -
    -    if drain_val.is_dust(drain_script) {
    -        let dust_threshold = drain_script.dust_value().to_sat();
    -        Excess::NoChange {
    -            dust_threshold,
    -            change_fee,
    -            remaining_amount,
    +/// Decide if change can be created
    +///
    +/// - `remaining_amount`: the amount in which the selected coins exceed the target amount
    +/// - `fee_rate`: required fee rate for the current selection
    +/// - `drain_script`: script to consider change creation
    +pub fn decide_change(remaining_amount: u64, fee_rate: FeeRate, drain_script: &Script) -> Excess {
    +    // drain_output_len = size(len(script_pubkey)) + len(script_pubkey) + size(output_value)
    +    let drain_output_len = serialize(drain_script).len() + 8usize;
    +    let change_fee = fee_rate.fee_vb(drain_output_len);
    +    let drain_val = remaining_amount.saturating_sub(change_fee);
    +
    +    if drain_val.is_dust(drain_script) {
    +        let dust_threshold = drain_script.dust_value().to_sat();
    +        Excess::NoChange {
    +            dust_threshold,
    +            change_fee,
    +            remaining_amount,
             }
    -    } else {
    -        Excess::Change {
    -            amount: drain_val,
    -            fee: change_fee,
    +    } else {
    +        Excess::Change {
    +            amount: drain_val,
    +            fee: change_fee,
             }
         }
     }
     
    -fn select_sorted_utxos(
    -    utxos: impl Iterator<Item = (bool, WeightedUtxo)>,
    -    fee_rate: FeeRate,
    -    target_amount: u64,
    -    drain_script: &Script,
    -) -> Result<CoinSelectionResult, Error> {
    -    let mut selected_amount = 0;
    -    let mut fee_amount = 0;
    -    let selected = utxos
    -        .scan(
    -            (&mut selected_amount, &mut fee_amount),
    -            |(selected_amount, fee_amount), (must_use, weighted_utxo)| {
    -                if must_use || **selected_amount < target_amount + **fee_amount {
    -                    **fee_amount +=
    -                        fee_rate.fee_wu(TXIN_BASE_WEIGHT + weighted_utxo.satisfaction_weight);
    -                    **selected_amount += weighted_utxo.utxo.txout().value;
    +fn select_sorted_utxos(
    +    utxos: impl Iterator<Item = (bool, WeightedUtxo)>,
    +    fee_rate: FeeRate,
    +    target_amount: u64,
    +    drain_script: &Script,
    +) -> Result<CoinSelectionResult, Error> {
    +    let mut selected_amount = 0;
    +    let mut fee_amount = 0;
    +    let selected = utxos
    +        .scan(
    +            (&mut selected_amount, &mut fee_amount),
    +            |(selected_amount, fee_amount), (must_use, weighted_utxo)| {
    +                if must_use || **selected_amount < target_amount + **fee_amount {
    +                    **fee_amount +=
    +                        fee_rate.fee_wu(TXIN_BASE_WEIGHT + weighted_utxo.satisfaction_weight);
    +                    **selected_amount += weighted_utxo.utxo.txout().value;
     
                         log::debug!(
                             "Selected {}, updated fee_amount = `{}`",
    -                        weighted_utxo.utxo.outpoint(),
    -                        fee_amount
    +                        weighted_utxo.utxo.outpoint(),
    +                        fee_amount
                         );
     
    -                    Some(weighted_utxo.utxo)
    -                } else {
    -                    None
    -                }
    +                    Some(weighted_utxo.utxo)
    +                } else {
    +                    None
    +                }
                 },
             )
    -        .collect::<Vec<_>>();
    +        .collect::<Vec<_>>();
     
    -    let amount_needed_with_fees = target_amount + fee_amount;
    -    if selected_amount < amount_needed_with_fees {
    -        return Err(Error::InsufficientFunds {
    -            needed: amount_needed_with_fees,
    -            available: selected_amount,
    +    let amount_needed_with_fees = target_amount + fee_amount;
    +    if selected_amount < amount_needed_with_fees {
    +        return Err(Error::InsufficientFunds {
    +            needed: amount_needed_with_fees,
    +            available: selected_amount,
             });
         }
     
    -    let remaining_amount = selected_amount - amount_needed_with_fees;
    +    let remaining_amount = selected_amount - amount_needed_with_fees;
     
    -    let excess = decide_change(remaining_amount, fee_rate, drain_script);
    +    let excess = decide_change(remaining_amount, fee_rate, drain_script);
     
    -    Ok(CoinSelectionResult {
    -        selected,
    -        fee_amount,
    -        excess,
    +    Ok(CoinSelectionResult {
    +        selected,
    +        fee_amount,
    +        excess,
         })
     }
     
    -#[derive(Debug, Clone)]
    -// Adds fee information to an UTXO.
    -struct OutputGroup {
    -    weighted_utxo: WeightedUtxo,
    -    // Amount of fees for spending a certain utxo, calculated using a certain FeeRate
    -    fee: u64,
    -    // The effective value of the UTXO, i.e., the utxo value minus the fee for spending it
    -    effective_value: i64,
    +#[derive(Debug, Clone)]
    +// Adds fee information to an UTXO.
    +struct OutputGroup {
    +    weighted_utxo: WeightedUtxo,
    +    // Amount of fees for spending a certain utxo, calculated using a certain FeeRate
    +    fee: u64,
    +    // The effective value of the UTXO, i.e., the utxo value minus the fee for spending it
    +    effective_value: i64,
     }
     
    -impl OutputGroup {
    -    fn new(weighted_utxo: WeightedUtxo, fee_rate: FeeRate) -> Self {
    -        let fee = fee_rate.fee_wu(TXIN_BASE_WEIGHT + weighted_utxo.satisfaction_weight);
    -        let effective_value = weighted_utxo.utxo.txout().value as i64 - fee as i64;
    -        OutputGroup {
    -            weighted_utxo,
    -            fee,
    -            effective_value,
    +impl OutputGroup {
    +    fn new(weighted_utxo: WeightedUtxo, fee_rate: FeeRate) -> Self {
    +        let fee = fee_rate.fee_wu(TXIN_BASE_WEIGHT + weighted_utxo.satisfaction_weight);
    +        let effective_value = weighted_utxo.utxo.txout().value as i64 - fee as i64;
    +        OutputGroup {
    +            weighted_utxo,
    +            fee,
    +            effective_value,
             }
         }
     }
     
    -/// 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>
    -#[derive(Debug)]
    -pub struct BranchAndBoundCoinSelection {
    -    size_of_change: u64,
    +/// 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>
    +#[derive(Debug)]
    +pub struct BranchAndBoundCoinSelection {
    +    size_of_change: u64,
     }
     
    -impl Default for BranchAndBoundCoinSelection {
    -    fn default() -> Self {
    -        Self {
    -            // P2WPKH cost of change -> value (8 bytes) + script len (1 bytes) + script (22 bytes)
    -            size_of_change: 8 + 1 + 22,
    +impl Default for BranchAndBoundCoinSelection {
    +    fn default() -> Self {
    +        Self {
    +            // P2WPKH cost of change -> value (8 bytes) + script len (1 bytes) + script (22 bytes)
    +            size_of_change: 8 + 1 + 22,
             }
         }
     }
     
    -impl BranchAndBoundCoinSelection {
    -    /// Create new instance with target size for change output
    -    pub fn new(size_of_change: u64) -> Self {
    -        Self { size_of_change }
    +impl BranchAndBoundCoinSelection {
    +    /// Create new instance with target size for change output
    +    pub fn new(size_of_change: u64) -> Self {
    +        Self { size_of_change }
         }
     }
     
    -const BNB_TOTAL_TRIES: usize = 100_000;
    +const BNB_TOTAL_TRIES: usize = 100_000;
     
    -impl<D: Database> CoinSelectionAlgorithm<D> for BranchAndBoundCoinSelection {
    -    fn coin_select(
    +impl<D: Database> CoinSelectionAlgorithm<D> for BranchAndBoundCoinSelection {
    +    fn coin_select(
             &self,
    -        _database: &D,
    -        required_utxos: Vec<WeightedUtxo>,
    -        optional_utxos: Vec<WeightedUtxo>,
    -        fee_rate: FeeRate,
    -        target_amount: u64,
    -        drain_script: &Script,
    -    ) -> Result<CoinSelectionResult, Error> {
    -        // Mapping every (UTXO, usize) to an output group
    -        let required_utxos: Vec<OutputGroup> = required_utxos
    -            .into_iter()
    -            .map(|u| OutputGroup::new(u, fee_rate))
    -            .collect();
    -
    -        // Mapping every (UTXO, usize) to an output group, filtering UTXOs with a negative
    -        // effective value
    -        let optional_utxos: Vec<OutputGroup> = optional_utxos
    -            .into_iter()
    -            .map(|u| OutputGroup::new(u, fee_rate))
    -            .filter(|u| u.effective_value.is_positive())
    -            .collect();
    -
    -        let curr_value = required_utxos
    -            .iter()
    -            .fold(0, |acc, x| acc + x.effective_value);
    -
    -        let curr_available_value = optional_utxos
    -            .iter()
    -            .fold(0, |acc, x| acc + x.effective_value);
    -
    -        let cost_of_change = self.size_of_change as f32 * fee_rate.as_sat_per_vb();
    -
    -        // `curr_value` and `curr_available_value` are both the sum of *effective_values* of
    -        // the UTXOs. For the optional UTXOs (curr_available_value) we filter out UTXOs with
    -        // negative effective value, so it will always be positive.
    -        //
    -        // Since we are required to spend the required UTXOs (curr_value) we have to consider
    -        // all their effective values, even when negative, which means that curr_value could
    -        // be negative as well.
    -        //
    -        // If the sum of curr_value and curr_available_value is negative or lower than our target,
    -        // we can immediately exit with an error, as it's guaranteed we will never find a solution
    -        // if we actually run the BnB.
    -        let total_value: Result<u64, _> = (curr_available_value + curr_value).try_into();
    -        match total_value {
    -            Ok(v) if v >= target_amount => {}
    -            _ => {
    -                // Assume we spend all the UTXOs we can (all the required + all the optional with
    -                // positive effective value), sum their value and their fee cost.
    -                let (utxo_fees, utxo_value) = required_utxos
    -                    .iter()
    -                    .chain(optional_utxos.iter())
    -                    .fold((0, 0), |(mut fees, mut value), utxo| {
    -                        fees += utxo.fee;
    -                        value += utxo.weighted_utxo.utxo.txout().value;
    -
    -                        (fees, value)
    +        _database: &D,
    +        required_utxos: Vec<WeightedUtxo>,
    +        optional_utxos: Vec<WeightedUtxo>,
    +        fee_rate: FeeRate,
    +        target_amount: u64,
    +        drain_script: &Script,
    +    ) -> Result<CoinSelectionResult, Error> {
    +        // Mapping every (UTXO, usize) to an output group
    +        let required_utxos: Vec<OutputGroup> = required_utxos
    +            .into_iter()
    +            .map(|u| OutputGroup::new(u, fee_rate))
    +            .collect();
    +
    +        // Mapping every (UTXO, usize) to an output group, filtering UTXOs with a negative
    +        // effective value
    +        let optional_utxos: Vec<OutputGroup> = optional_utxos
    +            .into_iter()
    +            .map(|u| OutputGroup::new(u, fee_rate))
    +            .filter(|u| u.effective_value.is_positive())
    +            .collect();
    +
    +        let curr_value = required_utxos
    +            .iter()
    +            .fold(0, |acc, x| acc + x.effective_value);
    +
    +        let curr_available_value = optional_utxos
    +            .iter()
    +            .fold(0, |acc, x| acc + x.effective_value);
    +
    +        let cost_of_change = self.size_of_change as f32 * fee_rate.as_sat_per_vb();
    +
    +        // `curr_value` and `curr_available_value` are both the sum of *effective_values* of
    +        // the UTXOs. For the optional UTXOs (curr_available_value) we filter out UTXOs with
    +        // negative effective value, so it will always be positive.
    +        //
    +        // Since we are required to spend the required UTXOs (curr_value) we have to consider
    +        // all their effective values, even when negative, which means that curr_value could
    +        // be negative as well.
    +        //
    +        // If the sum of curr_value and curr_available_value is negative or lower than our target,
    +        // we can immediately exit with an error, as it's guaranteed we will never find a solution
    +        // if we actually run the BnB.
    +        let total_value: Result<u64, _> = (curr_available_value + curr_value).try_into();
    +        match total_value {
    +            Ok(v) if v >= target_amount => {}
    +            _ => {
    +                // Assume we spend all the UTXOs we can (all the required + all the optional with
    +                // positive effective value), sum their value and their fee cost.
    +                let (utxo_fees, utxo_value) = required_utxos
    +                    .iter()
    +                    .chain(optional_utxos.iter())
    +                    .fold((0, 0), |(mut fees, mut value), utxo| {
    +                        fees += utxo.fee;
    +                        value += utxo.weighted_utxo.utxo.txout().value;
    +
    +                        (fees, value)
                         });
     
    -                // Add to the target the fee cost of the UTXOs
    -                return Err(Error::InsufficientFunds {
    -                    needed: target_amount + utxo_fees,
    -                    available: utxo_value,
    +                // Add to the target the fee cost of the UTXOs
    +                return Err(Error::InsufficientFunds {
    +                    needed: target_amount + utxo_fees,
    +                    available: utxo_value,
                     });
                 }
             }
     
    -        let target_amount = target_amount
    -            .try_into()
    -            .expect("Bitcoin amount to fit into i64");
    +        let target_amount = target_amount
    +            .try_into()
    +            .expect("Bitcoin amount to fit into i64");
     
    -        if curr_value > target_amount {
    -            // 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 = (curr_value - target_amount) as u64;
    +        if curr_value > target_amount {
    +            // 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 = (curr_value - target_amount) as u64;
     
    -            let excess = decide_change(remaining_amount, fee_rate, drain_script);
    +            let excess = decide_change(remaining_amount, fee_rate, drain_script);
     
    -            return Ok(BranchAndBoundCoinSelection::calculate_cs_result(
    +            return Ok(BranchAndBoundCoinSelection::calculate_cs_result(
                     vec![],
    -                required_utxos,
    -                excess,
    +                required_utxos,
    +                excess,
                 ));
             }
     
    -        Ok(self
    -            .bnb(
    -                required_utxos.clone(),
    -                optional_utxos.clone(),
    -                curr_value,
    -                curr_available_value,
    -                target_amount,
    -                cost_of_change,
    -                drain_script,
    -                fee_rate,
    +        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,
    +            .unwrap_or_else(|_| {
    +                self.single_random_draw(
    +                    required_utxos,
    +                    optional_utxos,
    +                    curr_value,
    +                    target_amount,
    +                    drain_script,
    +                    fee_rate,
                     )
                 }))
         }
     }
     
    -impl BranchAndBoundCoinSelection {
    -    // TODO: make this more Rust-onic :)
    -    // (And perhaps refactor with less arguments?)
    -    #[allow(clippy::too_many_arguments)]
    -    fn bnb(
    +impl BranchAndBoundCoinSelection {
    +    // TODO: make this more Rust-onic :)
    +    // (And perhaps refactor with less arguments?)
    +    #[allow(clippy::too_many_arguments)]
    +    fn bnb(
             &self,
    -        required_utxos: Vec<OutputGroup>,
    -        mut optional_utxos: Vec<OutputGroup>,
    -        mut curr_value: i64,
    -        mut curr_available_value: i64,
    -        target_amount: i64,
    -        cost_of_change: f32,
    -        drain_script: &Script,
    -        fee_rate: FeeRate,
    -    ) -> Result<CoinSelectionResult, Error> {
    -        // current_selection[i] will contain true if we are using optional_utxos[i],
    -        // false otherwise. Note that current_selection.len() could be less than
    -        // optional_utxos.len(), it just means that we still haven't decided if we should keep
    -        // certain optional_utxos or not.
    -        let mut current_selection: Vec<bool> = Vec::with_capacity(optional_utxos.len());
    -
    -        // Sort the utxo_pool
    -        optional_utxos.sort_unstable_by_key(|a| a.effective_value);
    -        optional_utxos.reverse();
    -
    -        // Contains the best selection we found
    -        let mut best_selection = Vec::new();
    -        let mut best_selection_value = None;
    -
    -        // Depth First search loop for choosing the UTXOs
    -        for _ in 0..BNB_TOTAL_TRIES {
    -            // Conditions for starting a backtrack
    -            let mut backtrack = false;
    -            // Cannot possibly reach target with the amount remaining in the curr_available_value,
    -            // or the selected value is out of range.
    -            // Go back and try other branch
    -            if curr_value + curr_available_value < target_amount
    -                || curr_value > target_amount + cost_of_change as i64
    +        required_utxos: Vec<OutputGroup>,
    +        mut optional_utxos: Vec<OutputGroup>,
    +        mut curr_value: i64,
    +        mut curr_available_value: i64,
    +        target_amount: i64,
    +        cost_of_change: f32,
    +        drain_script: &Script,
    +        fee_rate: FeeRate,
    +    ) -> Result<CoinSelectionResult, Error> {
    +        // current_selection[i] will contain true if we are using optional_utxos[i],
    +        // false otherwise. Note that current_selection.len() could be less than
    +        // optional_utxos.len(), it just means that we still haven't decided if we should keep
    +        // certain optional_utxos or not.
    +        let mut current_selection: Vec<bool> = Vec::with_capacity(optional_utxos.len());
    +
    +        // Sort the utxo_pool
    +        optional_utxos.sort_unstable_by_key(|a| a.effective_value);
    +        optional_utxos.reverse();
    +
    +        // Contains the best selection we found
    +        let mut best_selection = Vec::new();
    +        let mut best_selection_value = None;
    +
    +        // Depth First search loop for choosing the UTXOs
    +        for _ in 0..BNB_TOTAL_TRIES {
    +            // Conditions for starting a backtrack
    +            let mut backtrack = false;
    +            // Cannot possibly reach target with the amount remaining in the curr_available_value,
    +            // or the selected value is out of range.
    +            // Go back and try other branch
    +            if curr_value + curr_available_value < target_amount
    +                || curr_value > target_amount + cost_of_change as i64
                 {
    -                backtrack = true;
    -            } else if curr_value >= target_amount {
    -                // Selected value is within range, there's no point in going forward. Start
    -                // backtracking
    -                backtrack = true;
    -
    -                // If we found a solution better than the previous one, or if there wasn't previous
    -                // solution, update the best solution
    -                if best_selection_value.is_none() || curr_value < best_selection_value.unwrap() {
    -                    best_selection = current_selection.clone();
    -                    best_selection_value = Some(curr_value);
    +                backtrack = true;
    +            } else if curr_value >= target_amount {
    +                // Selected value is within range, there's no point in going forward. Start
    +                // backtracking
    +                backtrack = true;
    +
    +                // If we found a solution better than the previous one, or if there wasn't previous
    +                // solution, update the best solution
    +                if best_selection_value.is_none() || curr_value < best_selection_value.unwrap() {
    +                    best_selection = current_selection.clone();
    +                    best_selection_value = Some(curr_value);
                     }
     
    -                // If we found a perfect match, break here
    -                if curr_value == target_amount {
    +                // If we found a perfect match, break here
    +                if curr_value == target_amount {
                         break;
                     }
                 }
     
    -            // Backtracking, moving backwards
    -            if backtrack {
    -                // Walk backwards to find the last included UTXO that still needs to have its omission branch traversed.
    -                while let Some(false) = current_selection.last() {
    -                    current_selection.pop();
    -                    curr_available_value += optional_utxos[current_selection.len()].effective_value;
    +            // Backtracking, moving backwards
    +            if backtrack {
    +                // Walk backwards to find the last included UTXO that still needs to have its omission branch traversed.
    +                while let Some(false) = current_selection.last() {
    +                    current_selection.pop();
    +                    curr_available_value += optional_utxos[current_selection.len()].effective_value;
                     }
     
    -                if current_selection.last_mut().is_none() {
    -                    // We have walked back to the first utxo and no branch is untraversed. All solutions searched
    -                    // If best selection is empty, then there's no exact match
    -                    if best_selection.is_empty() {
    -                        return Err(Error::BnBNoExactMatch);
    +                if current_selection.last_mut().is_none() {
    +                    // We have walked back to the first utxo and no branch is untraversed. All solutions searched
    +                    // If best selection is empty, then there's no exact match
    +                    if best_selection.is_empty() {
    +                        return Err(Error::BnBNoExactMatch);
                         }
                         break;
                     }
     
    -                if let Some(c) = current_selection.last_mut() {
    -                    // Output was included on previous iterations, try excluding now.
    -                    *c = false;
    +                if let Some(c) = current_selection.last_mut() {
    +                    // Output was included on previous iterations, try excluding now.
    +                    *c = false;
                     }
     
    -                let utxo = &optional_utxos[current_selection.len() - 1];
    -                curr_value -= utxo.effective_value;
    -            } else {
    -                // Moving forwards, continuing down this branch
    -                let utxo = &optional_utxos[current_selection.len()];
    +                let utxo = &optional_utxos[current_selection.len() - 1];
    +                curr_value -= utxo.effective_value;
    +            } else {
    +                // Moving forwards, continuing down this branch
    +                let utxo = &optional_utxos[current_selection.len()];
     
    -                // Remove this utxo from the curr_available_value utxo amount
    -                curr_available_value -= utxo.effective_value;
    +                // Remove this utxo from the curr_available_value utxo amount
    +                curr_available_value -= utxo.effective_value;
     
    -                // Inclusion branch first (Largest First Exploration)
    -                current_selection.push(true);
    -                curr_value += utxo.effective_value;
    +                // Inclusion branch first (Largest First Exploration)
    +                current_selection.push(true);
    +                curr_value += utxo.effective_value;
                 }
             }
     
    -        // Check for solution
    -        if best_selection.is_empty() {
    -            return Err(Error::BnBTotalTriesExceeded);
    +        // Check for solution
    +        if best_selection.is_empty() {
    +            return Err(Error::BnBTotalTriesExceeded);
             }
     
    -        // Set output set
    -        let selected_utxos = optional_utxos
    -            .into_iter()
    -            .zip(best_selection)
    -            .filter_map(|(optional, is_in_best)| if is_in_best { Some(optional) } else { None })
    -            .collect::<Vec<OutputGroup>>();
    +        // Set output set
    +        let selected_utxos = optional_utxos
    +            .into_iter()
    +            .zip(best_selection)
    +            .filter_map(|(optional, is_in_best)| if is_in_best { Some(optional) } else { None })
    +            .collect::<Vec<OutputGroup>>();
     
    -        let selected_amount = best_selection_value.unwrap();
    +        let selected_amount = best_selection_value.unwrap();
     
    -        // 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_amount - target_amount) as u64;
    +        // 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_amount - target_amount) as u64;
     
    -        let excess = decide_change(remaining_amount, fee_rate, drain_script);
    +        let excess = decide_change(remaining_amount, fee_rate, drain_script);
     
    -        Ok(BranchAndBoundCoinSelection::calculate_cs_result(
    -            selected_utxos,
    -            required_utxos,
    -            excess,
    +        Ok(BranchAndBoundCoinSelection::calculate_cs_result(
    +            selected_utxos,
    +            required_utxos,
    +            excess,
             ))
         }
     
    -    #[allow(clippy::too_many_arguments)]
    -    fn single_random_draw(
    +    #[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 {
    -        #[cfg(not(test))]
    -        optional_utxos.shuffle(&mut thread_rng());
    -        #[cfg(test)]
    -        {
    -            let seed = [0; 32];
    -            let mut rng: StdRng = SeedableRng::from_seed(seed);
    -            optional_utxos.shuffle(&mut rng);
    +        required_utxos: Vec<OutputGroup>,
    +        mut optional_utxos: Vec<OutputGroup>,
    +        curr_value: i64,
    +        target_amount: i64,
    +        drain_script: &Script,
    +        fee_rate: FeeRate,
    +    ) -> CoinSelectionResult {
    +        #[cfg(not(test))]
    +        optional_utxos.shuffle(&mut thread_rng());
    +        #[cfg(test)]
    +        {
    +            let seed = [0; 32];
    +            let mut rng: StdRng = SeedableRng::from_seed(seed);
    +            optional_utxos.shuffle(&mut 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)
    +        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;
    +        // 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);
    +        let excess = decide_change(remaining_amount, fee_rate, drain_script);
     
    -        BranchAndBoundCoinSelection::calculate_cs_result(selected_utxos.1, required_utxos, excess)
    +        BranchAndBoundCoinSelection::calculate_cs_result(selected_utxos.1, required_utxos, excess)
         }
     
    -    fn calculate_cs_result(
    -        mut selected_utxos: Vec<OutputGroup>,
    -        mut required_utxos: Vec<OutputGroup>,
    -        excess: Excess,
    -    ) -> CoinSelectionResult {
    -        selected_utxos.append(&mut required_utxos);
    -        let fee_amount = selected_utxos.iter().map(|u| u.fee).sum::<u64>();
    -        let selected = selected_utxos
    -            .into_iter()
    -            .map(|u| u.weighted_utxo.utxo)
    -            .collect::<Vec<_>>();
    -
    -        CoinSelectionResult {
    -            selected,
    -            fee_amount,
    -            excess,
    +    fn calculate_cs_result(
    +        mut selected_utxos: Vec<OutputGroup>,
    +        mut required_utxos: Vec<OutputGroup>,
    +        excess: Excess,
    +    ) -> CoinSelectionResult {
    +        selected_utxos.append(&mut required_utxos);
    +        let fee_amount = selected_utxos.iter().map(|u| u.fee).sum::<u64>();
    +        let selected = selected_utxos
    +            .into_iter()
    +            .map(|u| u.weighted_utxo.utxo)
    +            .collect::<Vec<_>>();
    +
    +        CoinSelectionResult {
    +            selected,
    +            fee_amount,
    +            excess,
             }
         }
     }
     
    -#[cfg(test)]
    -mod test {
    -    use std::str::FromStr;
    +#[cfg(test)]
    +mod test {
    +    use std::str::FromStr;
     
    -    use bitcoin::{OutPoint, Script, TxOut};
    +    use bitcoin::{OutPoint, Script, TxOut};
     
    -    use super::*;
    -    use crate::database::{BatchOperations, MemoryDatabase};
    -    use crate::types::*;
    -    use crate::wallet::Vbytes;
    +    use super::*;
    +    use crate::database::{BatchOperations, MemoryDatabase};
    +    use crate::types::*;
    +    use crate::wallet::Vbytes;
     
    -    use rand::rngs::StdRng;
    -    use rand::seq::SliceRandom;
    -    use rand::{Rng, SeedableRng};
    +    use rand::rngs::StdRng;
    +    use rand::seq::SliceRandom;
    +    use rand::{Rng, SeedableRng};
     
    -    // n. of items on witness (1WU) + signature len (1WU) + signature and sighash (72WU)
    -    // + pubkey len (1WU) + pubkey (33WU) + script sig len (1 byte, 4WU)
    -    const P2WPKH_SATISFACTION_SIZE: usize = 1 + 1 + 72 + 1 + 33 + 4;
    +    // n. of items on witness (1WU) + signature len (1WU) + signature and sighash (72WU)
    +    // + pubkey len (1WU) + pubkey (33WU) + script sig len (1 byte, 4WU)
    +    const P2WPKH_SATISFACTION_SIZE: usize = 1 + 1 + 72 + 1 + 33 + 4;
     
    -    const FEE_AMOUNT: u64 = 50;
    +    const FEE_AMOUNT: u64 = 50;
     
    -    fn utxo(value: u64, index: u32) -> WeightedUtxo {
    -        assert!(index < 10);
    -        let outpoint = OutPoint::from_str(&format!(
    +    fn utxo(value: u64, index: u32) -> WeightedUtxo {
    +        assert!(index < 10);
    +        let outpoint = OutPoint::from_str(&format!(
                 "000000000000000000000000000000000000000000000000000000000000000{}:0",
    -            index
    +            index
             ))
    -        .unwrap();
    -        WeightedUtxo {
    -            satisfaction_weight: P2WPKH_SATISFACTION_SIZE,
    -            utxo: Utxo::Local(LocalUtxo {
    -                outpoint,
    -                txout: TxOut {
    -                    value,
    -                    script_pubkey: Script::new(),
    +        .unwrap();
    +        WeightedUtxo {
    +            satisfaction_weight: P2WPKH_SATISFACTION_SIZE,
    +            utxo: Utxo::Local(LocalUtxo {
    +                outpoint,
    +                txout: TxOut {
    +                    value,
    +                    script_pubkey: Script::new(),
                     },
    -                keychain: KeychainKind::External,
    -                is_spent: false,
    +                keychain: KeychainKind::External,
    +                is_spent: false,
                 }),
             }
         }
     
    -    fn get_test_utxos() -> Vec<WeightedUtxo> {
    +    fn get_test_utxos() -> Vec<WeightedUtxo> {
             vec![
    -            utxo(100_000, 0),
    -            utxo(FEE_AMOUNT as u64 - 40, 1),
    -            utxo(200_000, 2),
    +            utxo(100_000, 0),
    +            utxo(FEE_AMOUNT as u64 - 40, 1),
    +            utxo(200_000, 2),
             ]
         }
     
    -    fn setup_database_and_get_oldest_first_test_utxos<D: Database>(
    -        database: &mut D,
    -    ) -> Vec<WeightedUtxo> {
    -        // ensure utxos are from different tx
    -        let utxo1 = utxo(120_000, 1);
    -        let utxo2 = utxo(80_000, 2);
    -        let utxo3 = utxo(300_000, 3);
    -
    -        // add tx to DB so utxos are sorted by blocktime asc
    -        // utxos will be selected by the following order
    -        // utxo1(blockheight 1) -> utxo2(blockheight 2), utxo3 (blockheight 3)
    -        // timestamp are all set as the same to ensure that only block height is used in sorting
    -        let utxo1_tx_details = TransactionDetails {
    -            transaction: None,
    -            txid: utxo1.utxo.outpoint().txid,
    -            received: 1,
    -            sent: 0,
    -            fee: None,
    -            confirmation_time: Some(BlockTime {
    -                height: 1,
    -                timestamp: 1231006505,
    +    fn setup_database_and_get_oldest_first_test_utxos<D: Database>(
    +        database: &mut D,
    +    ) -> Vec<WeightedUtxo> {
    +        // ensure utxos are from different tx
    +        let utxo1 = utxo(120_000, 1);
    +        let utxo2 = utxo(80_000, 2);
    +        let utxo3 = utxo(300_000, 3);
    +
    +        // add tx to DB so utxos are sorted by blocktime asc
    +        // utxos will be selected by the following order
    +        // utxo1(blockheight 1) -> utxo2(blockheight 2), utxo3 (blockheight 3)
    +        // timestamp are all set as the same to ensure that only block height is used in sorting
    +        let utxo1_tx_details = TransactionDetails {
    +            transaction: None,
    +            txid: utxo1.utxo.outpoint().txid,
    +            received: 1,
    +            sent: 0,
    +            fee: None,
    +            confirmation_time: Some(BlockTime {
    +                height: 1,
    +                timestamp: 1231006505,
                 }),
             };
     
    -        let utxo2_tx_details = TransactionDetails {
    -            transaction: None,
    -            txid: utxo2.utxo.outpoint().txid,
    -            received: 1,
    -            sent: 0,
    -            fee: None,
    -            confirmation_time: Some(BlockTime {
    -                height: 2,
    -                timestamp: 1231006505,
    +        let utxo2_tx_details = TransactionDetails {
    +            transaction: None,
    +            txid: utxo2.utxo.outpoint().txid,
    +            received: 1,
    +            sent: 0,
    +            fee: None,
    +            confirmation_time: Some(BlockTime {
    +                height: 2,
    +                timestamp: 1231006505,
                 }),
             };
     
    -        let utxo3_tx_details = TransactionDetails {
    -            transaction: None,
    -            txid: utxo3.utxo.outpoint().txid,
    -            received: 1,
    -            sent: 0,
    -            fee: None,
    -            confirmation_time: Some(BlockTime {
    -                height: 3,
    -                timestamp: 1231006505,
    +        let utxo3_tx_details = TransactionDetails {
    +            transaction: None,
    +            txid: utxo3.utxo.outpoint().txid,
    +            received: 1,
    +            sent: 0,
    +            fee: None,
    +            confirmation_time: Some(BlockTime {
    +                height: 3,
    +                timestamp: 1231006505,
                 }),
             };
     
    -        database.set_tx(&utxo1_tx_details).unwrap();
    -        database.set_tx(&utxo2_tx_details).unwrap();
    -        database.set_tx(&utxo3_tx_details).unwrap();
    +        database.set_tx(&utxo1_tx_details).unwrap();
    +        database.set_tx(&utxo2_tx_details).unwrap();
    +        database.set_tx(&utxo3_tx_details).unwrap();
     
    -        vec![utxo1, utxo2, utxo3]
    +        vec![utxo1, utxo2, utxo3]
         }
     
    -    fn generate_random_utxos(rng: &mut StdRng, utxos_number: usize) -> Vec<WeightedUtxo> {
    -        let mut res = Vec::new();
    -        for _ in 0..utxos_number {
    -            res.push(WeightedUtxo {
    -                satisfaction_weight: P2WPKH_SATISFACTION_SIZE,
    -                utxo: Utxo::Local(LocalUtxo {
    -                    outpoint: OutPoint::from_str(
    +    fn generate_random_utxos(rng: &mut StdRng, utxos_number: usize) -> Vec<WeightedUtxo> {
    +        let mut res = Vec::new();
    +        for _ in 0..utxos_number {
    +            res.push(WeightedUtxo {
    +                satisfaction_weight: P2WPKH_SATISFACTION_SIZE,
    +                utxo: Utxo::Local(LocalUtxo {
    +                    outpoint: OutPoint::from_str(
                             "ebd9813ecebc57ff8f30797de7c205e3c7498ca950ea4341ee51a685ff2fa30a:0",
                         )
    -                    .unwrap(),
    -                    txout: TxOut {
    -                        value: rng.gen_range(0..200000000),
    -                        script_pubkey: Script::new(),
    +                    .unwrap(),
    +                    txout: TxOut {
    +                        value: rng.gen_range(0..200000000),
    +                        script_pubkey: Script::new(),
                         },
    -                    keychain: KeychainKind::External,
    -                    is_spent: false,
    +                    keychain: KeychainKind::External,
    +                    is_spent: false,
                     }),
                 });
             }
    -        res
    +        res
         }
     
    -    fn generate_same_value_utxos(utxos_value: u64, utxos_number: usize) -> Vec<WeightedUtxo> {
    -        let utxo = WeightedUtxo {
    -            satisfaction_weight: P2WPKH_SATISFACTION_SIZE,
    -            utxo: Utxo::Local(LocalUtxo {
    -                outpoint: OutPoint::from_str(
    +    fn generate_same_value_utxos(utxos_value: u64, utxos_number: usize) -> Vec<WeightedUtxo> {
    +        let utxo = WeightedUtxo {
    +            satisfaction_weight: P2WPKH_SATISFACTION_SIZE,
    +            utxo: Utxo::Local(LocalUtxo {
    +                outpoint: OutPoint::from_str(
                         "ebd9813ecebc57ff8f30797de7c205e3c7498ca950ea4341ee51a685ff2fa30a:0",
                     )
    -                .unwrap(),
    -                txout: TxOut {
    -                    value: utxos_value,
    -                    script_pubkey: Script::new(),
    +                .unwrap(),
    +                txout: TxOut {
    +                    value: utxos_value,
    +                    script_pubkey: Script::new(),
                     },
    -                keychain: KeychainKind::External,
    -                is_spent: false,
    +                keychain: KeychainKind::External,
    +                is_spent: false,
                 }),
             };
    -        vec![utxo; utxos_number]
    +        vec![utxo; utxos_number]
         }
     
    -    fn sum_random_utxos(mut rng: &mut StdRng, utxos: &mut Vec<WeightedUtxo>) -> u64 {
    -        let utxos_picked_len = rng.gen_range(2..utxos.len() / 2);
    -        utxos.shuffle(&mut rng);
    -        utxos[..utxos_picked_len]
    -            .iter()
    -            .map(|u| u.utxo.txout().value)
    -            .sum()
    +    fn sum_random_utxos(mut rng: &mut StdRng, utxos: &mut Vec<WeightedUtxo>) -> u64 {
    +        let utxos_picked_len = rng.gen_range(2..utxos.len() / 2);
    +        utxos.shuffle(&mut rng);
    +        utxos[..utxos_picked_len]
    +            .iter()
    +            .map(|u| u.utxo.txout().value)
    +            .sum()
         }
     
    -    #[test]
    -    fn test_largest_first_coin_selection_success() {
    -        let utxos = get_test_utxos();
    -        let database = MemoryDatabase::default();
    -        let drain_script = Script::default();
    -        let target_amount = 250_000 + FEE_AMOUNT;
    -
    -        let result = LargestFirstCoinSelection::default()
    -            .coin_select(
    -                &database,
    -                utxos,
    +    #[test]
    +    fn test_largest_first_coin_selection_success() {
    +        let utxos = get_test_utxos();
    +        let database = MemoryDatabase::default();
    +        let drain_script = Script::default();
    +        let target_amount = 250_000 + FEE_AMOUNT;
    +
    +        let result = LargestFirstCoinSelection::default()
    +            .coin_select(
    +                &database,
    +                utxos,
                     vec![],
    -                FeeRate::from_sat_per_vb(1.0),
    -                target_amount,
    -                &drain_script,
    +                FeeRate::from_sat_per_vb(1.0),
    +                target_amount,
    +                &drain_script,
                 )
    -            .unwrap();
    +            .unwrap();
     
    -        assert_eq!(result.selected.len(), 3);
    -        assert_eq!(result.selected_amount(), 300_010);
    -        assert_eq!(result.fee_amount, 204)
    +        assert_eq!(result.selected.len(), 3);
    +        assert_eq!(result.selected_amount(), 300_010);
    +        assert_eq!(result.fee_amount, 204)
         }
     
    -    #[test]
    -    fn test_largest_first_coin_selection_use_all() {
    -        let utxos = get_test_utxos();
    -        let database = MemoryDatabase::default();
    -        let drain_script = Script::default();
    -        let target_amount = 20_000 + FEE_AMOUNT;
    -
    -        let result = LargestFirstCoinSelection::default()
    -            .coin_select(
    -                &database,
    -                utxos,
    +    #[test]
    +    fn test_largest_first_coin_selection_use_all() {
    +        let utxos = get_test_utxos();
    +        let database = MemoryDatabase::default();
    +        let drain_script = Script::default();
    +        let target_amount = 20_000 + FEE_AMOUNT;
    +
    +        let result = LargestFirstCoinSelection::default()
    +            .coin_select(
    +                &database,
    +                utxos,
                     vec![],
    -                FeeRate::from_sat_per_vb(1.0),
    -                target_amount,
    -                &drain_script,
    +                FeeRate::from_sat_per_vb(1.0),
    +                target_amount,
    +                &drain_script,
                 )
    -            .unwrap();
    +            .unwrap();
     
    -        assert_eq!(result.selected.len(), 3);
    -        assert_eq!(result.selected_amount(), 300_010);
    -        assert_eq!(result.fee_amount, 204);
    +        assert_eq!(result.selected.len(), 3);
    +        assert_eq!(result.selected_amount(), 300_010);
    +        assert_eq!(result.fee_amount, 204);
         }
     
    -    #[test]
    -    fn test_largest_first_coin_selection_use_only_necessary() {
    -        let utxos = get_test_utxos();
    -        let database = MemoryDatabase::default();
    -        let drain_script = Script::default();
    -        let target_amount = 20_000 + FEE_AMOUNT;
    +    #[test]
    +    fn test_largest_first_coin_selection_use_only_necessary() {
    +        let utxos = get_test_utxos();
    +        let database = MemoryDatabase::default();
    +        let drain_script = Script::default();
    +        let target_amount = 20_000 + FEE_AMOUNT;
     
    -        let result = LargestFirstCoinSelection::default()
    -            .coin_select(
    -                &database,
    +        let result = LargestFirstCoinSelection::default()
    +            .coin_select(
    +                &database,
                     vec![],
    -                utxos,
    -                FeeRate::from_sat_per_vb(1.0),
    -                target_amount,
    -                &drain_script,
    +                utxos,
    +                FeeRate::from_sat_per_vb(1.0),
    +                target_amount,
    +                &drain_script,
                 )
    -            .unwrap();
    +            .unwrap();
     
    -        assert_eq!(result.selected.len(), 1);
    -        assert_eq!(result.selected_amount(), 200_000);
    -        assert_eq!(result.fee_amount, 68);
    +        assert_eq!(result.selected.len(), 1);
    +        assert_eq!(result.selected_amount(), 200_000);
    +        assert_eq!(result.fee_amount, 68);
         }
     
    -    #[test]
    -    #[should_panic(expected = "InsufficientFunds")]
    -    fn test_largest_first_coin_selection_insufficient_funds() {
    -        let utxos = get_test_utxos();
    -        let database = MemoryDatabase::default();
    -        let drain_script = Script::default();
    -        let target_amount = 500_000 + FEE_AMOUNT;
    -
    -        LargestFirstCoinSelection::default()
    -            .coin_select(
    -                &database,
    +    #[test]
    +    #[should_panic(expected = "InsufficientFunds")]
    +    fn test_largest_first_coin_selection_insufficient_funds() {
    +        let utxos = get_test_utxos();
    +        let database = MemoryDatabase::default();
    +        let drain_script = Script::default();
    +        let target_amount = 500_000 + FEE_AMOUNT;
    +
    +        LargestFirstCoinSelection::default()
    +            .coin_select(
    +                &database,
                     vec![],
    -                utxos,
    -                FeeRate::from_sat_per_vb(1.0),
    -                target_amount,
    -                &drain_script,
    +                utxos,
    +                FeeRate::from_sat_per_vb(1.0),
    +                target_amount,
    +                &drain_script,
                 )
    -            .unwrap();
    +            .unwrap();
         }
     
    -    #[test]
    -    #[should_panic(expected = "InsufficientFunds")]
    -    fn test_largest_first_coin_selection_insufficient_funds_high_fees() {
    -        let utxos = get_test_utxos();
    -        let database = MemoryDatabase::default();
    -        let drain_script = Script::default();
    -        let target_amount = 250_000 + FEE_AMOUNT;
    -
    -        LargestFirstCoinSelection::default()
    -            .coin_select(
    -                &database,
    +    #[test]
    +    #[should_panic(expected = "InsufficientFunds")]
    +    fn test_largest_first_coin_selection_insufficient_funds_high_fees() {
    +        let utxos = get_test_utxos();
    +        let database = MemoryDatabase::default();
    +        let drain_script = Script::default();
    +        let target_amount = 250_000 + FEE_AMOUNT;
    +
    +        LargestFirstCoinSelection::default()
    +            .coin_select(
    +                &database,
                     vec![],
    -                utxos,
    -                FeeRate::from_sat_per_vb(1000.0),
    -                target_amount,
    -                &drain_script,
    +                utxos,
    +                FeeRate::from_sat_per_vb(1000.0),
    +                target_amount,
    +                &drain_script,
                 )
    -            .unwrap();
    +            .unwrap();
         }
     
    -    #[test]
    -    fn test_oldest_first_coin_selection_success() {
    -        let mut database = MemoryDatabase::default();
    -        let utxos = setup_database_and_get_oldest_first_test_utxos(&mut database);
    -        let drain_script = Script::default();
    -        let target_amount = 180_000 + FEE_AMOUNT;
    +    #[test]
    +    fn test_oldest_first_coin_selection_success() {
    +        let mut database = MemoryDatabase::default();
    +        let utxos = setup_database_and_get_oldest_first_test_utxos(&mut database);
    +        let drain_script = Script::default();
    +        let target_amount = 180_000 + FEE_AMOUNT;
     
    -        let result = OldestFirstCoinSelection::default()
    -            .coin_select(
    -                &database,
    +        let result = OldestFirstCoinSelection::default()
    +            .coin_select(
    +                &database,
                     vec![],
    -                utxos,
    -                FeeRate::from_sat_per_vb(1.0),
    -                target_amount,
    -                &drain_script,
    +                utxos,
    +                FeeRate::from_sat_per_vb(1.0),
    +                target_amount,
    +                &drain_script,
                 )
    -            .unwrap();
    +            .unwrap();
     
    -        assert_eq!(result.selected.len(), 2);
    -        assert_eq!(result.selected_amount(), 200_000);
    -        assert_eq!(result.fee_amount, 136)
    +        assert_eq!(result.selected.len(), 2);
    +        assert_eq!(result.selected_amount(), 200_000);
    +        assert_eq!(result.fee_amount, 136)
         }
     
    -    #[test]
    -    fn test_oldest_first_coin_selection_utxo_not_in_db_will_be_selected_last() {
    -        // ensure utxos are from different tx
    -        let utxo1 = utxo(120_000, 1);
    -        let utxo2 = utxo(80_000, 2);
    -        let utxo3 = utxo(300_000, 3);
    -        let drain_script = Script::default();
    -
    -        let mut database = MemoryDatabase::default();
    -
    -        // add tx to DB so utxos are sorted by blocktime asc
    -        // utxos will be selected by the following order
    -        // utxo1(blockheight 1) -> utxo2(blockheight 2), utxo3 (not exist in DB)
    -        // timestamp are all set as the same to ensure that only block height is used in sorting
    -        let utxo1_tx_details = TransactionDetails {
    -            transaction: None,
    -            txid: utxo1.utxo.outpoint().txid,
    -            received: 1,
    -            sent: 0,
    -            fee: None,
    -            confirmation_time: Some(BlockTime {
    -                height: 1,
    -                timestamp: 1231006505,
    +    #[test]
    +    fn test_oldest_first_coin_selection_utxo_not_in_db_will_be_selected_last() {
    +        // ensure utxos are from different tx
    +        let utxo1 = utxo(120_000, 1);
    +        let utxo2 = utxo(80_000, 2);
    +        let utxo3 = utxo(300_000, 3);
    +        let drain_script = Script::default();
    +
    +        let mut database = MemoryDatabase::default();
    +
    +        // add tx to DB so utxos are sorted by blocktime asc
    +        // utxos will be selected by the following order
    +        // utxo1(blockheight 1) -> utxo2(blockheight 2), utxo3 (not exist in DB)
    +        // timestamp are all set as the same to ensure that only block height is used in sorting
    +        let utxo1_tx_details = TransactionDetails {
    +            transaction: None,
    +            txid: utxo1.utxo.outpoint().txid,
    +            received: 1,
    +            sent: 0,
    +            fee: None,
    +            confirmation_time: Some(BlockTime {
    +                height: 1,
    +                timestamp: 1231006505,
                 }),
             };
     
    -        let utxo2_tx_details = TransactionDetails {
    -            transaction: None,
    -            txid: utxo2.utxo.outpoint().txid,
    -            received: 1,
    -            sent: 0,
    -            fee: None,
    -            confirmation_time: Some(BlockTime {
    -                height: 2,
    -                timestamp: 1231006505,
    +        let utxo2_tx_details = TransactionDetails {
    +            transaction: None,
    +            txid: utxo2.utxo.outpoint().txid,
    +            received: 1,
    +            sent: 0,
    +            fee: None,
    +            confirmation_time: Some(BlockTime {
    +                height: 2,
    +                timestamp: 1231006505,
                 }),
             };
     
    -        database.set_tx(&utxo1_tx_details).unwrap();
    -        database.set_tx(&utxo2_tx_details).unwrap();
    +        database.set_tx(&utxo1_tx_details).unwrap();
    +        database.set_tx(&utxo2_tx_details).unwrap();
     
    -        let target_amount = 180_000 + FEE_AMOUNT;
    +        let target_amount = 180_000 + FEE_AMOUNT;
     
    -        let result = OldestFirstCoinSelection::default()
    -            .coin_select(
    -                &database,
    +        let result = OldestFirstCoinSelection::default()
    +            .coin_select(
    +                &database,
                     vec![],
    -                vec![utxo3, utxo1, utxo2],
    -                FeeRate::from_sat_per_vb(1.0),
    -                target_amount,
    -                &drain_script,
    +                vec![utxo3, utxo1, utxo2],
    +                FeeRate::from_sat_per_vb(1.0),
    +                target_amount,
    +                &drain_script,
                 )
    -            .unwrap();
    +            .unwrap();
     
    -        assert_eq!(result.selected.len(), 2);
    -        assert_eq!(result.selected_amount(), 200_000);
    -        assert_eq!(result.fee_amount, 136)
    +        assert_eq!(result.selected.len(), 2);
    +        assert_eq!(result.selected_amount(), 200_000);
    +        assert_eq!(result.fee_amount, 136)
         }
     
    -    #[test]
    -    fn test_oldest_first_coin_selection_use_all() {
    -        let mut database = MemoryDatabase::default();
    -        let utxos = setup_database_and_get_oldest_first_test_utxos(&mut database);
    -        let drain_script = Script::default();
    -        let target_amount = 20_000 + FEE_AMOUNT;
    -
    -        let result = OldestFirstCoinSelection::default()
    -            .coin_select(
    -                &database,
    -                utxos,
    +    #[test]
    +    fn test_oldest_first_coin_selection_use_all() {
    +        let mut database = MemoryDatabase::default();
    +        let utxos = setup_database_and_get_oldest_first_test_utxos(&mut database);
    +        let drain_script = Script::default();
    +        let target_amount = 20_000 + FEE_AMOUNT;
    +
    +        let result = OldestFirstCoinSelection::default()
    +            .coin_select(
    +                &database,
    +                utxos,
                     vec![],
    -                FeeRate::from_sat_per_vb(1.0),
    -                target_amount,
    -                &drain_script,
    +                FeeRate::from_sat_per_vb(1.0),
    +                target_amount,
    +                &drain_script,
                 )
    -            .unwrap();
    +            .unwrap();
     
    -        assert_eq!(result.selected.len(), 3);
    -        assert_eq!(result.selected_amount(), 500_000);
    -        assert_eq!(result.fee_amount, 204);
    +        assert_eq!(result.selected.len(), 3);
    +        assert_eq!(result.selected_amount(), 500_000);
    +        assert_eq!(result.fee_amount, 204);
         }
     
    -    #[test]
    -    fn test_oldest_first_coin_selection_use_only_necessary() {
    -        let mut database = MemoryDatabase::default();
    -        let utxos = setup_database_and_get_oldest_first_test_utxos(&mut database);
    -        let drain_script = Script::default();
    -        let target_amount = 20_000 + FEE_AMOUNT;
    +    #[test]
    +    fn test_oldest_first_coin_selection_use_only_necessary() {
    +        let mut database = MemoryDatabase::default();
    +        let utxos = setup_database_and_get_oldest_first_test_utxos(&mut database);
    +        let drain_script = Script::default();
    +        let target_amount = 20_000 + FEE_AMOUNT;
     
    -        let result = OldestFirstCoinSelection::default()
    -            .coin_select(
    -                &database,
    +        let result = OldestFirstCoinSelection::default()
    +            .coin_select(
    +                &database,
                     vec![],
    -                utxos,
    -                FeeRate::from_sat_per_vb(1.0),
    -                target_amount,
    -                &drain_script,
    +                utxos,
    +                FeeRate::from_sat_per_vb(1.0),
    +                target_amount,
    +                &drain_script,
                 )
    -            .unwrap();
    +            .unwrap();
     
    -        assert_eq!(result.selected.len(), 1);
    -        assert_eq!(result.selected_amount(), 120_000);
    -        assert_eq!(result.fee_amount, 68);
    +        assert_eq!(result.selected.len(), 1);
    +        assert_eq!(result.selected_amount(), 120_000);
    +        assert_eq!(result.fee_amount, 68);
         }
     
    -    #[test]
    -    #[should_panic(expected = "InsufficientFunds")]
    -    fn test_oldest_first_coin_selection_insufficient_funds() {
    -        let mut database = MemoryDatabase::default();
    -        let utxos = setup_database_and_get_oldest_first_test_utxos(&mut database);
    -        let drain_script = Script::default();
    -        let target_amount = 600_000 + FEE_AMOUNT;
    -
    -        OldestFirstCoinSelection::default()
    -            .coin_select(
    -                &database,
    +    #[test]
    +    #[should_panic(expected = "InsufficientFunds")]
    +    fn test_oldest_first_coin_selection_insufficient_funds() {
    +        let mut database = MemoryDatabase::default();
    +        let utxos = setup_database_and_get_oldest_first_test_utxos(&mut database);
    +        let drain_script = Script::default();
    +        let target_amount = 600_000 + FEE_AMOUNT;
    +
    +        OldestFirstCoinSelection::default()
    +            .coin_select(
    +                &database,
                     vec![],
    -                utxos,
    -                FeeRate::from_sat_per_vb(1.0),
    -                target_amount,
    -                &drain_script,
    +                utxos,
    +                FeeRate::from_sat_per_vb(1.0),
    +                target_amount,
    +                &drain_script,
                 )
    -            .unwrap();
    +            .unwrap();
         }
     
    -    #[test]
    -    #[should_panic(expected = "InsufficientFunds")]
    -    fn test_oldest_first_coin_selection_insufficient_funds_high_fees() {
    -        let mut database = MemoryDatabase::default();
    -        let utxos = setup_database_and_get_oldest_first_test_utxos(&mut database);
    +    #[test]
    +    #[should_panic(expected = "InsufficientFunds")]
    +    fn test_oldest_first_coin_selection_insufficient_funds_high_fees() {
    +        let mut database = MemoryDatabase::default();
    +        let utxos = setup_database_and_get_oldest_first_test_utxos(&mut database);
     
    -        let target_amount: u64 = utxos.iter().map(|wu| wu.utxo.txout().value).sum::<u64>() - 50;
    -        let drain_script = Script::default();
    +        let target_amount: u64 = utxos.iter().map(|wu| wu.utxo.txout().value).sum::<u64>() - 50;
    +        let drain_script = Script::default();
     
    -        OldestFirstCoinSelection::default()
    -            .coin_select(
    -                &database,
    +        OldestFirstCoinSelection::default()
    +            .coin_select(
    +                &database,
                     vec![],
    -                utxos,
    -                FeeRate::from_sat_per_vb(1000.0),
    -                target_amount,
    -                &drain_script,
    +                utxos,
    +                FeeRate::from_sat_per_vb(1000.0),
    +                target_amount,
    +                &drain_script,
                 )
    -            .unwrap();
    +            .unwrap();
         }
     
    -    #[test]
    -    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);
    +    #[test]
    +    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 database = MemoryDatabase::default();
    -        let drain_script = Script::default();
    +        let database = MemoryDatabase::default();
    +        let drain_script = Script::default();
     
    -        let target_amount = 250_000 + FEE_AMOUNT;
    +        let target_amount = 250_000 + FEE_AMOUNT;
     
    -        let result = BranchAndBoundCoinSelection::default()
    -            .coin_select(
    -                &database,
    +        let result = BranchAndBoundCoinSelection::default()
    +            .coin_select(
    +                &database,
                     vec![],
    -                utxos,
    -                FeeRate::from_sat_per_vb(1.0),
    -                target_amount,
    -                &drain_script,
    +                utxos,
    +                FeeRate::from_sat_per_vb(1.0),
    +                target_amount,
    +                &drain_script,
                 )
    -            .unwrap();
    +            .unwrap();
     
    -        assert_eq!(result.selected.len(), 3);
    -        assert_eq!(result.selected_amount(), 300_000);
    -        assert_eq!(result.fee_amount, 204);
    +        assert_eq!(result.selected.len(), 3);
    +        assert_eq!(result.selected_amount(), 300_000);
    +        assert_eq!(result.fee_amount, 204);
         }
     
    -    #[test]
    -    fn test_bnb_coin_selection_required_are_enough() {
    -        let utxos = get_test_utxos();
    -        let database = MemoryDatabase::default();
    -        let drain_script = Script::default();
    -        let target_amount = 20_000 + FEE_AMOUNT;
    -
    -        let result = BranchAndBoundCoinSelection::default()
    -            .coin_select(
    -                &database,
    -                utxos.clone(),
    -                utxos,
    -                FeeRate::from_sat_per_vb(1.0),
    -                target_amount,
    -                &drain_script,
    +    #[test]
    +    fn test_bnb_coin_selection_required_are_enough() {
    +        let utxos = get_test_utxos();
    +        let database = MemoryDatabase::default();
    +        let drain_script = Script::default();
    +        let target_amount = 20_000 + FEE_AMOUNT;
    +
    +        let result = BranchAndBoundCoinSelection::default()
    +            .coin_select(
    +                &database,
    +                utxos.clone(),
    +                utxos,
    +                FeeRate::from_sat_per_vb(1.0),
    +                target_amount,
    +                &drain_script,
                 )
    -            .unwrap();
    +            .unwrap();
     
    -        assert_eq!(result.selected.len(), 3);
    -        assert_eq!(result.selected_amount(), 300_010);
    -        assert_eq!(result.fee_amount, 204);
    +        assert_eq!(result.selected.len(), 3);
    +        assert_eq!(result.selected_amount(), 300_010);
    +        assert_eq!(result.fee_amount, 204);
         }
     
    -    #[test]
    -    fn test_bnb_coin_selection_optional_are_enough() {
    -        let utxos = get_test_utxos();
    -        let database = MemoryDatabase::default();
    -        let drain_script = Script::default();
    -        let target_amount = 299756 + FEE_AMOUNT;
    +    #[test]
    +    fn test_bnb_coin_selection_optional_are_enough() {
    +        let utxos = get_test_utxos();
    +        let database = MemoryDatabase::default();
    +        let drain_script = Script::default();
    +        let target_amount = 299756 + FEE_AMOUNT;
     
    -        let result = BranchAndBoundCoinSelection::default()
    -            .coin_select(
    -                &database,
    +        let result = BranchAndBoundCoinSelection::default()
    +            .coin_select(
    +                &database,
                     vec![],
    -                utxos,
    -                FeeRate::from_sat_per_vb(1.0),
    -                target_amount,
    -                &drain_script,
    +                utxos,
    +                FeeRate::from_sat_per_vb(1.0),
    +                target_amount,
    +                &drain_script,
                 )
    -            .unwrap();
    +            .unwrap();
     
    -        assert_eq!(result.selected.len(), 2);
    -        assert_eq!(result.selected_amount(), 300000);
    -        assert_eq!(result.fee_amount, 136);
    +        assert_eq!(result.selected.len(), 2);
    +        assert_eq!(result.selected_amount(), 300000);
    +        assert_eq!(result.fee_amount, 136);
         }
     
    -    #[test]
    -    #[ignore]
    -    fn test_bnb_coin_selection_required_not_enough() {
    -        let utxos = get_test_utxos();
    -        let database = MemoryDatabase::default();
    -
    -        let required = vec![utxos[0].clone()];
    -        let mut optional = utxos[1..].to_vec();
    -        optional.push(utxo(500_000, 3));
    -
    -        // Defensive assertions, for sanity and in case someone changes the test utxos vector.
    -        let amount: u64 = required.iter().map(|u| u.utxo.txout().value).sum();
    -        assert_eq!(amount, 100_000);
    -        let amount: u64 = optional.iter().map(|u| u.utxo.txout().value).sum();
    -        assert!(amount > 150_000);
    -        let drain_script = Script::default();
    -
    -        let target_amount = 150_000 + FEE_AMOUNT;
    -
    -        let result = BranchAndBoundCoinSelection::default()
    -            .coin_select(
    -                &database,
    -                required,
    -                optional,
    -                FeeRate::from_sat_per_vb(1.0),
    -                target_amount,
    -                &drain_script,
    +    #[test]
    +    #[ignore]
    +    fn test_bnb_coin_selection_required_not_enough() {
    +        let utxos = get_test_utxos();
    +        let database = MemoryDatabase::default();
    +
    +        let required = vec![utxos[0].clone()];
    +        let mut optional = utxos[1..].to_vec();
    +        optional.push(utxo(500_000, 3));
    +
    +        // Defensive assertions, for sanity and in case someone changes the test utxos vector.
    +        let amount: u64 = required.iter().map(|u| u.utxo.txout().value).sum();
    +        assert_eq!(amount, 100_000);
    +        let amount: u64 = optional.iter().map(|u| u.utxo.txout().value).sum();
    +        assert!(amount > 150_000);
    +        let drain_script = Script::default();
    +
    +        let target_amount = 150_000 + FEE_AMOUNT;
    +
    +        let result = BranchAndBoundCoinSelection::default()
    +            .coin_select(
    +                &database,
    +                required,
    +                optional,
    +                FeeRate::from_sat_per_vb(1.0),
    +                target_amount,
    +                &drain_script,
                 )
    -            .unwrap();
    +            .unwrap();
     
    -        assert_eq!(result.selected.len(), 2);
    -        assert_eq!(result.selected_amount(), 300_000);
    -        assert_eq!(result.fee_amount, 136);
    +        assert_eq!(result.selected.len(), 2);
    +        assert_eq!(result.selected_amount(), 300_000);
    +        assert_eq!(result.fee_amount, 136);
         }
     
    -    #[test]
    -    #[should_panic(expected = "InsufficientFunds")]
    -    fn test_bnb_coin_selection_insufficient_funds() {
    -        let utxos = get_test_utxos();
    -        let database = MemoryDatabase::default();
    -        let drain_script = Script::default();
    -        let target_amount = 500_000 + FEE_AMOUNT;
    -
    -        BranchAndBoundCoinSelection::default()
    -            .coin_select(
    -                &database,
    +    #[test]
    +    #[should_panic(expected = "InsufficientFunds")]
    +    fn test_bnb_coin_selection_insufficient_funds() {
    +        let utxos = get_test_utxos();
    +        let database = MemoryDatabase::default();
    +        let drain_script = Script::default();
    +        let target_amount = 500_000 + FEE_AMOUNT;
    +
    +        BranchAndBoundCoinSelection::default()
    +            .coin_select(
    +                &database,
                     vec![],
    -                utxos,
    -                FeeRate::from_sat_per_vb(1.0),
    -                target_amount,
    -                &drain_script,
    +                utxos,
    +                FeeRate::from_sat_per_vb(1.0),
    +                target_amount,
    +                &drain_script,
                 )
    -            .unwrap();
    +            .unwrap();
         }
     
    -    #[test]
    -    #[should_panic(expected = "InsufficientFunds")]
    -    fn test_bnb_coin_selection_insufficient_funds_high_fees() {
    -        let utxos = get_test_utxos();
    -        let database = MemoryDatabase::default();
    -        let drain_script = Script::default();
    -        let target_amount = 250_000 + FEE_AMOUNT;
    -
    -        BranchAndBoundCoinSelection::default()
    -            .coin_select(
    -                &database,
    +    #[test]
    +    #[should_panic(expected = "InsufficientFunds")]
    +    fn test_bnb_coin_selection_insufficient_funds_high_fees() {
    +        let utxos = get_test_utxos();
    +        let database = MemoryDatabase::default();
    +        let drain_script = Script::default();
    +        let target_amount = 250_000 + FEE_AMOUNT;
    +
    +        BranchAndBoundCoinSelection::default()
    +            .coin_select(
    +                &database,
                     vec![],
    -                utxos,
    -                FeeRate::from_sat_per_vb(1000.0),
    -                target_amount,
    -                &drain_script,
    +                utxos,
    +                FeeRate::from_sat_per_vb(1000.0),
    +                target_amount,
    +                &drain_script,
                 )
    -            .unwrap();
    +            .unwrap();
         }
     
    -    #[test]
    -    fn test_bnb_coin_selection_check_fee_rate() {
    -        let utxos = get_test_utxos();
    -        let database = MemoryDatabase::default();
    -        let drain_script = Script::default();
    -        let target_amount = 99932; // first utxo's effective value
    +    #[test]
    +    fn test_bnb_coin_selection_check_fee_rate() {
    +        let utxos = get_test_utxos();
    +        let database = MemoryDatabase::default();
    +        let drain_script = Script::default();
    +        let target_amount = 99932; // first utxo's effective value
     
    -        let result = BranchAndBoundCoinSelection::new(0)
    -            .coin_select(
    -                &database,
    +        let result = BranchAndBoundCoinSelection::new(0)
    +            .coin_select(
    +                &database,
                     vec![],
    -                utxos,
    -                FeeRate::from_sat_per_vb(1.0),
    -                target_amount,
    -                &drain_script,
    +                utxos,
    +                FeeRate::from_sat_per_vb(1.0),
    +                target_amount,
    +                &drain_script,
                 )
    -            .unwrap();
    +            .unwrap();
     
    -        assert_eq!(result.selected.len(), 1);
    -        assert_eq!(result.selected_amount(), 100_000);
    -        let input_size = (TXIN_BASE_WEIGHT + P2WPKH_SATISFACTION_SIZE).vbytes();
    -        // the final fee rate should be exactly the same as the fee rate given
    -        assert!((1.0 - (result.fee_amount as f32 / input_size as f32)).abs() < f32::EPSILON);
    +        assert_eq!(result.selected.len(), 1);
    +        assert_eq!(result.selected_amount(), 100_000);
    +        let input_size = (TXIN_BASE_WEIGHT + P2WPKH_SATISFACTION_SIZE).vbytes();
    +        // the final fee rate should be exactly the same as the fee rate given
    +        assert!((1.0 - (result.fee_amount as f32 / input_size as f32)).abs() < f32::EPSILON);
         }
     
    -    #[test]
    -    fn test_bnb_coin_selection_exact_match() {
    -        let seed = [0; 32];
    -        let mut rng: StdRng = SeedableRng::from_seed(seed);
    -        let database = MemoryDatabase::default();
    -
    -        for _i in 0..200 {
    -            let mut optional_utxos = generate_random_utxos(&mut rng, 16);
    -            let target_amount = sum_random_utxos(&mut rng, &mut optional_utxos);
    -            let drain_script = Script::default();
    -            let result = BranchAndBoundCoinSelection::new(0)
    -                .coin_select(
    -                    &database,
    +    #[test]
    +    fn test_bnb_coin_selection_exact_match() {
    +        let seed = [0; 32];
    +        let mut rng: StdRng = SeedableRng::from_seed(seed);
    +        let database = MemoryDatabase::default();
    +
    +        for _i in 0..200 {
    +            let mut optional_utxos = generate_random_utxos(&mut rng, 16);
    +            let target_amount = sum_random_utxos(&mut rng, &mut optional_utxos);
    +            let drain_script = Script::default();
    +            let result = BranchAndBoundCoinSelection::new(0)
    +                .coin_select(
    +                    &database,
                         vec![],
    -                    optional_utxos,
    -                    FeeRate::from_sat_per_vb(0.0),
    -                    target_amount,
    -                    &drain_script,
    +                    optional_utxos,
    +                    FeeRate::from_sat_per_vb(0.0),
    +                    target_amount,
    +                    &drain_script,
                     )
    -                .unwrap();
    -            assert_eq!(result.selected_amount(), target_amount);
    +                .unwrap();
    +            assert_eq!(result.selected_amount(), target_amount);
             }
         }
     
    -    #[test]
    -    #[should_panic(expected = "BnBNoExactMatch")]
    -    fn test_bnb_function_no_exact_match() {
    -        let fee_rate = FeeRate::from_sat_per_vb(10.0);
    -        let utxos: Vec<OutputGroup> = get_test_utxos()
    -            .into_iter()
    -            .map(|u| OutputGroup::new(u, fee_rate))
    -            .collect();
    +    #[test]
    +    #[should_panic(expected = "BnBNoExactMatch")]
    +    fn test_bnb_function_no_exact_match() {
    +        let fee_rate = FeeRate::from_sat_per_vb(10.0);
    +        let utxos: Vec<OutputGroup> = get_test_utxos()
    +            .into_iter()
    +            .map(|u| OutputGroup::new(u, fee_rate))
    +            .collect();
     
    -        let curr_available_value = utxos.iter().fold(0, |acc, x| acc + x.effective_value);
    +        let curr_available_value = utxos.iter().fold(0, |acc, x| acc + x.effective_value);
     
    -        let size_of_change = 31;
    -        let cost_of_change = size_of_change as f32 * fee_rate.as_sat_per_vb();
    +        let size_of_change = 31;
    +        let cost_of_change = size_of_change as f32 * fee_rate.as_sat_per_vb();
     
    -        let drain_script = Script::default();
    -        let target_amount = 20_000 + FEE_AMOUNT;
    -        BranchAndBoundCoinSelection::new(size_of_change)
    -            .bnb(
    +        let drain_script = Script::default();
    +        let target_amount = 20_000 + FEE_AMOUNT;
    +        BranchAndBoundCoinSelection::new(size_of_change)
    +            .bnb(
                     vec![],
    -                utxos,
    +                utxos,
                     0,
    -                curr_available_value,
    -                target_amount as i64,
    -                cost_of_change,
    -                &drain_script,
    -                fee_rate,
    +                curr_available_value,
    +                target_amount as i64,
    +                cost_of_change,
    +                &drain_script,
    +                fee_rate,
                 )
    -            .unwrap();
    +            .unwrap();
         }
     
    -    #[test]
    -    #[should_panic(expected = "BnBTotalTriesExceeded")]
    -    fn test_bnb_function_tries_exceeded() {
    -        let fee_rate = FeeRate::from_sat_per_vb(10.0);
    -        let utxos: Vec<OutputGroup> = generate_same_value_utxos(100_000, 100_000)
    -            .into_iter()
    -            .map(|u| OutputGroup::new(u, fee_rate))
    -            .collect();
    +    #[test]
    +    #[should_panic(expected = "BnBTotalTriesExceeded")]
    +    fn test_bnb_function_tries_exceeded() {
    +        let fee_rate = FeeRate::from_sat_per_vb(10.0);
    +        let utxos: Vec<OutputGroup> = generate_same_value_utxos(100_000, 100_000)
    +            .into_iter()
    +            .map(|u| OutputGroup::new(u, fee_rate))
    +            .collect();
     
    -        let curr_available_value = utxos.iter().fold(0, |acc, x| acc + x.effective_value);
    +        let curr_available_value = utxos.iter().fold(0, |acc, x| acc + x.effective_value);
     
    -        let size_of_change = 31;
    -        let cost_of_change = size_of_change as f32 * fee_rate.as_sat_per_vb();
    -        let target_amount = 20_000 + FEE_AMOUNT;
    +        let size_of_change = 31;
    +        let cost_of_change = size_of_change as f32 * fee_rate.as_sat_per_vb();
    +        let target_amount = 20_000 + FEE_AMOUNT;
     
    -        let drain_script = Script::default();
    +        let drain_script = Script::default();
     
    -        BranchAndBoundCoinSelection::new(size_of_change)
    -            .bnb(
    +        BranchAndBoundCoinSelection::new(size_of_change)
    +            .bnb(
                     vec![],
    -                utxos,
    +                utxos,
                     0,
    -                curr_available_value,
    -                target_amount as i64,
    -                cost_of_change,
    -                &drain_script,
    -                fee_rate,
    +                curr_available_value,
    +                target_amount as i64,
    +                cost_of_change,
    +                &drain_script,
    +                fee_rate,
                 )
    -            .unwrap();
    +            .unwrap();
         }
     
    -    // The match won't be exact but still in the range
    -    #[test]
    -    fn test_bnb_function_almost_exact_match_with_fees() {
    -        let fee_rate = FeeRate::from_sat_per_vb(1.0);
    -        let size_of_change = 31;
    -        let cost_of_change = size_of_change as f32 * fee_rate.as_sat_per_vb();
    +    // The match won't be exact but still in the range
    +    #[test]
    +    fn test_bnb_function_almost_exact_match_with_fees() {
    +        let fee_rate = FeeRate::from_sat_per_vb(1.0);
    +        let size_of_change = 31;
    +        let cost_of_change = size_of_change as f32 * fee_rate.as_sat_per_vb();
     
    -        let utxos: Vec<_> = generate_same_value_utxos(50_000, 10)
    -            .into_iter()
    -            .map(|u| OutputGroup::new(u, fee_rate))
    -            .collect();
    +        let utxos: Vec<_> = generate_same_value_utxos(50_000, 10)
    +            .into_iter()
    +            .map(|u| OutputGroup::new(u, fee_rate))
    +            .collect();
     
    -        let curr_value = 0;
    +        let curr_value = 0;
     
    -        let curr_available_value = utxos.iter().fold(0, |acc, x| acc + x.effective_value);
    +        let curr_available_value = utxos.iter().fold(0, |acc, x| acc + x.effective_value);
     
    -        // 2*(value of 1 utxo)  - 2*(1 utxo fees with 1.0sat/vbyte fee rate) -
    -        // cost_of_change + 5.
    -        let target_amount = 2 * 50_000 - 2 * 67 - cost_of_change.ceil() as i64 + 5;
    +        // 2*(value of 1 utxo)  - 2*(1 utxo fees with 1.0sat/vbyte fee rate) -
    +        // cost_of_change + 5.
    +        let target_amount = 2 * 50_000 - 2 * 67 - cost_of_change.ceil() as i64 + 5;
     
    -        let drain_script = Script::default();
    +        let drain_script = Script::default();
     
    -        let result = BranchAndBoundCoinSelection::new(size_of_change)
    -            .bnb(
    +        let result = BranchAndBoundCoinSelection::new(size_of_change)
    +            .bnb(
                     vec![],
    -                utxos,
    -                curr_value,
    -                curr_available_value,
    -                target_amount,
    -                cost_of_change,
    -                &drain_script,
    -                fee_rate,
    +                utxos,
    +                curr_value,
    +                curr_available_value,
    +                target_amount,
    +                cost_of_change,
    +                &drain_script,
    +                fee_rate,
                 )
    -            .unwrap();
    -        assert_eq!(result.selected_amount(), 100_000);
    -        assert_eq!(result.fee_amount, 136);
    +            .unwrap();
    +        assert_eq!(result.selected_amount(), 100_000);
    +        assert_eq!(result.fee_amount, 136);
         }
     
    -    // TODO: bnb() function should be optimized, and this test should be done with more utxos
    -    #[test]
    -    fn test_bnb_function_exact_match_more_utxos() {
    -        let seed = [0; 32];
    -        let mut rng: StdRng = SeedableRng::from_seed(seed);
    -        let fee_rate = FeeRate::from_sat_per_vb(0.0);
    +    // TODO: bnb() function should be optimized, and this test should be done with more utxos
    +    #[test]
    +    fn test_bnb_function_exact_match_more_utxos() {
    +        let seed = [0; 32];
    +        let mut rng: StdRng = SeedableRng::from_seed(seed);
    +        let fee_rate = FeeRate::from_sat_per_vb(0.0);
     
    -        for _ in 0..200 {
    -            let optional_utxos: Vec<_> = generate_random_utxos(&mut rng, 40)
    -                .into_iter()
    -                .map(|u| OutputGroup::new(u, fee_rate))
    -                .collect();
    +        for _ in 0..200 {
    +            let optional_utxos: Vec<_> = generate_random_utxos(&mut rng, 40)
    +                .into_iter()
    +                .map(|u| OutputGroup::new(u, fee_rate))
    +                .collect();
     
    -            let curr_value = 0;
    +            let curr_value = 0;
     
    -            let curr_available_value = optional_utxos
    -                .iter()
    -                .fold(0, |acc, x| acc + x.effective_value);
    +            let curr_available_value = optional_utxos
    +                .iter()
    +                .fold(0, |acc, x| acc + x.effective_value);
     
    -            let target_amount =
    -                optional_utxos[3].effective_value + optional_utxos[23].effective_value;
    +            let target_amount =
    +                optional_utxos[3].effective_value + optional_utxos[23].effective_value;
     
    -            let drain_script = Script::default();
    +            let drain_script = Script::default();
     
    -            let result = BranchAndBoundCoinSelection::new(0)
    -                .bnb(
    +            let result = BranchAndBoundCoinSelection::new(0)
    +                .bnb(
                         vec![],
    -                    optional_utxos,
    -                    curr_value,
    -                    curr_available_value,
    -                    target_amount,
    +                    optional_utxos,
    +                    curr_value,
    +                    curr_available_value,
    +                    target_amount,
                         0.0,
    -                    &drain_script,
    -                    fee_rate,
    +                    &drain_script,
    +                    fee_rate,
                     )
    -                .unwrap();
    -            assert_eq!(result.selected_amount(), target_amount as u64);
    +                .unwrap();
    +            assert_eq!(result.selected_amount(), target_amount as u64);
             }
         }
     
    -    #[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;
    +    #[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(1.0);
    -        let utxos: Vec<OutputGroup> = utxos
    -            .into_iter()
    -            .map(|u| OutputGroup::new(u, fee_rate))
    -            .collect();
    +        let fee_rate = FeeRate::from_sat_per_vb(1.0);
    +        let utxos: Vec<OutputGroup> = utxos
    +            .into_iter()
    +            .map(|u| OutputGroup::new(u, fee_rate))
    +            .collect();
     
    -        let drain_script = Script::default();
    +        let drain_script = Script::default();
     
    -        let result = BranchAndBoundCoinSelection::default().single_random_draw(
    +        let result = BranchAndBoundCoinSelection::default().single_random_draw(
                 vec![],
    -            utxos,
    +            utxos,
                 0,
    -            target_amount as i64,
    -            &drain_script,
    -            fee_rate,
    +            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);
    +        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();
    -        let database = MemoryDatabase::default();
    -        let drain_script = Script::default();
    +    #[test]
    +    fn test_bnb_exclude_negative_effective_value() {
    +        let utxos = get_test_utxos();
    +        let database = MemoryDatabase::default();
    +        let drain_script = Script::default();
     
    -        let err = BranchAndBoundCoinSelection::default()
    -            .coin_select(
    -                &database,
    +        let err = BranchAndBoundCoinSelection::default()
    +            .coin_select(
    +                &database,
                     vec![],
    -                utxos,
    -                FeeRate::from_sat_per_vb(10.0),
    +                utxos,
    +                FeeRate::from_sat_per_vb(10.0),
                     500_000,
    -                &drain_script,
    +                &drain_script,
                 )
    -            .unwrap_err();
    +            .unwrap_err();
     
             assert!(matches!(
    -            err,
    -            Error::InsufficientFunds {
    -                available: 300_000,
    +            err,
    +            Error::InsufficientFunds {
    +                available: 300_000,
                     ..
                 }
             ));
         }
     
    -    #[test]
    -    fn test_bnb_include_negative_effective_value_when_required() {
    -        let utxos = get_test_utxos();
    -        let database = MemoryDatabase::default();
    -        let drain_script = Script::default();
    -
    -        let (required, optional) = utxos
    -            .into_iter()
    -            .partition(|u| matches!(u, WeightedUtxo { utxo, .. } if utxo.txout().value < 1000));
    -
    -        let err = BranchAndBoundCoinSelection::default()
    -            .coin_select(
    -                &database,
    -                required,
    -                optional,
    -                FeeRate::from_sat_per_vb(10.0),
    +    #[test]
    +    fn test_bnb_include_negative_effective_value_when_required() {
    +        let utxos = get_test_utxos();
    +        let database = MemoryDatabase::default();
    +        let drain_script = Script::default();
    +
    +        let (required, optional) = utxos
    +            .into_iter()
    +            .partition(|u| matches!(u, WeightedUtxo { utxo, .. } if utxo.txout().value < 1000));
    +
    +        let err = BranchAndBoundCoinSelection::default()
    +            .coin_select(
    +                &database,
    +                required,
    +                optional,
    +                FeeRate::from_sat_per_vb(10.0),
                     500_000,
    -                &drain_script,
    +                &drain_script,
                 )
    -            .unwrap_err();
    +            .unwrap_err();
     
             assert!(matches!(
    -            err,
    -            Error::InsufficientFunds {
    -                available: 300_010,
    +            err,
    +            Error::InsufficientFunds {
    +                available: 300_010,
                     ..
                 }
             ));
         }
     
    -    #[test]
    -    fn test_bnb_sum_of_effective_value_negative() {
    -        let utxos = get_test_utxos();
    -        let database = MemoryDatabase::default();
    -        let drain_script = Script::default();
    +    #[test]
    +    fn test_bnb_sum_of_effective_value_negative() {
    +        let utxos = get_test_utxos();
    +        let database = MemoryDatabase::default();
    +        let drain_script = Script::default();
     
    -        let err = BranchAndBoundCoinSelection::default()
    -            .coin_select(
    -                &database,
    -                utxos,
    +        let err = BranchAndBoundCoinSelection::default()
    +            .coin_select(
    +                &database,
    +                utxos,
                     vec![],
    -                FeeRate::from_sat_per_vb(10_000.0),
    +                FeeRate::from_sat_per_vb(10_000.0),
                     500_000,
    -                &drain_script,
    +                &drain_script,
                 )
    -            .unwrap_err();
    +            .unwrap_err();
     
             assert!(matches!(
    -            err,
    -            Error::InsufficientFunds {
    -                available: 300_010,
    +            err,
    +            Error::InsufficientFunds {
    +                available: 300_010,
                     ..
                 }
             ));
         }
     }
     
    -
    - \ No newline at end of file +
    \ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/src/bdk/wallet/export.rs.html b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/src/bdk/wallet/export.rs.html index f9e4c1762f..0ba7466ad6 100644 --- a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/src/bdk/wallet/export.rs.html +++ b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/src/bdk/wallet/export.rs.html @@ -1,774 +1,767 @@ -export.rs - source - -
      1
    -  2
    -  3
    -  4
    -  5
    -  6
    -  7
    -  8
    -  9
    - 10
    - 11
    - 12
    - 13
    - 14
    - 15
    - 16
    - 17
    - 18
    - 19
    - 20
    - 21
    - 22
    - 23
    - 24
    - 25
    - 26
    - 27
    - 28
    - 29
    - 30
    - 31
    - 32
    - 33
    - 34
    - 35
    - 36
    - 37
    - 38
    - 39
    - 40
    - 41
    - 42
    - 43
    - 44
    - 45
    - 46
    - 47
    - 48
    - 49
    - 50
    - 51
    - 52
    - 53
    - 54
    - 55
    - 56
    - 57
    - 58
    - 59
    - 60
    - 61
    - 62
    - 63
    - 64
    - 65
    - 66
    - 67
    - 68
    - 69
    - 70
    - 71
    - 72
    - 73
    - 74
    - 75
    - 76
    - 77
    - 78
    - 79
    - 80
    - 81
    - 82
    - 83
    - 84
    - 85
    - 86
    - 87
    - 88
    - 89
    - 90
    - 91
    - 92
    - 93
    - 94
    - 95
    - 96
    - 97
    - 98
    - 99
    -100
    -101
    -102
    -103
    -104
    -105
    -106
    -107
    -108
    -109
    -110
    -111
    -112
    -113
    -114
    -115
    -116
    -117
    -118
    -119
    -120
    -121
    -122
    -123
    -124
    -125
    -126
    -127
    -128
    -129
    -130
    -131
    -132
    -133
    -134
    -135
    -136
    -137
    -138
    -139
    -140
    -141
    -142
    -143
    -144
    -145
    -146
    -147
    -148
    -149
    -150
    -151
    -152
    -153
    -154
    -155
    -156
    -157
    -158
    -159
    -160
    -161
    -162
    -163
    -164
    -165
    -166
    -167
    -168
    -169
    -170
    -171
    -172
    -173
    -174
    -175
    -176
    -177
    -178
    -179
    -180
    -181
    -182
    -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
    -245
    -246
    -247
    -248
    -249
    -250
    -251
    -252
    -253
    -254
    -255
    -256
    -257
    -258
    -259
    -260
    -261
    -262
    -263
    -264
    -265
    -266
    -267
    -268
    -269
    -270
    -271
    -272
    -273
    -274
    -275
    -276
    -277
    -278
    -279
    -280
    -281
    -282
    -283
    -284
    -285
    -286
    -287
    -288
    -289
    -290
    -291
    -292
    -293
    -294
    -295
    -296
    -297
    -298
    -299
    -300
    -301
    -302
    -303
    -304
    -305
    -306
    -307
    -308
    -309
    -310
    -311
    -312
    -313
    -314
    -315
    -316
    -317
    -318
    -319
    -320
    -321
    -322
    -323
    -324
    -325
    -326
    -327
    -328
    -329
    -330
    -331
    -332
    -333
    -334
    -335
    -336
    -337
    -338
    -339
    -340
    -341
    -342
    -343
    -344
    -345
    -346
    -347
    -348
    -349
    -350
    -351
    -352
    -353
    -354
    -355
    -356
    -357
    -358
    -359
    -360
    -361
    -362
    -363
    -364
    -365
    -366
    -367
    -368
    -369
    -370
    -371
    -372
    -373
    -374
    -375
    -376
    -377
    -378
    -379
    -380
    -381
    -382
    -
    // Bitcoin Dev Kit
    -// Written in 2020 by Alekos Filini <alekos.filini@gmail.com>
    -//
    -// Copyright (c) 2020-2021 Bitcoin Dev Kit Developers
    -//
    -// This file is licensed under the Apache License, Version 2.0 <LICENSE-APACHE
    -// or http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
    -// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your option.
    -// You may not use this file except in accordance with one or both of these
    -// licenses.
    -
    -//! Wallet export
    -//!
    -//! This modules implements the wallet export format used by [FullyNoded](https://github.com/Fonta1n3/FullyNoded/blob/10b7808c8b929b171cca537fb50522d015168ac9/Docs/Wallets/Wallet-Export-Spec.md).
    -//!
    -//! ## Examples
    -//!
    -//! ### Import from JSON
    -//!
    -//! ```
    -//! # use std::str::FromStr;
    -//! # use bitcoin::*;
    -//! # use bdk::database::*;
    -//! # use bdk::wallet::export::*;
    -//! # use bdk::*;
    -//! let import = r#"{
    -//!     "descriptor": "wpkh([c258d2e4\/84h\/1h\/0h]tpubDD3ynpHgJQW8VvWRzQ5WFDCrs4jqVFGHB3vLC3r49XHJSqP8bHKdK4AriuUKLccK68zfzowx7YhmDN8SiSkgCDENUFx9qVw65YyqM78vyVe\/0\/*)",
    -//!     "blockheight":1782088,
    -//!     "label":"testnet"
    -//! }"#;
    -//!
    -//! let import = FullyNodedExport::from_str(import)?;
    -//! let wallet = Wallet::new(
    -//!     &import.descriptor(),
    -//!     import.change_descriptor().as_ref(),
    -//!     Network::Testnet,
    -//!     MemoryDatabase::default(),
    -//! )?;
    -//! # Ok::<_, bdk::Error>(())
    -//! ```
    -//!
    -//! ### Export a `Wallet`
    -//! ```
    -//! # use bitcoin::*;
    -//! # use bdk::database::*;
    -//! # use bdk::wallet::export::*;
    -//! # use bdk::*;
    -//! let wallet = Wallet::new(
    -//!     "wpkh([c258d2e4/84h/1h/0h]tpubDD3ynpHgJQW8VvWRzQ5WFDCrs4jqVFGHB3vLC3r49XHJSqP8bHKdK4AriuUKLccK68zfzowx7YhmDN8SiSkgCDENUFx9qVw65YyqM78vyVe/0/*)",
    -//!     Some("wpkh([c258d2e4/84h/1h/0h]tpubDD3ynpHgJQW8VvWRzQ5WFDCrs4jqVFGHB3vLC3r49XHJSqP8bHKdK4AriuUKLccK68zfzowx7YhmDN8SiSkgCDENUFx9qVw65YyqM78vyVe/1/*)"),
    -//!     Network::Testnet,
    -//!     MemoryDatabase::default()
    -//! )?;
    -//! let export = FullyNodedExport::export_wallet(&wallet, "exported wallet", true)
    -//!     .map_err(ToString::to_string)
    -//!     .map_err(bdk::Error::Generic)?;
    -//!
    -//! println!("Exported: {}", export.to_string());
    -//! # Ok::<_, bdk::Error>(())
    -//! ```
    -
    -use std::str::FromStr;
    -
    -use serde::{Deserialize, Serialize};
    -
    -use miniscript::descriptor::{ShInner, WshInner};
    -use miniscript::{Descriptor, ScriptContext, Terminal};
    -
    -use crate::database::BatchDatabase;
    -use crate::types::KeychainKind;
    -use crate::wallet::Wallet;
    -
    -/// Alias for [`FullyNodedExport`]
    -#[deprecated(since = "0.18.0", note = "Please use [`FullyNodedExport`] instead")]
    -pub type WalletExport = FullyNodedExport;
    -
    -/// Structure that contains the export of a wallet
    -///
    -/// For a usage example see [this module](crate::wallet::export)'s documentation.
    -#[derive(Debug, Serialize, Deserialize)]
    -pub struct FullyNodedExport {
    -    descriptor: String,
    -    /// Earliest block to rescan when looking for the wallet's transactions
    -    pub blockheight: u32,
    -    /// Arbitrary label for the wallet
    -    pub label: String,
    +export.rs - source
    1
    +2
    +3
    +4
    +5
    +6
    +7
    +8
    +9
    +10
    +11
    +12
    +13
    +14
    +15
    +16
    +17
    +18
    +19
    +20
    +21
    +22
    +23
    +24
    +25
    +26
    +27
    +28
    +29
    +30
    +31
    +32
    +33
    +34
    +35
    +36
    +37
    +38
    +39
    +40
    +41
    +42
    +43
    +44
    +45
    +46
    +47
    +48
    +49
    +50
    +51
    +52
    +53
    +54
    +55
    +56
    +57
    +58
    +59
    +60
    +61
    +62
    +63
    +64
    +65
    +66
    +67
    +68
    +69
    +70
    +71
    +72
    +73
    +74
    +75
    +76
    +77
    +78
    +79
    +80
    +81
    +82
    +83
    +84
    +85
    +86
    +87
    +88
    +89
    +90
    +91
    +92
    +93
    +94
    +95
    +96
    +97
    +98
    +99
    +100
    +101
    +102
    +103
    +104
    +105
    +106
    +107
    +108
    +109
    +110
    +111
    +112
    +113
    +114
    +115
    +116
    +117
    +118
    +119
    +120
    +121
    +122
    +123
    +124
    +125
    +126
    +127
    +128
    +129
    +130
    +131
    +132
    +133
    +134
    +135
    +136
    +137
    +138
    +139
    +140
    +141
    +142
    +143
    +144
    +145
    +146
    +147
    +148
    +149
    +150
    +151
    +152
    +153
    +154
    +155
    +156
    +157
    +158
    +159
    +160
    +161
    +162
    +163
    +164
    +165
    +166
    +167
    +168
    +169
    +170
    +171
    +172
    +173
    +174
    +175
    +176
    +177
    +178
    +179
    +180
    +181
    +182
    +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
    +245
    +246
    +247
    +248
    +249
    +250
    +251
    +252
    +253
    +254
    +255
    +256
    +257
    +258
    +259
    +260
    +261
    +262
    +263
    +264
    +265
    +266
    +267
    +268
    +269
    +270
    +271
    +272
    +273
    +274
    +275
    +276
    +277
    +278
    +279
    +280
    +281
    +282
    +283
    +284
    +285
    +286
    +287
    +288
    +289
    +290
    +291
    +292
    +293
    +294
    +295
    +296
    +297
    +298
    +299
    +300
    +301
    +302
    +303
    +304
    +305
    +306
    +307
    +308
    +309
    +310
    +311
    +312
    +313
    +314
    +315
    +316
    +317
    +318
    +319
    +320
    +321
    +322
    +323
    +324
    +325
    +326
    +327
    +328
    +329
    +330
    +331
    +332
    +333
    +334
    +335
    +336
    +337
    +338
    +339
    +340
    +341
    +342
    +343
    +344
    +345
    +346
    +347
    +348
    +349
    +350
    +351
    +352
    +353
    +354
    +355
    +356
    +357
    +358
    +359
    +360
    +361
    +362
    +363
    +364
    +365
    +366
    +367
    +368
    +369
    +370
    +371
    +372
    +373
    +374
    +375
    +376
    +377
    +378
    +379
    +380
    +381
    +382
    +
    // Bitcoin Dev Kit
    +// Written in 2020 by Alekos Filini <alekos.filini@gmail.com>
    +//
    +// Copyright (c) 2020-2021 Bitcoin Dev Kit Developers
    +//
    +// This file is licensed under the Apache License, Version 2.0 <LICENSE-APACHE
    +// or http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
    +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your option.
    +// You may not use this file except in accordance with one or both of these
    +// licenses.
    +
    +//! Wallet export
    +//!
    +//! This modules implements the wallet export format used by [FullyNoded](https://github.com/Fonta1n3/FullyNoded/blob/10b7808c8b929b171cca537fb50522d015168ac9/Docs/Wallets/Wallet-Export-Spec.md).
    +//!
    +//! ## Examples
    +//!
    +//! ### Import from JSON
    +//!
    +//! ```
    +//! # use std::str::FromStr;
    +//! # use bitcoin::*;
    +//! # use bdk::database::*;
    +//! # use bdk::wallet::export::*;
    +//! # use bdk::*;
    +//! let import = r#"{
    +//!     "descriptor": "wpkh([c258d2e4\/84h\/1h\/0h]tpubDD3ynpHgJQW8VvWRzQ5WFDCrs4jqVFGHB3vLC3r49XHJSqP8bHKdK4AriuUKLccK68zfzowx7YhmDN8SiSkgCDENUFx9qVw65YyqM78vyVe\/0\/*)",
    +//!     "blockheight":1782088,
    +//!     "label":"testnet"
    +//! }"#;
    +//!
    +//! let import = FullyNodedExport::from_str(import)?;
    +//! let wallet = Wallet::new(
    +//!     &import.descriptor(),
    +//!     import.change_descriptor().as_ref(),
    +//!     Network::Testnet,
    +//!     MemoryDatabase::default(),
    +//! )?;
    +//! # Ok::<_, bdk::Error>(())
    +//! ```
    +//!
    +//! ### Export a `Wallet`
    +//! ```
    +//! # use bitcoin::*;
    +//! # use bdk::database::*;
    +//! # use bdk::wallet::export::*;
    +//! # use bdk::*;
    +//! let wallet = Wallet::new(
    +//!     "wpkh([c258d2e4/84h/1h/0h]tpubDD3ynpHgJQW8VvWRzQ5WFDCrs4jqVFGHB3vLC3r49XHJSqP8bHKdK4AriuUKLccK68zfzowx7YhmDN8SiSkgCDENUFx9qVw65YyqM78vyVe/0/*)",
    +//!     Some("wpkh([c258d2e4/84h/1h/0h]tpubDD3ynpHgJQW8VvWRzQ5WFDCrs4jqVFGHB3vLC3r49XHJSqP8bHKdK4AriuUKLccK68zfzowx7YhmDN8SiSkgCDENUFx9qVw65YyqM78vyVe/1/*)"),
    +//!     Network::Testnet,
    +//!     MemoryDatabase::default()
    +//! )?;
    +//! let export = FullyNodedExport::export_wallet(&wallet, "exported wallet", true)
    +//!     .map_err(ToString::to_string)
    +//!     .map_err(bdk::Error::Generic)?;
    +//!
    +//! println!("Exported: {}", export.to_string());
    +//! # Ok::<_, bdk::Error>(())
    +//! ```
    +
    +use std::str::FromStr;
    +
    +use serde::{Deserialize, Serialize};
    +
    +use miniscript::descriptor::{ShInner, WshInner};
    +use miniscript::{Descriptor, ScriptContext, Terminal};
    +
    +use crate::database::BatchDatabase;
    +use crate::types::KeychainKind;
    +use crate::wallet::Wallet;
    +
    +/// Alias for [`FullyNodedExport`]
    +#[deprecated(since = "0.18.0", note = "Please use [`FullyNodedExport`] instead")]
    +pub type WalletExport = FullyNodedExport;
    +
    +/// Structure that contains the export of a wallet
    +///
    +/// For a usage example see [this module](crate::wallet::export)'s documentation.
    +#[derive(Debug, Serialize, Deserialize)]
    +pub struct FullyNodedExport {
    +    descriptor: String,
    +    /// Earliest block to rescan when looking for the wallet's transactions
    +    pub blockheight: u32,
    +    /// Arbitrary label for the wallet
    +    pub label: String,
     }
     
    -impl ToString for FullyNodedExport {
    -    fn to_string(&self) -> String {
    -        serde_json::to_string(self).unwrap()
    +impl ToString for FullyNodedExport {
    +    fn to_string(&self) -> String {
    +        serde_json::to_string(self).unwrap()
         }
     }
     
    -impl FromStr for FullyNodedExport {
    -    type Err = serde_json::Error;
    +impl FromStr for FullyNodedExport {
    +    type Err = serde_json::Error;
     
    -    fn from_str(s: &str) -> Result<Self, Self::Err> {
    -        serde_json::from_str(s)
    +    fn from_str(s: &str) -> Result<Self, Self::Err> {
    +        serde_json::from_str(s)
         }
     }
     
    -fn remove_checksum(s: String) -> String {
    -    s.split_once('#').map(|(a, _)| String::from(a)).unwrap()
    +fn remove_checksum(s: String) -> String {
    +    s.split_once('#').map(|(a, _)| String::from(a)).unwrap()
     }
     
    -impl FullyNodedExport {
    -    /// Export a wallet
    -    ///
    -    /// This function returns an error if it determines that the `wallet`'s descriptor(s) are not
    -    /// supported by Bitcoin Core or don't follow the standard derivation paths defined by BIP44
    -    /// and others.
    -    ///
    -    /// If `include_blockheight` is `true`, this function will look into the `wallet`'s database
    -    /// for the oldest transaction it knows and use that as the earliest block to rescan.
    -    ///
    -    /// If the database is empty or `include_blockheight` is false, the `blockheight` field
    -    /// returned will be `0`.
    -    pub fn export_wallet<D: BatchDatabase>(
    -        wallet: &Wallet<D>,
    -        label: &str,
    -        include_blockheight: bool,
    -    ) -> Result<Self, &'static str> {
    -        let descriptor = wallet
    -            .get_descriptor_for_keychain(KeychainKind::External)
    -            .to_string_with_secret(
    -                &wallet
    -                    .get_signers(KeychainKind::External)
    -                    .as_key_map(wallet.secp_ctx()),
    +impl FullyNodedExport {
    +    /// Export a wallet
    +    ///
    +    /// This function returns an error if it determines that the `wallet`'s descriptor(s) are not
    +    /// supported by Bitcoin Core or don't follow the standard derivation paths defined by BIP44
    +    /// and others.
    +    ///
    +    /// If `include_blockheight` is `true`, this function will look into the `wallet`'s database
    +    /// for the oldest transaction it knows and use that as the earliest block to rescan.
    +    ///
    +    /// If the database is empty or `include_blockheight` is false, the `blockheight` field
    +    /// returned will be `0`.
    +    pub fn export_wallet<D: BatchDatabase>(
    +        wallet: &Wallet<D>,
    +        label: &str,
    +        include_blockheight: bool,
    +    ) -> Result<Self, &'static str> {
    +        let descriptor = wallet
    +            .get_descriptor_for_keychain(KeychainKind::External)
    +            .to_string_with_secret(
    +                &wallet
    +                    .get_signers(KeychainKind::External)
    +                    .as_key_map(wallet.secp_ctx()),
                 );
    -        let descriptor = remove_checksum(descriptor);
    -        Self::is_compatible_with_core(&descriptor)?;
    +        let descriptor = remove_checksum(descriptor);
    +        Self::is_compatible_with_core(&descriptor)?;
     
    -        let blockheight = match wallet.database.borrow().iter_txs(false) {
    -            _ if !include_blockheight => 0,
    +        let blockheight = match wallet.database.borrow().iter_txs(false) {
    +            _ if !include_blockheight => 0,
                 Err(_) => 0,
    -            Ok(txs) => txs
    -                .into_iter()
    -                .filter_map(|tx| tx.confirmation_time.map(|c| c.height))
    -                .min()
    -                .unwrap_or(0),
    +            Ok(txs) => txs
    +                .into_iter()
    +                .filter_map(|tx| tx.confirmation_time.map(|c| c.height))
    +                .min()
    +                .unwrap_or(0),
             };
     
    -        let export = FullyNodedExport {
    -            descriptor,
    -            label: label.into(),
    -            blockheight,
    +        let export = FullyNodedExport {
    +            descriptor,
    +            label: label.into(),
    +            blockheight,
             };
     
    -        let change_descriptor = match wallet
    -            .public_descriptor(KeychainKind::Internal)
    -            .map_err(|_| "Invalid change descriptor")?
    -            .is_some()
    +        let change_descriptor = match wallet
    +            .public_descriptor(KeychainKind::Internal)
    +            .map_err(|_| "Invalid change descriptor")?
    +            .is_some()
             {
    -            false => None,
    -            true => {
    -                let descriptor = wallet
    -                    .get_descriptor_for_keychain(KeychainKind::Internal)
    -                    .to_string_with_secret(
    -                        &wallet
    -                            .get_signers(KeychainKind::Internal)
    -                            .as_key_map(wallet.secp_ctx()),
    +            false => None,
    +            true => {
    +                let descriptor = wallet
    +                    .get_descriptor_for_keychain(KeychainKind::Internal)
    +                    .to_string_with_secret(
    +                        &wallet
    +                            .get_signers(KeychainKind::Internal)
    +                            .as_key_map(wallet.secp_ctx()),
                         );
    -                Some(remove_checksum(descriptor))
    +                Some(remove_checksum(descriptor))
                 }
             };
    -        if export.change_descriptor() != change_descriptor {
    -            return Err("Incompatible change descriptor");
    +        if export.change_descriptor() != change_descriptor {
    +            return Err("Incompatible change descriptor");
             }
     
    -        Ok(export)
    +        Ok(export)
         }
     
    -    fn is_compatible_with_core(descriptor: &str) -> Result<(), &'static str> {
    -        fn check_ms<Ctx: ScriptContext>(
    -            terminal: &Terminal<String, Ctx>,
    -        ) -> Result<(), &'static str> {
    -            if let Terminal::Multi(_, _) = terminal {
    +    fn is_compatible_with_core(descriptor: &str) -> Result<(), &'static str> {
    +        fn check_ms<Ctx: ScriptContext>(
    +            terminal: &Terminal<String, Ctx>,
    +        ) -> Result<(), &'static str> {
    +            if let Terminal::Multi(_, _) = terminal {
                     Ok(())
    -            } else {
    +            } else {
                     Err("The descriptor contains operators not supported by Bitcoin Core")
                 }
             }
     
    -        // pkh(), wpkh(), sh(wpkh()) are always fine, as well as multi() and sortedmulti()
    -        match Descriptor::<String>::from_str(descriptor).map_err(|_| "Invalid descriptor")? {
    -            Descriptor::Pkh(_) | Descriptor::Wpkh(_) => Ok(()),
    -            Descriptor::Sh(sh) => match sh.as_inner() {
    -                ShInner::Wpkh(_) => Ok(()),
    -                ShInner::SortedMulti(_) => Ok(()),
    -                ShInner::Wsh(wsh) => match wsh.as_inner() {
    -                    WshInner::SortedMulti(_) => Ok(()),
    -                    WshInner::Ms(ms) => check_ms(&ms.node),
    +        // pkh(), wpkh(), sh(wpkh()) are always fine, as well as multi() and sortedmulti()
    +        match Descriptor::<String>::from_str(descriptor).map_err(|_| "Invalid descriptor")? {
    +            Descriptor::Pkh(_) | Descriptor::Wpkh(_) => Ok(()),
    +            Descriptor::Sh(sh) => match sh.as_inner() {
    +                ShInner::Wpkh(_) => Ok(()),
    +                ShInner::SortedMulti(_) => Ok(()),
    +                ShInner::Wsh(wsh) => match wsh.as_inner() {
    +                    WshInner::SortedMulti(_) => Ok(()),
    +                    WshInner::Ms(ms) => check_ms(&ms.node),
                     },
    -                ShInner::Ms(ms) => check_ms(&ms.node),
    +                ShInner::Ms(ms) => check_ms(&ms.node),
                 },
    -            Descriptor::Wsh(wsh) => match wsh.as_inner() {
    -                WshInner::SortedMulti(_) => Ok(()),
    -                WshInner::Ms(ms) => check_ms(&ms.node),
    +            Descriptor::Wsh(wsh) => match wsh.as_inner() {
    +                WshInner::SortedMulti(_) => Ok(()),
    +                WshInner::Ms(ms) => check_ms(&ms.node),
                 },
    -            _ => Err("The descriptor is not compatible with Bitcoin Core"),
    +            _ => Err("The descriptor is not compatible with Bitcoin Core"),
             }
         }
     
    -    /// Return the external descriptor
    -    pub fn descriptor(&self) -> String {
    -        self.descriptor.clone()
    +    /// Return the external descriptor
    +    pub fn descriptor(&self) -> String {
    +        self.descriptor.clone()
         }
     
    -    /// Return the internal descriptor, if present
    -    pub fn change_descriptor(&self) -> Option<String> {
    -        let replaced = self.descriptor.replace("/0/*", "/1/*");
    +    /// Return the internal descriptor, if present
    +    pub fn change_descriptor(&self) -> Option<String> {
    +        let replaced = self.descriptor.replace("/0/*", "/1/*");
     
    -        if replaced != self.descriptor {
    -            Some(replaced)
    -        } else {
    -            None
    -        }
    +        if replaced != self.descriptor {
    +            Some(replaced)
    +        } else {
    +            None
    +        }
         }
     }
     
    -#[cfg(test)]
    -mod test {
    -    use std::str::FromStr;
    +#[cfg(test)]
    +mod test {
    +    use std::str::FromStr;
     
    -    use bitcoin::{Network, Txid};
    +    use bitcoin::{Network, Txid};
     
    -    use super::*;
    -    use crate::database::{memory::MemoryDatabase, BatchOperations};
    -    use crate::types::TransactionDetails;
    -    use crate::wallet::Wallet;
    -    use crate::BlockTime;
    +    use super::*;
    +    use crate::database::{memory::MemoryDatabase, BatchOperations};
    +    use crate::types::TransactionDetails;
    +    use crate::wallet::Wallet;
    +    use crate::BlockTime;
     
    -    fn get_test_db() -> MemoryDatabase {
    -        let mut db = MemoryDatabase::new();
    -        db.set_tx(&TransactionDetails {
    -            transaction: None,
    -            txid: Txid::from_str(
    +    fn get_test_db() -> MemoryDatabase {
    +        let mut db = MemoryDatabase::new();
    +        db.set_tx(&TransactionDetails {
    +            transaction: None,
    +            txid: Txid::from_str(
                     "4ddff1fa33af17f377f62b72357b43107c19110a8009b36fb832af505efed98a",
                 )
    -            .unwrap(),
    -
    -            received: 100_000,
    -            sent: 0,
    -            fee: Some(500),
    -            confirmation_time: Some(BlockTime {
    -                timestamp: 12345678,
    -                height: 5001,
    +            .unwrap(),
    +
    +            received: 100_000,
    +            sent: 0,
    +            fee: Some(500),
    +            confirmation_time: Some(BlockTime {
    +                timestamp: 12345678,
    +                height: 5001,
                 }),
             })
    -        .unwrap();
    +        .unwrap();
     
    -        db.set_tx(&TransactionDetails {
    -            transaction: None,
    -            txid: Txid::from_str(
    +        db.set_tx(&TransactionDetails {
    +            transaction: None,
    +            txid: Txid::from_str(
                     "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
                 )
    -            .unwrap(),
    -            received: 25_000,
    -            sent: 0,
    -            fee: Some(300),
    -            confirmation_time: Some(BlockTime {
    -                timestamp: 12345677,
    -                height: 5000,
    +            .unwrap(),
    +            received: 25_000,
    +            sent: 0,
    +            fee: Some(300),
    +            confirmation_time: Some(BlockTime {
    +                timestamp: 12345677,
    +                height: 5000,
                 }),
             })
    -        .unwrap();
    +        .unwrap();
     
    -        db
    +        db
         }
     
    -    #[test]
    -    fn test_export_bip44() {
    -        let descriptor = "wpkh(xprv9s21ZrQH143K4CTb63EaMxja1YiTnSEWKMbn23uoEnAzxjdUJRQkazCAtzxGm4LSoTSVTptoV9RbchnKPW9HxKtZumdyxyikZFDLhogJ5Uj/44'/0'/0'/0/*)";
    -        let change_descriptor = "wpkh(xprv9s21ZrQH143K4CTb63EaMxja1YiTnSEWKMbn23uoEnAzxjdUJRQkazCAtzxGm4LSoTSVTptoV9RbchnKPW9HxKtZumdyxyikZFDLhogJ5Uj/44'/0'/0'/1/*)";
    +    #[test]
    +    fn test_export_bip44() {
    +        let descriptor = "wpkh(xprv9s21ZrQH143K4CTb63EaMxja1YiTnSEWKMbn23uoEnAzxjdUJRQkazCAtzxGm4LSoTSVTptoV9RbchnKPW9HxKtZumdyxyikZFDLhogJ5Uj/44'/0'/0'/0/*)";
    +        let change_descriptor = "wpkh(xprv9s21ZrQH143K4CTb63EaMxja1YiTnSEWKMbn23uoEnAzxjdUJRQkazCAtzxGm4LSoTSVTptoV9RbchnKPW9HxKtZumdyxyikZFDLhogJ5Uj/44'/0'/0'/1/*)";
     
    -        let wallet = Wallet::new(
    -            descriptor,
    -            Some(change_descriptor),
    -            Network::Bitcoin,
    -            get_test_db(),
    +        let wallet = Wallet::new(
    +            descriptor,
    +            Some(change_descriptor),
    +            Network::Bitcoin,
    +            get_test_db(),
             )
    -        .unwrap();
    -        let export = FullyNodedExport::export_wallet(&wallet, "Test Label", true).unwrap();
    +        .unwrap();
    +        let export = FullyNodedExport::export_wallet(&wallet, "Test Label", true).unwrap();
     
    -        assert_eq!(export.descriptor(), descriptor);
    -        assert_eq!(export.change_descriptor(), Some(change_descriptor.into()));
    -        assert_eq!(export.blockheight, 5000);
    -        assert_eq!(export.label, "Test Label");
    +        assert_eq!(export.descriptor(), descriptor);
    +        assert_eq!(export.change_descriptor(), Some(change_descriptor.into()));
    +        assert_eq!(export.blockheight, 5000);
    +        assert_eq!(export.label, "Test Label");
         }
     
    -    #[test]
    -    #[should_panic(expected = "Incompatible change descriptor")]
    -    fn test_export_no_change() {
    -        // This wallet explicitly doesn't have a change descriptor. It should be impossible to
    -        // export, because exporting this kind of external descriptor normally implies the
    -        // existence of an internal descriptor
    +    #[test]
    +    #[should_panic(expected = "Incompatible change descriptor")]
    +    fn test_export_no_change() {
    +        // This wallet explicitly doesn't have a change descriptor. It should be impossible to
    +        // export, because exporting this kind of external descriptor normally implies the
    +        // existence of an internal descriptor
     
    -        let descriptor = "wpkh(xprv9s21ZrQH143K4CTb63EaMxja1YiTnSEWKMbn23uoEnAzxjdUJRQkazCAtzxGm4LSoTSVTptoV9RbchnKPW9HxKtZumdyxyikZFDLhogJ5Uj/44'/0'/0'/0/*)";
    +        let descriptor = "wpkh(xprv9s21ZrQH143K4CTb63EaMxja1YiTnSEWKMbn23uoEnAzxjdUJRQkazCAtzxGm4LSoTSVTptoV9RbchnKPW9HxKtZumdyxyikZFDLhogJ5Uj/44'/0'/0'/0/*)";
     
    -        let wallet = Wallet::new(descriptor, None, Network::Bitcoin, get_test_db()).unwrap();
    -        FullyNodedExport::export_wallet(&wallet, "Test Label", true).unwrap();
    +        let wallet = Wallet::new(descriptor, None, Network::Bitcoin, get_test_db()).unwrap();
    +        FullyNodedExport::export_wallet(&wallet, "Test Label", true).unwrap();
         }
     
    -    #[test]
    -    #[should_panic(expected = "Incompatible change descriptor")]
    -    fn test_export_incompatible_change() {
    -        // This wallet has a change descriptor, but the derivation path is not in the "standard"
    -        // bip44/49/etc format
    +    #[test]
    +    #[should_panic(expected = "Incompatible change descriptor")]
    +    fn test_export_incompatible_change() {
    +        // This wallet has a change descriptor, but the derivation path is not in the "standard"
    +        // bip44/49/etc format
     
    -        let descriptor = "wpkh(xprv9s21ZrQH143K4CTb63EaMxja1YiTnSEWKMbn23uoEnAzxjdUJRQkazCAtzxGm4LSoTSVTptoV9RbchnKPW9HxKtZumdyxyikZFDLhogJ5Uj/44'/0'/0'/0/*)";
    -        let change_descriptor = "wpkh(xprv9s21ZrQH143K4CTb63EaMxja1YiTnSEWKMbn23uoEnAzxjdUJRQkazCAtzxGm4LSoTSVTptoV9RbchnKPW9HxKtZumdyxyikZFDLhogJ5Uj/50'/0'/1/*)";
    +        let descriptor = "wpkh(xprv9s21ZrQH143K4CTb63EaMxja1YiTnSEWKMbn23uoEnAzxjdUJRQkazCAtzxGm4LSoTSVTptoV9RbchnKPW9HxKtZumdyxyikZFDLhogJ5Uj/44'/0'/0'/0/*)";
    +        let change_descriptor = "wpkh(xprv9s21ZrQH143K4CTb63EaMxja1YiTnSEWKMbn23uoEnAzxjdUJRQkazCAtzxGm4LSoTSVTptoV9RbchnKPW9HxKtZumdyxyikZFDLhogJ5Uj/50'/0'/1/*)";
     
    -        let wallet = Wallet::new(
    -            descriptor,
    -            Some(change_descriptor),
    -            Network::Bitcoin,
    -            get_test_db(),
    +        let wallet = Wallet::new(
    +            descriptor,
    +            Some(change_descriptor),
    +            Network::Bitcoin,
    +            get_test_db(),
             )
    -        .unwrap();
    -        FullyNodedExport::export_wallet(&wallet, "Test Label", true).unwrap();
    +        .unwrap();
    +        FullyNodedExport::export_wallet(&wallet, "Test Label", true).unwrap();
         }
     
    -    #[test]
    -    fn test_export_multi() {
    -        let descriptor = "wsh(multi(2,\
    +    #[test]
    +    fn test_export_multi() {
    +        let descriptor = "wsh(multi(2,\
                                     [73756c7f/48'/0'/0'/2']tpubDCKxNyM3bLgbEX13Mcd8mYxbVg9ajDkWXMh29hMWBurKfVmBfWAM96QVP3zaUcN51HvkZ3ar4VwP82kC8JZhhux8vFQoJintSpVBwpFvyU3/0/*,\
                                     [f9f62194/48'/0'/0'/2']tpubDDp3ZSH1yCwusRppH7zgSxq2t1VEUyXSeEp8E5aFS8m43MknUjiF1bSLo3CGWAxbDyhF1XowA5ukPzyJZjznYk3kYi6oe7QxtX2euvKWsk4/0/*,\
                                     [c98b1535/48'/0'/0'/2']tpubDCDi5W4sP6zSnzJeowy8rQDVhBdRARaPhK1axABi8V1661wEPeanpEXj4ZLAUEoikVtoWcyK26TKKJSecSfeKxwHCcRrge9k1ybuiL71z4a/0/*\
                               ))";
    -        let change_descriptor = "wsh(multi(2,\
    +        let change_descriptor = "wsh(multi(2,\
                                            [73756c7f/48'/0'/0'/2']tpubDCKxNyM3bLgbEX13Mcd8mYxbVg9ajDkWXMh29hMWBurKfVmBfWAM96QVP3zaUcN51HvkZ3ar4VwP82kC8JZhhux8vFQoJintSpVBwpFvyU3/1/*,\
                                            [f9f62194/48'/0'/0'/2']tpubDDp3ZSH1yCwusRppH7zgSxq2t1VEUyXSeEp8E5aFS8m43MknUjiF1bSLo3CGWAxbDyhF1XowA5ukPzyJZjznYk3kYi6oe7QxtX2euvKWsk4/1/*,\
                                            [c98b1535/48'/0'/0'/2']tpubDCDi5W4sP6zSnzJeowy8rQDVhBdRARaPhK1axABi8V1661wEPeanpEXj4ZLAUEoikVtoWcyK26TKKJSecSfeKxwHCcRrge9k1ybuiL71z4a/1/*\
                                      ))";
     
    -        let wallet = Wallet::new(
    -            descriptor,
    -            Some(change_descriptor),
    -            Network::Testnet,
    -            get_test_db(),
    +        let wallet = Wallet::new(
    +            descriptor,
    +            Some(change_descriptor),
    +            Network::Testnet,
    +            get_test_db(),
             )
    -        .unwrap();
    -        let export = FullyNodedExport::export_wallet(&wallet, "Test Label", true).unwrap();
    +        .unwrap();
    +        let export = FullyNodedExport::export_wallet(&wallet, "Test Label", true).unwrap();
     
    -        assert_eq!(export.descriptor(), descriptor);
    -        assert_eq!(export.change_descriptor(), Some(change_descriptor.into()));
    -        assert_eq!(export.blockheight, 5000);
    -        assert_eq!(export.label, "Test Label");
    +        assert_eq!(export.descriptor(), descriptor);
    +        assert_eq!(export.change_descriptor(), Some(change_descriptor.into()));
    +        assert_eq!(export.blockheight, 5000);
    +        assert_eq!(export.label, "Test Label");
         }
     
    -    #[test]
    -    fn test_export_to_json() {
    -        let descriptor = "wpkh(xprv9s21ZrQH143K4CTb63EaMxja1YiTnSEWKMbn23uoEnAzxjdUJRQkazCAtzxGm4LSoTSVTptoV9RbchnKPW9HxKtZumdyxyikZFDLhogJ5Uj/44'/0'/0'/0/*)";
    -        let change_descriptor = "wpkh(xprv9s21ZrQH143K4CTb63EaMxja1YiTnSEWKMbn23uoEnAzxjdUJRQkazCAtzxGm4LSoTSVTptoV9RbchnKPW9HxKtZumdyxyikZFDLhogJ5Uj/44'/0'/0'/1/*)";
    +    #[test]
    +    fn test_export_to_json() {
    +        let descriptor = "wpkh(xprv9s21ZrQH143K4CTb63EaMxja1YiTnSEWKMbn23uoEnAzxjdUJRQkazCAtzxGm4LSoTSVTptoV9RbchnKPW9HxKtZumdyxyikZFDLhogJ5Uj/44'/0'/0'/0/*)";
    +        let change_descriptor = "wpkh(xprv9s21ZrQH143K4CTb63EaMxja1YiTnSEWKMbn23uoEnAzxjdUJRQkazCAtzxGm4LSoTSVTptoV9RbchnKPW9HxKtZumdyxyikZFDLhogJ5Uj/44'/0'/0'/1/*)";
     
    -        let wallet = Wallet::new(
    -            descriptor,
    -            Some(change_descriptor),
    -            Network::Bitcoin,
    -            get_test_db(),
    +        let wallet = Wallet::new(
    +            descriptor,
    +            Some(change_descriptor),
    +            Network::Bitcoin,
    +            get_test_db(),
             )
    -        .unwrap();
    -        let export = FullyNodedExport::export_wallet(&wallet, "Test Label", true).unwrap();
    +        .unwrap();
    +        let export = FullyNodedExport::export_wallet(&wallet, "Test Label", true).unwrap();
     
    -        assert_eq!(export.to_string(), "{\"descriptor\":\"wpkh(xprv9s21ZrQH143K4CTb63EaMxja1YiTnSEWKMbn23uoEnAzxjdUJRQkazCAtzxGm4LSoTSVTptoV9RbchnKPW9HxKtZumdyxyikZFDLhogJ5Uj/44\'/0\'/0\'/0/*)\",\"blockheight\":5000,\"label\":\"Test Label\"}");
    +        assert_eq!(export.to_string(), "{\"descriptor\":\"wpkh(xprv9s21ZrQH143K4CTb63EaMxja1YiTnSEWKMbn23uoEnAzxjdUJRQkazCAtzxGm4LSoTSVTptoV9RbchnKPW9HxKtZumdyxyikZFDLhogJ5Uj/44\'/0\'/0\'/0/*)\",\"blockheight\":5000,\"label\":\"Test Label\"}");
         }
     
    -    #[test]
    -    fn test_export_from_json() {
    -        let descriptor = "wpkh(xprv9s21ZrQH143K4CTb63EaMxja1YiTnSEWKMbn23uoEnAzxjdUJRQkazCAtzxGm4LSoTSVTptoV9RbchnKPW9HxKtZumdyxyikZFDLhogJ5Uj/44'/0'/0'/0/*)";
    -        let change_descriptor = "wpkh(xprv9s21ZrQH143K4CTb63EaMxja1YiTnSEWKMbn23uoEnAzxjdUJRQkazCAtzxGm4LSoTSVTptoV9RbchnKPW9HxKtZumdyxyikZFDLhogJ5Uj/44'/0'/0'/1/*)";
    +    #[test]
    +    fn test_export_from_json() {
    +        let descriptor = "wpkh(xprv9s21ZrQH143K4CTb63EaMxja1YiTnSEWKMbn23uoEnAzxjdUJRQkazCAtzxGm4LSoTSVTptoV9RbchnKPW9HxKtZumdyxyikZFDLhogJ5Uj/44'/0'/0'/0/*)";
    +        let change_descriptor = "wpkh(xprv9s21ZrQH143K4CTb63EaMxja1YiTnSEWKMbn23uoEnAzxjdUJRQkazCAtzxGm4LSoTSVTptoV9RbchnKPW9HxKtZumdyxyikZFDLhogJ5Uj/44'/0'/0'/1/*)";
     
    -        let import_str = "{\"descriptor\":\"wpkh(xprv9s21ZrQH143K4CTb63EaMxja1YiTnSEWKMbn23uoEnAzxjdUJRQkazCAtzxGm4LSoTSVTptoV9RbchnKPW9HxKtZumdyxyikZFDLhogJ5Uj/44\'/0\'/0\'/0/*)\",\"blockheight\":5000,\"label\":\"Test Label\"}";
    -        let export = FullyNodedExport::from_str(import_str).unwrap();
    +        let import_str = "{\"descriptor\":\"wpkh(xprv9s21ZrQH143K4CTb63EaMxja1YiTnSEWKMbn23uoEnAzxjdUJRQkazCAtzxGm4LSoTSVTptoV9RbchnKPW9HxKtZumdyxyikZFDLhogJ5Uj/44\'/0\'/0\'/0/*)\",\"blockheight\":5000,\"label\":\"Test Label\"}";
    +        let export = FullyNodedExport::from_str(import_str).unwrap();
     
    -        assert_eq!(export.descriptor(), descriptor);
    -        assert_eq!(export.change_descriptor(), Some(change_descriptor.into()));
    -        assert_eq!(export.blockheight, 5000);
    -        assert_eq!(export.label, "Test Label");
    +        assert_eq!(export.descriptor(), descriptor);
    +        assert_eq!(export.change_descriptor(), Some(change_descriptor.into()));
    +        assert_eq!(export.blockheight, 5000);
    +        assert_eq!(export.label, "Test Label");
         }
     }
     
    -
    - \ No newline at end of file +
    \ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/src/bdk/wallet/hardwaresigner.rs.html b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/src/bdk/wallet/hardwaresigner.rs.html index bb2d1e8bcd..605db6daa3 100644 --- a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/src/bdk/wallet/hardwaresigner.rs.html +++ b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/src/bdk/wallet/hardwaresigner.rs.html @@ -1,204 +1,197 @@ -hardwaresigner.rs - source - -
     1
    - 2
    - 3
    - 4
    - 5
    - 6
    - 7
    - 8
    - 9
    -10
    -11
    -12
    -13
    -14
    -15
    -16
    -17
    -18
    -19
    -20
    -21
    -22
    -23
    -24
    -25
    -26
    -27
    -28
    -29
    -30
    -31
    -32
    -33
    -34
    -35
    -36
    -37
    -38
    -39
    -40
    -41
    -42
    -43
    -44
    -45
    -46
    -47
    -48
    -49
    -50
    -51
    -52
    -53
    -54
    -55
    -56
    -57
    -58
    -59
    -60
    -61
    -62
    -63
    -64
    -65
    -66
    -67
    -68
    -69
    -70
    -71
    -72
    -73
    -74
    -75
    -76
    -77
    -78
    -79
    -80
    -81
    -82
    -83
    -84
    -85
    -86
    -87
    -88
    -89
    -90
    -91
    -92
    -93
    -94
    -95
    -96
    -97
    -
    // Bitcoin Dev Kit
    -// Written in 2020 by Alekos Filini <alekos.filini@gmail.com>
    -//
    -// Copyright (c) 2020-2021 Bitcoin Dev Kit Developers
    -//
    -// This file is licensed under the Apache License, Version 2.0 <LICENSE-APACHE
    -// or http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
    -// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your option.
    -// You may not use this file except in accordance with one or both of these
    -// licenses.
    +hardwaresigner.rs - source
    1
    +2
    +3
    +4
    +5
    +6
    +7
    +8
    +9
    +10
    +11
    +12
    +13
    +14
    +15
    +16
    +17
    +18
    +19
    +20
    +21
    +22
    +23
    +24
    +25
    +26
    +27
    +28
    +29
    +30
    +31
    +32
    +33
    +34
    +35
    +36
    +37
    +38
    +39
    +40
    +41
    +42
    +43
    +44
    +45
    +46
    +47
    +48
    +49
    +50
    +51
    +52
    +53
    +54
    +55
    +56
    +57
    +58
    +59
    +60
    +61
    +62
    +63
    +64
    +65
    +66
    +67
    +68
    +69
    +70
    +71
    +72
    +73
    +74
    +75
    +76
    +77
    +78
    +79
    +80
    +81
    +82
    +83
    +84
    +85
    +86
    +87
    +88
    +89
    +90
    +91
    +92
    +93
    +94
    +95
    +96
    +97
    +
    // Bitcoin Dev Kit
    +// Written in 2020 by Alekos Filini <alekos.filini@gmail.com>
    +//
    +// Copyright (c) 2020-2021 Bitcoin Dev Kit Developers
    +//
    +// This file is licensed under the Apache License, Version 2.0 <LICENSE-APACHE
    +// or http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
    +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your option.
    +// You may not use this file except in accordance with one or both of these
    +// licenses.
     
    -//! HWI Signer
    -//!
    -//! This module contains HWISigner, an implementation of a [TransactionSigner] to be
    -//! used with hardware wallets.
    -//! ```no_run
    -//! # use bdk::bitcoin::Network;
    -//! # use bdk::database::MemoryDatabase;
    -//! # use bdk::signer::SignerOrdering;
    -//! # use bdk::wallet::hardwaresigner::HWISigner;
    -//! # use bdk::wallet::AddressIndex::New;
    -//! # use bdk::{FeeRate, KeychainKind, SignOptions, SyncOptions, Wallet};
    -//! # use hwi::{types::HWIChain, HWIClient};
    -//! # use std::sync::Arc;
    -//! #
    -//! # fn main() -> Result<(), Box<dyn std::error::Error>> {
    -//! let devices = HWIClient::enumerate()?;
    -//! let first_device = devices.first().expect("No devices found!");
    -//! let custom_signer = HWISigner::from_device(first_device, HWIChain::Test)?;
    -//!
    -//! # let mut wallet = Wallet::new(
    -//! #     "",
    -//! #     None,
    -//! #     Network::Testnet,
    -//! #     MemoryDatabase::default(),
    -//! # )?;
    -//! #
    -//! // Adding the hardware signer to the BDK wallet
    -//! wallet.add_signer(
    -//!     KeychainKind::External,
    -//!     SignerOrdering(200),
    -//!     Arc::new(custom_signer),
    -//! );
    -//!
    -//! # Ok(())
    -//! # }
    -//! ```
    +//! HWI Signer
    +//!
    +//! This module contains HWISigner, an implementation of a [TransactionSigner] to be
    +//! used with hardware wallets.
    +//! ```no_run
    +//! # use bdk::bitcoin::Network;
    +//! # use bdk::database::MemoryDatabase;
    +//! # use bdk::signer::SignerOrdering;
    +//! # use bdk::wallet::hardwaresigner::HWISigner;
    +//! # use bdk::wallet::AddressIndex::New;
    +//! # use bdk::{FeeRate, KeychainKind, SignOptions, SyncOptions, Wallet};
    +//! # use hwi::{types::HWIChain, HWIClient};
    +//! # use std::sync::Arc;
    +//! #
    +//! # fn main() -> Result<(), Box<dyn std::error::Error>> {
    +//! let devices = HWIClient::enumerate()?;
    +//! let first_device = devices.first().expect("No devices found!");
    +//! let custom_signer = HWISigner::from_device(first_device, HWIChain::Test)?;
    +//!
    +//! # let mut wallet = Wallet::new(
    +//! #     "",
    +//! #     None,
    +//! #     Network::Testnet,
    +//! #     MemoryDatabase::default(),
    +//! # )?;
    +//! #
    +//! // Adding the hardware signer to the BDK wallet
    +//! wallet.add_signer(
    +//!     KeychainKind::External,
    +//!     SignerOrdering(200),
    +//!     Arc::new(custom_signer),
    +//! );
    +//!
    +//! # Ok(())
    +//! # }
    +//! ```
     
    -use bitcoin::psbt::PartiallySignedTransaction;
    -use bitcoin::secp256k1::{All, Secp256k1};
    -use bitcoin::util::bip32::Fingerprint;
    +use bitcoin::psbt::PartiallySignedTransaction;
    +use bitcoin::secp256k1::{All, Secp256k1};
    +use bitcoin::util::bip32::Fingerprint;
     
    -use hwi::error::Error;
    -use hwi::types::{HWIChain, HWIDevice};
    -use hwi::HWIClient;
    +use hwi::error::Error;
    +use hwi::types::{HWIChain, HWIDevice};
    +use hwi::HWIClient;
     
    -use crate::signer::{SignerCommon, SignerError, SignerId, TransactionSigner};
    +use crate::signer::{SignerCommon, SignerError, SignerId, TransactionSigner};
     
    -#[derive(Debug)]
    -/// Custom signer for Hardware Wallets
    -///
    -/// This ignores `sign_options` and leaves the decisions up to the hardware wallet.
    -pub struct HWISigner {
    -    fingerprint: Fingerprint,
    -    client: HWIClient,
    +#[derive(Debug)]
    +/// Custom signer for Hardware Wallets
    +///
    +/// This ignores `sign_options` and leaves the decisions up to the hardware wallet.
    +pub struct HWISigner {
    +    fingerprint: Fingerprint,
    +    client: HWIClient,
     }
     
    -impl HWISigner {
    -    /// Create a instance from the specified device and chain
    -    pub fn from_device(device: &HWIDevice, chain: HWIChain) -> Result<HWISigner, Error> {
    -        let client = HWIClient::get_client(device, false, chain)?;
    -        Ok(HWISigner {
    -            fingerprint: device.fingerprint,
    -            client,
    +impl HWISigner {
    +    /// Create a instance from the specified device and chain
    +    pub fn from_device(device: &HWIDevice, chain: HWIChain) -> Result<HWISigner, Error> {
    +        let client = HWIClient::get_client(device, false, chain)?;
    +        Ok(HWISigner {
    +            fingerprint: device.fingerprint,
    +            client,
             })
         }
     }
     
    -impl SignerCommon for HWISigner {
    -    fn id(&self, _secp: &Secp256k1<All>) -> SignerId {
    -        SignerId::Fingerprint(self.fingerprint)
    +impl SignerCommon for HWISigner {
    +    fn id(&self, _secp: &Secp256k1<All>) -> SignerId {
    +        SignerId::Fingerprint(self.fingerprint)
         }
     }
     
    -/// This implementation ignores `sign_options`
    -impl TransactionSigner for HWISigner {
    -    fn sign_transaction(
    +/// This implementation ignores `sign_options`
    +impl TransactionSigner for HWISigner {
    +    fn sign_transaction(
             &self,
    -        psbt: &mut PartiallySignedTransaction,
    -        _sign_options: &crate::SignOptions,
    -        _secp: &crate::wallet::utils::SecpCtx,
    -    ) -> Result<(), SignerError> {
    -        psbt.combine(self.client.sign_tx(psbt)?.psbt)
    -            .expect("Failed to combine HW signed psbt with passed PSBT");
    +        psbt: &mut PartiallySignedTransaction,
    +        _sign_options: &crate::SignOptions,
    +        _secp: &crate::wallet::utils::SecpCtx,
    +    ) -> Result<(), SignerError> {
    +        psbt.combine(self.client.sign_tx(psbt)?.psbt)
    +            .expect("Failed to combine HW signed psbt with passed PSBT");
             Ok(())
         }
     }
     
    -
    - \ No newline at end of file +
    \ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/src/bdk/wallet/mod.rs.html b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/src/bdk/wallet/mod.rs.html index 2d3b035152..b034fb818a 100644 --- a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/src/bdk/wallet/mod.rs.html +++ b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/src/bdk/wallet/mod.rs.html @@ -1,7270 +1,7264 @@ -mod.rs - source - -
       1
    -   2
    -   3
    -   4
    -   5
    -   6
    -   7
    -   8
    -   9
    -  10
    -  11
    -  12
    -  13
    -  14
    -  15
    -  16
    -  17
    -  18
    -  19
    -  20
    -  21
    -  22
    -  23
    -  24
    -  25
    -  26
    -  27
    -  28
    -  29
    -  30
    -  31
    -  32
    -  33
    -  34
    -  35
    -  36
    -  37
    -  38
    -  39
    -  40
    -  41
    -  42
    -  43
    -  44
    -  45
    -  46
    -  47
    -  48
    -  49
    -  50
    -  51
    -  52
    -  53
    -  54
    -  55
    -  56
    -  57
    -  58
    -  59
    -  60
    -  61
    -  62
    -  63
    -  64
    -  65
    -  66
    -  67
    -  68
    -  69
    -  70
    -  71
    -  72
    -  73
    -  74
    -  75
    -  76
    -  77
    -  78
    -  79
    -  80
    -  81
    -  82
    -  83
    -  84
    -  85
    -  86
    -  87
    -  88
    -  89
    -  90
    -  91
    -  92
    -  93
    -  94
    -  95
    -  96
    -  97
    -  98
    -  99
    - 100
    - 101
    - 102
    - 103
    - 104
    - 105
    - 106
    - 107
    - 108
    - 109
    - 110
    - 111
    - 112
    - 113
    - 114
    - 115
    - 116
    - 117
    - 118
    - 119
    - 120
    - 121
    - 122
    - 123
    - 124
    - 125
    - 126
    - 127
    - 128
    - 129
    - 130
    - 131
    - 132
    - 133
    - 134
    - 135
    - 136
    - 137
    - 138
    - 139
    - 140
    - 141
    - 142
    - 143
    - 144
    - 145
    - 146
    - 147
    - 148
    - 149
    - 150
    - 151
    - 152
    - 153
    - 154
    - 155
    - 156
    - 157
    - 158
    - 159
    - 160
    - 161
    - 162
    - 163
    - 164
    - 165
    - 166
    - 167
    - 168
    - 169
    - 170
    - 171
    - 172
    - 173
    - 174
    - 175
    - 176
    - 177
    - 178
    - 179
    - 180
    - 181
    - 182
    - 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
    - 245
    - 246
    - 247
    - 248
    - 249
    - 250
    - 251
    - 252
    - 253
    - 254
    - 255
    - 256
    - 257
    - 258
    - 259
    - 260
    - 261
    - 262
    - 263
    - 264
    - 265
    - 266
    - 267
    - 268
    - 269
    - 270
    - 271
    - 272
    - 273
    - 274
    - 275
    - 276
    - 277
    - 278
    - 279
    - 280
    - 281
    - 282
    - 283
    - 284
    - 285
    - 286
    - 287
    - 288
    - 289
    - 290
    - 291
    - 292
    - 293
    - 294
    - 295
    - 296
    - 297
    - 298
    - 299
    - 300
    - 301
    - 302
    - 303
    - 304
    - 305
    - 306
    - 307
    - 308
    - 309
    - 310
    - 311
    - 312
    - 313
    - 314
    - 315
    - 316
    - 317
    - 318
    - 319
    - 320
    - 321
    - 322
    - 323
    - 324
    - 325
    - 326
    - 327
    - 328
    - 329
    - 330
    - 331
    - 332
    - 333
    - 334
    - 335
    - 336
    - 337
    - 338
    - 339
    - 340
    - 341
    - 342
    - 343
    - 344
    - 345
    - 346
    - 347
    - 348
    - 349
    - 350
    - 351
    - 352
    - 353
    - 354
    - 355
    - 356
    - 357
    - 358
    - 359
    - 360
    - 361
    - 362
    - 363
    - 364
    - 365
    - 366
    - 367
    - 368
    - 369
    - 370
    - 371
    - 372
    - 373
    - 374
    - 375
    - 376
    - 377
    - 378
    - 379
    - 380
    - 381
    - 382
    - 383
    - 384
    - 385
    - 386
    - 387
    - 388
    - 389
    - 390
    - 391
    - 392
    - 393
    - 394
    - 395
    - 396
    - 397
    - 398
    - 399
    - 400
    - 401
    - 402
    - 403
    - 404
    - 405
    - 406
    - 407
    - 408
    - 409
    - 410
    - 411
    - 412
    - 413
    - 414
    - 415
    - 416
    - 417
    - 418
    - 419
    - 420
    - 421
    - 422
    - 423
    - 424
    - 425
    - 426
    - 427
    - 428
    - 429
    - 430
    - 431
    - 432
    - 433
    - 434
    - 435
    - 436
    - 437
    - 438
    - 439
    - 440
    - 441
    - 442
    - 443
    - 444
    - 445
    - 446
    - 447
    - 448
    - 449
    - 450
    - 451
    - 452
    - 453
    - 454
    - 455
    - 456
    - 457
    - 458
    - 459
    - 460
    - 461
    - 462
    - 463
    - 464
    - 465
    - 466
    - 467
    - 468
    - 469
    - 470
    - 471
    - 472
    - 473
    - 474
    - 475
    - 476
    - 477
    - 478
    - 479
    - 480
    - 481
    - 482
    - 483
    - 484
    - 485
    - 486
    - 487
    - 488
    - 489
    - 490
    - 491
    - 492
    - 493
    - 494
    - 495
    - 496
    - 497
    - 498
    - 499
    - 500
    - 501
    - 502
    - 503
    - 504
    - 505
    - 506
    - 507
    - 508
    - 509
    - 510
    - 511
    - 512
    - 513
    - 514
    - 515
    - 516
    - 517
    - 518
    - 519
    - 520
    - 521
    - 522
    - 523
    - 524
    - 525
    - 526
    - 527
    - 528
    - 529
    - 530
    - 531
    - 532
    - 533
    - 534
    - 535
    - 536
    - 537
    - 538
    - 539
    - 540
    - 541
    - 542
    - 543
    - 544
    - 545
    - 546
    - 547
    - 548
    - 549
    - 550
    - 551
    - 552
    - 553
    - 554
    - 555
    - 556
    - 557
    - 558
    - 559
    - 560
    - 561
    - 562
    - 563
    - 564
    - 565
    - 566
    - 567
    - 568
    - 569
    - 570
    - 571
    - 572
    - 573
    - 574
    - 575
    - 576
    - 577
    - 578
    - 579
    - 580
    - 581
    - 582
    - 583
    - 584
    - 585
    - 586
    - 587
    - 588
    - 589
    - 590
    - 591
    - 592
    - 593
    - 594
    - 595
    - 596
    - 597
    - 598
    - 599
    - 600
    - 601
    - 602
    - 603
    - 604
    - 605
    - 606
    - 607
    - 608
    - 609
    - 610
    - 611
    - 612
    - 613
    - 614
    - 615
    - 616
    - 617
    - 618
    - 619
    - 620
    - 621
    - 622
    - 623
    - 624
    - 625
    - 626
    - 627
    - 628
    - 629
    - 630
    - 631
    - 632
    - 633
    - 634
    - 635
    - 636
    - 637
    - 638
    - 639
    - 640
    - 641
    - 642
    - 643
    - 644
    - 645
    - 646
    - 647
    - 648
    - 649
    - 650
    - 651
    - 652
    - 653
    - 654
    - 655
    - 656
    - 657
    - 658
    - 659
    - 660
    - 661
    - 662
    - 663
    - 664
    - 665
    - 666
    - 667
    - 668
    - 669
    - 670
    - 671
    - 672
    - 673
    - 674
    - 675
    - 676
    - 677
    - 678
    - 679
    - 680
    - 681
    - 682
    - 683
    - 684
    - 685
    - 686
    - 687
    - 688
    - 689
    - 690
    - 691
    - 692
    - 693
    - 694
    - 695
    - 696
    - 697
    - 698
    - 699
    - 700
    - 701
    - 702
    - 703
    - 704
    - 705
    - 706
    - 707
    - 708
    - 709
    - 710
    - 711
    - 712
    - 713
    - 714
    - 715
    - 716
    - 717
    - 718
    - 719
    - 720
    - 721
    - 722
    - 723
    - 724
    - 725
    - 726
    - 727
    - 728
    - 729
    - 730
    - 731
    - 732
    - 733
    - 734
    - 735
    - 736
    - 737
    - 738
    - 739
    - 740
    - 741
    - 742
    - 743
    - 744
    - 745
    - 746
    - 747
    - 748
    - 749
    - 750
    - 751
    - 752
    - 753
    - 754
    - 755
    - 756
    - 757
    - 758
    - 759
    - 760
    - 761
    - 762
    - 763
    - 764
    - 765
    - 766
    - 767
    - 768
    - 769
    - 770
    - 771
    - 772
    - 773
    - 774
    - 775
    - 776
    - 777
    - 778
    - 779
    - 780
    - 781
    - 782
    - 783
    - 784
    - 785
    - 786
    - 787
    - 788
    - 789
    - 790
    - 791
    - 792
    - 793
    - 794
    - 795
    - 796
    - 797
    - 798
    - 799
    - 800
    - 801
    - 802
    - 803
    - 804
    - 805
    - 806
    - 807
    - 808
    - 809
    - 810
    - 811
    - 812
    - 813
    - 814
    - 815
    - 816
    - 817
    - 818
    - 819
    - 820
    - 821
    - 822
    - 823
    - 824
    - 825
    - 826
    - 827
    - 828
    - 829
    - 830
    - 831
    - 832
    - 833
    - 834
    - 835
    - 836
    - 837
    - 838
    - 839
    - 840
    - 841
    - 842
    - 843
    - 844
    - 845
    - 846
    - 847
    - 848
    - 849
    - 850
    - 851
    - 852
    - 853
    - 854
    - 855
    - 856
    - 857
    - 858
    - 859
    - 860
    - 861
    - 862
    - 863
    - 864
    - 865
    - 866
    - 867
    - 868
    - 869
    - 870
    - 871
    - 872
    - 873
    - 874
    - 875
    - 876
    - 877
    - 878
    - 879
    - 880
    - 881
    - 882
    - 883
    - 884
    - 885
    - 886
    - 887
    - 888
    - 889
    - 890
    - 891
    - 892
    - 893
    - 894
    - 895
    - 896
    - 897
    - 898
    - 899
    - 900
    - 901
    - 902
    - 903
    - 904
    - 905
    - 906
    - 907
    - 908
    - 909
    - 910
    - 911
    - 912
    - 913
    - 914
    - 915
    - 916
    - 917
    - 918
    - 919
    - 920
    - 921
    - 922
    - 923
    - 924
    - 925
    - 926
    - 927
    - 928
    - 929
    - 930
    - 931
    - 932
    - 933
    - 934
    - 935
    - 936
    - 937
    - 938
    - 939
    - 940
    - 941
    - 942
    - 943
    - 944
    - 945
    - 946
    - 947
    - 948
    - 949
    - 950
    - 951
    - 952
    - 953
    - 954
    - 955
    - 956
    - 957
    - 958
    - 959
    - 960
    - 961
    - 962
    - 963
    - 964
    - 965
    - 966
    - 967
    - 968
    - 969
    - 970
    - 971
    - 972
    - 973
    - 974
    - 975
    - 976
    - 977
    - 978
    - 979
    - 980
    - 981
    - 982
    - 983
    - 984
    - 985
    - 986
    - 987
    - 988
    - 989
    - 990
    - 991
    - 992
    - 993
    - 994
    - 995
    - 996
    - 997
    - 998
    - 999
    -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
    -1028
    -1029
    -1030
    -1031
    -1032
    -1033
    -1034
    -1035
    -1036
    -1037
    -1038
    -1039
    -1040
    -1041
    -1042
    -1043
    -1044
    -1045
    -1046
    -1047
    -1048
    -1049
    -1050
    -1051
    -1052
    -1053
    -1054
    -1055
    -1056
    -1057
    -1058
    -1059
    -1060
    -1061
    -1062
    -1063
    -1064
    -1065
    -1066
    -1067
    -1068
    -1069
    -1070
    -1071
    -1072
    -1073
    -1074
    -1075
    -1076
    -1077
    -1078
    -1079
    -1080
    -1081
    -1082
    -1083
    -1084
    -1085
    -1086
    -1087
    -1088
    -1089
    -1090
    -1091
    -1092
    -1093
    -1094
    -1095
    -1096
    -1097
    -1098
    -1099
    -1100
    -1101
    -1102
    -1103
    -1104
    -1105
    -1106
    -1107
    -1108
    -1109
    -1110
    -1111
    -1112
    -1113
    -1114
    -1115
    -1116
    -1117
    -1118
    -1119
    -1120
    -1121
    -1122
    -1123
    -1124
    -1125
    -1126
    -1127
    -1128
    -1129
    -1130
    -1131
    -1132
    -1133
    -1134
    -1135
    -1136
    -1137
    -1138
    -1139
    -1140
    -1141
    -1142
    -1143
    -1144
    -1145
    -1146
    -1147
    -1148
    -1149
    -1150
    -1151
    -1152
    -1153
    -1154
    -1155
    -1156
    -1157
    -1158
    -1159
    -1160
    -1161
    -1162
    -1163
    -1164
    -1165
    -1166
    -1167
    -1168
    -1169
    -1170
    -1171
    -1172
    -1173
    -1174
    -1175
    -1176
    -1177
    -1178
    -1179
    -1180
    -1181
    -1182
    -1183
    -1184
    -1185
    -1186
    -1187
    -1188
    -1189
    -1190
    -1191
    -1192
    -1193
    -1194
    -1195
    -1196
    -1197
    -1198
    -1199
    -1200
    -1201
    -1202
    -1203
    -1204
    -1205
    -1206
    -1207
    -1208
    -1209
    -1210
    -1211
    -1212
    -1213
    -1214
    -1215
    -1216
    -1217
    -1218
    -1219
    -1220
    -1221
    -1222
    -1223
    -1224
    -1225
    -1226
    -1227
    -1228
    -1229
    -1230
    -1231
    -1232
    -1233
    -1234
    -1235
    -1236
    -1237
    -1238
    -1239
    -1240
    -1241
    -1242
    -1243
    -1244
    -1245
    -1246
    -1247
    -1248
    -1249
    -1250
    -1251
    -1252
    -1253
    -1254
    -1255
    -1256
    -1257
    -1258
    -1259
    -1260
    -1261
    -1262
    -1263
    -1264
    -1265
    -1266
    -1267
    -1268
    -1269
    -1270
    -1271
    -1272
    -1273
    -1274
    -1275
    -1276
    -1277
    -1278
    -1279
    -1280
    -1281
    -1282
    -1283
    -1284
    -1285
    -1286
    -1287
    -1288
    -1289
    -1290
    -1291
    -1292
    -1293
    -1294
    -1295
    -1296
    -1297
    -1298
    -1299
    -1300
    -1301
    -1302
    -1303
    -1304
    -1305
    -1306
    -1307
    -1308
    -1309
    -1310
    -1311
    -1312
    -1313
    -1314
    -1315
    -1316
    -1317
    -1318
    -1319
    -1320
    -1321
    -1322
    -1323
    -1324
    -1325
    -1326
    -1327
    -1328
    -1329
    -1330
    -1331
    -1332
    -1333
    -1334
    -1335
    -1336
    -1337
    -1338
    -1339
    -1340
    -1341
    -1342
    -1343
    -1344
    -1345
    -1346
    -1347
    -1348
    -1349
    -1350
    -1351
    -1352
    -1353
    -1354
    -1355
    -1356
    -1357
    -1358
    -1359
    -1360
    -1361
    -1362
    -1363
    -1364
    -1365
    -1366
    -1367
    -1368
    -1369
    -1370
    -1371
    -1372
    -1373
    -1374
    -1375
    -1376
    -1377
    -1378
    -1379
    -1380
    -1381
    -1382
    -1383
    -1384
    -1385
    -1386
    -1387
    -1388
    -1389
    -1390
    -1391
    -1392
    -1393
    -1394
    -1395
    -1396
    -1397
    -1398
    -1399
    -1400
    -1401
    -1402
    -1403
    -1404
    -1405
    -1406
    -1407
    -1408
    -1409
    -1410
    -1411
    -1412
    -1413
    -1414
    -1415
    -1416
    -1417
    -1418
    -1419
    -1420
    -1421
    -1422
    -1423
    -1424
    -1425
    -1426
    -1427
    -1428
    -1429
    -1430
    -1431
    -1432
    -1433
    -1434
    -1435
    -1436
    -1437
    -1438
    -1439
    -1440
    -1441
    -1442
    -1443
    -1444
    -1445
    -1446
    -1447
    -1448
    -1449
    -1450
    -1451
    -1452
    -1453
    -1454
    -1455
    -1456
    -1457
    -1458
    -1459
    -1460
    -1461
    -1462
    -1463
    -1464
    -1465
    -1466
    -1467
    -1468
    -1469
    -1470
    -1471
    -1472
    -1473
    -1474
    -1475
    -1476
    -1477
    -1478
    -1479
    -1480
    -1481
    -1482
    -1483
    -1484
    -1485
    -1486
    -1487
    -1488
    -1489
    -1490
    -1491
    -1492
    -1493
    -1494
    -1495
    -1496
    -1497
    -1498
    -1499
    -1500
    -1501
    -1502
    -1503
    -1504
    -1505
    -1506
    -1507
    -1508
    -1509
    -1510
    -1511
    -1512
    -1513
    -1514
    -1515
    -1516
    -1517
    -1518
    -1519
    -1520
    -1521
    -1522
    -1523
    -1524
    -1525
    -1526
    -1527
    -1528
    -1529
    -1530
    -1531
    -1532
    -1533
    -1534
    -1535
    -1536
    -1537
    -1538
    -1539
    -1540
    -1541
    -1542
    -1543
    -1544
    -1545
    -1546
    -1547
    -1548
    -1549
    -1550
    -1551
    -1552
    -1553
    -1554
    -1555
    -1556
    -1557
    -1558
    -1559
    -1560
    -1561
    -1562
    -1563
    -1564
    -1565
    -1566
    -1567
    -1568
    -1569
    -1570
    -1571
    -1572
    -1573
    -1574
    -1575
    -1576
    -1577
    -1578
    -1579
    -1580
    -1581
    -1582
    -1583
    -1584
    -1585
    -1586
    -1587
    -1588
    -1589
    -1590
    -1591
    -1592
    -1593
    -1594
    -1595
    -1596
    -1597
    -1598
    -1599
    -1600
    -1601
    -1602
    -1603
    -1604
    -1605
    -1606
    -1607
    -1608
    -1609
    -1610
    -1611
    -1612
    -1613
    -1614
    -1615
    -1616
    -1617
    -1618
    -1619
    -1620
    -1621
    -1622
    -1623
    -1624
    -1625
    -1626
    -1627
    -1628
    -1629
    -1630
    -1631
    -1632
    -1633
    -1634
    -1635
    -1636
    -1637
    -1638
    -1639
    -1640
    -1641
    -1642
    -1643
    -1644
    -1645
    -1646
    -1647
    -1648
    -1649
    -1650
    -1651
    -1652
    -1653
    -1654
    -1655
    -1656
    -1657
    -1658
    -1659
    -1660
    -1661
    -1662
    -1663
    -1664
    -1665
    -1666
    -1667
    -1668
    -1669
    -1670
    -1671
    -1672
    -1673
    -1674
    -1675
    -1676
    -1677
    -1678
    -1679
    -1680
    -1681
    -1682
    -1683
    -1684
    -1685
    -1686
    -1687
    -1688
    -1689
    -1690
    -1691
    -1692
    -1693
    -1694
    -1695
    -1696
    -1697
    -1698
    -1699
    -1700
    -1701
    -1702
    -1703
    -1704
    -1705
    -1706
    -1707
    -1708
    -1709
    -1710
    -1711
    -1712
    -1713
    -1714
    -1715
    -1716
    -1717
    -1718
    -1719
    -1720
    -1721
    -1722
    -1723
    -1724
    -1725
    -1726
    -1727
    -1728
    -1729
    -1730
    -1731
    -1732
    -1733
    -1734
    -1735
    -1736
    -1737
    -1738
    -1739
    -1740
    -1741
    -1742
    -1743
    -1744
    -1745
    -1746
    -1747
    -1748
    -1749
    -1750
    -1751
    -1752
    -1753
    -1754
    -1755
    -1756
    -1757
    -1758
    -1759
    -1760
    -1761
    -1762
    -1763
    -1764
    -1765
    -1766
    -1767
    -1768
    -1769
    -1770
    -1771
    -1772
    -1773
    -1774
    -1775
    -1776
    -1777
    -1778
    -1779
    -1780
    -1781
    -1782
    -1783
    -1784
    -1785
    -1786
    -1787
    -1788
    -1789
    -1790
    -1791
    -1792
    -1793
    -1794
    -1795
    -1796
    -1797
    -1798
    -1799
    -1800
    -1801
    -1802
    -1803
    -1804
    -1805
    -1806
    -1807
    -1808
    -1809
    -1810
    -1811
    -1812
    -1813
    -1814
    -1815
    -1816
    -1817
    -1818
    -1819
    -1820
    -1821
    -1822
    -1823
    -1824
    -1825
    -1826
    -1827
    -1828
    -1829
    -1830
    -1831
    -1832
    -1833
    -1834
    -1835
    -1836
    -1837
    -1838
    -1839
    -1840
    -1841
    -1842
    -1843
    -1844
    -1845
    -1846
    -1847
    -1848
    -1849
    -1850
    -1851
    -1852
    -1853
    -1854
    -1855
    -1856
    -1857
    -1858
    -1859
    -1860
    -1861
    -1862
    -1863
    -1864
    -1865
    -1866
    -1867
    -1868
    -1869
    -1870
    -1871
    -1872
    -1873
    -1874
    -1875
    -1876
    -1877
    -1878
    -1879
    -1880
    -1881
    -1882
    -1883
    -1884
    -1885
    -1886
    -1887
    -1888
    -1889
    -1890
    -1891
    -1892
    -1893
    -1894
    -1895
    -1896
    -1897
    -1898
    -1899
    -1900
    -1901
    -1902
    -1903
    -1904
    -1905
    -1906
    -1907
    -1908
    -1909
    -1910
    -1911
    -1912
    -1913
    -1914
    -1915
    -1916
    -1917
    -1918
    -1919
    -1920
    -1921
    -1922
    -1923
    -1924
    -1925
    -1926
    -1927
    -1928
    -1929
    -1930
    -1931
    -1932
    -1933
    -1934
    -1935
    -1936
    -1937
    -1938
    -1939
    -1940
    -1941
    -1942
    -1943
    -1944
    -1945
    -1946
    -1947
    -1948
    -1949
    -1950
    -1951
    -1952
    -1953
    -1954
    -1955
    -1956
    -1957
    -1958
    -1959
    -1960
    -1961
    -1962
    -1963
    -1964
    -1965
    -1966
    -1967
    -1968
    -1969
    -1970
    -1971
    -1972
    -1973
    -1974
    -1975
    -1976
    -1977
    -1978
    -1979
    -1980
    -1981
    -1982
    -1983
    -1984
    -1985
    -1986
    -1987
    -1988
    -1989
    -1990
    -1991
    -1992
    -1993
    -1994
    -1995
    -1996
    -1997
    -1998
    -1999
    -2000
    -2001
    -2002
    -2003
    -2004
    -2005
    -2006
    -2007
    -2008
    -2009
    -2010
    -2011
    -2012
    -2013
    -2014
    -2015
    -2016
    -2017
    -2018
    -2019
    -2020
    -2021
    -2022
    -2023
    -2024
    -2025
    -2026
    -2027
    -2028
    -2029
    -2030
    -2031
    -2032
    -2033
    -2034
    -2035
    -2036
    -2037
    -2038
    -2039
    -2040
    -2041
    -2042
    -2043
    -2044
    -2045
    -2046
    -2047
    -2048
    -2049
    -2050
    -2051
    -2052
    -2053
    -2054
    -2055
    -2056
    -2057
    -2058
    -2059
    -2060
    -2061
    -2062
    -2063
    -2064
    -2065
    -2066
    -2067
    -2068
    -2069
    -2070
    -2071
    -2072
    -2073
    -2074
    -2075
    -2076
    -2077
    -2078
    -2079
    -2080
    -2081
    -2082
    -2083
    -2084
    -2085
    -2086
    -2087
    -2088
    -2089
    -2090
    -2091
    -2092
    -2093
    -2094
    -2095
    -2096
    -2097
    -2098
    -2099
    -2100
    -2101
    -2102
    -2103
    -2104
    -2105
    -2106
    -2107
    -2108
    -2109
    -2110
    -2111
    -2112
    -2113
    -2114
    -2115
    -2116
    -2117
    -2118
    -2119
    -2120
    -2121
    -2122
    -2123
    -2124
    -2125
    -2126
    -2127
    -2128
    -2129
    -2130
    -2131
    -2132
    -2133
    -2134
    -2135
    -2136
    -2137
    -2138
    -2139
    -2140
    -2141
    -2142
    -2143
    -2144
    -2145
    -2146
    -2147
    -2148
    -2149
    -2150
    -2151
    -2152
    -2153
    -2154
    -2155
    -2156
    -2157
    -2158
    -2159
    -2160
    -2161
    -2162
    -2163
    -2164
    -2165
    -2166
    -2167
    -2168
    -2169
    -2170
    -2171
    -2172
    -2173
    -2174
    -2175
    -2176
    -2177
    -2178
    -2179
    -2180
    -2181
    -2182
    -2183
    -2184
    -2185
    -2186
    -2187
    -2188
    -2189
    -2190
    -2191
    -2192
    -2193
    -2194
    -2195
    -2196
    -2197
    -2198
    -2199
    -2200
    -2201
    -2202
    -2203
    -2204
    -2205
    -2206
    -2207
    -2208
    -2209
    -2210
    -2211
    -2212
    -2213
    -2214
    -2215
    -2216
    -2217
    -2218
    -2219
    -2220
    -2221
    -2222
    -2223
    -2224
    -2225
    -2226
    -2227
    -2228
    -2229
    -2230
    -2231
    -2232
    -2233
    -2234
    -2235
    -2236
    -2237
    -2238
    -2239
    -2240
    -2241
    -2242
    -2243
    -2244
    -2245
    -2246
    -2247
    -2248
    -2249
    -2250
    -2251
    -2252
    -2253
    -2254
    -2255
    -2256
    -2257
    -2258
    -2259
    -2260
    -2261
    -2262
    -2263
    -2264
    -2265
    -2266
    -2267
    -2268
    -2269
    -2270
    -2271
    -2272
    -2273
    -2274
    -2275
    -2276
    -2277
    -2278
    -2279
    -2280
    -2281
    -2282
    -2283
    -2284
    -2285
    -2286
    -2287
    -2288
    -2289
    -2290
    -2291
    -2292
    -2293
    -2294
    -2295
    -2296
    -2297
    -2298
    -2299
    -2300
    -2301
    -2302
    -2303
    -2304
    -2305
    -2306
    -2307
    -2308
    -2309
    -2310
    -2311
    -2312
    -2313
    -2314
    -2315
    -2316
    -2317
    -2318
    -2319
    -2320
    -2321
    -2322
    -2323
    -2324
    -2325
    -2326
    -2327
    -2328
    -2329
    -2330
    -2331
    -2332
    -2333
    -2334
    -2335
    -2336
    -2337
    -2338
    -2339
    -2340
    -2341
    -2342
    -2343
    -2344
    -2345
    -2346
    -2347
    -2348
    -2349
    -2350
    -2351
    -2352
    -2353
    -2354
    -2355
    -2356
    -2357
    -2358
    -2359
    -2360
    -2361
    -2362
    -2363
    -2364
    -2365
    -2366
    -2367
    -2368
    -2369
    -2370
    -2371
    -2372
    -2373
    -2374
    -2375
    -2376
    -2377
    -2378
    -2379
    -2380
    -2381
    -2382
    -2383
    -2384
    -2385
    -2386
    -2387
    -2388
    -2389
    -2390
    -2391
    -2392
    -2393
    -2394
    -2395
    -2396
    -2397
    -2398
    -2399
    -2400
    -2401
    -2402
    -2403
    -2404
    -2405
    -2406
    -2407
    -2408
    -2409
    -2410
    -2411
    -2412
    -2413
    -2414
    -2415
    -2416
    -2417
    -2418
    -2419
    -2420
    -2421
    -2422
    -2423
    -2424
    -2425
    -2426
    -2427
    -2428
    -2429
    -2430
    -2431
    -2432
    -2433
    -2434
    -2435
    -2436
    -2437
    -2438
    -2439
    -2440
    -2441
    -2442
    -2443
    -2444
    -2445
    -2446
    -2447
    -2448
    -2449
    -2450
    -2451
    -2452
    -2453
    -2454
    -2455
    -2456
    -2457
    -2458
    -2459
    -2460
    -2461
    -2462
    -2463
    -2464
    -2465
    -2466
    -2467
    -2468
    -2469
    -2470
    -2471
    -2472
    -2473
    -2474
    -2475
    -2476
    -2477
    -2478
    -2479
    -2480
    -2481
    -2482
    -2483
    -2484
    -2485
    -2486
    -2487
    -2488
    -2489
    -2490
    -2491
    -2492
    -2493
    -2494
    -2495
    -2496
    -2497
    -2498
    -2499
    -2500
    -2501
    -2502
    -2503
    -2504
    -2505
    -2506
    -2507
    -2508
    -2509
    -2510
    -2511
    -2512
    -2513
    -2514
    -2515
    -2516
    -2517
    -2518
    -2519
    -2520
    -2521
    -2522
    -2523
    -2524
    -2525
    -2526
    -2527
    -2528
    -2529
    -2530
    -2531
    -2532
    -2533
    -2534
    -2535
    -2536
    -2537
    -2538
    -2539
    -2540
    -2541
    -2542
    -2543
    -2544
    -2545
    -2546
    -2547
    -2548
    -2549
    -2550
    -2551
    -2552
    -2553
    -2554
    -2555
    -2556
    -2557
    -2558
    -2559
    -2560
    -2561
    -2562
    -2563
    -2564
    -2565
    -2566
    -2567
    -2568
    -2569
    -2570
    -2571
    -2572
    -2573
    -2574
    -2575
    -2576
    -2577
    -2578
    -2579
    -2580
    -2581
    -2582
    -2583
    -2584
    -2585
    -2586
    -2587
    -2588
    -2589
    -2590
    -2591
    -2592
    -2593
    -2594
    -2595
    -2596
    -2597
    -2598
    -2599
    -2600
    -2601
    -2602
    -2603
    -2604
    -2605
    -2606
    -2607
    -2608
    -2609
    -2610
    -2611
    -2612
    -2613
    -2614
    -2615
    -2616
    -2617
    -2618
    -2619
    -2620
    -2621
    -2622
    -2623
    -2624
    -2625
    -2626
    -2627
    -2628
    -2629
    -2630
    -2631
    -2632
    -2633
    -2634
    -2635
    -2636
    -2637
    -2638
    -2639
    -2640
    -2641
    -2642
    -2643
    -2644
    -2645
    -2646
    -2647
    -2648
    -2649
    -2650
    -2651
    -2652
    -2653
    -2654
    -2655
    -2656
    -2657
    -2658
    -2659
    -2660
    -2661
    -2662
    -2663
    -2664
    -2665
    -2666
    -2667
    -2668
    -2669
    -2670
    -2671
    -2672
    -2673
    -2674
    -2675
    -2676
    -2677
    -2678
    -2679
    -2680
    -2681
    -2682
    -2683
    -2684
    -2685
    -2686
    -2687
    -2688
    -2689
    -2690
    -2691
    -2692
    -2693
    -2694
    -2695
    -2696
    -2697
    -2698
    -2699
    -2700
    -2701
    -2702
    -2703
    -2704
    -2705
    -2706
    -2707
    -2708
    -2709
    -2710
    -2711
    -2712
    -2713
    -2714
    -2715
    -2716
    -2717
    -2718
    -2719
    -2720
    -2721
    -2722
    -2723
    -2724
    -2725
    -2726
    -2727
    -2728
    -2729
    -2730
    -2731
    -2732
    -2733
    -2734
    -2735
    -2736
    -2737
    -2738
    -2739
    -2740
    -2741
    -2742
    -2743
    -2744
    -2745
    -2746
    -2747
    -2748
    -2749
    -2750
    -2751
    -2752
    -2753
    -2754
    -2755
    -2756
    -2757
    -2758
    -2759
    -2760
    -2761
    -2762
    -2763
    -2764
    -2765
    -2766
    -2767
    -2768
    -2769
    -2770
    -2771
    -2772
    -2773
    -2774
    -2775
    -2776
    -2777
    -2778
    -2779
    -2780
    -2781
    -2782
    -2783
    -2784
    -2785
    -2786
    -2787
    -2788
    -2789
    -2790
    -2791
    -2792
    -2793
    -2794
    -2795
    -2796
    -2797
    -2798
    -2799
    -2800
    -2801
    -2802
    -2803
    -2804
    -2805
    -2806
    -2807
    -2808
    -2809
    -2810
    -2811
    -2812
    -2813
    -2814
    -2815
    -2816
    -2817
    -2818
    -2819
    -2820
    -2821
    -2822
    -2823
    -2824
    -2825
    -2826
    -2827
    -2828
    -2829
    -2830
    -2831
    -2832
    -2833
    -2834
    -2835
    -2836
    -2837
    -2838
    -2839
    -2840
    -2841
    -2842
    -2843
    -2844
    -2845
    -2846
    -2847
    -2848
    -2849
    -2850
    -2851
    -2852
    -2853
    -2854
    -2855
    -2856
    -2857
    -2858
    -2859
    -2860
    -2861
    -2862
    -2863
    -2864
    -2865
    -2866
    -2867
    -2868
    -2869
    -2870
    -2871
    -2872
    -2873
    -2874
    -2875
    -2876
    -2877
    -2878
    -2879
    -2880
    -2881
    -2882
    -2883
    -2884
    -2885
    -2886
    -2887
    -2888
    -2889
    -2890
    -2891
    -2892
    -2893
    -2894
    -2895
    -2896
    -2897
    -2898
    -2899
    -2900
    -2901
    -2902
    -2903
    -2904
    -2905
    -2906
    -2907
    -2908
    -2909
    -2910
    -2911
    -2912
    -2913
    -2914
    -2915
    -2916
    -2917
    -2918
    -2919
    -2920
    -2921
    -2922
    -2923
    -2924
    -2925
    -2926
    -2927
    -2928
    -2929
    -2930
    -2931
    -2932
    -2933
    -2934
    -2935
    -2936
    -2937
    -2938
    -2939
    -2940
    -2941
    -2942
    -2943
    -2944
    -2945
    -2946
    -2947
    -2948
    -2949
    -2950
    -2951
    -2952
    -2953
    -2954
    -2955
    -2956
    -2957
    -2958
    -2959
    -2960
    -2961
    -2962
    -2963
    -2964
    -2965
    -2966
    -2967
    -2968
    -2969
    -2970
    -2971
    -2972
    -2973
    -2974
    -2975
    -2976
    -2977
    -2978
    -2979
    -2980
    -2981
    -2982
    -2983
    -2984
    -2985
    -2986
    -2987
    -2988
    -2989
    -2990
    -2991
    -2992
    -2993
    -2994
    -2995
    -2996
    -2997
    -2998
    -2999
    -3000
    -3001
    -3002
    -3003
    -3004
    -3005
    -3006
    -3007
    -3008
    -3009
    -3010
    -3011
    -3012
    -3013
    -3014
    -3015
    -3016
    -3017
    -3018
    -3019
    -3020
    -3021
    -3022
    -3023
    -3024
    -3025
    -3026
    -3027
    -3028
    -3029
    -3030
    -3031
    -3032
    -3033
    -3034
    -3035
    -3036
    -3037
    -3038
    -3039
    -3040
    -3041
    -3042
    -3043
    -3044
    -3045
    -3046
    -3047
    -3048
    -3049
    -3050
    -3051
    -3052
    -3053
    -3054
    -3055
    -3056
    -3057
    -3058
    -3059
    -3060
    -3061
    -3062
    -3063
    -3064
    -3065
    -3066
    -3067
    -3068
    -3069
    -3070
    -3071
    -3072
    -3073
    -3074
    -3075
    -3076
    -3077
    -3078
    -3079
    -3080
    -3081
    -3082
    -3083
    -3084
    -3085
    -3086
    -3087
    -3088
    -3089
    -3090
    -3091
    -3092
    -3093
    -3094
    -3095
    -3096
    -3097
    -3098
    -3099
    -3100
    -3101
    -3102
    -3103
    -3104
    -3105
    -3106
    -3107
    -3108
    -3109
    -3110
    -3111
    -3112
    -3113
    -3114
    -3115
    -3116
    -3117
    -3118
    -3119
    -3120
    -3121
    -3122
    -3123
    -3124
    -3125
    -3126
    -3127
    -3128
    -3129
    -3130
    -3131
    -3132
    -3133
    -3134
    -3135
    -3136
    -3137
    -3138
    -3139
    -3140
    -3141
    -3142
    -3143
    -3144
    -3145
    -3146
    -3147
    -3148
    -3149
    -3150
    -3151
    -3152
    -3153
    -3154
    -3155
    -3156
    -3157
    -3158
    -3159
    -3160
    -3161
    -3162
    -3163
    -3164
    -3165
    -3166
    -3167
    -3168
    -3169
    -3170
    -3171
    -3172
    -3173
    -3174
    -3175
    -3176
    -3177
    -3178
    -3179
    -3180
    -3181
    -3182
    -3183
    -3184
    -3185
    -3186
    -3187
    -3188
    -3189
    -3190
    -3191
    -3192
    -3193
    -3194
    -3195
    -3196
    -3197
    -3198
    -3199
    -3200
    -3201
    -3202
    -3203
    -3204
    -3205
    -3206
    -3207
    -3208
    -3209
    -3210
    -3211
    -3212
    -3213
    -3214
    -3215
    -3216
    -3217
    -3218
    -3219
    -3220
    -3221
    -3222
    -3223
    -3224
    -3225
    -3226
    -3227
    -3228
    -3229
    -3230
    -3231
    -3232
    -3233
    -3234
    -3235
    -3236
    -3237
    -3238
    -3239
    -3240
    -3241
    -3242
    -3243
    -3244
    -3245
    -3246
    -3247
    -3248
    -3249
    -3250
    -3251
    -3252
    -3253
    -3254
    -3255
    -3256
    -3257
    -3258
    -3259
    -3260
    -3261
    -3262
    -3263
    -3264
    -3265
    -3266
    -3267
    -3268
    -3269
    -3270
    -3271
    -3272
    -3273
    -3274
    -3275
    -3276
    -3277
    -3278
    -3279
    -3280
    -3281
    -3282
    -3283
    -3284
    -3285
    -3286
    -3287
    -3288
    -3289
    -3290
    -3291
    -3292
    -3293
    -3294
    -3295
    -3296
    -3297
    -3298
    -3299
    -3300
    -3301
    -3302
    -3303
    -3304
    -3305
    -3306
    -3307
    -3308
    -3309
    -3310
    -3311
    -3312
    -3313
    -3314
    -3315
    -3316
    -3317
    -3318
    -3319
    -3320
    -3321
    -3322
    -3323
    -3324
    -3325
    -3326
    -3327
    -3328
    -3329
    -3330
    -3331
    -3332
    -3333
    -3334
    -3335
    -3336
    -3337
    -3338
    -3339
    -3340
    -3341
    -3342
    -3343
    -3344
    -3345
    -3346
    -3347
    -3348
    -3349
    -3350
    -3351
    -3352
    -3353
    -3354
    -3355
    -3356
    -3357
    -3358
    -3359
    -3360
    -3361
    -3362
    -3363
    -3364
    -3365
    -3366
    -3367
    -3368
    -3369
    -3370
    -3371
    -3372
    -3373
    -3374
    -3375
    -3376
    -3377
    -3378
    -3379
    -3380
    -3381
    -3382
    -3383
    -3384
    -3385
    -3386
    -3387
    -3388
    -3389
    -3390
    -3391
    -3392
    -3393
    -3394
    -3395
    -3396
    -3397
    -3398
    -3399
    -3400
    -3401
    -3402
    -3403
    -3404
    -3405
    -3406
    -3407
    -3408
    -3409
    -3410
    -3411
    -3412
    -3413
    -3414
    -3415
    -3416
    -3417
    -3418
    -3419
    -3420
    -3421
    -3422
    -3423
    -3424
    -3425
    -3426
    -3427
    -3428
    -3429
    -3430
    -3431
    -3432
    -3433
    -3434
    -3435
    -3436
    -3437
    -3438
    -3439
    -3440
    -3441
    -3442
    -3443
    -3444
    -3445
    -3446
    -3447
    -3448
    -3449
    -3450
    -3451
    -3452
    -3453
    -3454
    -3455
    -3456
    -3457
    -3458
    -3459
    -3460
    -3461
    -3462
    -3463
    -3464
    -3465
    -3466
    -3467
    -3468
    -3469
    -3470
    -3471
    -3472
    -3473
    -3474
    -3475
    -3476
    -3477
    -3478
    -3479
    -3480
    -3481
    -3482
    -3483
    -3484
    -3485
    -3486
    -3487
    -3488
    -3489
    -3490
    -3491
    -3492
    -3493
    -3494
    -3495
    -3496
    -3497
    -3498
    -3499
    -3500
    -3501
    -3502
    -3503
    -3504
    -3505
    -3506
    -3507
    -3508
    -3509
    -3510
    -3511
    -3512
    -3513
    -3514
    -3515
    -3516
    -3517
    -3518
    -3519
    -3520
    -3521
    -3522
    -3523
    -3524
    -3525
    -3526
    -3527
    -3528
    -3529
    -3530
    -3531
    -3532
    -3533
    -3534
    -3535
    -3536
    -3537
    -3538
    -3539
    -3540
    -3541
    -3542
    -3543
    -3544
    -3545
    -3546
    -3547
    -3548
    -3549
    -3550
    -3551
    -3552
    -3553
    -3554
    -3555
    -3556
    -3557
    -3558
    -3559
    -3560
    -3561
    -3562
    -3563
    -3564
    -3565
    -3566
    -3567
    -3568
    -3569
    -3570
    -3571
    -3572
    -3573
    -3574
    -3575
    -3576
    -3577
    -3578
    -3579
    -3580
    -3581
    -3582
    -3583
    -3584
    -3585
    -3586
    -3587
    -3588
    -3589
    -3590
    -3591
    -3592
    -3593
    -3594
    -3595
    -3596
    -3597
    -3598
    -3599
    -3600
    -3601
    -3602
    -3603
    -3604
    -3605
    -3606
    -3607
    -3608
    -3609
    -3610
    -3611
    -3612
    -3613
    -3614
    -3615
    -3616
    -3617
    -3618
    -3619
    -3620
    -3621
    -3622
    -3623
    -3624
    -3625
    -3626
    -3627
    -3628
    -3629
    -3630
    -3631
    -3632
    -3633
    -3634
    -3635
    -3636
    -3637
    -3638
    -3639
    -3640
    -3641
    -3642
    -3643
    -3644
    -3645
    -3646
    -3647
    -3648
    -3649
    -3650
    -3651
    -3652
    -3653
    -3654
    -3655
    -3656
    -3657
    -3658
    -3659
    -3660
    -3661
    -3662
    -3663
    -3664
    -3665
    -3666
    -3667
    -3668
    -3669
    -3670
    -3671
    -3672
    -3673
    -3674
    -3675
    -3676
    -3677
    -3678
    -3679
    -3680
    -3681
    -3682
    -3683
    -3684
    -3685
    -3686
    -3687
    -3688
    -3689
    -3690
    -3691
    -3692
    -3693
    -3694
    -3695
    -3696
    -3697
    -3698
    -3699
    -3700
    -3701
    -3702
    -3703
    -3704
    -3705
    -3706
    -3707
    -3708
    -3709
    -3710
    -3711
    -3712
    -3713
    -3714
    -3715
    -3716
    -3717
    -3718
    -3719
    -3720
    -3721
    -3722
    -3723
    -3724
    -3725
    -3726
    -3727
    -3728
    -3729
    -3730
    -3731
    -3732
    -3733
    -3734
    -3735
    -3736
    -3737
    -3738
    -3739
    -3740
    -3741
    -3742
    -3743
    -3744
    -3745
    -3746
    -3747
    -3748
    -3749
    -3750
    -3751
    -3752
    -3753
    -3754
    -3755
    -3756
    -3757
    -3758
    -3759
    -3760
    -3761
    -3762
    -3763
    -3764
    -3765
    -3766
    -3767
    -3768
    -3769
    -3770
    -3771
    -3772
    -3773
    -3774
    -3775
    -3776
    -3777
    -3778
    -3779
    -3780
    -3781
    -3782
    -3783
    -3784
    -3785
    -3786
    -3787
    -3788
    -3789
    -3790
    -3791
    -3792
    -3793
    -3794
    -3795
    -3796
    -3797
    -3798
    -3799
    -3800
    -3801
    -3802
    -3803
    -3804
    -3805
    -3806
    -3807
    -3808
    -3809
    -3810
    -3811
    -3812
    -3813
    -3814
    -3815
    -3816
    -3817
    -3818
    -3819
    -3820
    -3821
    -3822
    -3823
    -3824
    -3825
    -3826
    -3827
    -3828
    -3829
    -3830
    -3831
    -3832
    -3833
    -3834
    -3835
    -3836
    -3837
    -3838
    -3839
    -3840
    -3841
    -3842
    -3843
    -3844
    -3845
    -3846
    -3847
    -3848
    -3849
    -3850
    -3851
    -3852
    -3853
    -3854
    -3855
    -3856
    -3857
    -3858
    -3859
    -3860
    -3861
    -3862
    -3863
    -3864
    -3865
    -3866
    -3867
    -3868
    -3869
    -3870
    -3871
    -3872
    -3873
    -3874
    -3875
    -3876
    -3877
    -3878
    -3879
    -3880
    -3881
    -3882
    -3883
    -3884
    -3885
    -3886
    -3887
    -3888
    -3889
    -3890
    -3891
    -3892
    -3893
    -3894
    -3895
    -3896
    -3897
    -3898
    -3899
    -3900
    -3901
    -3902
    -3903
    -3904
    -3905
    -3906
    -3907
    -3908
    -3909
    -3910
    -3911
    -3912
    -3913
    -3914
    -3915
    -3916
    -3917
    -3918
    -3919
    -3920
    -3921
    -3922
    -3923
    -3924
    -3925
    -3926
    -3927
    -3928
    -3929
    -3930
    -3931
    -3932
    -3933
    -3934
    -3935
    -3936
    -3937
    -3938
    -3939
    -3940
    -3941
    -3942
    -3943
    -3944
    -3945
    -3946
    -3947
    -3948
    -3949
    -3950
    -3951
    -3952
    -3953
    -3954
    -3955
    -3956
    -3957
    -3958
    -3959
    -3960
    -3961
    -3962
    -3963
    -3964
    -3965
    -3966
    -3967
    -3968
    -3969
    -3970
    -3971
    -3972
    -3973
    -3974
    -3975
    -3976
    -3977
    -3978
    -3979
    -3980
    -3981
    -3982
    -3983
    -3984
    -3985
    -3986
    -3987
    -3988
    -3989
    -3990
    -3991
    -3992
    -3993
    -3994
    -3995
    -3996
    -3997
    -3998
    -3999
    -4000
    -4001
    -4002
    -4003
    -4004
    -4005
    -4006
    -4007
    -4008
    -4009
    -4010
    -4011
    -4012
    -4013
    -4014
    -4015
    -4016
    -4017
    -4018
    -4019
    -4020
    -4021
    -4022
    -4023
    -4024
    -4025
    -4026
    -4027
    -4028
    -4029
    -4030
    -4031
    -4032
    -4033
    -4034
    -4035
    -4036
    -4037
    -4038
    -4039
    -4040
    -4041
    -4042
    -4043
    -4044
    -4045
    -4046
    -4047
    -4048
    -4049
    -4050
    -4051
    -4052
    -4053
    -4054
    -4055
    -4056
    -4057
    -4058
    -4059
    -4060
    -4061
    -4062
    -4063
    -4064
    -4065
    -4066
    -4067
    -4068
    -4069
    -4070
    -4071
    -4072
    -4073
    -4074
    -4075
    -4076
    -4077
    -4078
    -4079
    -4080
    -4081
    -4082
    -4083
    -4084
    -4085
    -4086
    -4087
    -4088
    -4089
    -4090
    -4091
    -4092
    -4093
    -4094
    -4095
    -4096
    -4097
    -4098
    -4099
    -4100
    -4101
    -4102
    -4103
    -4104
    -4105
    -4106
    -4107
    -4108
    -4109
    -4110
    -4111
    -4112
    -4113
    -4114
    -4115
    -4116
    -4117
    -4118
    -4119
    -4120
    -4121
    -4122
    -4123
    -4124
    -4125
    -4126
    -4127
    -4128
    -4129
    -4130
    -4131
    -4132
    -4133
    -4134
    -4135
    -4136
    -4137
    -4138
    -4139
    -4140
    -4141
    -4142
    -4143
    -4144
    -4145
    -4146
    -4147
    -4148
    -4149
    -4150
    -4151
    -4152
    -4153
    -4154
    -4155
    -4156
    -4157
    -4158
    -4159
    -4160
    -4161
    -4162
    -4163
    -4164
    -4165
    -4166
    -4167
    -4168
    -4169
    -4170
    -4171
    -4172
    -4173
    -4174
    -4175
    -4176
    -4177
    -4178
    -4179
    -4180
    -4181
    -4182
    -4183
    -4184
    -4185
    -4186
    -4187
    -4188
    -4189
    -4190
    -4191
    -4192
    -4193
    -4194
    -4195
    -4196
    -4197
    -4198
    -4199
    -4200
    -4201
    -4202
    -4203
    -4204
    -4205
    -4206
    -4207
    -4208
    -4209
    -4210
    -4211
    -4212
    -4213
    -4214
    -4215
    -4216
    -4217
    -4218
    -4219
    -4220
    -4221
    -4222
    -4223
    -4224
    -4225
    -4226
    -4227
    -4228
    -4229
    -4230
    -4231
    -4232
    -4233
    -4234
    -4235
    -4236
    -4237
    -4238
    -4239
    -4240
    -4241
    -4242
    -4243
    -4244
    -4245
    -4246
    -4247
    -4248
    -4249
    -4250
    -4251
    -4252
    -4253
    -4254
    -4255
    -4256
    -4257
    -4258
    -4259
    -4260
    -4261
    -4262
    -4263
    -4264
    -4265
    -4266
    -4267
    -4268
    -4269
    -4270
    -4271
    -4272
    -4273
    -4274
    -4275
    -4276
    -4277
    -4278
    -4279
    -4280
    -4281
    -4282
    -4283
    -4284
    -4285
    -4286
    -4287
    -4288
    -4289
    -4290
    -4291
    -4292
    -4293
    -4294
    -4295
    -4296
    -4297
    -4298
    -4299
    -4300
    -4301
    -4302
    -4303
    -4304
    -4305
    -4306
    -4307
    -4308
    -4309
    -4310
    -4311
    -4312
    -4313
    -4314
    -4315
    -4316
    -4317
    -4318
    -4319
    -4320
    -4321
    -4322
    -4323
    -4324
    -4325
    -4326
    -4327
    -4328
    -4329
    -4330
    -4331
    -4332
    -4333
    -4334
    -4335
    -4336
    -4337
    -4338
    -4339
    -4340
    -4341
    -4342
    -4343
    -4344
    -4345
    -4346
    -4347
    -4348
    -4349
    -4350
    -4351
    -4352
    -4353
    -4354
    -4355
    -4356
    -4357
    -4358
    -4359
    -4360
    -4361
    -4362
    -4363
    -4364
    -4365
    -4366
    -4367
    -4368
    -4369
    -4370
    -4371
    -4372
    -4373
    -4374
    -4375
    -4376
    -4377
    -4378
    -4379
    -4380
    -4381
    -4382
    -4383
    -4384
    -4385
    -4386
    -4387
    -4388
    -4389
    -4390
    -4391
    -4392
    -4393
    -4394
    -4395
    -4396
    -4397
    -4398
    -4399
    -4400
    -4401
    -4402
    -4403
    -4404
    -4405
    -4406
    -4407
    -4408
    -4409
    -4410
    -4411
    -4412
    -4413
    -4414
    -4415
    -4416
    -4417
    -4418
    -4419
    -4420
    -4421
    -4422
    -4423
    -4424
    -4425
    -4426
    -4427
    -4428
    -4429
    -4430
    -4431
    -4432
    -4433
    -4434
    -4435
    -4436
    -4437
    -4438
    -4439
    -4440
    -4441
    -4442
    -4443
    -4444
    -4445
    -4446
    -4447
    -4448
    -4449
    -4450
    -4451
    -4452
    -4453
    -4454
    -4455
    -4456
    -4457
    -4458
    -4459
    -4460
    -4461
    -4462
    -4463
    -4464
    -4465
    -4466
    -4467
    -4468
    -4469
    -4470
    -4471
    -4472
    -4473
    -4474
    -4475
    -4476
    -4477
    -4478
    -4479
    -4480
    -4481
    -4482
    -4483
    -4484
    -4485
    -4486
    -4487
    -4488
    -4489
    -4490
    -4491
    -4492
    -4493
    -4494
    -4495
    -4496
    -4497
    -4498
    -4499
    -4500
    -4501
    -4502
    -4503
    -4504
    -4505
    -4506
    -4507
    -4508
    -4509
    -4510
    -4511
    -4512
    -4513
    -4514
    -4515
    -4516
    -4517
    -4518
    -4519
    -4520
    -4521
    -4522
    -4523
    -4524
    -4525
    -4526
    -4527
    -4528
    -4529
    -4530
    -4531
    -4532
    -4533
    -4534
    -4535
    -4536
    -4537
    -4538
    -4539
    -4540
    -4541
    -4542
    -4543
    -4544
    -4545
    -4546
    -4547
    -4548
    -4549
    -4550
    -4551
    -4552
    -4553
    -4554
    -4555
    -4556
    -4557
    -4558
    -4559
    -4560
    -4561
    -4562
    -4563
    -4564
    -4565
    -4566
    -4567
    -4568
    -4569
    -4570
    -4571
    -4572
    -4573
    -4574
    -4575
    -4576
    -4577
    -4578
    -4579
    -4580
    -4581
    -4582
    -4583
    -4584
    -4585
    -4586
    -4587
    -4588
    -4589
    -4590
    -4591
    -4592
    -4593
    -4594
    -4595
    -4596
    -4597
    -4598
    -4599
    -4600
    -4601
    -4602
    -4603
    -4604
    -4605
    -4606
    -4607
    -4608
    -4609
    -4610
    -4611
    -4612
    -4613
    -4614
    -4615
    -4616
    -4617
    -4618
    -4619
    -4620
    -4621
    -4622
    -4623
    -4624
    -4625
    -4626
    -4627
    -4628
    -4629
    -4630
    -4631
    -4632
    -4633
    -4634
    -4635
    -4636
    -4637
    -4638
    -4639
    -4640
    -4641
    -4642
    -4643
    -4644
    -4645
    -4646
    -4647
    -4648
    -4649
    -4650
    -4651
    -4652
    -4653
    -4654
    -4655
    -4656
    -4657
    -4658
    -4659
    -4660
    -4661
    -4662
    -4663
    -4664
    -4665
    -4666
    -4667
    -4668
    -4669
    -4670
    -4671
    -4672
    -4673
    -4674
    -4675
    -4676
    -4677
    -4678
    -4679
    -4680
    -4681
    -4682
    -4683
    -4684
    -4685
    -4686
    -4687
    -4688
    -4689
    -4690
    -4691
    -4692
    -4693
    -4694
    -4695
    -4696
    -4697
    -4698
    -4699
    -4700
    -4701
    -4702
    -4703
    -4704
    -4705
    -4706
    -4707
    -4708
    -4709
    -4710
    -4711
    -4712
    -4713
    -4714
    -4715
    -4716
    -4717
    -4718
    -4719
    -4720
    -4721
    -4722
    -4723
    -4724
    -4725
    -4726
    -4727
    -4728
    -4729
    -4730
    -4731
    -4732
    -4733
    -4734
    -4735
    -4736
    -4737
    -4738
    -4739
    -4740
    -4741
    -4742
    -4743
    -4744
    -4745
    -4746
    -4747
    -4748
    -4749
    -4750
    -4751
    -4752
    -4753
    -4754
    -4755
    -4756
    -4757
    -4758
    -4759
    -4760
    -4761
    -4762
    -4763
    -4764
    -4765
    -4766
    -4767
    -4768
    -4769
    -4770
    -4771
    -4772
    -4773
    -4774
    -4775
    -4776
    -4777
    -4778
    -4779
    -4780
    -4781
    -4782
    -4783
    -4784
    -4785
    -4786
    -4787
    -4788
    -4789
    -4790
    -4791
    -4792
    -4793
    -4794
    -4795
    -4796
    -4797
    -4798
    -4799
    -4800
    -4801
    -4802
    -4803
    -4804
    -4805
    -4806
    -4807
    -4808
    -4809
    -4810
    -4811
    -4812
    -4813
    -4814
    -4815
    -4816
    -4817
    -4818
    -4819
    -4820
    -4821
    -4822
    -4823
    -4824
    -4825
    -4826
    -4827
    -4828
    -4829
    -4830
    -4831
    -4832
    -4833
    -4834
    -4835
    -4836
    -4837
    -4838
    -4839
    -4840
    -4841
    -4842
    -4843
    -4844
    -4845
    -4846
    -4847
    -4848
    -4849
    -4850
    -4851
    -4852
    -4853
    -4854
    -4855
    -4856
    -4857
    -4858
    -4859
    -4860
    -4861
    -4862
    -4863
    -4864
    -4865
    -4866
    -4867
    -4868
    -4869
    -4870
    -4871
    -4872
    -4873
    -4874
    -4875
    -4876
    -4877
    -4878
    -4879
    -4880
    -4881
    -4882
    -4883
    -4884
    -4885
    -4886
    -4887
    -4888
    -4889
    -4890
    -4891
    -4892
    -4893
    -4894
    -4895
    -4896
    -4897
    -4898
    -4899
    -4900
    -4901
    -4902
    -4903
    -4904
    -4905
    -4906
    -4907
    -4908
    -4909
    -4910
    -4911
    -4912
    -4913
    -4914
    -4915
    -4916
    -4917
    -4918
    -4919
    -4920
    -4921
    -4922
    -4923
    -4924
    -4925
    -4926
    -4927
    -4928
    -4929
    -4930
    -4931
    -4932
    -4933
    -4934
    -4935
    -4936
    -4937
    -4938
    -4939
    -4940
    -4941
    -4942
    -4943
    -4944
    -4945
    -4946
    -4947
    -4948
    -4949
    -4950
    -4951
    -4952
    -4953
    -4954
    -4955
    -4956
    -4957
    -4958
    -4959
    -4960
    -4961
    -4962
    -4963
    -4964
    -4965
    -4966
    -4967
    -4968
    -4969
    -4970
    -4971
    -4972
    -4973
    -4974
    -4975
    -4976
    -4977
    -4978
    -4979
    -4980
    -4981
    -4982
    -4983
    -4984
    -4985
    -4986
    -4987
    -4988
    -4989
    -4990
    -4991
    -4992
    -4993
    -4994
    -4995
    -4996
    -4997
    -4998
    -4999
    -5000
    -5001
    -5002
    -5003
    -5004
    -5005
    -5006
    -5007
    -5008
    -5009
    -5010
    -5011
    -5012
    -5013
    -5014
    -5015
    -5016
    -5017
    -5018
    -5019
    -5020
    -5021
    -5022
    -5023
    -5024
    -5025
    -5026
    -5027
    -5028
    -5029
    -5030
    -5031
    -5032
    -5033
    -5034
    -5035
    -5036
    -5037
    -5038
    -5039
    -5040
    -5041
    -5042
    -5043
    -5044
    -5045
    -5046
    -5047
    -5048
    -5049
    -5050
    -5051
    -5052
    -5053
    -5054
    -5055
    -5056
    -5057
    -5058
    -5059
    -5060
    -5061
    -5062
    -5063
    -5064
    -5065
    -5066
    -5067
    -5068
    -5069
    -5070
    -5071
    -5072
    -5073
    -5074
    -5075
    -5076
    -5077
    -5078
    -5079
    -5080
    -5081
    -5082
    -5083
    -5084
    -5085
    -5086
    -5087
    -5088
    -5089
    -5090
    -5091
    -5092
    -5093
    -5094
    -5095
    -5096
    -5097
    -5098
    -5099
    -5100
    -5101
    -5102
    -5103
    -5104
    -5105
    -5106
    -5107
    -5108
    -5109
    -5110
    -5111
    -5112
    -5113
    -5114
    -5115
    -5116
    -5117
    -5118
    -5119
    -5120
    -5121
    -5122
    -5123
    -5124
    -5125
    -5126
    -5127
    -5128
    -5129
    -5130
    -5131
    -5132
    -5133
    -5134
    -5135
    -5136
    -5137
    -5138
    -5139
    -5140
    -5141
    -5142
    -5143
    -5144
    -5145
    -5146
    -5147
    -5148
    -5149
    -5150
    -5151
    -5152
    -5153
    -5154
    -5155
    -5156
    -5157
    -5158
    -5159
    -5160
    -5161
    -5162
    -5163
    -5164
    -5165
    -5166
    -5167
    -5168
    -5169
    -5170
    -5171
    -5172
    -5173
    -5174
    -5175
    -5176
    -5177
    -5178
    -5179
    -5180
    -5181
    -5182
    -5183
    -5184
    -5185
    -5186
    -5187
    -5188
    -5189
    -5190
    -5191
    -5192
    -5193
    -5194
    -5195
    -5196
    -5197
    -5198
    -5199
    -5200
    -5201
    -5202
    -5203
    -5204
    -5205
    -5206
    -5207
    -5208
    -5209
    -5210
    -5211
    -5212
    -5213
    -5214
    -5215
    -5216
    -5217
    -5218
    -5219
    -5220
    -5221
    -5222
    -5223
    -5224
    -5225
    -5226
    -5227
    -5228
    -5229
    -5230
    -5231
    -5232
    -5233
    -5234
    -5235
    -5236
    -5237
    -5238
    -5239
    -5240
    -5241
    -5242
    -5243
    -5244
    -5245
    -5246
    -5247
    -5248
    -5249
    -5250
    -5251
    -5252
    -5253
    -5254
    -5255
    -5256
    -5257
    -5258
    -5259
    -5260
    -5261
    -5262
    -5263
    -5264
    -5265
    -5266
    -5267
    -5268
    -5269
    -5270
    -5271
    -5272
    -5273
    -5274
    -5275
    -5276
    -5277
    -5278
    -5279
    -5280
    -5281
    -5282
    -5283
    -5284
    -5285
    -5286
    -5287
    -5288
    -5289
    -5290
    -5291
    -5292
    -5293
    -5294
    -5295
    -5296
    -5297
    -5298
    -5299
    -5300
    -5301
    -5302
    -5303
    -5304
    -5305
    -5306
    -5307
    -5308
    -5309
    -5310
    -5311
    -5312
    -5313
    -5314
    -5315
    -5316
    -5317
    -5318
    -5319
    -5320
    -5321
    -5322
    -5323
    -5324
    -5325
    -5326
    -5327
    -5328
    -5329
    -5330
    -5331
    -5332
    -5333
    -5334
    -5335
    -5336
    -5337
    -5338
    -5339
    -5340
    -5341
    -5342
    -5343
    -5344
    -5345
    -5346
    -5347
    -5348
    -5349
    -5350
    -5351
    -5352
    -5353
    -5354
    -5355
    -5356
    -5357
    -5358
    -5359
    -5360
    -5361
    -5362
    -5363
    -5364
    -5365
    -5366
    -5367
    -5368
    -5369
    -5370
    -5371
    -5372
    -5373
    -5374
    -5375
    -5376
    -5377
    -5378
    -5379
    -5380
    -5381
    -5382
    -5383
    -5384
    -5385
    -5386
    -5387
    -5388
    -5389
    -5390
    -5391
    -5392
    -5393
    -5394
    -5395
    -5396
    -5397
    -5398
    -5399
    -5400
    -5401
    -5402
    -5403
    -5404
    -5405
    -5406
    -5407
    -5408
    -5409
    -5410
    -5411
    -5412
    -5413
    -5414
    -5415
    -5416
    -5417
    -5418
    -5419
    -5420
    -5421
    -5422
    -5423
    -5424
    -5425
    -5426
    -5427
    -5428
    -5429
    -5430
    -5431
    -5432
    -5433
    -5434
    -5435
    -5436
    -5437
    -5438
    -5439
    -5440
    -5441
    -5442
    -5443
    -5444
    -5445
    -5446
    -5447
    -5448
    -5449
    -5450
    -5451
    -5452
    -5453
    -5454
    -5455
    -5456
    -5457
    -5458
    -5459
    -5460
    -5461
    -5462
    -5463
    -5464
    -5465
    -5466
    -5467
    -5468
    -5469
    -5470
    -5471
    -5472
    -5473
    -5474
    -5475
    -5476
    -5477
    -5478
    -5479
    -5480
    -5481
    -5482
    -5483
    -5484
    -5485
    -5486
    -5487
    -5488
    -5489
    -5490
    -5491
    -5492
    -5493
    -5494
    -5495
    -5496
    -5497
    -5498
    -5499
    -5500
    -5501
    -5502
    -5503
    -5504
    -5505
    -5506
    -5507
    -5508
    -5509
    -5510
    -5511
    -5512
    -5513
    -5514
    -5515
    -5516
    -5517
    -5518
    -5519
    -5520
    -5521
    -5522
    -5523
    -5524
    -5525
    -5526
    -5527
    -5528
    -5529
    -5530
    -5531
    -5532
    -5533
    -5534
    -5535
    -5536
    -5537
    -5538
    -5539
    -5540
    -5541
    -5542
    -5543
    -5544
    -5545
    -5546
    -5547
    -5548
    -5549
    -5550
    -5551
    -5552
    -5553
    -5554
    -5555
    -5556
    -5557
    -5558
    -5559
    -5560
    -5561
    -5562
    -5563
    -5564
    -5565
    -5566
    -5567
    -5568
    -5569
    -5570
    -5571
    -5572
    -5573
    -5574
    -5575
    -5576
    -5577
    -5578
    -5579
    -5580
    -5581
    -5582
    -5583
    -5584
    -5585
    -
    // Bitcoin Dev Kit
    -// Written in 2020 by Alekos Filini <alekos.filini@gmail.com>
    -//
    -// Copyright (c) 2020-2021 Bitcoin Dev Kit Developers
    -//
    -// This file is licensed under the Apache License, Version 2.0 <LICENSE-APACHE
    -// or http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
    -// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your option.
    -// You may not use this file except in accordance with one or both of these
    -// licenses.
    -
    -//! Wallet
    -//!
    -//! This module defines the [`Wallet`] structure.
    -
    -use std::cell::RefCell;
    -use std::collections::HashMap;
    -use std::collections::{BTreeMap, HashSet};
    -use std::fmt;
    -use std::ops::{Deref, DerefMut};
    -use std::str::FromStr;
    -use std::sync::Arc;
    -
    -use bitcoin::secp256k1::Secp256k1;
    -
    -use bitcoin::consensus::encode::serialize;
    -use bitcoin::util::psbt;
    -use bitcoin::{
    -    Address, EcdsaSighashType, LockTime, Network, OutPoint, SchnorrSighashType, Script, Sequence,
    -    Transaction, TxOut, Txid, Witness,
    +mod.rs - source
    1
    +2
    +3
    +4
    +5
    +6
    +7
    +8
    +9
    +10
    +11
    +12
    +13
    +14
    +15
    +16
    +17
    +18
    +19
    +20
    +21
    +22
    +23
    +24
    +25
    +26
    +27
    +28
    +29
    +30
    +31
    +32
    +33
    +34
    +35
    +36
    +37
    +38
    +39
    +40
    +41
    +42
    +43
    +44
    +45
    +46
    +47
    +48
    +49
    +50
    +51
    +52
    +53
    +54
    +55
    +56
    +57
    +58
    +59
    +60
    +61
    +62
    +63
    +64
    +65
    +66
    +67
    +68
    +69
    +70
    +71
    +72
    +73
    +74
    +75
    +76
    +77
    +78
    +79
    +80
    +81
    +82
    +83
    +84
    +85
    +86
    +87
    +88
    +89
    +90
    +91
    +92
    +93
    +94
    +95
    +96
    +97
    +98
    +99
    +100
    +101
    +102
    +103
    +104
    +105
    +106
    +107
    +108
    +109
    +110
    +111
    +112
    +113
    +114
    +115
    +116
    +117
    +118
    +119
    +120
    +121
    +122
    +123
    +124
    +125
    +126
    +127
    +128
    +129
    +130
    +131
    +132
    +133
    +134
    +135
    +136
    +137
    +138
    +139
    +140
    +141
    +142
    +143
    +144
    +145
    +146
    +147
    +148
    +149
    +150
    +151
    +152
    +153
    +154
    +155
    +156
    +157
    +158
    +159
    +160
    +161
    +162
    +163
    +164
    +165
    +166
    +167
    +168
    +169
    +170
    +171
    +172
    +173
    +174
    +175
    +176
    +177
    +178
    +179
    +180
    +181
    +182
    +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
    +245
    +246
    +247
    +248
    +249
    +250
    +251
    +252
    +253
    +254
    +255
    +256
    +257
    +258
    +259
    +260
    +261
    +262
    +263
    +264
    +265
    +266
    +267
    +268
    +269
    +270
    +271
    +272
    +273
    +274
    +275
    +276
    +277
    +278
    +279
    +280
    +281
    +282
    +283
    +284
    +285
    +286
    +287
    +288
    +289
    +290
    +291
    +292
    +293
    +294
    +295
    +296
    +297
    +298
    +299
    +300
    +301
    +302
    +303
    +304
    +305
    +306
    +307
    +308
    +309
    +310
    +311
    +312
    +313
    +314
    +315
    +316
    +317
    +318
    +319
    +320
    +321
    +322
    +323
    +324
    +325
    +326
    +327
    +328
    +329
    +330
    +331
    +332
    +333
    +334
    +335
    +336
    +337
    +338
    +339
    +340
    +341
    +342
    +343
    +344
    +345
    +346
    +347
    +348
    +349
    +350
    +351
    +352
    +353
    +354
    +355
    +356
    +357
    +358
    +359
    +360
    +361
    +362
    +363
    +364
    +365
    +366
    +367
    +368
    +369
    +370
    +371
    +372
    +373
    +374
    +375
    +376
    +377
    +378
    +379
    +380
    +381
    +382
    +383
    +384
    +385
    +386
    +387
    +388
    +389
    +390
    +391
    +392
    +393
    +394
    +395
    +396
    +397
    +398
    +399
    +400
    +401
    +402
    +403
    +404
    +405
    +406
    +407
    +408
    +409
    +410
    +411
    +412
    +413
    +414
    +415
    +416
    +417
    +418
    +419
    +420
    +421
    +422
    +423
    +424
    +425
    +426
    +427
    +428
    +429
    +430
    +431
    +432
    +433
    +434
    +435
    +436
    +437
    +438
    +439
    +440
    +441
    +442
    +443
    +444
    +445
    +446
    +447
    +448
    +449
    +450
    +451
    +452
    +453
    +454
    +455
    +456
    +457
    +458
    +459
    +460
    +461
    +462
    +463
    +464
    +465
    +466
    +467
    +468
    +469
    +470
    +471
    +472
    +473
    +474
    +475
    +476
    +477
    +478
    +479
    +480
    +481
    +482
    +483
    +484
    +485
    +486
    +487
    +488
    +489
    +490
    +491
    +492
    +493
    +494
    +495
    +496
    +497
    +498
    +499
    +500
    +501
    +502
    +503
    +504
    +505
    +506
    +507
    +508
    +509
    +510
    +511
    +512
    +513
    +514
    +515
    +516
    +517
    +518
    +519
    +520
    +521
    +522
    +523
    +524
    +525
    +526
    +527
    +528
    +529
    +530
    +531
    +532
    +533
    +534
    +535
    +536
    +537
    +538
    +539
    +540
    +541
    +542
    +543
    +544
    +545
    +546
    +547
    +548
    +549
    +550
    +551
    +552
    +553
    +554
    +555
    +556
    +557
    +558
    +559
    +560
    +561
    +562
    +563
    +564
    +565
    +566
    +567
    +568
    +569
    +570
    +571
    +572
    +573
    +574
    +575
    +576
    +577
    +578
    +579
    +580
    +581
    +582
    +583
    +584
    +585
    +586
    +587
    +588
    +589
    +590
    +591
    +592
    +593
    +594
    +595
    +596
    +597
    +598
    +599
    +600
    +601
    +602
    +603
    +604
    +605
    +606
    +607
    +608
    +609
    +610
    +611
    +612
    +613
    +614
    +615
    +616
    +617
    +618
    +619
    +620
    +621
    +622
    +623
    +624
    +625
    +626
    +627
    +628
    +629
    +630
    +631
    +632
    +633
    +634
    +635
    +636
    +637
    +638
    +639
    +640
    +641
    +642
    +643
    +644
    +645
    +646
    +647
    +648
    +649
    +650
    +651
    +652
    +653
    +654
    +655
    +656
    +657
    +658
    +659
    +660
    +661
    +662
    +663
    +664
    +665
    +666
    +667
    +668
    +669
    +670
    +671
    +672
    +673
    +674
    +675
    +676
    +677
    +678
    +679
    +680
    +681
    +682
    +683
    +684
    +685
    +686
    +687
    +688
    +689
    +690
    +691
    +692
    +693
    +694
    +695
    +696
    +697
    +698
    +699
    +700
    +701
    +702
    +703
    +704
    +705
    +706
    +707
    +708
    +709
    +710
    +711
    +712
    +713
    +714
    +715
    +716
    +717
    +718
    +719
    +720
    +721
    +722
    +723
    +724
    +725
    +726
    +727
    +728
    +729
    +730
    +731
    +732
    +733
    +734
    +735
    +736
    +737
    +738
    +739
    +740
    +741
    +742
    +743
    +744
    +745
    +746
    +747
    +748
    +749
    +750
    +751
    +752
    +753
    +754
    +755
    +756
    +757
    +758
    +759
    +760
    +761
    +762
    +763
    +764
    +765
    +766
    +767
    +768
    +769
    +770
    +771
    +772
    +773
    +774
    +775
    +776
    +777
    +778
    +779
    +780
    +781
    +782
    +783
    +784
    +785
    +786
    +787
    +788
    +789
    +790
    +791
    +792
    +793
    +794
    +795
    +796
    +797
    +798
    +799
    +800
    +801
    +802
    +803
    +804
    +805
    +806
    +807
    +808
    +809
    +810
    +811
    +812
    +813
    +814
    +815
    +816
    +817
    +818
    +819
    +820
    +821
    +822
    +823
    +824
    +825
    +826
    +827
    +828
    +829
    +830
    +831
    +832
    +833
    +834
    +835
    +836
    +837
    +838
    +839
    +840
    +841
    +842
    +843
    +844
    +845
    +846
    +847
    +848
    +849
    +850
    +851
    +852
    +853
    +854
    +855
    +856
    +857
    +858
    +859
    +860
    +861
    +862
    +863
    +864
    +865
    +866
    +867
    +868
    +869
    +870
    +871
    +872
    +873
    +874
    +875
    +876
    +877
    +878
    +879
    +880
    +881
    +882
    +883
    +884
    +885
    +886
    +887
    +888
    +889
    +890
    +891
    +892
    +893
    +894
    +895
    +896
    +897
    +898
    +899
    +900
    +901
    +902
    +903
    +904
    +905
    +906
    +907
    +908
    +909
    +910
    +911
    +912
    +913
    +914
    +915
    +916
    +917
    +918
    +919
    +920
    +921
    +922
    +923
    +924
    +925
    +926
    +927
    +928
    +929
    +930
    +931
    +932
    +933
    +934
    +935
    +936
    +937
    +938
    +939
    +940
    +941
    +942
    +943
    +944
    +945
    +946
    +947
    +948
    +949
    +950
    +951
    +952
    +953
    +954
    +955
    +956
    +957
    +958
    +959
    +960
    +961
    +962
    +963
    +964
    +965
    +966
    +967
    +968
    +969
    +970
    +971
    +972
    +973
    +974
    +975
    +976
    +977
    +978
    +979
    +980
    +981
    +982
    +983
    +984
    +985
    +986
    +987
    +988
    +989
    +990
    +991
    +992
    +993
    +994
    +995
    +996
    +997
    +998
    +999
    +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
    +1028
    +1029
    +1030
    +1031
    +1032
    +1033
    +1034
    +1035
    +1036
    +1037
    +1038
    +1039
    +1040
    +1041
    +1042
    +1043
    +1044
    +1045
    +1046
    +1047
    +1048
    +1049
    +1050
    +1051
    +1052
    +1053
    +1054
    +1055
    +1056
    +1057
    +1058
    +1059
    +1060
    +1061
    +1062
    +1063
    +1064
    +1065
    +1066
    +1067
    +1068
    +1069
    +1070
    +1071
    +1072
    +1073
    +1074
    +1075
    +1076
    +1077
    +1078
    +1079
    +1080
    +1081
    +1082
    +1083
    +1084
    +1085
    +1086
    +1087
    +1088
    +1089
    +1090
    +1091
    +1092
    +1093
    +1094
    +1095
    +1096
    +1097
    +1098
    +1099
    +1100
    +1101
    +1102
    +1103
    +1104
    +1105
    +1106
    +1107
    +1108
    +1109
    +1110
    +1111
    +1112
    +1113
    +1114
    +1115
    +1116
    +1117
    +1118
    +1119
    +1120
    +1121
    +1122
    +1123
    +1124
    +1125
    +1126
    +1127
    +1128
    +1129
    +1130
    +1131
    +1132
    +1133
    +1134
    +1135
    +1136
    +1137
    +1138
    +1139
    +1140
    +1141
    +1142
    +1143
    +1144
    +1145
    +1146
    +1147
    +1148
    +1149
    +1150
    +1151
    +1152
    +1153
    +1154
    +1155
    +1156
    +1157
    +1158
    +1159
    +1160
    +1161
    +1162
    +1163
    +1164
    +1165
    +1166
    +1167
    +1168
    +1169
    +1170
    +1171
    +1172
    +1173
    +1174
    +1175
    +1176
    +1177
    +1178
    +1179
    +1180
    +1181
    +1182
    +1183
    +1184
    +1185
    +1186
    +1187
    +1188
    +1189
    +1190
    +1191
    +1192
    +1193
    +1194
    +1195
    +1196
    +1197
    +1198
    +1199
    +1200
    +1201
    +1202
    +1203
    +1204
    +1205
    +1206
    +1207
    +1208
    +1209
    +1210
    +1211
    +1212
    +1213
    +1214
    +1215
    +1216
    +1217
    +1218
    +1219
    +1220
    +1221
    +1222
    +1223
    +1224
    +1225
    +1226
    +1227
    +1228
    +1229
    +1230
    +1231
    +1232
    +1233
    +1234
    +1235
    +1236
    +1237
    +1238
    +1239
    +1240
    +1241
    +1242
    +1243
    +1244
    +1245
    +1246
    +1247
    +1248
    +1249
    +1250
    +1251
    +1252
    +1253
    +1254
    +1255
    +1256
    +1257
    +1258
    +1259
    +1260
    +1261
    +1262
    +1263
    +1264
    +1265
    +1266
    +1267
    +1268
    +1269
    +1270
    +1271
    +1272
    +1273
    +1274
    +1275
    +1276
    +1277
    +1278
    +1279
    +1280
    +1281
    +1282
    +1283
    +1284
    +1285
    +1286
    +1287
    +1288
    +1289
    +1290
    +1291
    +1292
    +1293
    +1294
    +1295
    +1296
    +1297
    +1298
    +1299
    +1300
    +1301
    +1302
    +1303
    +1304
    +1305
    +1306
    +1307
    +1308
    +1309
    +1310
    +1311
    +1312
    +1313
    +1314
    +1315
    +1316
    +1317
    +1318
    +1319
    +1320
    +1321
    +1322
    +1323
    +1324
    +1325
    +1326
    +1327
    +1328
    +1329
    +1330
    +1331
    +1332
    +1333
    +1334
    +1335
    +1336
    +1337
    +1338
    +1339
    +1340
    +1341
    +1342
    +1343
    +1344
    +1345
    +1346
    +1347
    +1348
    +1349
    +1350
    +1351
    +1352
    +1353
    +1354
    +1355
    +1356
    +1357
    +1358
    +1359
    +1360
    +1361
    +1362
    +1363
    +1364
    +1365
    +1366
    +1367
    +1368
    +1369
    +1370
    +1371
    +1372
    +1373
    +1374
    +1375
    +1376
    +1377
    +1378
    +1379
    +1380
    +1381
    +1382
    +1383
    +1384
    +1385
    +1386
    +1387
    +1388
    +1389
    +1390
    +1391
    +1392
    +1393
    +1394
    +1395
    +1396
    +1397
    +1398
    +1399
    +1400
    +1401
    +1402
    +1403
    +1404
    +1405
    +1406
    +1407
    +1408
    +1409
    +1410
    +1411
    +1412
    +1413
    +1414
    +1415
    +1416
    +1417
    +1418
    +1419
    +1420
    +1421
    +1422
    +1423
    +1424
    +1425
    +1426
    +1427
    +1428
    +1429
    +1430
    +1431
    +1432
    +1433
    +1434
    +1435
    +1436
    +1437
    +1438
    +1439
    +1440
    +1441
    +1442
    +1443
    +1444
    +1445
    +1446
    +1447
    +1448
    +1449
    +1450
    +1451
    +1452
    +1453
    +1454
    +1455
    +1456
    +1457
    +1458
    +1459
    +1460
    +1461
    +1462
    +1463
    +1464
    +1465
    +1466
    +1467
    +1468
    +1469
    +1470
    +1471
    +1472
    +1473
    +1474
    +1475
    +1476
    +1477
    +1478
    +1479
    +1480
    +1481
    +1482
    +1483
    +1484
    +1485
    +1486
    +1487
    +1488
    +1489
    +1490
    +1491
    +1492
    +1493
    +1494
    +1495
    +1496
    +1497
    +1498
    +1499
    +1500
    +1501
    +1502
    +1503
    +1504
    +1505
    +1506
    +1507
    +1508
    +1509
    +1510
    +1511
    +1512
    +1513
    +1514
    +1515
    +1516
    +1517
    +1518
    +1519
    +1520
    +1521
    +1522
    +1523
    +1524
    +1525
    +1526
    +1527
    +1528
    +1529
    +1530
    +1531
    +1532
    +1533
    +1534
    +1535
    +1536
    +1537
    +1538
    +1539
    +1540
    +1541
    +1542
    +1543
    +1544
    +1545
    +1546
    +1547
    +1548
    +1549
    +1550
    +1551
    +1552
    +1553
    +1554
    +1555
    +1556
    +1557
    +1558
    +1559
    +1560
    +1561
    +1562
    +1563
    +1564
    +1565
    +1566
    +1567
    +1568
    +1569
    +1570
    +1571
    +1572
    +1573
    +1574
    +1575
    +1576
    +1577
    +1578
    +1579
    +1580
    +1581
    +1582
    +1583
    +1584
    +1585
    +1586
    +1587
    +1588
    +1589
    +1590
    +1591
    +1592
    +1593
    +1594
    +1595
    +1596
    +1597
    +1598
    +1599
    +1600
    +1601
    +1602
    +1603
    +1604
    +1605
    +1606
    +1607
    +1608
    +1609
    +1610
    +1611
    +1612
    +1613
    +1614
    +1615
    +1616
    +1617
    +1618
    +1619
    +1620
    +1621
    +1622
    +1623
    +1624
    +1625
    +1626
    +1627
    +1628
    +1629
    +1630
    +1631
    +1632
    +1633
    +1634
    +1635
    +1636
    +1637
    +1638
    +1639
    +1640
    +1641
    +1642
    +1643
    +1644
    +1645
    +1646
    +1647
    +1648
    +1649
    +1650
    +1651
    +1652
    +1653
    +1654
    +1655
    +1656
    +1657
    +1658
    +1659
    +1660
    +1661
    +1662
    +1663
    +1664
    +1665
    +1666
    +1667
    +1668
    +1669
    +1670
    +1671
    +1672
    +1673
    +1674
    +1675
    +1676
    +1677
    +1678
    +1679
    +1680
    +1681
    +1682
    +1683
    +1684
    +1685
    +1686
    +1687
    +1688
    +1689
    +1690
    +1691
    +1692
    +1693
    +1694
    +1695
    +1696
    +1697
    +1698
    +1699
    +1700
    +1701
    +1702
    +1703
    +1704
    +1705
    +1706
    +1707
    +1708
    +1709
    +1710
    +1711
    +1712
    +1713
    +1714
    +1715
    +1716
    +1717
    +1718
    +1719
    +1720
    +1721
    +1722
    +1723
    +1724
    +1725
    +1726
    +1727
    +1728
    +1729
    +1730
    +1731
    +1732
    +1733
    +1734
    +1735
    +1736
    +1737
    +1738
    +1739
    +1740
    +1741
    +1742
    +1743
    +1744
    +1745
    +1746
    +1747
    +1748
    +1749
    +1750
    +1751
    +1752
    +1753
    +1754
    +1755
    +1756
    +1757
    +1758
    +1759
    +1760
    +1761
    +1762
    +1763
    +1764
    +1765
    +1766
    +1767
    +1768
    +1769
    +1770
    +1771
    +1772
    +1773
    +1774
    +1775
    +1776
    +1777
    +1778
    +1779
    +1780
    +1781
    +1782
    +1783
    +1784
    +1785
    +1786
    +1787
    +1788
    +1789
    +1790
    +1791
    +1792
    +1793
    +1794
    +1795
    +1796
    +1797
    +1798
    +1799
    +1800
    +1801
    +1802
    +1803
    +1804
    +1805
    +1806
    +1807
    +1808
    +1809
    +1810
    +1811
    +1812
    +1813
    +1814
    +1815
    +1816
    +1817
    +1818
    +1819
    +1820
    +1821
    +1822
    +1823
    +1824
    +1825
    +1826
    +1827
    +1828
    +1829
    +1830
    +1831
    +1832
    +1833
    +1834
    +1835
    +1836
    +1837
    +1838
    +1839
    +1840
    +1841
    +1842
    +1843
    +1844
    +1845
    +1846
    +1847
    +1848
    +1849
    +1850
    +1851
    +1852
    +1853
    +1854
    +1855
    +1856
    +1857
    +1858
    +1859
    +1860
    +1861
    +1862
    +1863
    +1864
    +1865
    +1866
    +1867
    +1868
    +1869
    +1870
    +1871
    +1872
    +1873
    +1874
    +1875
    +1876
    +1877
    +1878
    +1879
    +1880
    +1881
    +1882
    +1883
    +1884
    +1885
    +1886
    +1887
    +1888
    +1889
    +1890
    +1891
    +1892
    +1893
    +1894
    +1895
    +1896
    +1897
    +1898
    +1899
    +1900
    +1901
    +1902
    +1903
    +1904
    +1905
    +1906
    +1907
    +1908
    +1909
    +1910
    +1911
    +1912
    +1913
    +1914
    +1915
    +1916
    +1917
    +1918
    +1919
    +1920
    +1921
    +1922
    +1923
    +1924
    +1925
    +1926
    +1927
    +1928
    +1929
    +1930
    +1931
    +1932
    +1933
    +1934
    +1935
    +1936
    +1937
    +1938
    +1939
    +1940
    +1941
    +1942
    +1943
    +1944
    +1945
    +1946
    +1947
    +1948
    +1949
    +1950
    +1951
    +1952
    +1953
    +1954
    +1955
    +1956
    +1957
    +1958
    +1959
    +1960
    +1961
    +1962
    +1963
    +1964
    +1965
    +1966
    +1967
    +1968
    +1969
    +1970
    +1971
    +1972
    +1973
    +1974
    +1975
    +1976
    +1977
    +1978
    +1979
    +1980
    +1981
    +1982
    +1983
    +1984
    +1985
    +1986
    +1987
    +1988
    +1989
    +1990
    +1991
    +1992
    +1993
    +1994
    +1995
    +1996
    +1997
    +1998
    +1999
    +2000
    +2001
    +2002
    +2003
    +2004
    +2005
    +2006
    +2007
    +2008
    +2009
    +2010
    +2011
    +2012
    +2013
    +2014
    +2015
    +2016
    +2017
    +2018
    +2019
    +2020
    +2021
    +2022
    +2023
    +2024
    +2025
    +2026
    +2027
    +2028
    +2029
    +2030
    +2031
    +2032
    +2033
    +2034
    +2035
    +2036
    +2037
    +2038
    +2039
    +2040
    +2041
    +2042
    +2043
    +2044
    +2045
    +2046
    +2047
    +2048
    +2049
    +2050
    +2051
    +2052
    +2053
    +2054
    +2055
    +2056
    +2057
    +2058
    +2059
    +2060
    +2061
    +2062
    +2063
    +2064
    +2065
    +2066
    +2067
    +2068
    +2069
    +2070
    +2071
    +2072
    +2073
    +2074
    +2075
    +2076
    +2077
    +2078
    +2079
    +2080
    +2081
    +2082
    +2083
    +2084
    +2085
    +2086
    +2087
    +2088
    +2089
    +2090
    +2091
    +2092
    +2093
    +2094
    +2095
    +2096
    +2097
    +2098
    +2099
    +2100
    +2101
    +2102
    +2103
    +2104
    +2105
    +2106
    +2107
    +2108
    +2109
    +2110
    +2111
    +2112
    +2113
    +2114
    +2115
    +2116
    +2117
    +2118
    +2119
    +2120
    +2121
    +2122
    +2123
    +2124
    +2125
    +2126
    +2127
    +2128
    +2129
    +2130
    +2131
    +2132
    +2133
    +2134
    +2135
    +2136
    +2137
    +2138
    +2139
    +2140
    +2141
    +2142
    +2143
    +2144
    +2145
    +2146
    +2147
    +2148
    +2149
    +2150
    +2151
    +2152
    +2153
    +2154
    +2155
    +2156
    +2157
    +2158
    +2159
    +2160
    +2161
    +2162
    +2163
    +2164
    +2165
    +2166
    +2167
    +2168
    +2169
    +2170
    +2171
    +2172
    +2173
    +2174
    +2175
    +2176
    +2177
    +2178
    +2179
    +2180
    +2181
    +2182
    +2183
    +2184
    +2185
    +2186
    +2187
    +2188
    +2189
    +2190
    +2191
    +2192
    +2193
    +2194
    +2195
    +2196
    +2197
    +2198
    +2199
    +2200
    +2201
    +2202
    +2203
    +2204
    +2205
    +2206
    +2207
    +2208
    +2209
    +2210
    +2211
    +2212
    +2213
    +2214
    +2215
    +2216
    +2217
    +2218
    +2219
    +2220
    +2221
    +2222
    +2223
    +2224
    +2225
    +2226
    +2227
    +2228
    +2229
    +2230
    +2231
    +2232
    +2233
    +2234
    +2235
    +2236
    +2237
    +2238
    +2239
    +2240
    +2241
    +2242
    +2243
    +2244
    +2245
    +2246
    +2247
    +2248
    +2249
    +2250
    +2251
    +2252
    +2253
    +2254
    +2255
    +2256
    +2257
    +2258
    +2259
    +2260
    +2261
    +2262
    +2263
    +2264
    +2265
    +2266
    +2267
    +2268
    +2269
    +2270
    +2271
    +2272
    +2273
    +2274
    +2275
    +2276
    +2277
    +2278
    +2279
    +2280
    +2281
    +2282
    +2283
    +2284
    +2285
    +2286
    +2287
    +2288
    +2289
    +2290
    +2291
    +2292
    +2293
    +2294
    +2295
    +2296
    +2297
    +2298
    +2299
    +2300
    +2301
    +2302
    +2303
    +2304
    +2305
    +2306
    +2307
    +2308
    +2309
    +2310
    +2311
    +2312
    +2313
    +2314
    +2315
    +2316
    +2317
    +2318
    +2319
    +2320
    +2321
    +2322
    +2323
    +2324
    +2325
    +2326
    +2327
    +2328
    +2329
    +2330
    +2331
    +2332
    +2333
    +2334
    +2335
    +2336
    +2337
    +2338
    +2339
    +2340
    +2341
    +2342
    +2343
    +2344
    +2345
    +2346
    +2347
    +2348
    +2349
    +2350
    +2351
    +2352
    +2353
    +2354
    +2355
    +2356
    +2357
    +2358
    +2359
    +2360
    +2361
    +2362
    +2363
    +2364
    +2365
    +2366
    +2367
    +2368
    +2369
    +2370
    +2371
    +2372
    +2373
    +2374
    +2375
    +2376
    +2377
    +2378
    +2379
    +2380
    +2381
    +2382
    +2383
    +2384
    +2385
    +2386
    +2387
    +2388
    +2389
    +2390
    +2391
    +2392
    +2393
    +2394
    +2395
    +2396
    +2397
    +2398
    +2399
    +2400
    +2401
    +2402
    +2403
    +2404
    +2405
    +2406
    +2407
    +2408
    +2409
    +2410
    +2411
    +2412
    +2413
    +2414
    +2415
    +2416
    +2417
    +2418
    +2419
    +2420
    +2421
    +2422
    +2423
    +2424
    +2425
    +2426
    +2427
    +2428
    +2429
    +2430
    +2431
    +2432
    +2433
    +2434
    +2435
    +2436
    +2437
    +2438
    +2439
    +2440
    +2441
    +2442
    +2443
    +2444
    +2445
    +2446
    +2447
    +2448
    +2449
    +2450
    +2451
    +2452
    +2453
    +2454
    +2455
    +2456
    +2457
    +2458
    +2459
    +2460
    +2461
    +2462
    +2463
    +2464
    +2465
    +2466
    +2467
    +2468
    +2469
    +2470
    +2471
    +2472
    +2473
    +2474
    +2475
    +2476
    +2477
    +2478
    +2479
    +2480
    +2481
    +2482
    +2483
    +2484
    +2485
    +2486
    +2487
    +2488
    +2489
    +2490
    +2491
    +2492
    +2493
    +2494
    +2495
    +2496
    +2497
    +2498
    +2499
    +2500
    +2501
    +2502
    +2503
    +2504
    +2505
    +2506
    +2507
    +2508
    +2509
    +2510
    +2511
    +2512
    +2513
    +2514
    +2515
    +2516
    +2517
    +2518
    +2519
    +2520
    +2521
    +2522
    +2523
    +2524
    +2525
    +2526
    +2527
    +2528
    +2529
    +2530
    +2531
    +2532
    +2533
    +2534
    +2535
    +2536
    +2537
    +2538
    +2539
    +2540
    +2541
    +2542
    +2543
    +2544
    +2545
    +2546
    +2547
    +2548
    +2549
    +2550
    +2551
    +2552
    +2553
    +2554
    +2555
    +2556
    +2557
    +2558
    +2559
    +2560
    +2561
    +2562
    +2563
    +2564
    +2565
    +2566
    +2567
    +2568
    +2569
    +2570
    +2571
    +2572
    +2573
    +2574
    +2575
    +2576
    +2577
    +2578
    +2579
    +2580
    +2581
    +2582
    +2583
    +2584
    +2585
    +2586
    +2587
    +2588
    +2589
    +2590
    +2591
    +2592
    +2593
    +2594
    +2595
    +2596
    +2597
    +2598
    +2599
    +2600
    +2601
    +2602
    +2603
    +2604
    +2605
    +2606
    +2607
    +2608
    +2609
    +2610
    +2611
    +2612
    +2613
    +2614
    +2615
    +2616
    +2617
    +2618
    +2619
    +2620
    +2621
    +2622
    +2623
    +2624
    +2625
    +2626
    +2627
    +2628
    +2629
    +2630
    +2631
    +2632
    +2633
    +2634
    +2635
    +2636
    +2637
    +2638
    +2639
    +2640
    +2641
    +2642
    +2643
    +2644
    +2645
    +2646
    +2647
    +2648
    +2649
    +2650
    +2651
    +2652
    +2653
    +2654
    +2655
    +2656
    +2657
    +2658
    +2659
    +2660
    +2661
    +2662
    +2663
    +2664
    +2665
    +2666
    +2667
    +2668
    +2669
    +2670
    +2671
    +2672
    +2673
    +2674
    +2675
    +2676
    +2677
    +2678
    +2679
    +2680
    +2681
    +2682
    +2683
    +2684
    +2685
    +2686
    +2687
    +2688
    +2689
    +2690
    +2691
    +2692
    +2693
    +2694
    +2695
    +2696
    +2697
    +2698
    +2699
    +2700
    +2701
    +2702
    +2703
    +2704
    +2705
    +2706
    +2707
    +2708
    +2709
    +2710
    +2711
    +2712
    +2713
    +2714
    +2715
    +2716
    +2717
    +2718
    +2719
    +2720
    +2721
    +2722
    +2723
    +2724
    +2725
    +2726
    +2727
    +2728
    +2729
    +2730
    +2731
    +2732
    +2733
    +2734
    +2735
    +2736
    +2737
    +2738
    +2739
    +2740
    +2741
    +2742
    +2743
    +2744
    +2745
    +2746
    +2747
    +2748
    +2749
    +2750
    +2751
    +2752
    +2753
    +2754
    +2755
    +2756
    +2757
    +2758
    +2759
    +2760
    +2761
    +2762
    +2763
    +2764
    +2765
    +2766
    +2767
    +2768
    +2769
    +2770
    +2771
    +2772
    +2773
    +2774
    +2775
    +2776
    +2777
    +2778
    +2779
    +2780
    +2781
    +2782
    +2783
    +2784
    +2785
    +2786
    +2787
    +2788
    +2789
    +2790
    +2791
    +2792
    +2793
    +2794
    +2795
    +2796
    +2797
    +2798
    +2799
    +2800
    +2801
    +2802
    +2803
    +2804
    +2805
    +2806
    +2807
    +2808
    +2809
    +2810
    +2811
    +2812
    +2813
    +2814
    +2815
    +2816
    +2817
    +2818
    +2819
    +2820
    +2821
    +2822
    +2823
    +2824
    +2825
    +2826
    +2827
    +2828
    +2829
    +2830
    +2831
    +2832
    +2833
    +2834
    +2835
    +2836
    +2837
    +2838
    +2839
    +2840
    +2841
    +2842
    +2843
    +2844
    +2845
    +2846
    +2847
    +2848
    +2849
    +2850
    +2851
    +2852
    +2853
    +2854
    +2855
    +2856
    +2857
    +2858
    +2859
    +2860
    +2861
    +2862
    +2863
    +2864
    +2865
    +2866
    +2867
    +2868
    +2869
    +2870
    +2871
    +2872
    +2873
    +2874
    +2875
    +2876
    +2877
    +2878
    +2879
    +2880
    +2881
    +2882
    +2883
    +2884
    +2885
    +2886
    +2887
    +2888
    +2889
    +2890
    +2891
    +2892
    +2893
    +2894
    +2895
    +2896
    +2897
    +2898
    +2899
    +2900
    +2901
    +2902
    +2903
    +2904
    +2905
    +2906
    +2907
    +2908
    +2909
    +2910
    +2911
    +2912
    +2913
    +2914
    +2915
    +2916
    +2917
    +2918
    +2919
    +2920
    +2921
    +2922
    +2923
    +2924
    +2925
    +2926
    +2927
    +2928
    +2929
    +2930
    +2931
    +2932
    +2933
    +2934
    +2935
    +2936
    +2937
    +2938
    +2939
    +2940
    +2941
    +2942
    +2943
    +2944
    +2945
    +2946
    +2947
    +2948
    +2949
    +2950
    +2951
    +2952
    +2953
    +2954
    +2955
    +2956
    +2957
    +2958
    +2959
    +2960
    +2961
    +2962
    +2963
    +2964
    +2965
    +2966
    +2967
    +2968
    +2969
    +2970
    +2971
    +2972
    +2973
    +2974
    +2975
    +2976
    +2977
    +2978
    +2979
    +2980
    +2981
    +2982
    +2983
    +2984
    +2985
    +2986
    +2987
    +2988
    +2989
    +2990
    +2991
    +2992
    +2993
    +2994
    +2995
    +2996
    +2997
    +2998
    +2999
    +3000
    +3001
    +3002
    +3003
    +3004
    +3005
    +3006
    +3007
    +3008
    +3009
    +3010
    +3011
    +3012
    +3013
    +3014
    +3015
    +3016
    +3017
    +3018
    +3019
    +3020
    +3021
    +3022
    +3023
    +3024
    +3025
    +3026
    +3027
    +3028
    +3029
    +3030
    +3031
    +3032
    +3033
    +3034
    +3035
    +3036
    +3037
    +3038
    +3039
    +3040
    +3041
    +3042
    +3043
    +3044
    +3045
    +3046
    +3047
    +3048
    +3049
    +3050
    +3051
    +3052
    +3053
    +3054
    +3055
    +3056
    +3057
    +3058
    +3059
    +3060
    +3061
    +3062
    +3063
    +3064
    +3065
    +3066
    +3067
    +3068
    +3069
    +3070
    +3071
    +3072
    +3073
    +3074
    +3075
    +3076
    +3077
    +3078
    +3079
    +3080
    +3081
    +3082
    +3083
    +3084
    +3085
    +3086
    +3087
    +3088
    +3089
    +3090
    +3091
    +3092
    +3093
    +3094
    +3095
    +3096
    +3097
    +3098
    +3099
    +3100
    +3101
    +3102
    +3103
    +3104
    +3105
    +3106
    +3107
    +3108
    +3109
    +3110
    +3111
    +3112
    +3113
    +3114
    +3115
    +3116
    +3117
    +3118
    +3119
    +3120
    +3121
    +3122
    +3123
    +3124
    +3125
    +3126
    +3127
    +3128
    +3129
    +3130
    +3131
    +3132
    +3133
    +3134
    +3135
    +3136
    +3137
    +3138
    +3139
    +3140
    +3141
    +3142
    +3143
    +3144
    +3145
    +3146
    +3147
    +3148
    +3149
    +3150
    +3151
    +3152
    +3153
    +3154
    +3155
    +3156
    +3157
    +3158
    +3159
    +3160
    +3161
    +3162
    +3163
    +3164
    +3165
    +3166
    +3167
    +3168
    +3169
    +3170
    +3171
    +3172
    +3173
    +3174
    +3175
    +3176
    +3177
    +3178
    +3179
    +3180
    +3181
    +3182
    +3183
    +3184
    +3185
    +3186
    +3187
    +3188
    +3189
    +3190
    +3191
    +3192
    +3193
    +3194
    +3195
    +3196
    +3197
    +3198
    +3199
    +3200
    +3201
    +3202
    +3203
    +3204
    +3205
    +3206
    +3207
    +3208
    +3209
    +3210
    +3211
    +3212
    +3213
    +3214
    +3215
    +3216
    +3217
    +3218
    +3219
    +3220
    +3221
    +3222
    +3223
    +3224
    +3225
    +3226
    +3227
    +3228
    +3229
    +3230
    +3231
    +3232
    +3233
    +3234
    +3235
    +3236
    +3237
    +3238
    +3239
    +3240
    +3241
    +3242
    +3243
    +3244
    +3245
    +3246
    +3247
    +3248
    +3249
    +3250
    +3251
    +3252
    +3253
    +3254
    +3255
    +3256
    +3257
    +3258
    +3259
    +3260
    +3261
    +3262
    +3263
    +3264
    +3265
    +3266
    +3267
    +3268
    +3269
    +3270
    +3271
    +3272
    +3273
    +3274
    +3275
    +3276
    +3277
    +3278
    +3279
    +3280
    +3281
    +3282
    +3283
    +3284
    +3285
    +3286
    +3287
    +3288
    +3289
    +3290
    +3291
    +3292
    +3293
    +3294
    +3295
    +3296
    +3297
    +3298
    +3299
    +3300
    +3301
    +3302
    +3303
    +3304
    +3305
    +3306
    +3307
    +3308
    +3309
    +3310
    +3311
    +3312
    +3313
    +3314
    +3315
    +3316
    +3317
    +3318
    +3319
    +3320
    +3321
    +3322
    +3323
    +3324
    +3325
    +3326
    +3327
    +3328
    +3329
    +3330
    +3331
    +3332
    +3333
    +3334
    +3335
    +3336
    +3337
    +3338
    +3339
    +3340
    +3341
    +3342
    +3343
    +3344
    +3345
    +3346
    +3347
    +3348
    +3349
    +3350
    +3351
    +3352
    +3353
    +3354
    +3355
    +3356
    +3357
    +3358
    +3359
    +3360
    +3361
    +3362
    +3363
    +3364
    +3365
    +3366
    +3367
    +3368
    +3369
    +3370
    +3371
    +3372
    +3373
    +3374
    +3375
    +3376
    +3377
    +3378
    +3379
    +3380
    +3381
    +3382
    +3383
    +3384
    +3385
    +3386
    +3387
    +3388
    +3389
    +3390
    +3391
    +3392
    +3393
    +3394
    +3395
    +3396
    +3397
    +3398
    +3399
    +3400
    +3401
    +3402
    +3403
    +3404
    +3405
    +3406
    +3407
    +3408
    +3409
    +3410
    +3411
    +3412
    +3413
    +3414
    +3415
    +3416
    +3417
    +3418
    +3419
    +3420
    +3421
    +3422
    +3423
    +3424
    +3425
    +3426
    +3427
    +3428
    +3429
    +3430
    +3431
    +3432
    +3433
    +3434
    +3435
    +3436
    +3437
    +3438
    +3439
    +3440
    +3441
    +3442
    +3443
    +3444
    +3445
    +3446
    +3447
    +3448
    +3449
    +3450
    +3451
    +3452
    +3453
    +3454
    +3455
    +3456
    +3457
    +3458
    +3459
    +3460
    +3461
    +3462
    +3463
    +3464
    +3465
    +3466
    +3467
    +3468
    +3469
    +3470
    +3471
    +3472
    +3473
    +3474
    +3475
    +3476
    +3477
    +3478
    +3479
    +3480
    +3481
    +3482
    +3483
    +3484
    +3485
    +3486
    +3487
    +3488
    +3489
    +3490
    +3491
    +3492
    +3493
    +3494
    +3495
    +3496
    +3497
    +3498
    +3499
    +3500
    +3501
    +3502
    +3503
    +3504
    +3505
    +3506
    +3507
    +3508
    +3509
    +3510
    +3511
    +3512
    +3513
    +3514
    +3515
    +3516
    +3517
    +3518
    +3519
    +3520
    +3521
    +3522
    +3523
    +3524
    +3525
    +3526
    +3527
    +3528
    +3529
    +3530
    +3531
    +3532
    +3533
    +3534
    +3535
    +3536
    +3537
    +3538
    +3539
    +3540
    +3541
    +3542
    +3543
    +3544
    +3545
    +3546
    +3547
    +3548
    +3549
    +3550
    +3551
    +3552
    +3553
    +3554
    +3555
    +3556
    +3557
    +3558
    +3559
    +3560
    +3561
    +3562
    +3563
    +3564
    +3565
    +3566
    +3567
    +3568
    +3569
    +3570
    +3571
    +3572
    +3573
    +3574
    +3575
    +3576
    +3577
    +3578
    +3579
    +3580
    +3581
    +3582
    +3583
    +3584
    +3585
    +3586
    +3587
    +3588
    +3589
    +3590
    +3591
    +3592
    +3593
    +3594
    +3595
    +3596
    +3597
    +3598
    +3599
    +3600
    +3601
    +3602
    +3603
    +3604
    +3605
    +3606
    +3607
    +3608
    +3609
    +3610
    +3611
    +3612
    +3613
    +3614
    +3615
    +3616
    +3617
    +3618
    +3619
    +3620
    +3621
    +3622
    +3623
    +3624
    +3625
    +3626
    +3627
    +3628
    +3629
    +3630
    +3631
    +3632
    +3633
    +3634
    +3635
    +3636
    +3637
    +3638
    +3639
    +3640
    +3641
    +3642
    +3643
    +3644
    +3645
    +3646
    +3647
    +3648
    +3649
    +3650
    +3651
    +3652
    +3653
    +3654
    +3655
    +3656
    +3657
    +3658
    +3659
    +3660
    +3661
    +3662
    +3663
    +3664
    +3665
    +3666
    +3667
    +3668
    +3669
    +3670
    +3671
    +3672
    +3673
    +3674
    +3675
    +3676
    +3677
    +3678
    +3679
    +3680
    +3681
    +3682
    +3683
    +3684
    +3685
    +3686
    +3687
    +3688
    +3689
    +3690
    +3691
    +3692
    +3693
    +3694
    +3695
    +3696
    +3697
    +3698
    +3699
    +3700
    +3701
    +3702
    +3703
    +3704
    +3705
    +3706
    +3707
    +3708
    +3709
    +3710
    +3711
    +3712
    +3713
    +3714
    +3715
    +3716
    +3717
    +3718
    +3719
    +3720
    +3721
    +3722
    +3723
    +3724
    +3725
    +3726
    +3727
    +3728
    +3729
    +3730
    +3731
    +3732
    +3733
    +3734
    +3735
    +3736
    +3737
    +3738
    +3739
    +3740
    +3741
    +3742
    +3743
    +3744
    +3745
    +3746
    +3747
    +3748
    +3749
    +3750
    +3751
    +3752
    +3753
    +3754
    +3755
    +3756
    +3757
    +3758
    +3759
    +3760
    +3761
    +3762
    +3763
    +3764
    +3765
    +3766
    +3767
    +3768
    +3769
    +3770
    +3771
    +3772
    +3773
    +3774
    +3775
    +3776
    +3777
    +3778
    +3779
    +3780
    +3781
    +3782
    +3783
    +3784
    +3785
    +3786
    +3787
    +3788
    +3789
    +3790
    +3791
    +3792
    +3793
    +3794
    +3795
    +3796
    +3797
    +3798
    +3799
    +3800
    +3801
    +3802
    +3803
    +3804
    +3805
    +3806
    +3807
    +3808
    +3809
    +3810
    +3811
    +3812
    +3813
    +3814
    +3815
    +3816
    +3817
    +3818
    +3819
    +3820
    +3821
    +3822
    +3823
    +3824
    +3825
    +3826
    +3827
    +3828
    +3829
    +3830
    +3831
    +3832
    +3833
    +3834
    +3835
    +3836
    +3837
    +3838
    +3839
    +3840
    +3841
    +3842
    +3843
    +3844
    +3845
    +3846
    +3847
    +3848
    +3849
    +3850
    +3851
    +3852
    +3853
    +3854
    +3855
    +3856
    +3857
    +3858
    +3859
    +3860
    +3861
    +3862
    +3863
    +3864
    +3865
    +3866
    +3867
    +3868
    +3869
    +3870
    +3871
    +3872
    +3873
    +3874
    +3875
    +3876
    +3877
    +3878
    +3879
    +3880
    +3881
    +3882
    +3883
    +3884
    +3885
    +3886
    +3887
    +3888
    +3889
    +3890
    +3891
    +3892
    +3893
    +3894
    +3895
    +3896
    +3897
    +3898
    +3899
    +3900
    +3901
    +3902
    +3903
    +3904
    +3905
    +3906
    +3907
    +3908
    +3909
    +3910
    +3911
    +3912
    +3913
    +3914
    +3915
    +3916
    +3917
    +3918
    +3919
    +3920
    +3921
    +3922
    +3923
    +3924
    +3925
    +3926
    +3927
    +3928
    +3929
    +3930
    +3931
    +3932
    +3933
    +3934
    +3935
    +3936
    +3937
    +3938
    +3939
    +3940
    +3941
    +3942
    +3943
    +3944
    +3945
    +3946
    +3947
    +3948
    +3949
    +3950
    +3951
    +3952
    +3953
    +3954
    +3955
    +3956
    +3957
    +3958
    +3959
    +3960
    +3961
    +3962
    +3963
    +3964
    +3965
    +3966
    +3967
    +3968
    +3969
    +3970
    +3971
    +3972
    +3973
    +3974
    +3975
    +3976
    +3977
    +3978
    +3979
    +3980
    +3981
    +3982
    +3983
    +3984
    +3985
    +3986
    +3987
    +3988
    +3989
    +3990
    +3991
    +3992
    +3993
    +3994
    +3995
    +3996
    +3997
    +3998
    +3999
    +4000
    +4001
    +4002
    +4003
    +4004
    +4005
    +4006
    +4007
    +4008
    +4009
    +4010
    +4011
    +4012
    +4013
    +4014
    +4015
    +4016
    +4017
    +4018
    +4019
    +4020
    +4021
    +4022
    +4023
    +4024
    +4025
    +4026
    +4027
    +4028
    +4029
    +4030
    +4031
    +4032
    +4033
    +4034
    +4035
    +4036
    +4037
    +4038
    +4039
    +4040
    +4041
    +4042
    +4043
    +4044
    +4045
    +4046
    +4047
    +4048
    +4049
    +4050
    +4051
    +4052
    +4053
    +4054
    +4055
    +4056
    +4057
    +4058
    +4059
    +4060
    +4061
    +4062
    +4063
    +4064
    +4065
    +4066
    +4067
    +4068
    +4069
    +4070
    +4071
    +4072
    +4073
    +4074
    +4075
    +4076
    +4077
    +4078
    +4079
    +4080
    +4081
    +4082
    +4083
    +4084
    +4085
    +4086
    +4087
    +4088
    +4089
    +4090
    +4091
    +4092
    +4093
    +4094
    +4095
    +4096
    +4097
    +4098
    +4099
    +4100
    +4101
    +4102
    +4103
    +4104
    +4105
    +4106
    +4107
    +4108
    +4109
    +4110
    +4111
    +4112
    +4113
    +4114
    +4115
    +4116
    +4117
    +4118
    +4119
    +4120
    +4121
    +4122
    +4123
    +4124
    +4125
    +4126
    +4127
    +4128
    +4129
    +4130
    +4131
    +4132
    +4133
    +4134
    +4135
    +4136
    +4137
    +4138
    +4139
    +4140
    +4141
    +4142
    +4143
    +4144
    +4145
    +4146
    +4147
    +4148
    +4149
    +4150
    +4151
    +4152
    +4153
    +4154
    +4155
    +4156
    +4157
    +4158
    +4159
    +4160
    +4161
    +4162
    +4163
    +4164
    +4165
    +4166
    +4167
    +4168
    +4169
    +4170
    +4171
    +4172
    +4173
    +4174
    +4175
    +4176
    +4177
    +4178
    +4179
    +4180
    +4181
    +4182
    +4183
    +4184
    +4185
    +4186
    +4187
    +4188
    +4189
    +4190
    +4191
    +4192
    +4193
    +4194
    +4195
    +4196
    +4197
    +4198
    +4199
    +4200
    +4201
    +4202
    +4203
    +4204
    +4205
    +4206
    +4207
    +4208
    +4209
    +4210
    +4211
    +4212
    +4213
    +4214
    +4215
    +4216
    +4217
    +4218
    +4219
    +4220
    +4221
    +4222
    +4223
    +4224
    +4225
    +4226
    +4227
    +4228
    +4229
    +4230
    +4231
    +4232
    +4233
    +4234
    +4235
    +4236
    +4237
    +4238
    +4239
    +4240
    +4241
    +4242
    +4243
    +4244
    +4245
    +4246
    +4247
    +4248
    +4249
    +4250
    +4251
    +4252
    +4253
    +4254
    +4255
    +4256
    +4257
    +4258
    +4259
    +4260
    +4261
    +4262
    +4263
    +4264
    +4265
    +4266
    +4267
    +4268
    +4269
    +4270
    +4271
    +4272
    +4273
    +4274
    +4275
    +4276
    +4277
    +4278
    +4279
    +4280
    +4281
    +4282
    +4283
    +4284
    +4285
    +4286
    +4287
    +4288
    +4289
    +4290
    +4291
    +4292
    +4293
    +4294
    +4295
    +4296
    +4297
    +4298
    +4299
    +4300
    +4301
    +4302
    +4303
    +4304
    +4305
    +4306
    +4307
    +4308
    +4309
    +4310
    +4311
    +4312
    +4313
    +4314
    +4315
    +4316
    +4317
    +4318
    +4319
    +4320
    +4321
    +4322
    +4323
    +4324
    +4325
    +4326
    +4327
    +4328
    +4329
    +4330
    +4331
    +4332
    +4333
    +4334
    +4335
    +4336
    +4337
    +4338
    +4339
    +4340
    +4341
    +4342
    +4343
    +4344
    +4345
    +4346
    +4347
    +4348
    +4349
    +4350
    +4351
    +4352
    +4353
    +4354
    +4355
    +4356
    +4357
    +4358
    +4359
    +4360
    +4361
    +4362
    +4363
    +4364
    +4365
    +4366
    +4367
    +4368
    +4369
    +4370
    +4371
    +4372
    +4373
    +4374
    +4375
    +4376
    +4377
    +4378
    +4379
    +4380
    +4381
    +4382
    +4383
    +4384
    +4385
    +4386
    +4387
    +4388
    +4389
    +4390
    +4391
    +4392
    +4393
    +4394
    +4395
    +4396
    +4397
    +4398
    +4399
    +4400
    +4401
    +4402
    +4403
    +4404
    +4405
    +4406
    +4407
    +4408
    +4409
    +4410
    +4411
    +4412
    +4413
    +4414
    +4415
    +4416
    +4417
    +4418
    +4419
    +4420
    +4421
    +4422
    +4423
    +4424
    +4425
    +4426
    +4427
    +4428
    +4429
    +4430
    +4431
    +4432
    +4433
    +4434
    +4435
    +4436
    +4437
    +4438
    +4439
    +4440
    +4441
    +4442
    +4443
    +4444
    +4445
    +4446
    +4447
    +4448
    +4449
    +4450
    +4451
    +4452
    +4453
    +4454
    +4455
    +4456
    +4457
    +4458
    +4459
    +4460
    +4461
    +4462
    +4463
    +4464
    +4465
    +4466
    +4467
    +4468
    +4469
    +4470
    +4471
    +4472
    +4473
    +4474
    +4475
    +4476
    +4477
    +4478
    +4479
    +4480
    +4481
    +4482
    +4483
    +4484
    +4485
    +4486
    +4487
    +4488
    +4489
    +4490
    +4491
    +4492
    +4493
    +4494
    +4495
    +4496
    +4497
    +4498
    +4499
    +4500
    +4501
    +4502
    +4503
    +4504
    +4505
    +4506
    +4507
    +4508
    +4509
    +4510
    +4511
    +4512
    +4513
    +4514
    +4515
    +4516
    +4517
    +4518
    +4519
    +4520
    +4521
    +4522
    +4523
    +4524
    +4525
    +4526
    +4527
    +4528
    +4529
    +4530
    +4531
    +4532
    +4533
    +4534
    +4535
    +4536
    +4537
    +4538
    +4539
    +4540
    +4541
    +4542
    +4543
    +4544
    +4545
    +4546
    +4547
    +4548
    +4549
    +4550
    +4551
    +4552
    +4553
    +4554
    +4555
    +4556
    +4557
    +4558
    +4559
    +4560
    +4561
    +4562
    +4563
    +4564
    +4565
    +4566
    +4567
    +4568
    +4569
    +4570
    +4571
    +4572
    +4573
    +4574
    +4575
    +4576
    +4577
    +4578
    +4579
    +4580
    +4581
    +4582
    +4583
    +4584
    +4585
    +4586
    +4587
    +4588
    +4589
    +4590
    +4591
    +4592
    +4593
    +4594
    +4595
    +4596
    +4597
    +4598
    +4599
    +4600
    +4601
    +4602
    +4603
    +4604
    +4605
    +4606
    +4607
    +4608
    +4609
    +4610
    +4611
    +4612
    +4613
    +4614
    +4615
    +4616
    +4617
    +4618
    +4619
    +4620
    +4621
    +4622
    +4623
    +4624
    +4625
    +4626
    +4627
    +4628
    +4629
    +4630
    +4631
    +4632
    +4633
    +4634
    +4635
    +4636
    +4637
    +4638
    +4639
    +4640
    +4641
    +4642
    +4643
    +4644
    +4645
    +4646
    +4647
    +4648
    +4649
    +4650
    +4651
    +4652
    +4653
    +4654
    +4655
    +4656
    +4657
    +4658
    +4659
    +4660
    +4661
    +4662
    +4663
    +4664
    +4665
    +4666
    +4667
    +4668
    +4669
    +4670
    +4671
    +4672
    +4673
    +4674
    +4675
    +4676
    +4677
    +4678
    +4679
    +4680
    +4681
    +4682
    +4683
    +4684
    +4685
    +4686
    +4687
    +4688
    +4689
    +4690
    +4691
    +4692
    +4693
    +4694
    +4695
    +4696
    +4697
    +4698
    +4699
    +4700
    +4701
    +4702
    +4703
    +4704
    +4705
    +4706
    +4707
    +4708
    +4709
    +4710
    +4711
    +4712
    +4713
    +4714
    +4715
    +4716
    +4717
    +4718
    +4719
    +4720
    +4721
    +4722
    +4723
    +4724
    +4725
    +4726
    +4727
    +4728
    +4729
    +4730
    +4731
    +4732
    +4733
    +4734
    +4735
    +4736
    +4737
    +4738
    +4739
    +4740
    +4741
    +4742
    +4743
    +4744
    +4745
    +4746
    +4747
    +4748
    +4749
    +4750
    +4751
    +4752
    +4753
    +4754
    +4755
    +4756
    +4757
    +4758
    +4759
    +4760
    +4761
    +4762
    +4763
    +4764
    +4765
    +4766
    +4767
    +4768
    +4769
    +4770
    +4771
    +4772
    +4773
    +4774
    +4775
    +4776
    +4777
    +4778
    +4779
    +4780
    +4781
    +4782
    +4783
    +4784
    +4785
    +4786
    +4787
    +4788
    +4789
    +4790
    +4791
    +4792
    +4793
    +4794
    +4795
    +4796
    +4797
    +4798
    +4799
    +4800
    +4801
    +4802
    +4803
    +4804
    +4805
    +4806
    +4807
    +4808
    +4809
    +4810
    +4811
    +4812
    +4813
    +4814
    +4815
    +4816
    +4817
    +4818
    +4819
    +4820
    +4821
    +4822
    +4823
    +4824
    +4825
    +4826
    +4827
    +4828
    +4829
    +4830
    +4831
    +4832
    +4833
    +4834
    +4835
    +4836
    +4837
    +4838
    +4839
    +4840
    +4841
    +4842
    +4843
    +4844
    +4845
    +4846
    +4847
    +4848
    +4849
    +4850
    +4851
    +4852
    +4853
    +4854
    +4855
    +4856
    +4857
    +4858
    +4859
    +4860
    +4861
    +4862
    +4863
    +4864
    +4865
    +4866
    +4867
    +4868
    +4869
    +4870
    +4871
    +4872
    +4873
    +4874
    +4875
    +4876
    +4877
    +4878
    +4879
    +4880
    +4881
    +4882
    +4883
    +4884
    +4885
    +4886
    +4887
    +4888
    +4889
    +4890
    +4891
    +4892
    +4893
    +4894
    +4895
    +4896
    +4897
    +4898
    +4899
    +4900
    +4901
    +4902
    +4903
    +4904
    +4905
    +4906
    +4907
    +4908
    +4909
    +4910
    +4911
    +4912
    +4913
    +4914
    +4915
    +4916
    +4917
    +4918
    +4919
    +4920
    +4921
    +4922
    +4923
    +4924
    +4925
    +4926
    +4927
    +4928
    +4929
    +4930
    +4931
    +4932
    +4933
    +4934
    +4935
    +4936
    +4937
    +4938
    +4939
    +4940
    +4941
    +4942
    +4943
    +4944
    +4945
    +4946
    +4947
    +4948
    +4949
    +4950
    +4951
    +4952
    +4953
    +4954
    +4955
    +4956
    +4957
    +4958
    +4959
    +4960
    +4961
    +4962
    +4963
    +4964
    +4965
    +4966
    +4967
    +4968
    +4969
    +4970
    +4971
    +4972
    +4973
    +4974
    +4975
    +4976
    +4977
    +4978
    +4979
    +4980
    +4981
    +4982
    +4983
    +4984
    +4985
    +4986
    +4987
    +4988
    +4989
    +4990
    +4991
    +4992
    +4993
    +4994
    +4995
    +4996
    +4997
    +4998
    +4999
    +5000
    +5001
    +5002
    +5003
    +5004
    +5005
    +5006
    +5007
    +5008
    +5009
    +5010
    +5011
    +5012
    +5013
    +5014
    +5015
    +5016
    +5017
    +5018
    +5019
    +5020
    +5021
    +5022
    +5023
    +5024
    +5025
    +5026
    +5027
    +5028
    +5029
    +5030
    +5031
    +5032
    +5033
    +5034
    +5035
    +5036
    +5037
    +5038
    +5039
    +5040
    +5041
    +5042
    +5043
    +5044
    +5045
    +5046
    +5047
    +5048
    +5049
    +5050
    +5051
    +5052
    +5053
    +5054
    +5055
    +5056
    +5057
    +5058
    +5059
    +5060
    +5061
    +5062
    +5063
    +5064
    +5065
    +5066
    +5067
    +5068
    +5069
    +5070
    +5071
    +5072
    +5073
    +5074
    +5075
    +5076
    +5077
    +5078
    +5079
    +5080
    +5081
    +5082
    +5083
    +5084
    +5085
    +5086
    +5087
    +5088
    +5089
    +5090
    +5091
    +5092
    +5093
    +5094
    +5095
    +5096
    +5097
    +5098
    +5099
    +5100
    +5101
    +5102
    +5103
    +5104
    +5105
    +5106
    +5107
    +5108
    +5109
    +5110
    +5111
    +5112
    +5113
    +5114
    +5115
    +5116
    +5117
    +5118
    +5119
    +5120
    +5121
    +5122
    +5123
    +5124
    +5125
    +5126
    +5127
    +5128
    +5129
    +5130
    +5131
    +5132
    +5133
    +5134
    +5135
    +5136
    +5137
    +5138
    +5139
    +5140
    +5141
    +5142
    +5143
    +5144
    +5145
    +5146
    +5147
    +5148
    +5149
    +5150
    +5151
    +5152
    +5153
    +5154
    +5155
    +5156
    +5157
    +5158
    +5159
    +5160
    +5161
    +5162
    +5163
    +5164
    +5165
    +5166
    +5167
    +5168
    +5169
    +5170
    +5171
    +5172
    +5173
    +5174
    +5175
    +5176
    +5177
    +5178
    +5179
    +5180
    +5181
    +5182
    +5183
    +5184
    +5185
    +5186
    +5187
    +5188
    +5189
    +5190
    +5191
    +5192
    +5193
    +5194
    +5195
    +5196
    +5197
    +5198
    +5199
    +5200
    +5201
    +5202
    +5203
    +5204
    +5205
    +5206
    +5207
    +5208
    +5209
    +5210
    +5211
    +5212
    +5213
    +5214
    +5215
    +5216
    +5217
    +5218
    +5219
    +5220
    +5221
    +5222
    +5223
    +5224
    +5225
    +5226
    +5227
    +5228
    +5229
    +5230
    +5231
    +5232
    +5233
    +5234
    +5235
    +5236
    +5237
    +5238
    +5239
    +5240
    +5241
    +5242
    +5243
    +5244
    +5245
    +5246
    +5247
    +5248
    +5249
    +5250
    +5251
    +5252
    +5253
    +5254
    +5255
    +5256
    +5257
    +5258
    +5259
    +5260
    +5261
    +5262
    +5263
    +5264
    +5265
    +5266
    +5267
    +5268
    +5269
    +5270
    +5271
    +5272
    +5273
    +5274
    +5275
    +5276
    +5277
    +5278
    +5279
    +5280
    +5281
    +5282
    +5283
    +5284
    +5285
    +5286
    +5287
    +5288
    +5289
    +5290
    +5291
    +5292
    +5293
    +5294
    +5295
    +5296
    +5297
    +5298
    +5299
    +5300
    +5301
    +5302
    +5303
    +5304
    +5305
    +5306
    +5307
    +5308
    +5309
    +5310
    +5311
    +5312
    +5313
    +5314
    +5315
    +5316
    +5317
    +5318
    +5319
    +5320
    +5321
    +5322
    +5323
    +5324
    +5325
    +5326
    +5327
    +5328
    +5329
    +5330
    +5331
    +5332
    +5333
    +5334
    +5335
    +5336
    +5337
    +5338
    +5339
    +5340
    +5341
    +5342
    +5343
    +5344
    +5345
    +5346
    +5347
    +5348
    +5349
    +5350
    +5351
    +5352
    +5353
    +5354
    +5355
    +5356
    +5357
    +5358
    +5359
    +5360
    +5361
    +5362
    +5363
    +5364
    +5365
    +5366
    +5367
    +5368
    +5369
    +5370
    +5371
    +5372
    +5373
    +5374
    +5375
    +5376
    +5377
    +5378
    +5379
    +5380
    +5381
    +5382
    +5383
    +5384
    +5385
    +5386
    +5387
    +5388
    +5389
    +5390
    +5391
    +5392
    +5393
    +5394
    +5395
    +5396
    +5397
    +5398
    +5399
    +5400
    +5401
    +5402
    +5403
    +5404
    +5405
    +5406
    +5407
    +5408
    +5409
    +5410
    +5411
    +5412
    +5413
    +5414
    +5415
    +5416
    +5417
    +5418
    +5419
    +5420
    +5421
    +5422
    +5423
    +5424
    +5425
    +5426
    +5427
    +5428
    +5429
    +5430
    +5431
    +5432
    +5433
    +5434
    +5435
    +5436
    +5437
    +5438
    +5439
    +5440
    +5441
    +5442
    +5443
    +5444
    +5445
    +5446
    +5447
    +5448
    +5449
    +5450
    +5451
    +5452
    +5453
    +5454
    +5455
    +5456
    +5457
    +5458
    +5459
    +5460
    +5461
    +5462
    +5463
    +5464
    +5465
    +5466
    +5467
    +5468
    +5469
    +5470
    +5471
    +5472
    +5473
    +5474
    +5475
    +5476
    +5477
    +5478
    +5479
    +5480
    +5481
    +5482
    +5483
    +5484
    +5485
    +5486
    +5487
    +5488
    +5489
    +5490
    +5491
    +5492
    +5493
    +5494
    +5495
    +5496
    +5497
    +5498
    +5499
    +5500
    +5501
    +5502
    +5503
    +5504
    +5505
    +5506
    +5507
    +5508
    +5509
    +5510
    +5511
    +5512
    +5513
    +5514
    +5515
    +5516
    +5517
    +5518
    +5519
    +5520
    +5521
    +5522
    +5523
    +5524
    +5525
    +5526
    +5527
    +5528
    +5529
    +5530
    +5531
    +5532
    +5533
    +5534
    +5535
    +5536
    +5537
    +5538
    +5539
    +5540
    +5541
    +5542
    +5543
    +5544
    +5545
    +5546
    +5547
    +5548
    +5549
    +5550
    +5551
    +5552
    +5553
    +5554
    +5555
    +5556
    +5557
    +5558
    +5559
    +5560
    +5561
    +5562
    +5563
    +5564
    +5565
    +5566
    +5567
    +5568
    +5569
    +5570
    +5571
    +5572
    +5573
    +5574
    +5575
    +5576
    +5577
    +5578
    +5579
    +5580
    +5581
    +5582
    +5583
    +5584
    +5585
    +
    // Bitcoin Dev Kit
    +// Written in 2020 by Alekos Filini <alekos.filini@gmail.com>
    +//
    +// Copyright (c) 2020-2021 Bitcoin Dev Kit Developers
    +//
    +// This file is licensed under the Apache License, Version 2.0 <LICENSE-APACHE
    +// or http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
    +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your option.
    +// You may not use this file except in accordance with one or both of these
    +// licenses.
    +
    +//! Wallet
    +//!
    +//! This module defines the [`Wallet`] structure.
    +
    +use std::cell::RefCell;
    +use std::collections::HashMap;
    +use std::collections::{BTreeMap, HashSet};
    +use std::fmt;
    +use std::ops::{Deref, DerefMut};
    +use std::str::FromStr;
    +use std::sync::Arc;
    +
    +use bitcoin::secp256k1::Secp256k1;
    +
    +use bitcoin::consensus::encode::serialize;
    +use bitcoin::util::psbt;
    +use bitcoin::{
    +    Address, EcdsaSighashType, LockTime, Network, OutPoint, SchnorrSighashType, Script, Sequence,
    +    Transaction, TxOut, Txid, Witness,
     };
     
    -use miniscript::psbt::{PsbtExt, PsbtInputExt, PsbtInputSatisfier};
    -
    -#[allow(unused_imports)]
    -use log::{debug, error, info, trace};
    -
    -pub mod coin_selection;
    -pub mod export;
    -pub mod signer;
    -pub mod time;
    -pub mod tx_builder;
    -pub(crate) mod utils;
    -#[cfg(feature = "verify")]
    -#[cfg_attr(docsrs, doc(cfg(feature = "verify")))]
    -pub mod verify;
    -
    -#[cfg(feature = "hardware-signer")]
    -#[cfg_attr(docsrs, doc(cfg(feature = "hardware-signer")))]
    -pub mod hardwaresigner;
    -
    -pub use utils::IsDust;
    -
    -use coin_selection::DefaultCoinSelectionAlgorithm;
    -use signer::{SignOptions, SignerOrdering, SignersContainer, TransactionSigner};
    -use tx_builder::{BumpFee, CreateTx, FeePolicy, TxBuilder, TxParams};
    -use utils::{check_nsequence_rbf, After, Older, SecpCtx};
    -
    -use crate::blockchain::{GetHeight, NoopProgress, Progress, WalletSync};
    -use crate::database::memory::MemoryDatabase;
    -use crate::database::{AnyDatabase, BatchDatabase, BatchOperations, DatabaseUtils, SyncTime};
    -use crate::descriptor::checksum::calc_checksum_bytes_internal;
    -use crate::descriptor::policy::BuildSatisfaction;
    -use crate::descriptor::{
    -    calc_checksum, into_wallet_descriptor_checked, DerivedDescriptor, DescriptorMeta,
    -    ExtendedDescriptor, ExtractPolicy, IntoWalletDescriptor, Policy, XKeyUtils,
    +use miniscript::psbt::{PsbtExt, PsbtInputExt, PsbtInputSatisfier};
    +
    +#[allow(unused_imports)]
    +use log::{debug, error, info, trace};
    +
    +pub mod coin_selection;
    +pub mod export;
    +pub mod signer;
    +pub mod time;
    +pub mod tx_builder;
    +pub(crate) mod utils;
    +#[cfg(feature = "verify")]
    +#[cfg_attr(docsrs, doc(cfg(feature = "verify")))]
    +pub mod verify;
    +
    +#[cfg(feature = "hardware-signer")]
    +#[cfg_attr(docsrs, doc(cfg(feature = "hardware-signer")))]
    +pub mod hardwaresigner;
    +
    +pub use utils::IsDust;
    +
    +use coin_selection::DefaultCoinSelectionAlgorithm;
    +use signer::{SignOptions, SignerOrdering, SignersContainer, TransactionSigner};
    +use tx_builder::{BumpFee, CreateTx, FeePolicy, TxBuilder, TxParams};
    +use utils::{check_nsequence_rbf, After, Older, SecpCtx};
    +
    +use crate::blockchain::{GetHeight, NoopProgress, Progress, WalletSync};
    +use crate::database::memory::MemoryDatabase;
    +use crate::database::{AnyDatabase, BatchDatabase, BatchOperations, DatabaseUtils, SyncTime};
    +use crate::descriptor::checksum::calc_checksum_bytes_internal;
    +use crate::descriptor::policy::BuildSatisfaction;
    +use crate::descriptor::{
    +    calc_checksum, into_wallet_descriptor_checked, DerivedDescriptor, DescriptorMeta,
    +    ExtendedDescriptor, ExtractPolicy, IntoWalletDescriptor, Policy, XKeyUtils,
     };
    -use crate::error::{Error, MiniscriptPsbtError};
    -use crate::psbt::PsbtUtils;
    -use crate::signer::SignerError;
    -use crate::testutils;
    -use crate::types::*;
    -use crate::wallet::coin_selection::Excess::{Change, NoChange};
    -
    -const CACHE_ADDR_BATCH_SIZE: u32 = 100;
    -const COINBASE_MATURITY: u32 = 100;
    -
    -/// A Bitcoin wallet
    -///
    -/// The `Wallet` struct acts as a way of coherently interfacing with output descriptors and related transactions.
    -/// Its main components are:
    -///
    -/// 1. output *descriptors* from which it can derive addresses.
    -/// 2. A [`Database`] where it tracks transactions and utxos related to the descriptors.
    -/// 3. [`signer`]s that can contribute signatures to addresses instantiated from the descriptors.
    -///
    -/// [`Database`]: crate::database::Database
    -/// [`signer`]: crate::signer
    -#[derive(Debug)]
    -pub struct Wallet<D> {
    -    descriptor: ExtendedDescriptor,
    -    change_descriptor: Option<ExtendedDescriptor>,
    -
    -    signers: Arc<SignersContainer>,
    -    change_signers: Arc<SignersContainer>,
    -
    -    network: Network,
    -
    -    database: RefCell<D>,
    -
    -    secp: SecpCtx,
    +use crate::error::{Error, MiniscriptPsbtError};
    +use crate::psbt::PsbtUtils;
    +use crate::signer::SignerError;
    +use crate::testutils;
    +use crate::types::*;
    +use crate::wallet::coin_selection::Excess::{Change, NoChange};
    +
    +const CACHE_ADDR_BATCH_SIZE: u32 = 100;
    +const COINBASE_MATURITY: u32 = 100;
    +
    +/// A Bitcoin wallet
    +///
    +/// The `Wallet` struct acts as a way of coherently interfacing with output descriptors and related transactions.
    +/// Its main components are:
    +///
    +/// 1. output *descriptors* from which it can derive addresses.
    +/// 2. A [`Database`] where it tracks transactions and utxos related to the descriptors.
    +/// 3. [`signer`]s that can contribute signatures to addresses instantiated from the descriptors.
    +///
    +/// [`Database`]: crate::database::Database
    +/// [`signer`]: crate::signer
    +#[derive(Debug)]
    +pub struct Wallet<D> {
    +    descriptor: ExtendedDescriptor,
    +    change_descriptor: Option<ExtendedDescriptor>,
    +
    +    signers: Arc<SignersContainer>,
    +    change_signers: Arc<SignersContainer>,
    +
    +    network: Network,
    +
    +    database: RefCell<D>,
    +
    +    secp: SecpCtx,
     }
     
    -/// The address index selection strategy to use to derived an address from the wallet's external
    -/// descriptor. See [`Wallet::get_address`]. If you're unsure which one to use use `WalletIndex::New`.
    -#[derive(Debug)]
    -pub enum AddressIndex {
    -    /// Return a new address after incrementing the current descriptor index.
    -    New,
    -    /// Return the address for the current descriptor index if it has not been used in a received
    -    /// transaction. Otherwise return a new address as with [`AddressIndex::New`].
    -    ///
    -    /// Use with caution, if the wallet has not yet detected an address has been used it could
    -    /// return an already used address. This function is primarily meant for situations where the
    -    /// caller is untrusted; for example when deriving donation addresses on-demand for a public
    -    /// web page.
    -    LastUnused,
    -    /// Return the address for a specific descriptor index. Does not change the current descriptor
    -    /// index used by `AddressIndex::New` and `AddressIndex::LastUsed`.
    -    ///
    -    /// Use with caution, if an index is given that is less than the current descriptor index
    -    /// then the returned address may have already been used.
    -    Peek(u32),
    -    /// Return the address for a specific descriptor index and reset the current descriptor index
    -    /// used by `AddressIndex::New` and `AddressIndex::LastUsed` to this value.
    -    ///
    -    /// Use with caution, if an index is given that is less than the current descriptor index
    -    /// then the returned address and subsequent addresses returned by calls to `AddressIndex::New`
    -    /// and `AddressIndex::LastUsed` may have already been used. Also if the index is reset to a
    -    /// value earlier than the [`crate::blockchain::Blockchain`] stop_gap (default is 20) then a
    -    /// larger stop_gap should be used to monitor for all possibly used addresses.
    -    Reset(u32),
    +/// The address index selection strategy to use to derived an address from the wallet's external
    +/// descriptor. See [`Wallet::get_address`]. If you're unsure which one to use use `WalletIndex::New`.
    +#[derive(Debug)]
    +pub enum AddressIndex {
    +    /// Return a new address after incrementing the current descriptor index.
    +    New,
    +    /// Return the address for the current descriptor index if it has not been used in a received
    +    /// transaction. Otherwise return a new address as with [`AddressIndex::New`].
    +    ///
    +    /// Use with caution, if the wallet has not yet detected an address has been used it could
    +    /// return an already used address. This function is primarily meant for situations where the
    +    /// caller is untrusted; for example when deriving donation addresses on-demand for a public
    +    /// web page.
    +    LastUnused,
    +    /// Return the address for a specific descriptor index. Does not change the current descriptor
    +    /// index used by `AddressIndex::New` and `AddressIndex::LastUsed`.
    +    ///
    +    /// Use with caution, if an index is given that is less than the current descriptor index
    +    /// then the returned address may have already been used.
    +    Peek(u32),
    +    /// Return the address for a specific descriptor index and reset the current descriptor index
    +    /// used by `AddressIndex::New` and `AddressIndex::LastUsed` to this value.
    +    ///
    +    /// Use with caution, if an index is given that is less than the current descriptor index
    +    /// then the returned address and subsequent addresses returned by calls to `AddressIndex::New`
    +    /// and `AddressIndex::LastUsed` may have already been used. Also if the index is reset to a
    +    /// value earlier than the [`crate::blockchain::Blockchain`] stop_gap (default is 20) then a
    +    /// larger stop_gap should be used to monitor for all possibly used addresses.
    +    Reset(u32),
     }
     
    -/// A derived address and the index it was found at
    -/// For convenience this automatically derefs to `Address`
    -#[derive(Debug, PartialEq, Eq)]
    -pub struct AddressInfo {
    -    /// Child index of this address
    -    pub index: u32,
    -    /// Address
    -    pub address: Address,
    -    /// Type of keychain
    -    pub keychain: KeychainKind,
    +/// A derived address and the index it was found at
    +/// For convenience this automatically derefs to `Address`
    +#[derive(Debug, PartialEq, Eq)]
    +pub struct AddressInfo {
    +    /// Child index of this address
    +    pub index: u32,
    +    /// Address
    +    pub address: Address,
    +    /// Type of keychain
    +    pub keychain: KeychainKind,
     }
     
    -impl Deref for AddressInfo {
    -    type Target = Address;
    +impl Deref for AddressInfo {
    +    type Target = Address;
     
    -    fn deref(&self) -> &Self::Target {
    -        &self.address
    +    fn deref(&self) -> &Self::Target {
    +        &self.address
         }
     }
     
    -impl fmt::Display for AddressInfo {
    -    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
    -        write!(f, "{}", self.address)
    +impl fmt::Display for AddressInfo {
    +    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
    +        write!(f, "{}", self.address)
         }
     }
     
    -#[derive(Debug, Default)]
    -/// Options to a [`sync`].
    -///
    -/// [`sync`]: Wallet::sync
    -pub struct SyncOptions {
    -    /// The progress tracker which may be informed when progress is made.
    -    pub progress: Option<Box<dyn Progress>>,
    +#[derive(Debug, Default)]
    +/// Options to a [`sync`].
    +///
    +/// [`sync`]: Wallet::sync
    +pub struct SyncOptions {
    +    /// The progress tracker which may be informed when progress is made.
    +    pub progress: Option<Box<dyn Progress>>,
     }
     
    -impl<D> Wallet<D>
    -where
    -    D: BatchDatabase,
    +impl<D> Wallet<D>
    +where
    +    D: BatchDatabase,
     {
    -    #[deprecated = "Just use Wallet::new -- all wallets are offline now!"]
    -    /// Create a new "offline" wallet
    -    pub fn new_offline<E: IntoWalletDescriptor>(
    -        descriptor: E,
    -        change_descriptor: Option<E>,
    -        network: Network,
    -        database: D,
    -    ) -> Result<Self, Error> {
    -        Self::new(descriptor, change_descriptor, network, database)
    -    }
    -
    -    /// Create a wallet.
    -    ///
    -    /// The only way this can fail is if the descriptors passed in do not match the checksums in `database`.
    -    pub fn new<E: IntoWalletDescriptor>(
    -        descriptor: E,
    -        change_descriptor: Option<E>,
    -        network: Network,
    -        mut database: D,
    -    ) -> Result<Self, Error> {
    -        let secp = Secp256k1::new();
    -
    -        let (descriptor, keymap) = into_wallet_descriptor_checked(descriptor, &secp, network)?;
    -        Self::db_checksum(
    -            &mut database,
    -            &descriptor.to_string(),
    -            KeychainKind::External,
    +    #[deprecated = "Just use Wallet::new -- all wallets are offline now!"]
    +    /// Create a new "offline" wallet
    +    pub fn new_offline<E: IntoWalletDescriptor>(
    +        descriptor: E,
    +        change_descriptor: Option<E>,
    +        network: Network,
    +        database: D,
    +    ) -> Result<Self, Error> {
    +        Self::new(descriptor, change_descriptor, network, database)
    +    }
    +
    +    /// Create a wallet.
    +    ///
    +    /// The only way this can fail is if the descriptors passed in do not match the checksums in `database`.
    +    pub fn new<E: IntoWalletDescriptor>(
    +        descriptor: E,
    +        change_descriptor: Option<E>,
    +        network: Network,
    +        mut database: D,
    +    ) -> Result<Self, Error> {
    +        let secp = Secp256k1::new();
    +
    +        let (descriptor, keymap) = into_wallet_descriptor_checked(descriptor, &secp, network)?;
    +        Self::db_checksum(
    +            &mut database,
    +            &descriptor.to_string(),
    +            KeychainKind::External,
             )?;
    -        let signers = Arc::new(SignersContainer::build(keymap, &descriptor, &secp));
    -        let (change_descriptor, change_signers) = match change_descriptor {
    -            Some(desc) => {
    -                let (change_descriptor, change_keymap) =
    -                    into_wallet_descriptor_checked(desc, &secp, network)?;
    -                Self::db_checksum(
    -                    &mut database,
    -                    &change_descriptor.to_string(),
    -                    KeychainKind::Internal,
    +        let signers = Arc::new(SignersContainer::build(keymap, &descriptor, &secp));
    +        let (change_descriptor, change_signers) = match change_descriptor {
    +            Some(desc) => {
    +                let (change_descriptor, change_keymap) =
    +                    into_wallet_descriptor_checked(desc, &secp, network)?;
    +                Self::db_checksum(
    +                    &mut database,
    +                    &change_descriptor.to_string(),
    +                    KeychainKind::Internal,
                     )?;
     
    -                let change_signers = Arc::new(SignersContainer::build(
    -                    change_keymap,
    -                    &change_descriptor,
    -                    &secp,
    +                let change_signers = Arc::new(SignersContainer::build(
    +                    change_keymap,
    +                    &change_descriptor,
    +                    &secp,
                     ));
     
    -                (Some(change_descriptor), change_signers)
    +                (Some(change_descriptor), change_signers)
                 }
    -            None => (None, Arc::new(SignersContainer::new())),
    +            None => (None, Arc::new(SignersContainer::new())),
             };
     
    -        Ok(Wallet {
    -            descriptor,
    -            change_descriptor,
    -            signers,
    -            change_signers,
    -            network,
    -            database: RefCell::new(database),
    -            secp,
    +        Ok(Wallet {
    +            descriptor,
    +            change_descriptor,
    +            signers,
    +            change_signers,
    +            network,
    +            database: RefCell::new(database),
    +            secp,
             })
         }
     
    -    /// This checks the checksum within [`BatchDatabase`] twice (if needed). The first time with the
    -    /// actual checksum, and the second time with the checksum of `descriptor+checksum`. The second
    -    /// check is necessary for backwards compatibility of a checksum-inception bug.
    -    fn db_checksum(db: &mut D, desc: &str, kind: KeychainKind) -> Result<(), Error> {
    -        let checksum = calc_checksum_bytes_internal(desc, true)?;
    -        if db.check_descriptor_checksum(kind, checksum).is_ok() {
    -            return Ok(());
    +    /// This checks the checksum within [`BatchDatabase`] twice (if needed). The first time with the
    +    /// actual checksum, and the second time with the checksum of `descriptor+checksum`. The second
    +    /// check is necessary for backwards compatibility of a checksum-inception bug.
    +    fn db_checksum(db: &mut D, desc: &str, kind: KeychainKind) -> Result<(), Error> {
    +        let checksum = calc_checksum_bytes_internal(desc, true)?;
    +        if db.check_descriptor_checksum(kind, checksum).is_ok() {
    +            return Ok(());
             }
     
    -        let checksum_inception = calc_checksum_bytes_internal(desc, false)?;
    -        db.check_descriptor_checksum(kind, checksum_inception)
    +        let checksum_inception = calc_checksum_bytes_internal(desc, false)?;
    +        db.check_descriptor_checksum(kind, checksum_inception)
         }
     
    -    /// Get the Bitcoin network the wallet is using.
    -    pub fn network(&self) -> Network {
    -        self.network
    +    /// Get the Bitcoin network the wallet is using.
    +    pub fn network(&self) -> Network {
    +        self.network
         }
     
    -    // Return a newly derived address for the specified `keychain`.
    -    fn get_new_address(&self, keychain: KeychainKind) -> Result<AddressInfo, Error> {
    -        let incremented_index = self.fetch_and_increment_index(keychain)?;
    +    // Return a newly derived address for the specified `keychain`.
    +    fn get_new_address(&self, keychain: KeychainKind) -> Result<AddressInfo, Error> {
    +        let incremented_index = self.fetch_and_increment_index(keychain)?;
     
    -        let address_result = self
    -            .get_descriptor_for_keychain(keychain)
    -            .at_derivation_index(incremented_index)
    -            .address(self.network);
    +        let address_result = self
    +            .get_descriptor_for_keychain(keychain)
    +            .at_derivation_index(incremented_index)
    +            .address(self.network);
     
    -        address_result
    -            .map(|address| AddressInfo {
    -                address,
    -                index: incremented_index,
    -                keychain,
    +        address_result
    +            .map(|address| AddressInfo {
    +                address,
    +                index: incremented_index,
    +                keychain,
                 })
    -            .map_err(|_| Error::ScriptDoesntHaveAddressForm)
    -    }
    -
    -    // Return the the last previously derived address for `keychain` if it has not been used in a
    -    // received transaction. Otherwise return a new address using [`Wallet::get_new_address`].
    -    fn get_unused_address(&self, keychain: KeychainKind) -> Result<AddressInfo, Error> {
    -        let current_index = self.fetch_index(keychain)?;
    -
    -        let derived_key = self
    -            .get_descriptor_for_keychain(keychain)
    -            .at_derivation_index(current_index);
    -
    -        let script_pubkey = derived_key.script_pubkey();
    -
    -        let found_used = self
    -            .list_transactions(true)?
    -            .iter()
    -            .flat_map(|tx_details| tx_details.transaction.as_ref())
    -            .flat_map(|tx| tx.output.iter())
    -            .any(|o| o.script_pubkey == script_pubkey);
    -
    -        if found_used {
    -            self.get_new_address(keychain)
    -        } else {
    -            derived_key
    -                .address(self.network)
    -                .map(|address| AddressInfo {
    -                    address,
    -                    index: current_index,
    -                    keychain,
    +            .map_err(|_| Error::ScriptDoesntHaveAddressForm)
    +    }
    +
    +    // Return the the last previously derived address for `keychain` if it has not been used in a
    +    // received transaction. Otherwise return a new address using [`Wallet::get_new_address`].
    +    fn get_unused_address(&self, keychain: KeychainKind) -> Result<AddressInfo, Error> {
    +        let current_index = self.fetch_index(keychain)?;
    +
    +        let derived_key = self
    +            .get_descriptor_for_keychain(keychain)
    +            .at_derivation_index(current_index);
    +
    +        let script_pubkey = derived_key.script_pubkey();
    +
    +        let found_used = self
    +            .list_transactions(true)?
    +            .iter()
    +            .flat_map(|tx_details| tx_details.transaction.as_ref())
    +            .flat_map(|tx| tx.output.iter())
    +            .any(|o| o.script_pubkey == script_pubkey);
    +
    +        if found_used {
    +            self.get_new_address(keychain)
    +        } else {
    +            derived_key
    +                .address(self.network)
    +                .map(|address| AddressInfo {
    +                    address,
    +                    index: current_index,
    +                    keychain,
                     })
    -                .map_err(|_| Error::ScriptDoesntHaveAddressForm)
    +                .map_err(|_| Error::ScriptDoesntHaveAddressForm)
             }
         }
     
    -    // Return derived address for the descriptor of given [`KeychainKind`] at a specific index
    -    fn peek_address(&self, index: u32, keychain: KeychainKind) -> Result<AddressInfo, Error> {
    -        self.get_descriptor_for_keychain(keychain)
    -            .at_derivation_index(index)
    -            .address(self.network)
    -            .map(|address| AddressInfo {
    -                index,
    -                address,
    -                keychain,
    +    // Return derived address for the descriptor of given [`KeychainKind`] at a specific index
    +    fn peek_address(&self, index: u32, keychain: KeychainKind) -> Result<AddressInfo, Error> {
    +        self.get_descriptor_for_keychain(keychain)
    +            .at_derivation_index(index)
    +            .address(self.network)
    +            .map(|address| AddressInfo {
    +                index,
    +                address,
    +                keychain,
                 })
    -            .map_err(|_| Error::ScriptDoesntHaveAddressForm)
    +            .map_err(|_| Error::ScriptDoesntHaveAddressForm)
         }
     
    -    // Return derived address for `keychain` at a specific index and reset current
    -    // address index
    -    fn reset_address(&self, index: u32, keychain: KeychainKind) -> Result<AddressInfo, Error> {
    -        self.set_index(keychain, index)?;
    +    // Return derived address for `keychain` at a specific index and reset current
    +    // address index
    +    fn reset_address(&self, index: u32, keychain: KeychainKind) -> Result<AddressInfo, Error> {
    +        self.set_index(keychain, index)?;
     
    -        self.get_descriptor_for_keychain(keychain)
    -            .at_derivation_index(index)
    -            .address(self.network)
    -            .map(|address| AddressInfo {
    -                index,
    -                address,
    -                keychain,
    +        self.get_descriptor_for_keychain(keychain)
    +            .at_derivation_index(index)
    +            .address(self.network)
    +            .map(|address| AddressInfo {
    +                index,
    +                address,
    +                keychain,
                 })
    -            .map_err(|_| Error::ScriptDoesntHaveAddressForm)
    +            .map_err(|_| Error::ScriptDoesntHaveAddressForm)
         }
     
    -    /// Return a derived address using the external descriptor, see [`AddressIndex`] for
    -    /// available address index selection strategies. If none of the keys in the descriptor are derivable
    -    /// (i.e. does not end with /*) then the same address will always be returned for any [`AddressIndex`].
    -    pub fn get_address(&self, address_index: AddressIndex) -> Result<AddressInfo, Error> {
    -        self._get_address(address_index, KeychainKind::External)
    +    /// Return a derived address using the external descriptor, see [`AddressIndex`] for
    +    /// available address index selection strategies. If none of the keys in the descriptor are derivable
    +    /// (i.e. does not end with /*) then the same address will always be returned for any [`AddressIndex`].
    +    pub fn get_address(&self, address_index: AddressIndex) -> Result<AddressInfo, Error> {
    +        self._get_address(address_index, KeychainKind::External)
         }
     
    -    /// Return a derived address using the internal (change) descriptor.
    -    ///
    -    /// If the wallet doesn't have an internal descriptor it will use the external descriptor.
    -    ///
    -    /// see [`AddressIndex`] for available address index selection strategies. If none of the keys
    -    /// in the descriptor are derivable (i.e. does not end with /*) then the same address will always
    -    /// be returned for any [`AddressIndex`].
    -    pub fn get_internal_address(&self, address_index: AddressIndex) -> Result<AddressInfo, Error> {
    -        self._get_address(address_index, KeychainKind::Internal)
    +    /// Return a derived address using the internal (change) descriptor.
    +    ///
    +    /// If the wallet doesn't have an internal descriptor it will use the external descriptor.
    +    ///
    +    /// see [`AddressIndex`] for available address index selection strategies. If none of the keys
    +    /// in the descriptor are derivable (i.e. does not end with /*) then the same address will always
    +    /// be returned for any [`AddressIndex`].
    +    pub fn get_internal_address(&self, address_index: AddressIndex) -> Result<AddressInfo, Error> {
    +        self._get_address(address_index, KeychainKind::Internal)
         }
     
    -    fn _get_address(
    +    fn _get_address(
             &self,
    -        address_index: AddressIndex,
    -        keychain: KeychainKind,
    -    ) -> Result<AddressInfo, Error> {
    -        match address_index {
    -            AddressIndex::New => self.get_new_address(keychain),
    -            AddressIndex::LastUnused => self.get_unused_address(keychain),
    -            AddressIndex::Peek(index) => self.peek_address(index, keychain),
    -            AddressIndex::Reset(index) => self.reset_address(index, keychain),
    +        address_index: AddressIndex,
    +        keychain: KeychainKind,
    +    ) -> Result<AddressInfo, Error> {
    +        match address_index {
    +            AddressIndex::New => self.get_new_address(keychain),
    +            AddressIndex::LastUnused => self.get_unused_address(keychain),
    +            AddressIndex::Peek(index) => self.peek_address(index, keychain),
    +            AddressIndex::Reset(index) => self.reset_address(index, keychain),
             }
         }
     
    -    /// Ensures that there are at least `max_addresses` addresses cached in the database if the
    -    /// descriptor is derivable, or 1 address if it is not.
    -    /// Will return `Ok(true)` if there are new addresses generated (either external or internal),
    -    /// and `Ok(false)` if all the required addresses are already cached. This function is useful to
    -    /// explicitly cache addresses in a wallet to do things like check [`Wallet::is_mine`] on
    -    /// transaction output scripts.
    -    pub fn ensure_addresses_cached(&self, max_addresses: u32) -> Result<bool, Error> {
    -        let mut new_addresses_cached = false;
    -        let max_address = match self.descriptor.has_wildcard() {
    -            false => 0,
    -            true => max_addresses,
    +    /// Ensures that there are at least `max_addresses` addresses cached in the database if the
    +    /// descriptor is derivable, or 1 address if it is not.
    +    /// Will return `Ok(true)` if there are new addresses generated (either external or internal),
    +    /// and `Ok(false)` if all the required addresses are already cached. This function is useful to
    +    /// explicitly cache addresses in a wallet to do things like check [`Wallet::is_mine`] on
    +    /// transaction output scripts.
    +    pub fn ensure_addresses_cached(&self, max_addresses: u32) -> Result<bool, Error> {
    +        let mut new_addresses_cached = false;
    +        let max_address = match self.descriptor.has_wildcard() {
    +            false => 0,
    +            true => max_addresses,
             };
    -        debug!("max_address {}", max_address);
    -        if self
    -            .database
    -            .borrow()
    -            .get_script_pubkey_from_path(KeychainKind::External, max_address.saturating_sub(1))?
    -            .is_none()
    +        debug!("max_address {}", max_address);
    +        if self
    +            .database
    +            .borrow()
    +            .get_script_pubkey_from_path(KeychainKind::External, max_address.saturating_sub(1))?
    +            .is_none()
             {
                 debug!("caching external addresses");
    -            new_addresses_cached = true;
    -            self.cache_addresses(KeychainKind::External, 0, max_address)?;
    +            new_addresses_cached = true;
    +            self.cache_addresses(KeychainKind::External, 0, max_address)?;
             }
     
    -        if let Some(change_descriptor) = &self.change_descriptor {
    -            let max_address = match change_descriptor.has_wildcard() {
    -                false => 0,
    -                true => max_addresses,
    +        if let Some(change_descriptor) = &self.change_descriptor {
    +            let max_address = match change_descriptor.has_wildcard() {
    +                false => 0,
    +                true => max_addresses,
                 };
     
    -            if self
    -                .database
    -                .borrow()
    -                .get_script_pubkey_from_path(KeychainKind::Internal, max_address.saturating_sub(1))?
    -                .is_none()
    +            if self
    +                .database
    +                .borrow()
    +                .get_script_pubkey_from_path(KeychainKind::Internal, max_address.saturating_sub(1))?
    +                .is_none()
                 {
                     debug!("caching internal addresses");
    -                new_addresses_cached = true;
    -                self.cache_addresses(KeychainKind::Internal, 0, max_address)?;
    +                new_addresses_cached = true;
    +                self.cache_addresses(KeychainKind::Internal, 0, max_address)?;
                 }
             }
    -        Ok(new_addresses_cached)
    -    }
    -
    -    /// Return whether or not a `script` is part of this wallet (either internal or external)
    -    pub fn is_mine(&self, script: &Script) -> Result<bool, Error> {
    -        self.database.borrow().is_mine(script)
    -    }
    -
    -    /// Return the list of unspent outputs of this wallet
    -    ///
    -    /// Note that this method only operates on the internal database, which first needs to be
    -    /// [`Wallet::sync`] manually.
    -    pub fn list_unspent(&self) -> Result<Vec<LocalUtxo>, Error> {
    -        Ok(self
    -            .database
    -            .borrow()
    -            .iter_utxos()?
    -            .into_iter()
    -            .filter(|l| !l.is_spent)
    -            .collect())
    -    }
    -
    -    /// Returns the `UTXO` owned by this wallet corresponding to `outpoint` if it exists in the
    -    /// wallet's database.
    -    pub fn get_utxo(&self, outpoint: OutPoint) -> Result<Option<LocalUtxo>, Error> {
    -        self.database.borrow().get_utxo(&outpoint)
    -    }
    -
    -    /// Return a single transactions made and received by the wallet
    -    ///
    -    /// Optionally fill the [`TransactionDetails::transaction`] field with the raw transaction if
    -    /// `include_raw` is `true`.
    -    ///
    -    /// Note that this method only operates on the internal database, which first needs to be
    -    /// [`Wallet::sync`] manually.
    -    pub fn get_tx(
    +        Ok(new_addresses_cached)
    +    }
    +
    +    /// Return whether or not a `script` is part of this wallet (either internal or external)
    +    pub fn is_mine(&self, script: &Script) -> Result<bool, Error> {
    +        self.database.borrow().is_mine(script)
    +    }
    +
    +    /// Return the list of unspent outputs of this wallet
    +    ///
    +    /// Note that this method only operates on the internal database, which first needs to be
    +    /// [`Wallet::sync`] manually.
    +    pub fn list_unspent(&self) -> Result<Vec<LocalUtxo>, Error> {
    +        Ok(self
    +            .database
    +            .borrow()
    +            .iter_utxos()?
    +            .into_iter()
    +            .filter(|l| !l.is_spent)
    +            .collect())
    +    }
    +
    +    /// Returns the `UTXO` owned by this wallet corresponding to `outpoint` if it exists in the
    +    /// wallet's database.
    +    pub fn get_utxo(&self, outpoint: OutPoint) -> Result<Option<LocalUtxo>, Error> {
    +        self.database.borrow().get_utxo(&outpoint)
    +    }
    +
    +    /// Return a single transactions made and received by the wallet
    +    ///
    +    /// Optionally fill the [`TransactionDetails::transaction`] field with the raw transaction if
    +    /// `include_raw` is `true`.
    +    ///
    +    /// Note that this method only operates on the internal database, which first needs to be
    +    /// [`Wallet::sync`] manually.
    +    pub fn get_tx(
             &self,
    -        txid: &Txid,
    -        include_raw: bool,
    -    ) -> Result<Option<TransactionDetails>, Error> {
    -        self.database.borrow().get_tx(txid, include_raw)
    -    }
    -
    -    /// Return an unsorted list of transactions made and received by the wallet
    -    ///
    -    /// Optionally fill the [`TransactionDetails::transaction`] field with the raw transaction if
    -    /// `include_raw` is `true`.
    -    ///
    -    /// To sort transactions, the following code can be used:
    -    /// ```no_run
    -    /// # let mut tx_list: Vec<bdk::TransactionDetails> = vec![];
    -    /// tx_list.sort_by(|a, b| {
    -    ///     b.confirmation_time
    -    ///         .as_ref()
    -    ///         .map(|t| t.height)
    -    ///         .cmp(&a.confirmation_time.as_ref().map(|t| t.height))
    -    /// });
    -    /// ```
    -    ///
    -    /// Note that this method only operates on the internal database, which first needs to be
    -    /// [`Wallet::sync`] manually.
    -    pub fn list_transactions(&self, include_raw: bool) -> Result<Vec<TransactionDetails>, Error> {
    -        self.database.borrow().iter_txs(include_raw)
    -    }
    -
    -    /// Return the balance, separated into available, trusted-pending, untrusted-pending and immature
    -    /// values.
    -    ///
    -    /// Note that this method only operates on the internal database, which first needs to be
    -    /// [`Wallet::sync`] manually.
    -    pub fn get_balance(&self) -> Result<Balance, Error> {
    -        let mut immature = 0;
    -        let mut trusted_pending = 0;
    -        let mut untrusted_pending = 0;
    -        let mut confirmed = 0;
    -        let utxos = self.list_unspent()?;
    -        let database = self.database.borrow();
    -        let last_sync_height = match database
    -            .get_sync_time()?
    -            .map(|sync_time| sync_time.block_time.height)
    +        txid: &Txid,
    +        include_raw: bool,
    +    ) -> Result<Option<TransactionDetails>, Error> {
    +        self.database.borrow().get_tx(txid, include_raw)
    +    }
    +
    +    /// Return an unsorted list of transactions made and received by the wallet
    +    ///
    +    /// Optionally fill the [`TransactionDetails::transaction`] field with the raw transaction if
    +    /// `include_raw` is `true`.
    +    ///
    +    /// To sort transactions, the following code can be used:
    +    /// ```no_run
    +    /// # let mut tx_list: Vec<bdk::TransactionDetails> = vec![];
    +    /// tx_list.sort_by(|a, b| {
    +    ///     b.confirmation_time
    +    ///         .as_ref()
    +    ///         .map(|t| t.height)
    +    ///         .cmp(&a.confirmation_time.as_ref().map(|t| t.height))
    +    /// });
    +    /// ```
    +    ///
    +    /// Note that this method only operates on the internal database, which first needs to be
    +    /// [`Wallet::sync`] manually.
    +    pub fn list_transactions(&self, include_raw: bool) -> Result<Vec<TransactionDetails>, Error> {
    +        self.database.borrow().iter_txs(include_raw)
    +    }
    +
    +    /// Return the balance, separated into available, trusted-pending, untrusted-pending and immature
    +    /// values.
    +    ///
    +    /// Note that this method only operates on the internal database, which first needs to be
    +    /// [`Wallet::sync`] manually.
    +    pub fn get_balance(&self) -> Result<Balance, Error> {
    +        let mut immature = 0;
    +        let mut trusted_pending = 0;
    +        let mut untrusted_pending = 0;
    +        let mut confirmed = 0;
    +        let utxos = self.list_unspent()?;
    +        let database = self.database.borrow();
    +        let last_sync_height = match database
    +            .get_sync_time()?
    +            .map(|sync_time| sync_time.block_time.height)
             {
    -            Some(height) => height,
    -            // None means database was never synced
    -            None => return Ok(Balance::default()),
    +            Some(height) => height,
    +            // None means database was never synced
    +            None => return Ok(Balance::default()),
             };
    -        for u in utxos {
    -            // Unwrap used since utxo set is created from database
    -            let tx = database
    -                .get_tx(&u.outpoint.txid, true)?
    -                .expect("Transaction not found in database");
    -            if let Some(tx_conf_time) = &tx.confirmation_time {
    -                if tx.transaction.expect("No transaction").is_coin_base()
    -                    && (last_sync_height - tx_conf_time.height) < COINBASE_MATURITY
    +        for u in utxos {
    +            // Unwrap used since utxo set is created from database
    +            let tx = database
    +                .get_tx(&u.outpoint.txid, true)?
    +                .expect("Transaction not found in database");
    +            if let Some(tx_conf_time) = &tx.confirmation_time {
    +                if tx.transaction.expect("No transaction").is_coin_base()
    +                    && (last_sync_height - tx_conf_time.height) < COINBASE_MATURITY
                     {
    -                    immature += u.txout.value;
    -                } else {
    -                    confirmed += u.txout.value;
    +                    immature += u.txout.value;
    +                } else {
    +                    confirmed += u.txout.value;
                     }
    -            } else if u.keychain == KeychainKind::Internal {
    -                trusted_pending += u.txout.value;
    -            } else {
    -                untrusted_pending += u.txout.value;
    +            } else if u.keychain == KeychainKind::Internal {
    +                trusted_pending += u.txout.value;
    +            } else {
    +                untrusted_pending += u.txout.value;
                 }
             }
     
    -        Ok(Balance {
    -            immature,
    -            trusted_pending,
    -            untrusted_pending,
    -            confirmed,
    +        Ok(Balance {
    +            immature,
    +            trusted_pending,
    +            untrusted_pending,
    +            confirmed,
             })
         }
     
    -    /// Add an external signer
    -    ///
    -    /// See [the `signer` module](signer) for an example.
    -    pub fn add_signer(
    -        &mut self,
    -        keychain: KeychainKind,
    -        ordering: SignerOrdering,
    -        signer: Arc<dyn TransactionSigner>,
    +    /// Add an external signer
    +    ///
    +    /// See [the `signer` module](signer) for an example.
    +    pub fn add_signer(
    +        &mut self,
    +        keychain: KeychainKind,
    +        ordering: SignerOrdering,
    +        signer: Arc<dyn TransactionSigner>,
         ) {
    -        let signers = match keychain {
    -            KeychainKind::External => Arc::make_mut(&mut self.signers),
    -            KeychainKind::Internal => Arc::make_mut(&mut self.change_signers),
    +        let signers = match keychain {
    +            KeychainKind::External => Arc::make_mut(&mut self.signers),
    +            KeychainKind::Internal => Arc::make_mut(&mut self.change_signers),
             };
     
    -        signers.add_external(signer.id(&self.secp), ordering, signer);
    -    }
    -
    -    /// Get the signers
    -    ///
    -    /// ## Example
    -    ///
    -    /// ```
    -    /// # use bdk::{Wallet, KeychainKind};
    -    /// # use bdk::bitcoin::Network;
    -    /// # use bdk::database::MemoryDatabase;
    -    /// let wallet = Wallet::new("wpkh(tprv8ZgxMBicQKsPe73PBRSmNbTfbcsZnwWhz5eVmhHpi31HW29Z7mc9B4cWGRQzopNUzZUT391DeDJxL2PefNunWyLgqCKRMDkU1s2s8bAfoSk/84'/0'/0'/0/*)", None, Network::Testnet, MemoryDatabase::new())?;
    -    /// for secret_key in wallet.get_signers(KeychainKind::External).signers().iter().filter_map(|s| s.descriptor_secret_key()) {
    -    ///     // secret_key: tprv8ZgxMBicQKsPe73PBRSmNbTfbcsZnwWhz5eVmhHpi31HW29Z7mc9B4cWGRQzopNUzZUT391DeDJxL2PefNunWyLgqCKRMDkU1s2s8bAfoSk/84'/0'/0'/0/*
    -    ///     println!("secret_key: {}", secret_key);
    -    /// }
    -    ///
    -    /// Ok::<(), Box<dyn std::error::Error>>(())
    -    /// ```
    -    pub fn get_signers(&self, keychain: KeychainKind) -> Arc<SignersContainer> {
    -        match keychain {
    -            KeychainKind::External => Arc::clone(&self.signers),
    -            KeychainKind::Internal => Arc::clone(&self.change_signers),
    +        signers.add_external(signer.id(&self.secp), ordering, signer);
    +    }
    +
    +    /// Get the signers
    +    ///
    +    /// ## Example
    +    ///
    +    /// ```
    +    /// # use bdk::{Wallet, KeychainKind};
    +    /// # use bdk::bitcoin::Network;
    +    /// # use bdk::database::MemoryDatabase;
    +    /// let wallet = Wallet::new("wpkh(tprv8ZgxMBicQKsPe73PBRSmNbTfbcsZnwWhz5eVmhHpi31HW29Z7mc9B4cWGRQzopNUzZUT391DeDJxL2PefNunWyLgqCKRMDkU1s2s8bAfoSk/84'/0'/0'/0/*)", None, Network::Testnet, MemoryDatabase::new())?;
    +    /// for secret_key in wallet.get_signers(KeychainKind::External).signers().iter().filter_map(|s| s.descriptor_secret_key()) {
    +    ///     // secret_key: tprv8ZgxMBicQKsPe73PBRSmNbTfbcsZnwWhz5eVmhHpi31HW29Z7mc9B4cWGRQzopNUzZUT391DeDJxL2PefNunWyLgqCKRMDkU1s2s8bAfoSk/84'/0'/0'/0/*
    +    ///     println!("secret_key: {}", secret_key);
    +    /// }
    +    ///
    +    /// Ok::<(), Box<dyn std::error::Error>>(())
    +    /// ```
    +    pub fn get_signers(&self, keychain: KeychainKind) -> Arc<SignersContainer> {
    +        match keychain {
    +            KeychainKind::External => Arc::clone(&self.signers),
    +            KeychainKind::Internal => Arc::clone(&self.change_signers),
             }
         }
     
    -    /// Start building a transaction.
    -    ///
    -    /// This returns a blank [`TxBuilder`] from which you can specify the parameters for the transaction.
    -    ///
    -    /// ## Example
    -    ///
    -    /// ```
    -    /// # use std::str::FromStr;
    -    /// # use bitcoin::*;
    -    /// # use bdk::*;
    -    /// # use bdk::database::*;
    -    /// # let descriptor = "wpkh(tpubD6NzVbkrYhZ4Xferm7Pz4VnjdcDPFyjVu5K4iZXQ4pVN8Cks4pHVowTBXBKRhX64pkRyJZJN5xAKj4UDNnLPb5p2sSKXhewoYx5GbTdUFWq/*)";
    -    /// # let wallet = doctest_wallet!();
    -    /// # let to_address = Address::from_str("2N4eQYCbKUHCCTUjBJeHcJp9ok6J2GZsTDt").unwrap();
    -    /// let (psbt, details) = {
    -    ///    let mut builder =  wallet.build_tx();
    -    ///    builder
    -    ///        .add_recipient(to_address.script_pubkey(), 50_000);
    -    ///    builder.finish()?
    -    /// };
    -    ///
    -    /// // sign and broadcast ...
    -    /// # Ok::<(), bdk::Error>(())
    -    /// ```
    -    ///
    -    /// [`TxBuilder`]: crate::TxBuilder
    -    pub fn build_tx(&self) -> TxBuilder<'_, D, DefaultCoinSelectionAlgorithm, CreateTx> {
    -        TxBuilder {
    -            wallet: self,
    -            params: TxParams::default(),
    -            coin_selection: DefaultCoinSelectionAlgorithm::default(),
    -            phantom: core::marker::PhantomData,
    +    /// Start building a transaction.
    +    ///
    +    /// This returns a blank [`TxBuilder`] from which you can specify the parameters for the transaction.
    +    ///
    +    /// ## Example
    +    ///
    +    /// ```
    +    /// # use std::str::FromStr;
    +    /// # use bitcoin::*;
    +    /// # use bdk::*;
    +    /// # use bdk::database::*;
    +    /// # let descriptor = "wpkh(tpubD6NzVbkrYhZ4Xferm7Pz4VnjdcDPFyjVu5K4iZXQ4pVN8Cks4pHVowTBXBKRhX64pkRyJZJN5xAKj4UDNnLPb5p2sSKXhewoYx5GbTdUFWq/*)";
    +    /// # let wallet = doctest_wallet!();
    +    /// # let to_address = Address::from_str("2N4eQYCbKUHCCTUjBJeHcJp9ok6J2GZsTDt").unwrap();
    +    /// let (psbt, details) = {
    +    ///    let mut builder =  wallet.build_tx();
    +    ///    builder
    +    ///        .add_recipient(to_address.script_pubkey(), 50_000);
    +    ///    builder.finish()?
    +    /// };
    +    ///
    +    /// // sign and broadcast ...
    +    /// # Ok::<(), bdk::Error>(())
    +    /// ```
    +    ///
    +    /// [`TxBuilder`]: crate::TxBuilder
    +    pub fn build_tx(&self) -> TxBuilder<'_, D, DefaultCoinSelectionAlgorithm, CreateTx> {
    +        TxBuilder {
    +            wallet: self,
    +            params: TxParams::default(),
    +            coin_selection: DefaultCoinSelectionAlgorithm::default(),
    +            phantom: core::marker::PhantomData,
             }
         }
     
    -    pub(crate) fn create_tx<Cs: coin_selection::CoinSelectionAlgorithm<D>>(
    +    pub(crate) fn create_tx<Cs: coin_selection::CoinSelectionAlgorithm<D>>(
             &self,
    -        coin_selection: Cs,
    -        params: TxParams,
    -    ) -> Result<(psbt::PartiallySignedTransaction, TransactionDetails), Error> {
    -        let external_policy = self
    -            .descriptor
    -            .extract_policy(&self.signers, BuildSatisfaction::None, &self.secp)?
    -            .unwrap();
    -        let internal_policy = self
    -            .change_descriptor
    -            .as_ref()
    -            .map(|desc| {
    -                Ok::<_, Error>(
    -                    desc.extract_policy(&self.change_signers, BuildSatisfaction::None, &self.secp)?
    -                        .unwrap(),
    +        coin_selection: Cs,
    +        params: TxParams,
    +    ) -> Result<(psbt::PartiallySignedTransaction, TransactionDetails), Error> {
    +        let external_policy = self
    +            .descriptor
    +            .extract_policy(&self.signers, BuildSatisfaction::None, &self.secp)?
    +            .unwrap();
    +        let internal_policy = self
    +            .change_descriptor
    +            .as_ref()
    +            .map(|desc| {
    +                Ok::<_, Error>(
    +                    desc.extract_policy(&self.change_signers, BuildSatisfaction::None, &self.secp)?
    +                        .unwrap(),
                     )
                 })
    -            .transpose()?;
    +            .transpose()?;
     
    -        // The policy allows spending external outputs, but it requires a policy path that hasn't been
    -        // provided
    -        if params.change_policy != tx_builder::ChangeSpendPolicy::OnlyChange
    -            && external_policy.requires_path()
    -            && params.external_policy_path.is_none()
    +        // The policy allows spending external outputs, but it requires a policy path that hasn't been
    +        // provided
    +        if params.change_policy != tx_builder::ChangeSpendPolicy::OnlyChange
    +            && external_policy.requires_path()
    +            && params.external_policy_path.is_none()
             {
    -            return Err(Error::SpendingPolicyRequired(KeychainKind::External));
    +            return Err(Error::SpendingPolicyRequired(KeychainKind::External));
             };
    -        // Same for the internal_policy path, if present
    -        if let Some(internal_policy) = &internal_policy {
    -            if params.change_policy != tx_builder::ChangeSpendPolicy::ChangeForbidden
    -                && internal_policy.requires_path()
    -                && params.internal_policy_path.is_none()
    +        // Same for the internal_policy path, if present
    +        if let Some(internal_policy) = &internal_policy {
    +            if params.change_policy != tx_builder::ChangeSpendPolicy::ChangeForbidden
    +                && internal_policy.requires_path()
    +                && params.internal_policy_path.is_none()
                 {
    -                return Err(Error::SpendingPolicyRequired(KeychainKind::Internal));
    +                return Err(Error::SpendingPolicyRequired(KeychainKind::Internal));
                 };
             }
     
    -        let external_requirements = external_policy.get_condition(
    -            params
    -                .external_policy_path
    -                .as_ref()
    -                .unwrap_or(&BTreeMap::new()),
    +        let external_requirements = external_policy.get_condition(
    +            params
    +                .external_policy_path
    +                .as_ref()
    +                .unwrap_or(&BTreeMap::new()),
             )?;
    -        let internal_requirements = internal_policy
    -            .map(|policy| {
    -                Ok::<_, Error>(
    -                    policy.get_condition(
    -                        params
    -                            .internal_policy_path
    -                            .as_ref()
    -                            .unwrap_or(&BTreeMap::new()),
    +        let internal_requirements = internal_policy
    +            .map(|policy| {
    +                Ok::<_, Error>(
    +                    policy.get_condition(
    +                        params
    +                            .internal_policy_path
    +                            .as_ref()
    +                            .unwrap_or(&BTreeMap::new()),
                         )?,
                     )
                 })
    -            .transpose()?;
    +            .transpose()?;
     
    -        let requirements =
    -            external_requirements.merge(&internal_requirements.unwrap_or_default())?;
    -        debug!("Policy requirements: {:?}", requirements);
    +        let requirements =
    +            external_requirements.merge(&internal_requirements.unwrap_or_default())?;
    +        debug!("Policy requirements: {:?}", requirements);
     
    -        let version = match params.version {
    -            Some(tx_builder::Version(0)) => {
    -                return Err(Error::Generic("Invalid version `0`".into()))
    +        let version = match params.version {
    +            Some(tx_builder::Version(0)) => {
    +                return Err(Error::Generic("Invalid version `0`".into()))
                 }
    -            Some(tx_builder::Version(1)) if requirements.csv.is_some() => {
    -                return Err(Error::Generic(
    -                    "TxBuilder requested version `1`, but at least `2` is needed to use OP_CSV"
    -                        .into(),
    +            Some(tx_builder::Version(1)) if requirements.csv.is_some() => {
    +                return Err(Error::Generic(
    +                    "TxBuilder requested version `1`, but at least `2` is needed to use OP_CSV"
    +                        .into(),
                     ))
                 }
    -            Some(tx_builder::Version(x)) => x,
    -            None if requirements.csv.is_some() => 2,
    -            _ => 1,
    +            Some(tx_builder::Version(x)) => x,
    +            None if requirements.csv.is_some() => 2,
    +            _ => 1,
             };
     
    -        // We use a match here instead of a map_or_else as it's way more readable :)
    -        let current_height = match params.current_height {
    -            // If they didn't tell us the current height, we assume it's the latest sync height.
    -            None => self.database().get_sync_time()?.map(|sync_time| {
    -                LockTime::from_height(sync_time.block_time.height).expect("Invalid height")
    +        // We use a match here instead of a map_or_else as it's way more readable :)
    +        let current_height = match params.current_height {
    +            // If they didn't tell us the current height, we assume it's the latest sync height.
    +            None => self.database().get_sync_time()?.map(|sync_time| {
    +                LockTime::from_height(sync_time.block_time.height).expect("Invalid height")
                 }),
    -            h => h,
    +            h => h,
             };
     
    -        let lock_time = match params.locktime {
    -            // When no nLockTime is specified, we try to prevent fee sniping, if possible
    -            None => {
    -                // Fee sniping can be partially prevented by setting the timelock
    -                // to current_height. If we don't know the current_height,
    -                // we default to 0.
    -                let fee_sniping_height = current_height.unwrap_or(LockTime::ZERO);
    -
    -                // We choose the biggest between the required nlocktime and the fee sniping
    -                // height
    -                match requirements.timelock {
    -                    // No requirement, just use the fee_sniping_height
    -                    None => fee_sniping_height,
    -                    // There's a block-based requirement, but the value is lower than the fee_sniping_height
    -                    Some(value @ LockTime::Blocks(_)) if value < fee_sniping_height => fee_sniping_height,
    -                    // There's a time-based requirement or a block-based requirement greater
    -                    // than the fee_sniping_height use that value
    -                    Some(value) => value,
    +        let lock_time = match params.locktime {
    +            // When no nLockTime is specified, we try to prevent fee sniping, if possible
    +            None => {
    +                // Fee sniping can be partially prevented by setting the timelock
    +                // to current_height. If we don't know the current_height,
    +                // we default to 0.
    +                let fee_sniping_height = current_height.unwrap_or(LockTime::ZERO);
    +
    +                // We choose the biggest between the required nlocktime and the fee sniping
    +                // height
    +                match requirements.timelock {
    +                    // No requirement, just use the fee_sniping_height
    +                    None => fee_sniping_height,
    +                    // There's a block-based requirement, but the value is lower than the fee_sniping_height
    +                    Some(value @ LockTime::Blocks(_)) if value < fee_sniping_height => fee_sniping_height,
    +                    // There's a time-based requirement or a block-based requirement greater
    +                    // than the fee_sniping_height use that value
    +                    Some(value) => value,
                     }
                 }
    -            // Specific nLockTime required and we have no constraints, so just set to that value
    -            Some(x) if requirements.timelock.is_none() => x,
    -            // Specific nLockTime required and it's compatible with the constraints
    -            Some(x) if requirements.timelock.unwrap().is_same_unit(x) && x >= requirements.timelock.unwrap() => x,
    -            // Invalid nLockTime required
    -            Some(x) => return Err(Error::Generic(format!("TxBuilder requested timelock of `{:?}`, but at least `{:?}` is required to spend from this script", x, requirements.timelock.unwrap())))
    +            // Specific nLockTime required and we have no constraints, so just set to that value
    +            Some(x) if requirements.timelock.is_none() => x,
    +            // Specific nLockTime required and it's compatible with the constraints
    +            Some(x) if requirements.timelock.unwrap().is_same_unit(x) && x >= requirements.timelock.unwrap() => x,
    +            // Invalid nLockTime required
    +            Some(x) => return Err(Error::Generic(format!("TxBuilder requested timelock of `{:?}`, but at least `{:?}` is required to spend from this script", x, requirements.timelock.unwrap())))
             };
     
    -        let n_sequence = match (params.rbf, requirements.csv) {
    -            // No RBF or CSV but there's an nLockTime, so the nSequence cannot be final
    -            (None, None) if lock_time != LockTime::ZERO => Sequence::ENABLE_LOCKTIME_NO_RBF,
    -            // No RBF, CSV or nLockTime, make the transaction final
    -            (None, None) => Sequence::MAX,
    -
    -            // No RBF requested, use the value from CSV. Note that this value is by definition
    -            // non-final, so even if a timelock is enabled this nSequence is fine, hence why we
    -            // don't bother checking for it here. The same is true for all the other branches below
    -            (None, Some(csv)) => csv,
    -
    -            // RBF with a specific value but that value is too high
    -            (Some(tx_builder::RbfValue::Value(rbf)), _) if !rbf.is_rbf() => {
    -                return Err(Error::Generic(
    -                    "Cannot enable RBF with a nSequence >= 0xFFFFFFFE".into(),
    +        let n_sequence = match (params.rbf, requirements.csv) {
    +            // No RBF or CSV but there's an nLockTime, so the nSequence cannot be final
    +            (None, None) if lock_time != LockTime::ZERO => Sequence::ENABLE_LOCKTIME_NO_RBF,
    +            // No RBF, CSV or nLockTime, make the transaction final
    +            (None, None) => Sequence::MAX,
    +
    +            // No RBF requested, use the value from CSV. Note that this value is by definition
    +            // non-final, so even if a timelock is enabled this nSequence is fine, hence why we
    +            // don't bother checking for it here. The same is true for all the other branches below
    +            (None, Some(csv)) => csv,
    +
    +            // RBF with a specific value but that value is too high
    +            (Some(tx_builder::RbfValue::Value(rbf)), _) if !rbf.is_rbf() => {
    +                return Err(Error::Generic(
    +                    "Cannot enable RBF with a nSequence >= 0xFFFFFFFE".into(),
                     ))
                 }
    -            // RBF with a specific value requested, but the value is incompatible with CSV
    -            (Some(tx_builder::RbfValue::Value(rbf)), Some(csv))
    -                if !check_nsequence_rbf(rbf, csv) =>
    +            // RBF with a specific value requested, but the value is incompatible with CSV
    +            (Some(tx_builder::RbfValue::Value(rbf)), Some(csv))
    +                if !check_nsequence_rbf(rbf, csv) =>
                 {
    -                return Err(Error::Generic(format!(
    +                return Err(Error::Generic(format!(
                         "Cannot enable RBF with nSequence `{:?}` given a required OP_CSV of `{:?}`",
    -                    rbf, csv
    +                    rbf, csv
                     )))
                 }
     
    -            // RBF enabled with the default value with CSV also enabled. CSV takes precedence
    -            (Some(tx_builder::RbfValue::Default), Some(csv)) => csv,
    -            // Valid RBF, either default or with a specific value. We ignore the `CSV` value
    -            // because we've already checked it before
    -            (Some(rbf), _) => rbf.get_value(),
    +            // RBF enabled with the default value with CSV also enabled. CSV takes precedence
    +            (Some(tx_builder::RbfValue::Default), Some(csv)) => csv,
    +            // Valid RBF, either default or with a specific value. We ignore the `CSV` value
    +            // because we've already checked it before
    +            (Some(rbf), _) => rbf.get_value(),
             };
     
    -        let (fee_rate, mut fee_amount) = match params
    -            .fee_policy
    -            .as_ref()
    -            .unwrap_or(&FeePolicy::FeeRate(FeeRate::default()))
    +        let (fee_rate, mut fee_amount) = match params
    +            .fee_policy
    +            .as_ref()
    +            .unwrap_or(&FeePolicy::FeeRate(FeeRate::default()))
             {
    -            //FIXME: see https://github.com/bitcoindevkit/bdk/issues/256
    -            FeePolicy::FeeAmount(fee) => {
    -                if let Some(previous_fee) = params.bumping_fee {
    -                    if *fee < previous_fee.absolute {
    -                        return Err(Error::FeeTooLow {
    -                            required: previous_fee.absolute,
    +            //FIXME: see https://github.com/bitcoindevkit/bdk/issues/256
    +            FeePolicy::FeeAmount(fee) => {
    +                if let Some(previous_fee) = params.bumping_fee {
    +                    if *fee < previous_fee.absolute {
    +                        return Err(Error::FeeTooLow {
    +                            required: previous_fee.absolute,
                             });
                         }
                     }
    -                (FeeRate::from_sat_per_vb(0.0), *fee)
    +                (FeeRate::from_sat_per_vb(0.0), *fee)
                 }
    -            FeePolicy::FeeRate(rate) => {
    -                if let Some(previous_fee) = params.bumping_fee {
    -                    let required_feerate = FeeRate::from_sat_per_vb(previous_fee.rate + 1.0);
    -                    if *rate < required_feerate {
    -                        return Err(Error::FeeRateTooLow {
    -                            required: required_feerate,
    +            FeePolicy::FeeRate(rate) => {
    +                if let Some(previous_fee) = params.bumping_fee {
    +                    let required_feerate = FeeRate::from_sat_per_vb(previous_fee.rate + 1.0);
    +                    if *rate < required_feerate {
    +                        return Err(Error::FeeRateTooLow {
    +                            required: required_feerate,
                             });
                         }
                     }
    -                (*rate, 0)
    +                (*rate, 0)
                 }
             };
     
    -        let mut tx = Transaction {
    -            version,
    -            lock_time: lock_time.into(),
    -            input: vec![],
    -            output: vec![],
    +        let mut tx = Transaction {
    +            version,
    +            lock_time: lock_time.into(),
    +            input: vec![],
    +            output: vec![],
             };
     
    -        if params.manually_selected_only && params.utxos.is_empty() {
    -            return Err(Error::NoUtxosSelected);
    +        if params.manually_selected_only && params.utxos.is_empty() {
    +            return Err(Error::NoUtxosSelected);
             }
     
    -        // we keep it as a float while we accumulate it, and only round it at the end
    -        let mut outgoing: u64 = 0;
    -        let mut received: u64 = 0;
    +        // we keep it as a float while we accumulate it, and only round it at the end
    +        let mut outgoing: u64 = 0;
    +        let mut received: u64 = 0;
     
    -        let recipients = params.recipients.iter().map(|(r, v)| (r, *v));
    +        let recipients = params.recipients.iter().map(|(r, v)| (r, *v));
     
    -        for (index, (script_pubkey, value)) in recipients.enumerate() {
    -            if !params.allow_dust
    -                && value.is_dust(script_pubkey)
    -                && !script_pubkey.is_provably_unspendable()
    +        for (index, (script_pubkey, value)) in recipients.enumerate() {
    +            if !params.allow_dust
    +                && value.is_dust(script_pubkey)
    +                && !script_pubkey.is_provably_unspendable()
                 {
    -                return Err(Error::OutputBelowDustLimit(index));
    +                return Err(Error::OutputBelowDustLimit(index));
                 }
     
    -            if self.is_mine(script_pubkey)? {
    -                received += value;
    +            if self.is_mine(script_pubkey)? {
    +                received += value;
                 }
     
    -            let new_out = TxOut {
    -                script_pubkey: script_pubkey.clone(),
    -                value,
    +            let new_out = TxOut {
    +                script_pubkey: script_pubkey.clone(),
    +                value,
                 };
     
    -            tx.output.push(new_out);
    +            tx.output.push(new_out);
     
    -            outgoing += value;
    +            outgoing += value;
             }
     
    -        fee_amount += fee_rate.fee_wu(tx.weight());
    -
    -        // Segwit transactions' header is 2WU larger than legacy txs' header,
    -        // as they contain a witness marker (1WU) and a witness flag (1WU) (see BIP144).
    -        // At this point we really don't know if the resulting transaction will be segwit
    -        // or legacy, so we just add this 2WU to the fee_amount - overshooting the fee amount
    -        // is better than undershooting it.
    -        // If we pass a fee_amount that is slightly higher than the final fee_amount, we
    -        // end up with a transaction with a slightly higher fee rate than the requested one.
    -        // If, instead, we undershoot, we may end up with a feerate lower than the requested one
    -        // - we might come up with non broadcastable txs!
    -        fee_amount += fee_rate.fee_wu(2);
    -
    -        if params.change_policy != tx_builder::ChangeSpendPolicy::ChangeAllowed
    -            && self.change_descriptor.is_none()
    +        fee_amount += fee_rate.fee_wu(tx.weight());
    +
    +        // Segwit transactions' header is 2WU larger than legacy txs' header,
    +        // as they contain a witness marker (1WU) and a witness flag (1WU) (see BIP144).
    +        // At this point we really don't know if the resulting transaction will be segwit
    +        // or legacy, so we just add this 2WU to the fee_amount - overshooting the fee amount
    +        // is better than undershooting it.
    +        // If we pass a fee_amount that is slightly higher than the final fee_amount, we
    +        // end up with a transaction with a slightly higher fee rate than the requested one.
    +        // If, instead, we undershoot, we may end up with a feerate lower than the requested one
    +        // - we might come up with non broadcastable txs!
    +        fee_amount += fee_rate.fee_wu(2);
    +
    +        if params.change_policy != tx_builder::ChangeSpendPolicy::ChangeAllowed
    +            && self.change_descriptor.is_none()
             {
    -            return Err(Error::Generic(
    -                "The `change_policy` can be set only if the wallet has a change_descriptor".into(),
    +            return Err(Error::Generic(
    +                "The `change_policy` can be set only if the wallet has a change_descriptor".into(),
                 ));
             }
     
    -        let (required_utxos, optional_utxos) = self.preselect_utxos(
    -            params.change_policy,
    -            &params.unspendable,
    -            params.utxos.clone(),
    -            params.drain_wallet,
    -            params.manually_selected_only,
    -            params.bumping_fee.is_some(), // we mandate confirmed transactions if we're bumping the fee
    -            current_height.map(LockTime::to_consensus_u32),
    +        let (required_utxos, optional_utxos) = self.preselect_utxos(
    +            params.change_policy,
    +            &params.unspendable,
    +            params.utxos.clone(),
    +            params.drain_wallet,
    +            params.manually_selected_only,
    +            params.bumping_fee.is_some(), // we mandate confirmed transactions if we're bumping the fee
    +            current_height.map(LockTime::to_consensus_u32),
             )?;
     
    -        // get drain script
    -        let drain_script = match params.drain_to {
    -            Some(ref drain_recipient) => drain_recipient.clone(),
    -            None => self
    -                .get_internal_address(AddressIndex::New)?
    -                .address
    -                .script_pubkey(),
    +        // get drain script
    +        let drain_script = match params.drain_to {
    +            Some(ref drain_recipient) => drain_recipient.clone(),
    +            None => self
    +                .get_internal_address(AddressIndex::New)?
    +                .address
    +                .script_pubkey(),
             };
     
    -        let coin_selection = coin_selection.coin_select(
    -            self.database.borrow().deref(),
    -            required_utxos,
    -            optional_utxos,
    -            fee_rate,
    -            outgoing + fee_amount,
    -            &drain_script,
    +        let coin_selection = coin_selection.coin_select(
    +            self.database.borrow().deref(),
    +            required_utxos,
    +            optional_utxos,
    +            fee_rate,
    +            outgoing + fee_amount,
    +            &drain_script,
             )?;
    -        fee_amount += coin_selection.fee_amount;
    -        let excess = &coin_selection.excess;
    -
    -        tx.input = coin_selection
    -            .selected
    -            .iter()
    -            .map(|u| bitcoin::TxIn {
    -                previous_output: u.outpoint(),
    -                script_sig: Script::default(),
    -                sequence: n_sequence,
    -                witness: Witness::new(),
    +        fee_amount += coin_selection.fee_amount;
    +        let excess = &coin_selection.excess;
    +
    +        tx.input = coin_selection
    +            .selected
    +            .iter()
    +            .map(|u| bitcoin::TxIn {
    +                previous_output: u.outpoint(),
    +                script_sig: Script::default(),
    +                sequence: n_sequence,
    +                witness: Witness::new(),
                 })
    -            .collect();
    -
    -        if tx.output.is_empty() {
    -            // Uh oh, our transaction has no outputs.
    -            // We allow this when:
    -            // - We have a drain_to address and the utxos we must spend (this happens,
    -            // for example, when we RBF)
    -            // - We have a drain_to address and drain_wallet set
    -            // Otherwise, we don't know who we should send the funds to, and how much
    -            // we should send!
    -            if params.drain_to.is_some() && (params.drain_wallet || !params.utxos.is_empty()) {
    -                if let NoChange {
    -                    dust_threshold,
    -                    remaining_amount,
    -                    change_fee,
    -                } = excess
    +            .collect();
    +
    +        if tx.output.is_empty() {
    +            // Uh oh, our transaction has no outputs.
    +            // We allow this when:
    +            // - We have a drain_to address and the utxos we must spend (this happens,
    +            // for example, when we RBF)
    +            // - We have a drain_to address and drain_wallet set
    +            // Otherwise, we don't know who we should send the funds to, and how much
    +            // we should send!
    +            if params.drain_to.is_some() && (params.drain_wallet || !params.utxos.is_empty()) {
    +                if let NoChange {
    +                    dust_threshold,
    +                    remaining_amount,
    +                    change_fee,
    +                } = excess
                     {
    -                    return Err(Error::InsufficientFunds {
    -                        needed: *dust_threshold,
    -                        available: remaining_amount.saturating_sub(*change_fee),
    +                    return Err(Error::InsufficientFunds {
    +                        needed: *dust_threshold,
    +                        available: remaining_amount.saturating_sub(*change_fee),
                         });
                     }
    -            } else {
    -                return Err(Error::NoRecipients);
    +            } else {
    +                return Err(Error::NoRecipients);
                 }
             }
     
    -        match excess {
    -            NoChange {
    -                remaining_amount, ..
    -            } => fee_amount += remaining_amount,
    -            Change { amount, fee } => {
    -                if self.is_mine(&drain_script)? {
    -                    received += amount;
    +        match excess {
    +            NoChange {
    +                remaining_amount, ..
    +            } => fee_amount += remaining_amount,
    +            Change { amount, fee } => {
    +                if self.is_mine(&drain_script)? {
    +                    received += amount;
                     }
    -                fee_amount += fee;
    +                fee_amount += fee;
     
    -                // create drain output
    -                let drain_output = TxOut {
    -                    value: *amount,
    -                    script_pubkey: drain_script,
    +                // create drain output
    +                let drain_output = TxOut {
    +                    value: *amount,
    +                    script_pubkey: drain_script,
                     };
     
    -                // TODO: We should pay attention when adding a new output: this might increase
    -                // the lenght of the "number of vouts" parameter by 2 bytes, potentially making
    -                // our feerate too low
    -                tx.output.push(drain_output);
    +                // TODO: We should pay attention when adding a new output: this might increase
    +                // the lenght of the "number of vouts" parameter by 2 bytes, potentially making
    +                // our feerate too low
    +                tx.output.push(drain_output);
                 }
             };
     
    -        // sort input/outputs according to the chosen algorithm
    -        params.ordering.sort_tx(&mut tx);
    +        // sort input/outputs according to the chosen algorithm
    +        params.ordering.sort_tx(&mut tx);
     
    -        let txid = tx.txid();
    -        let sent = coin_selection.local_selected_amount();
    -        let psbt = self.complete_transaction(tx, coin_selection.selected, params)?;
    +        let txid = tx.txid();
    +        let sent = coin_selection.local_selected_amount();
    +        let psbt = self.complete_transaction(tx, coin_selection.selected, params)?;
     
    -        let transaction_details = TransactionDetails {
    -            transaction: None,
    -            txid,
    -            confirmation_time: None,
    -            received,
    -            sent,
    -            fee: Some(fee_amount),
    +        let transaction_details = TransactionDetails {
    +            transaction: None,
    +            txid,
    +            confirmation_time: None,
    +            received,
    +            sent,
    +            fee: Some(fee_amount),
             };
     
    -        Ok((psbt, transaction_details))
    -    }
    -
    -    /// Bump the fee of a transaction previously created with this wallet.
    -    ///
    -    /// Returns an error if the transaction is already confirmed or doesn't explicitly signal
    -    /// *replace by fee* (RBF). If the transaction can be fee bumped then it returns a [`TxBuilder`]
    -    /// pre-populated with the inputs and outputs of the original transaction.
    -    ///
    -    /// ## Example
    -    ///
    -    /// ```no_run
    -    /// # // TODO: remove norun -- bumping fee seems to need the tx in the wallet database first.
    -    /// # use std::str::FromStr;
    -    /// # use bitcoin::*;
    -    /// # use bdk::*;
    -    /// # use bdk::database::*;
    -    /// # let descriptor = "wpkh(tpubD6NzVbkrYhZ4Xferm7Pz4VnjdcDPFyjVu5K4iZXQ4pVN8Cks4pHVowTBXBKRhX64pkRyJZJN5xAKj4UDNnLPb5p2sSKXhewoYx5GbTdUFWq/*)";
    -    /// # let wallet = doctest_wallet!();
    -    /// # let to_address = Address::from_str("2N4eQYCbKUHCCTUjBJeHcJp9ok6J2GZsTDt").unwrap();
    -    /// let (mut psbt, _) = {
    -    ///     let mut builder = wallet.build_tx();
    -    ///     builder
    -    ///         .add_recipient(to_address.script_pubkey(), 50_000)
    -    ///         .enable_rbf();
    -    ///     builder.finish()?
    -    /// };
    -    /// let _ = wallet.sign(&mut psbt, SignOptions::default())?;
    -    /// let tx = psbt.extract_tx();
    -    /// // broadcast tx but it's taking too long to confirm so we want to bump the fee
    -    /// let (mut psbt, _) =  {
    -    ///     let mut builder = wallet.build_fee_bump(tx.txid())?;
    -    ///     builder
    -    ///         .fee_rate(FeeRate::from_sat_per_vb(5.0));
    -    ///     builder.finish()?
    -    /// };
    -    ///
    -    /// let _ = wallet.sign(&mut psbt, SignOptions::default())?;
    -    /// let fee_bumped_tx = psbt.extract_tx();
    -    /// // broadcast fee_bumped_tx to replace original
    -    /// # Ok::<(), bdk::Error>(())
    -    /// ```
    -    // TODO: support for merging multiple transactions while bumping the fees
    -    pub fn build_fee_bump(
    +        Ok((psbt, transaction_details))
    +    }
    +
    +    /// Bump the fee of a transaction previously created with this wallet.
    +    ///
    +    /// Returns an error if the transaction is already confirmed or doesn't explicitly signal
    +    /// *replace by fee* (RBF). If the transaction can be fee bumped then it returns a [`TxBuilder`]
    +    /// pre-populated with the inputs and outputs of the original transaction.
    +    ///
    +    /// ## Example
    +    ///
    +    /// ```no_run
    +    /// # // TODO: remove norun -- bumping fee seems to need the tx in the wallet database first.
    +    /// # use std::str::FromStr;
    +    /// # use bitcoin::*;
    +    /// # use bdk::*;
    +    /// # use bdk::database::*;
    +    /// # let descriptor = "wpkh(tpubD6NzVbkrYhZ4Xferm7Pz4VnjdcDPFyjVu5K4iZXQ4pVN8Cks4pHVowTBXBKRhX64pkRyJZJN5xAKj4UDNnLPb5p2sSKXhewoYx5GbTdUFWq/*)";
    +    /// # let wallet = doctest_wallet!();
    +    /// # let to_address = Address::from_str("2N4eQYCbKUHCCTUjBJeHcJp9ok6J2GZsTDt").unwrap();
    +    /// let (mut psbt, _) = {
    +    ///     let mut builder = wallet.build_tx();
    +    ///     builder
    +    ///         .add_recipient(to_address.script_pubkey(), 50_000)
    +    ///         .enable_rbf();
    +    ///     builder.finish()?
    +    /// };
    +    /// let _ = wallet.sign(&mut psbt, SignOptions::default())?;
    +    /// let tx = psbt.extract_tx();
    +    /// // broadcast tx but it's taking too long to confirm so we want to bump the fee
    +    /// let (mut psbt, _) =  {
    +    ///     let mut builder = wallet.build_fee_bump(tx.txid())?;
    +    ///     builder
    +    ///         .fee_rate(FeeRate::from_sat_per_vb(5.0));
    +    ///     builder.finish()?
    +    /// };
    +    ///
    +    /// let _ = wallet.sign(&mut psbt, SignOptions::default())?;
    +    /// let fee_bumped_tx = psbt.extract_tx();
    +    /// // broadcast fee_bumped_tx to replace original
    +    /// # Ok::<(), bdk::Error>(())
    +    /// ```
    +    // TODO: support for merging multiple transactions while bumping the fees
    +    pub fn build_fee_bump(
             &self,
    -        txid: Txid,
    -    ) -> Result<TxBuilder<'_, D, DefaultCoinSelectionAlgorithm, BumpFee>, Error> {
    -        let mut details = match self.database.borrow().get_tx(&txid, true)? {
    -            None => return Err(Error::TransactionNotFound),
    -            Some(tx) if tx.transaction.is_none() => return Err(Error::TransactionNotFound),
    -            Some(tx) if tx.confirmation_time.is_some() => return Err(Error::TransactionConfirmed),
    -            Some(tx) => tx,
    +        txid: Txid,
    +    ) -> Result<TxBuilder<'_, D, DefaultCoinSelectionAlgorithm, BumpFee>, Error> {
    +        let mut details = match self.database.borrow().get_tx(&txid, true)? {
    +            None => return Err(Error::TransactionNotFound),
    +            Some(tx) if tx.transaction.is_none() => return Err(Error::TransactionNotFound),
    +            Some(tx) if tx.confirmation_time.is_some() => return Err(Error::TransactionConfirmed),
    +            Some(tx) => tx,
             };
    -        let mut tx = details.transaction.take().unwrap();
    -        if !tx
    -            .input
    -            .iter()
    -            .any(|txin| txin.sequence.to_consensus_u32() <= 0xFFFFFFFD)
    +        let mut tx = details.transaction.take().unwrap();
    +        if !tx
    +            .input
    +            .iter()
    +            .any(|txin| txin.sequence.to_consensus_u32() <= 0xFFFFFFFD)
             {
    -            return Err(Error::IrreplaceableTransaction);
    +            return Err(Error::IrreplaceableTransaction);
             }
     
    -        let feerate = FeeRate::from_wu(details.fee.ok_or(Error::FeeRateUnavailable)?, tx.weight());
    -
    -        // remove the inputs from the tx and process them
    -        let original_txin = tx.input.drain(..).collect::<Vec<_>>();
    -        let original_utxos = original_txin
    -            .iter()
    -            .map(|txin| -> Result<_, Error> {
    -                let txout = self
    -                    .database
    -                    .borrow()
    -                    .get_previous_output(&txin.previous_output)?
    -                    .ok_or(Error::UnknownUtxo)?;
    -
    -                let (weight, keychain) = match self
    -                    .database
    -                    .borrow()
    -                    .get_path_from_script_pubkey(&txout.script_pubkey)?
    -                {
    -                    Some((keychain, _)) => (
    -                        self._get_descriptor_for_keychain(keychain)
    -                            .0
    -                            .max_satisfaction_weight()
    -                            .unwrap(),
    -                        keychain,
    +        let feerate = FeeRate::from_wu(details.fee.ok_or(Error::FeeRateUnavailable)?, tx.weight());
    +
    +        // remove the inputs from the tx and process them
    +        let original_txin = tx.input.drain(..).collect::<Vec<_>>();
    +        let original_utxos = original_txin
    +            .iter()
    +            .map(|txin| -> Result<_, Error> {
    +                let txout = self
    +                    .database
    +                    .borrow()
    +                    .get_previous_output(&txin.previous_output)?
    +                    .ok_or(Error::UnknownUtxo)?;
    +
    +                let (weight, keychain) = match self
    +                    .database
    +                    .borrow()
    +                    .get_path_from_script_pubkey(&txout.script_pubkey)?
    +                {
    +                    Some((keychain, _)) => (
    +                        self._get_descriptor_for_keychain(keychain)
    +                            .0
    +                            .max_satisfaction_weight()
    +                            .unwrap(),
    +                        keychain,
                         ),
    -                    None => {
    -                        // estimate the weight based on the scriptsig/witness size present in the
    -                        // original transaction
    -                        let weight =
    -                            serialize(&txin.script_sig).len() * 4 + serialize(&txin.witness).len();
    -                        (weight, KeychainKind::External)
    +                    None => {
    +                        // estimate the weight based on the scriptsig/witness size present in the
    +                        // original transaction
    +                        let weight =
    +                            serialize(&txin.script_sig).len() * 4 + serialize(&txin.witness).len();
    +                        (weight, KeychainKind::External)
                         }
                     };
     
    -                let utxo = LocalUtxo {
    -                    outpoint: txin.previous_output,
    -                    txout,
    -                    keychain,
    -                    is_spent: true,
    +                let utxo = LocalUtxo {
    +                    outpoint: txin.previous_output,
    +                    txout,
    +                    keychain,
    +                    is_spent: true,
                     };
     
    -                Ok(WeightedUtxo {
    -                    satisfaction_weight: weight,
    -                    utxo: Utxo::Local(utxo),
    +                Ok(WeightedUtxo {
    +                    satisfaction_weight: weight,
    +                    utxo: Utxo::Local(utxo),
                     })
                 })
    -            .collect::<Result<Vec<_>, _>>()?;
    -
    -        if tx.output.len() > 1 {
    -            let mut change_index = None;
    -            for (index, txout) in tx.output.iter().enumerate() {
    -                let (_, change_type) = self._get_descriptor_for_keychain(KeychainKind::Internal);
    -                match self
    -                    .database
    -                    .borrow()
    -                    .get_path_from_script_pubkey(&txout.script_pubkey)?
    -                {
    -                    Some((keychain, _)) if keychain == change_type => change_index = Some(index),
    -                    _ => {}
    +            .collect::<Result<Vec<_>, _>>()?;
    +
    +        if tx.output.len() > 1 {
    +            let mut change_index = None;
    +            for (index, txout) in tx.output.iter().enumerate() {
    +                let (_, change_type) = self._get_descriptor_for_keychain(KeychainKind::Internal);
    +                match self
    +                    .database
    +                    .borrow()
    +                    .get_path_from_script_pubkey(&txout.script_pubkey)?
    +                {
    +                    Some((keychain, _)) if keychain == change_type => change_index = Some(index),
    +                    _ => {}
                     }
                 }
     
    -            if let Some(change_index) = change_index {
    -                tx.output.remove(change_index);
    +            if let Some(change_index) = change_index {
    +                tx.output.remove(change_index);
                 }
             }
     
    -        let params = TxParams {
    -            // TODO: figure out what rbf option should be?
    -            version: Some(tx_builder::Version(tx.version)),
    -            recipients: tx
    -                .output
    -                .into_iter()
    -                .map(|txout| (txout.script_pubkey, txout.value))
    -                .collect(),
    -            utxos: original_utxos,
    -            bumping_fee: Some(tx_builder::PreviousFee {
    -                absolute: details.fee.ok_or(Error::FeeRateUnavailable)?,
    -                rate: feerate.as_sat_per_vb(),
    +        let params = TxParams {
    +            // TODO: figure out what rbf option should be?
    +            version: Some(tx_builder::Version(tx.version)),
    +            recipients: tx
    +                .output
    +                .into_iter()
    +                .map(|txout| (txout.script_pubkey, txout.value))
    +                .collect(),
    +            utxos: original_utxos,
    +            bumping_fee: Some(tx_builder::PreviousFee {
    +                absolute: details.fee.ok_or(Error::FeeRateUnavailable)?,
    +                rate: feerate.as_sat_per_vb(),
                 }),
    -            ..Default::default()
    +            ..Default::default()
             };
     
    -        Ok(TxBuilder {
    -            wallet: self,
    -            params,
    -            coin_selection: DefaultCoinSelectionAlgorithm::default(),
    -            phantom: core::marker::PhantomData,
    +        Ok(TxBuilder {
    +            wallet: self,
    +            params,
    +            coin_selection: DefaultCoinSelectionAlgorithm::default(),
    +            phantom: core::marker::PhantomData,
             })
         }
     
    -    /// Sign a transaction with all the wallet's signers, in the order specified by every signer's
    -    /// [`SignerOrdering`]
    -    ///
    -    /// The [`SignOptions`] can be used to tweak the behavior of the software signers, and the way
    -    /// the transaction is finalized at the end. Note that it can't be guaranteed that *every*
    -    /// signers will follow the options, but the "software signers" (WIF keys and `xprv`) defined
    -    /// in this library will.
    -    ///
    -    /// ## Example
    -    ///
    -    /// ```
    -    /// # use std::str::FromStr;
    -    /// # use bitcoin::*;
    -    /// # use bdk::*;
    -    /// # use bdk::database::*;
    -    /// # let descriptor = "wpkh(tpubD6NzVbkrYhZ4Xferm7Pz4VnjdcDPFyjVu5K4iZXQ4pVN8Cks4pHVowTBXBKRhX64pkRyJZJN5xAKj4UDNnLPb5p2sSKXhewoYx5GbTdUFWq/*)";
    -    /// # let wallet = doctest_wallet!();
    -    /// # let to_address = Address::from_str("2N4eQYCbKUHCCTUjBJeHcJp9ok6J2GZsTDt").unwrap();
    -    /// let (mut psbt, _) = {
    -    ///     let mut builder = wallet.build_tx();
    -    ///     builder.add_recipient(to_address.script_pubkey(), 50_000);
    -    ///     builder.finish()?
    -    /// };
    -    /// let  finalized = wallet.sign(&mut psbt, SignOptions::default())?;
    -    /// assert!(finalized, "we should have signed all the inputs");
    -    /// # Ok::<(), bdk::Error>(())
    -    pub fn sign(
    +    /// Sign a transaction with all the wallet's signers, in the order specified by every signer's
    +    /// [`SignerOrdering`]
    +    ///
    +    /// The [`SignOptions`] can be used to tweak the behavior of the software signers, and the way
    +    /// the transaction is finalized at the end. Note that it can't be guaranteed that *every*
    +    /// signers will follow the options, but the "software signers" (WIF keys and `xprv`) defined
    +    /// in this library will.
    +    ///
    +    /// ## Example
    +    ///
    +    /// ```
    +    /// # use std::str::FromStr;
    +    /// # use bitcoin::*;
    +    /// # use bdk::*;
    +    /// # use bdk::database::*;
    +    /// # let descriptor = "wpkh(tpubD6NzVbkrYhZ4Xferm7Pz4VnjdcDPFyjVu5K4iZXQ4pVN8Cks4pHVowTBXBKRhX64pkRyJZJN5xAKj4UDNnLPb5p2sSKXhewoYx5GbTdUFWq/*)";
    +    /// # let wallet = doctest_wallet!();
    +    /// # let to_address = Address::from_str("2N4eQYCbKUHCCTUjBJeHcJp9ok6J2GZsTDt").unwrap();
    +    /// let (mut psbt, _) = {
    +    ///     let mut builder = wallet.build_tx();
    +    ///     builder.add_recipient(to_address.script_pubkey(), 50_000);
    +    ///     builder.finish()?
    +    /// };
    +    /// let  finalized = wallet.sign(&mut psbt, SignOptions::default())?;
    +    /// assert!(finalized, "we should have signed all the inputs");
    +    /// # Ok::<(), bdk::Error>(())
    +    pub fn sign(
             &self,
    -        psbt: &mut psbt::PartiallySignedTransaction,
    -        sign_options: SignOptions,
    -    ) -> Result<bool, Error> {
    -        // This adds all the PSBT metadata for the inputs, which will help us later figure out how
    -        // to derive our keys
    -        self.update_psbt_with_descriptor(psbt)?;
    -
    -        // If we aren't allowed to use `witness_utxo`, ensure that every input (except p2tr and finalized ones)
    -        // has the `non_witness_utxo`
    -        if !sign_options.trust_witness_utxo
    -            && psbt
    -                .inputs
    -                .iter()
    -                .filter(|i| i.final_script_witness.is_none() && i.final_script_sig.is_none())
    -                .filter(|i| i.tap_internal_key.is_none() && i.tap_merkle_root.is_none())
    -                .any(|i| i.non_witness_utxo.is_none())
    +        psbt: &mut psbt::PartiallySignedTransaction,
    +        sign_options: SignOptions,
    +    ) -> Result<bool, Error> {
    +        // This adds all the PSBT metadata for the inputs, which will help us later figure out how
    +        // to derive our keys
    +        self.update_psbt_with_descriptor(psbt)?;
    +
    +        // If we aren't allowed to use `witness_utxo`, ensure that every input (except p2tr and finalized ones)
    +        // has the `non_witness_utxo`
    +        if !sign_options.trust_witness_utxo
    +            && psbt
    +                .inputs
    +                .iter()
    +                .filter(|i| i.final_script_witness.is_none() && i.final_script_sig.is_none())
    +                .filter(|i| i.tap_internal_key.is_none() && i.tap_merkle_root.is_none())
    +                .any(|i| i.non_witness_utxo.is_none())
             {
    -            return Err(Error::Signer(signer::SignerError::MissingNonWitnessUtxo));
    +            return Err(Error::Signer(signer::SignerError::MissingNonWitnessUtxo));
             }
     
    -        // If the user hasn't explicitly opted-in, refuse to sign the transaction unless every input
    -        // is using `SIGHASH_ALL` or `SIGHASH_DEFAULT` for taproot
    -        if !sign_options.allow_all_sighashes
    -            && !psbt.inputs.iter().all(|i| {
    -                i.sighash_type.is_none()
    -                    || i.sighash_type == Some(EcdsaSighashType::All.into())
    -                    || i.sighash_type == Some(SchnorrSighashType::All.into())
    -                    || i.sighash_type == Some(SchnorrSighashType::Default.into())
    +        // If the user hasn't explicitly opted-in, refuse to sign the transaction unless every input
    +        // is using `SIGHASH_ALL` or `SIGHASH_DEFAULT` for taproot
    +        if !sign_options.allow_all_sighashes
    +            && !psbt.inputs.iter().all(|i| {
    +                i.sighash_type.is_none()
    +                    || i.sighash_type == Some(EcdsaSighashType::All.into())
    +                    || i.sighash_type == Some(SchnorrSighashType::All.into())
    +                    || i.sighash_type == Some(SchnorrSighashType::Default.into())
                 })
             {
    -            return Err(Error::Signer(signer::SignerError::NonStandardSighash));
    +            return Err(Error::Signer(signer::SignerError::NonStandardSighash));
             }
     
    -        for signer in self
    -            .signers
    -            .signers()
    -            .iter()
    -            .chain(self.change_signers.signers().iter())
    +        for signer in self
    +            .signers
    +            .signers()
    +            .iter()
    +            .chain(self.change_signers.signers().iter())
             {
    -            signer.sign_transaction(psbt, &sign_options, &self.secp)?;
    +            signer.sign_transaction(psbt, &sign_options, &self.secp)?;
             }
     
    -        // attempt to finalize
    -        if sign_options.try_finalize {
    -            self.finalize_psbt(psbt, sign_options)
    -        } else {
    +        // attempt to finalize
    +        if sign_options.try_finalize {
    +            self.finalize_psbt(psbt, sign_options)
    +        } else {
                 Ok(false)
             }
         }
     
    -    /// Return the spending policies for the wallet's descriptor
    -    pub fn policies(&self, keychain: KeychainKind) -> Result<Option<Policy>, Error> {
    -        match (keychain, self.change_descriptor.as_ref()) {
    -            (KeychainKind::External, _) => Ok(self.descriptor.extract_policy(
    -                &self.signers,
    -                BuildSatisfaction::None,
    -                &self.secp,
    +    /// Return the spending policies for the wallet's descriptor
    +    pub fn policies(&self, keychain: KeychainKind) -> Result<Option<Policy>, Error> {
    +        match (keychain, self.change_descriptor.as_ref()) {
    +            (KeychainKind::External, _) => Ok(self.descriptor.extract_policy(
    +                &self.signers,
    +                BuildSatisfaction::None,
    +                &self.secp,
                 )?),
    -            (KeychainKind::Internal, None) => Ok(None),
    -            (KeychainKind::Internal, Some(desc)) => Ok(desc.extract_policy(
    -                &self.change_signers,
    -                BuildSatisfaction::None,
    -                &self.secp,
    +            (KeychainKind::Internal, None) => Ok(None),
    +            (KeychainKind::Internal, Some(desc)) => Ok(desc.extract_policy(
    +                &self.change_signers,
    +                BuildSatisfaction::None,
    +                &self.secp,
                 )?),
             }
         }
     
    -    /// 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
    -    pub fn public_descriptor(
    +    /// 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
    +    pub fn public_descriptor(
             &self,
    -        keychain: KeychainKind,
    -    ) -> Result<Option<ExtendedDescriptor>, Error> {
    -        match (keychain, self.change_descriptor.as_ref()) {
    -            (KeychainKind::External, _) => Ok(Some(self.descriptor.clone())),
    -            (KeychainKind::Internal, None) => Ok(None),
    -            (KeychainKind::Internal, Some(desc)) => Ok(Some(desc.clone())),
    +        keychain: KeychainKind,
    +    ) -> Result<Option<ExtendedDescriptor>, Error> {
    +        match (keychain, self.change_descriptor.as_ref()) {
    +            (KeychainKind::External, _) => Ok(Some(self.descriptor.clone())),
    +            (KeychainKind::Internal, None) => Ok(None),
    +            (KeychainKind::Internal, Some(desc)) => Ok(Some(desc.clone())),
             }
         }
     
    -    /// Finalize a PSBT, i.e., for each input determine if sufficient data is available to pass
    -    /// validation and construct the respective `scriptSig` or `scriptWitness`. Please refer to
    -    /// [BIP174](https://github.com/bitcoin/bips/blob/master/bip-0174.mediawiki#Input_Finalizer)
    -    /// 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.
    -    pub fn finalize_psbt(
    +    /// Finalize a PSBT, i.e., for each input determine if sufficient data is available to pass
    +    /// validation and construct the respective `scriptSig` or `scriptWitness`. Please refer to
    +    /// [BIP174](https://github.com/bitcoin/bips/blob/master/bip-0174.mediawiki#Input_Finalizer)
    +    /// 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.
    +    pub fn finalize_psbt(
             &self,
    -        psbt: &mut psbt::PartiallySignedTransaction,
    -        sign_options: SignOptions,
    -    ) -> Result<bool, Error> {
    -        let tx = &psbt.unsigned_tx;
    -        let mut finished = true;
    -
    -        for (n, input) in tx.input.iter().enumerate() {
    -            let psbt_input = &psbt
    -                .inputs
    -                .get(n)
    -                .ok_or(Error::Signer(SignerError::InputIndexOutOfRange))?;
    -            if psbt_input.final_script_sig.is_some() || psbt_input.final_script_witness.is_some() {
    +        psbt: &mut psbt::PartiallySignedTransaction,
    +        sign_options: SignOptions,
    +    ) -> Result<bool, Error> {
    +        let tx = &psbt.unsigned_tx;
    +        let mut finished = true;
    +
    +        for (n, input) in tx.input.iter().enumerate() {
    +            let psbt_input = &psbt
    +                .inputs
    +                .get(n)
    +                .ok_or(Error::Signer(SignerError::InputIndexOutOfRange))?;
    +            if psbt_input.final_script_sig.is_some() || psbt_input.final_script_witness.is_some() {
                     continue;
                 }
    -            // if the height is None in the database it means it's still unconfirmed, so consider
    -            // that as a very high value
    -            let create_height = self
    -                .database
    -                .borrow()
    -                .get_tx(&input.previous_output.txid, false)?
    -                .map(|tx| tx.confirmation_time.map(|c| c.height).unwrap_or(u32::MAX));
    -            let last_sync_height = self
    -                .database()
    -                .get_sync_time()?
    -                .map(|sync_time| sync_time.block_time.height);
    -            let current_height = sign_options.assume_height.or(last_sync_height);
    +            // if the height is None in the database it means it's still unconfirmed, so consider
    +            // that as a very high value
    +            let create_height = self
    +                .database
    +                .borrow()
    +                .get_tx(&input.previous_output.txid, false)?
    +                .map(|tx| tx.confirmation_time.map(|c| c.height).unwrap_or(u32::MAX));
    +            let last_sync_height = self
    +                .database()
    +                .get_sync_time()?
    +                .map(|sync_time| sync_time.block_time.height);
    +            let current_height = sign_options.assume_height.or(last_sync_height);
     
                 debug!(
                     "Input #{} - {}, using `create_height` = {:?}, `current_height` = {:?}",
    -                n, input.previous_output, create_height, current_height
    +                n, input.previous_output, create_height, current_height
                 );
     
    -            // - Try to derive the descriptor by looking at the txout. If it's in our database, we
    -            //   know exactly which `keychain` to use, and which derivation index it is
    -            // - If that fails, try to derive it by looking at the psbt input: the complete logic
    -            //   is in `src/descriptor/mod.rs`, but it will basically look at `bip32_derivation`,
    -            //   `redeem_script` and `witness_script` to determine the right derivation
    -            // - If that also fails, it will try it on the internal descriptor, if present
    -            let desc = psbt
    -                .get_utxo_for(n)
    -                .map(|txout| self.get_descriptor_for_txout(&txout))
    -                .transpose()?
    -                .flatten()
    -                .or_else(|| {
    -                    self.descriptor.derive_from_psbt_input(
    -                        psbt_input,
    -                        psbt.get_utxo_for(n),
    -                        &self.secp,
    +            // - Try to derive the descriptor by looking at the txout. If it's in our database, we
    +            //   know exactly which `keychain` to use, and which derivation index it is
    +            // - If that fails, try to derive it by looking at the psbt input: the complete logic
    +            //   is in `src/descriptor/mod.rs`, but it will basically look at `bip32_derivation`,
    +            //   `redeem_script` and `witness_script` to determine the right derivation
    +            // - If that also fails, it will try it on the internal descriptor, if present
    +            let desc = psbt
    +                .get_utxo_for(n)
    +                .map(|txout| self.get_descriptor_for_txout(&txout))
    +                .transpose()?
    +                .flatten()
    +                .or_else(|| {
    +                    self.descriptor.derive_from_psbt_input(
    +                        psbt_input,
    +                        psbt.get_utxo_for(n),
    +                        &self.secp,
                         )
                     })
    -                .or_else(|| {
    -                    self.change_descriptor.as_ref().and_then(|desc| {
    -                        desc.derive_from_psbt_input(psbt_input, psbt.get_utxo_for(n), &self.secp)
    +                .or_else(|| {
    +                    self.change_descriptor.as_ref().and_then(|desc| {
    +                        desc.derive_from_psbt_input(psbt_input, psbt.get_utxo_for(n), &self.secp)
                         })
                     });
     
    -            match desc {
    -                Some(desc) => {
    -                    let mut tmp_input = bitcoin::TxIn::default();
    -                    match desc.satisfy(
    -                        &mut tmp_input,
    +            match desc {
    +                Some(desc) => {
    +                    let mut tmp_input = bitcoin::TxIn::default();
    +                    match desc.satisfy(
    +                        &mut tmp_input,
                             (
    -                            PsbtInputSatisfier::new(psbt, n),
    -                            After::new(current_height, false),
    -                            Older::new(current_height, create_height, false),
    +                            PsbtInputSatisfier::new(psbt, n),
    +                            After::new(current_height, false),
    +                            Older::new(current_height, create_height, false),
                             ),
                         ) {
                             Ok(_) => {
    -                            let psbt_input = &mut psbt.inputs[n];
    -                            psbt_input.final_script_sig = Some(tmp_input.script_sig);
    -                            psbt_input.final_script_witness = Some(tmp_input.witness);
    -                            if sign_options.remove_partial_sigs {
    -                                psbt_input.partial_sigs.clear();
    +                            let psbt_input = &mut psbt.inputs[n];
    +                            psbt_input.final_script_sig = Some(tmp_input.script_sig);
    +                            psbt_input.final_script_witness = Some(tmp_input.witness);
    +                            if sign_options.remove_partial_sigs {
    +                                psbt_input.partial_sigs.clear();
                                 }
                             }
    -                        Err(e) => {
    -                            debug!("satisfy error {:?} for input {}", e, n);
    -                            finished = false
    -                        }
    +                        Err(e) => {
    +                            debug!("satisfy error {:?} for input {}", e, n);
    +                            finished = false
    +                        }
                         }
                     }
    -                None => finished = false,
    +                None => finished = false,
                 }
             }
     
    -        Ok(finished)
    +        Ok(finished)
         }
     
    -    /// Return the secp256k1 context used for all signing operations
    -    pub fn secp_ctx(&self) -> &SecpCtx {
    -        &self.secp
    +    /// Return the secp256k1 context used for all signing operations
    +    pub fn secp_ctx(&self) -> &SecpCtx {
    +        &self.secp
         }
     
    -    /// Returns the descriptor used to create addresses for a particular `keychain`.
    -    pub fn get_descriptor_for_keychain(&self, keychain: KeychainKind) -> &ExtendedDescriptor {
    -        let (descriptor, _) = self._get_descriptor_for_keychain(keychain);
    -        descriptor
    +    /// Returns the descriptor used to create addresses for a particular `keychain`.
    +    pub fn get_descriptor_for_keychain(&self, keychain: KeychainKind) -> &ExtendedDescriptor {
    +        let (descriptor, _) = self._get_descriptor_for_keychain(keychain);
    +        descriptor
         }
     
    -    // Internals
    +    // Internals
     
    -    fn _get_descriptor_for_keychain(
    +    fn _get_descriptor_for_keychain(
             &self,
    -        keychain: KeychainKind,
    -    ) -> (&ExtendedDescriptor, KeychainKind) {
    -        match keychain {
    -            KeychainKind::Internal if self.change_descriptor.is_some() => (
    -                self.change_descriptor.as_ref().unwrap(),
    -                KeychainKind::Internal,
    +        keychain: KeychainKind,
    +    ) -> (&ExtendedDescriptor, KeychainKind) {
    +        match keychain {
    +            KeychainKind::Internal if self.change_descriptor.is_some() => (
    +                self.change_descriptor.as_ref().unwrap(),
    +                KeychainKind::Internal,
                 ),
    -            _ => (&self.descriptor, KeychainKind::External),
    +            _ => (&self.descriptor, KeychainKind::External),
             }
         }
     
    -    fn get_descriptor_for_txout(&self, txout: &TxOut) -> Result<Option<DerivedDescriptor>, Error> {
    -        Ok(self
    -            .database
    -            .borrow()
    -            .get_path_from_script_pubkey(&txout.script_pubkey)?
    -            .map(|(keychain, child)| (self.get_descriptor_for_keychain(keychain), child))
    -            .map(|(desc, child)| desc.at_derivation_index(child)))
    +    fn get_descriptor_for_txout(&self, txout: &TxOut) -> Result<Option<DerivedDescriptor>, Error> {
    +        Ok(self
    +            .database
    +            .borrow()
    +            .get_path_from_script_pubkey(&txout.script_pubkey)?
    +            .map(|(keychain, child)| (self.get_descriptor_for_keychain(keychain), child))
    +            .map(|(desc, child)| desc.at_derivation_index(child)))
         }
     
    -    fn fetch_and_increment_index(&self, keychain: KeychainKind) -> Result<u32, Error> {
    -        let (descriptor, keychain) = self._get_descriptor_for_keychain(keychain);
    -        let index = match descriptor.has_wildcard() {
    -            false => 0,
    -            true => self.database.borrow_mut().increment_last_index(keychain)?,
    +    fn fetch_and_increment_index(&self, keychain: KeychainKind) -> Result<u32, Error> {
    +        let (descriptor, keychain) = self._get_descriptor_for_keychain(keychain);
    +        let index = match descriptor.has_wildcard() {
    +            false => 0,
    +            true => self.database.borrow_mut().increment_last_index(keychain)?,
             };
     
    -        if self
    -            .database
    -            .borrow()
    -            .get_script_pubkey_from_path(keychain, index)?
    -            .is_none()
    +        if self
    +            .database
    +            .borrow()
    +            .get_script_pubkey_from_path(keychain, index)?
    +            .is_none()
             {
    -            self.cache_addresses(keychain, index, CACHE_ADDR_BATCH_SIZE)?;
    +            self.cache_addresses(keychain, index, CACHE_ADDR_BATCH_SIZE)?;
             }
     
    -        Ok(index)
    +        Ok(index)
         }
     
    -    fn fetch_index(&self, keychain: KeychainKind) -> Result<u32, Error> {
    -        let (descriptor, keychain) = self._get_descriptor_for_keychain(keychain);
    -        let index = match descriptor.has_wildcard() {
    -            false => Some(0),
    -            true => self.database.borrow_mut().get_last_index(keychain)?,
    +    fn fetch_index(&self, keychain: KeychainKind) -> Result<u32, Error> {
    +        let (descriptor, keychain) = self._get_descriptor_for_keychain(keychain);
    +        let index = match descriptor.has_wildcard() {
    +            false => Some(0),
    +            true => self.database.borrow_mut().get_last_index(keychain)?,
             };
     
    -        if let Some(i) = index {
    -            Ok(i)
    -        } else {
    -            self.fetch_and_increment_index(keychain)
    +        if let Some(i) = index {
    +            Ok(i)
    +        } else {
    +            self.fetch_and_increment_index(keychain)
             }
         }
     
    -    fn set_index(&self, keychain: KeychainKind, index: u32) -> Result<(), Error> {
    -        self.database.borrow_mut().set_last_index(keychain, index)?;
    +    fn set_index(&self, keychain: KeychainKind, index: u32) -> Result<(), Error> {
    +        self.database.borrow_mut().set_last_index(keychain, index)?;
             Ok(())
         }
     
    -    fn cache_addresses(
    +    fn cache_addresses(
             &self,
    -        keychain: KeychainKind,
    -        from: u32,
    -        mut count: u32,
    -    ) -> Result<(), Error> {
    -        let (descriptor, keychain) = self._get_descriptor_for_keychain(keychain);
    -        if !descriptor.has_wildcard() {
    -            if from > 0 {
    -                return Ok(());
    +        keychain: KeychainKind,
    +        from: u32,
    +        mut count: u32,
    +    ) -> Result<(), Error> {
    +        let (descriptor, keychain) = self._get_descriptor_for_keychain(keychain);
    +        if !descriptor.has_wildcard() {
    +            if from > 0 {
    +                return Ok(());
                 }
     
    -            count = 1;
    +            count = 1;
             }
     
    -        let mut address_batch = self.database.borrow().begin_batch();
    +        let mut address_batch = self.database.borrow().begin_batch();
     
    -        let start_time = time::Instant::new();
    -        for i in from..(from + count) {
    -            address_batch.set_script_pubkey(
    -                &descriptor.at_derivation_index(i).script_pubkey(),
    -                keychain,
    -                i,
    +        let start_time = time::Instant::new();
    +        for i in from..(from + count) {
    +            address_batch.set_script_pubkey(
    +                &descriptor.at_derivation_index(i).script_pubkey(),
    +                keychain,
    +                i,
                 )?;
             }
     
             info!(
                 "Derivation of {} addresses from {} took {} ms",
    -            count,
    -            from,
    -            start_time.elapsed().as_millis()
    +            count,
    +            from,
    +            start_time.elapsed().as_millis()
             );
     
    -        self.database.borrow_mut().commit_batch(address_batch)?;
    +        self.database.borrow_mut().commit_batch(address_batch)?;
     
             Ok(())
         }
     
    -    fn get_available_utxos(&self) -> Result<Vec<(LocalUtxo, usize)>, Error> {
    -        Ok(self
    -            .list_unspent()?
    -            .into_iter()
    -            .map(|utxo| {
    -                let keychain = utxo.keychain;
    +    fn get_available_utxos(&self) -> Result<Vec<(LocalUtxo, usize)>, Error> {
    +        Ok(self
    +            .list_unspent()?
    +            .into_iter()
    +            .map(|utxo| {
    +                let keychain = utxo.keychain;
                     (
    -                    utxo,
    -                    self.get_descriptor_for_keychain(keychain)
    -                        .max_satisfaction_weight()
    -                        .unwrap(),
    +                    utxo,
    +                    self.get_descriptor_for_keychain(keychain)
    +                        .max_satisfaction_weight()
    +                        .unwrap(),
                     )
                 })
    -            .collect())
    +            .collect())
         }
     
    -    /// Given the options returns the list of utxos that must be used to form the
    -    /// transaction and any further that may be used if needed.
    -    #[allow(clippy::type_complexity)]
    -    #[allow(clippy::too_many_arguments)]
    -    fn preselect_utxos(
    +    /// Given the options returns the list of utxos that must be used to form the
    +    /// transaction and any further that may be used if needed.
    +    #[allow(clippy::type_complexity)]
    +    #[allow(clippy::too_many_arguments)]
    +    fn preselect_utxos(
             &self,
    -        change_policy: tx_builder::ChangeSpendPolicy,
    -        unspendable: &HashSet<OutPoint>,
    -        manually_selected: Vec<WeightedUtxo>,
    -        must_use_all_available: bool,
    -        manual_only: bool,
    -        must_only_use_confirmed_tx: bool,
    -        current_height: Option<u32>,
    -    ) -> Result<(Vec<WeightedUtxo>, Vec<WeightedUtxo>), Error> {
    -        //    must_spend <- manually selected utxos
    -        //    may_spend  <- all other available utxos
    -        let mut may_spend = self.get_available_utxos()?;
    -
    -        may_spend.retain(|may_spend| {
    -            !manually_selected
    -                .iter()
    -                .any(|manually_selected| manually_selected.utxo.outpoint() == may_spend.0.outpoint)
    +        change_policy: tx_builder::ChangeSpendPolicy,
    +        unspendable: &HashSet<OutPoint>,
    +        manually_selected: Vec<WeightedUtxo>,
    +        must_use_all_available: bool,
    +        manual_only: bool,
    +        must_only_use_confirmed_tx: bool,
    +        current_height: Option<u32>,
    +    ) -> Result<(Vec<WeightedUtxo>, Vec<WeightedUtxo>), Error> {
    +        //    must_spend <- manually selected utxos
    +        //    may_spend  <- all other available utxos
    +        let mut may_spend = self.get_available_utxos()?;
    +
    +        may_spend.retain(|may_spend| {
    +            !manually_selected
    +                .iter()
    +                .any(|manually_selected| manually_selected.utxo.outpoint() == may_spend.0.outpoint)
             });
    -        let mut must_spend = manually_selected;
    +        let mut must_spend = manually_selected;
     
    -        // NOTE: we are intentionally ignoring `unspendable` here. i.e manual
    -        // selection overrides unspendable.
    -        if manual_only {
    -            return Ok((must_spend, vec![]));
    +        // NOTE: we are intentionally ignoring `unspendable` here. i.e manual
    +        // selection overrides unspendable.
    +        if manual_only {
    +            return Ok((must_spend, vec![]));
             }
     
    -        let database = self.database.borrow();
    -        let satisfies_confirmed = may_spend
    -            .iter()
    -            .map(|u| {
    -                database
    -                    .get_tx(&u.0.outpoint.txid, true)
    -                    .map(|tx| match tx {
    -                        // We don't have the tx in the db for some reason,
    -                        // so we can't know for sure if it's mature or not.
    -                        // We prefer not to spend it.
    -                        None => false,
    -                        Some(tx) => {
    -                            // Whether the UTXO is mature and, if needed, confirmed
    -                            let mut spendable = true;
    -                            if must_only_use_confirmed_tx && tx.confirmation_time.is_none() {
    -                                return false;
    +        let database = self.database.borrow();
    +        let satisfies_confirmed = may_spend
    +            .iter()
    +            .map(|u| {
    +                database
    +                    .get_tx(&u.0.outpoint.txid, true)
    +                    .map(|tx| match tx {
    +                        // We don't have the tx in the db for some reason,
    +                        // so we can't know for sure if it's mature or not.
    +                        // We prefer not to spend it.
    +                        None => false,
    +                        Some(tx) => {
    +                            // Whether the UTXO is mature and, if needed, confirmed
    +                            let mut spendable = true;
    +                            if must_only_use_confirmed_tx && tx.confirmation_time.is_none() {
    +                                return false;
                                 }
    -                            if tx
    -                                .transaction
    -                                .expect("We specifically ask for the transaction above")
    -                                .is_coin_base()
    +                            if tx
    +                                .transaction
    +                                .expect("We specifically ask for the transaction above")
    +                                .is_coin_base()
                                 {
    -                                if let Some(current_height) = current_height {
    -                                    match &tx.confirmation_time {
    -                                        Some(t) => {
    -                                            // https://github.com/bitcoin/bitcoin/blob/c5e67be03bb06a5d7885c55db1f016fbf2333fe3/src/validation.cpp#L373-L375
    -                                            spendable &= (current_height.saturating_sub(t.height))
    -                                                >= COINBASE_MATURITY;
    +                                if let Some(current_height) = current_height {
    +                                    match &tx.confirmation_time {
    +                                        Some(t) => {
    +                                            // https://github.com/bitcoin/bitcoin/blob/c5e67be03bb06a5d7885c55db1f016fbf2333fe3/src/validation.cpp#L373-L375
    +                                            spendable &= (current_height.saturating_sub(t.height))
    +                                                >= COINBASE_MATURITY;
                                             }
    -                                        None => spendable = false,
    +                                        None => spendable = false,
                                         }
                                     }
                                 }
    -                            spendable
    +                            spendable
                             }
                         })
                 })
    -            .collect::<Result<Vec<_>, _>>()?;
    -
    -        let mut i = 0;
    -        may_spend.retain(|u| {
    -            let retain = change_policy.is_satisfied_by(&u.0)
    -                && !unspendable.contains(&u.0.outpoint)
    -                && satisfies_confirmed[i];
    -            i += 1;
    -            retain
    +            .collect::<Result<Vec<_>, _>>()?;
    +
    +        let mut i = 0;
    +        may_spend.retain(|u| {
    +            let retain = change_policy.is_satisfied_by(&u.0)
    +                && !unspendable.contains(&u.0.outpoint)
    +                && satisfies_confirmed[i];
    +            i += 1;
    +            retain
             });
     
    -        let mut may_spend = may_spend
    -            .into_iter()
    -            .map(|(local_utxo, satisfaction_weight)| WeightedUtxo {
    -                satisfaction_weight,
    -                utxo: Utxo::Local(local_utxo),
    +        let mut may_spend = may_spend
    +            .into_iter()
    +            .map(|(local_utxo, satisfaction_weight)| WeightedUtxo {
    +                satisfaction_weight,
    +                utxo: Utxo::Local(local_utxo),
                 })
    -            .collect();
    +            .collect();
     
    -        if must_use_all_available {
    -            must_spend.append(&mut may_spend);
    +        if must_use_all_available {
    +            must_spend.append(&mut may_spend);
             }
     
    -        Ok((must_spend, may_spend))
    +        Ok((must_spend, may_spend))
         }
     
    -    fn complete_transaction(
    +    fn complete_transaction(
             &self,
    -        tx: Transaction,
    -        selected: Vec<Utxo>,
    -        params: TxParams,
    -    ) -> Result<psbt::PartiallySignedTransaction, Error> {
    -        let mut psbt = psbt::PartiallySignedTransaction::from_unsigned_tx(tx)?;
    -
    -        if params.add_global_xpubs {
    -            let mut all_xpubs = self.descriptor.get_extended_keys()?;
    -            if let Some(change_descriptor) = &self.change_descriptor {
    -                all_xpubs.extend(change_descriptor.get_extended_keys()?);
    +        tx: Transaction,
    +        selected: Vec<Utxo>,
    +        params: TxParams,
    +    ) -> Result<psbt::PartiallySignedTransaction, Error> {
    +        let mut psbt = psbt::PartiallySignedTransaction::from_unsigned_tx(tx)?;
    +
    +        if params.add_global_xpubs {
    +            let mut all_xpubs = self.descriptor.get_extended_keys()?;
    +            if let Some(change_descriptor) = &self.change_descriptor {
    +                all_xpubs.extend(change_descriptor.get_extended_keys()?);
                 }
     
    -            for xpub in all_xpubs {
    -                let origin = match xpub.origin {
    -                    Some(origin) => origin,
    -                    None if xpub.xkey.depth == 0 => {
    -                        (xpub.root_fingerprint(&self.secp), vec![].into())
    +            for xpub in all_xpubs {
    +                let origin = match xpub.origin {
    +                    Some(origin) => origin,
    +                    None if xpub.xkey.depth == 0 => {
    +                        (xpub.root_fingerprint(&self.secp), vec![].into())
                         }
    -                    _ => return Err(Error::MissingKeyOrigin(xpub.xkey.to_string())),
    +                    _ => return Err(Error::MissingKeyOrigin(xpub.xkey.to_string())),
                     };
     
    -                psbt.xpub.insert(xpub.xkey, origin);
    +                psbt.xpub.insert(xpub.xkey, origin);
                 }
             }
     
    -        let mut lookup_output = selected
    -            .into_iter()
    -            .map(|utxo| (utxo.outpoint(), utxo))
    -            .collect::<HashMap<_, _>>();
    +        let mut lookup_output = selected
    +            .into_iter()
    +            .map(|utxo| (utxo.outpoint(), utxo))
    +            .collect::<HashMap<_, _>>();
     
    -        // add metadata for the inputs
    -        for (psbt_input, input) in psbt.inputs.iter_mut().zip(psbt.unsigned_tx.input.iter()) {
    -            let utxo = match lookup_output.remove(&input.previous_output) {
    -                Some(utxo) => utxo,
    -                None => continue,
    +        // add metadata for the inputs
    +        for (psbt_input, input) in psbt.inputs.iter_mut().zip(psbt.unsigned_tx.input.iter()) {
    +            let utxo = match lookup_output.remove(&input.previous_output) {
    +                Some(utxo) => utxo,
    +                None => continue,
                 };
     
    -            match utxo {
    -                Utxo::Local(utxo) => {
    -                    *psbt_input =
    -                        match self.get_psbt_input(utxo, params.sighash, params.only_witness_utxo) {
    -                            Ok(psbt_input) => psbt_input,
    -                            Err(e) => match e {
    -                                Error::UnknownUtxo => psbt::Input {
    -                                    sighash_type: params.sighash,
    -                                    ..psbt::Input::default()
    +            match utxo {
    +                Utxo::Local(utxo) => {
    +                    *psbt_input =
    +                        match self.get_psbt_input(utxo, params.sighash, params.only_witness_utxo) {
    +                            Ok(psbt_input) => psbt_input,
    +                            Err(e) => match e {
    +                                Error::UnknownUtxo => psbt::Input {
    +                                    sighash_type: params.sighash,
    +                                    ..psbt::Input::default()
                                     },
    -                                _ => return Err(e),
    +                                _ => return Err(e),
                                 },
                             }
                     }
    -                Utxo::Foreign {
    -                    psbt_input: foreign_psbt_input,
    -                    outpoint,
    +                Utxo::Foreign {
    +                    psbt_input: foreign_psbt_input,
    +                    outpoint,
                     } => {
    -                    let is_taproot = foreign_psbt_input
    -                        .witness_utxo
    -                        .as_ref()
    -                        .map(|txout| txout.script_pubkey.is_v1_p2tr())
    -                        .unwrap_or(false);
    -                    if !is_taproot
    -                        && !params.only_witness_utxo
    -                        && foreign_psbt_input.non_witness_utxo.is_none()
    +                    let is_taproot = foreign_psbt_input
    +                        .witness_utxo
    +                        .as_ref()
    +                        .map(|txout| txout.script_pubkey.is_v1_p2tr())
    +                        .unwrap_or(false);
    +                    if !is_taproot
    +                        && !params.only_witness_utxo
    +                        && foreign_psbt_input.non_witness_utxo.is_none()
                         {
    -                        return Err(Error::Generic(format!(
    +                        return Err(Error::Generic(format!(
                                 "Missing non_witness_utxo on foreign utxo {}",
    -                            outpoint
    +                            outpoint
                             )));
                         }
    -                    *psbt_input = *foreign_psbt_input;
    +                    *psbt_input = *foreign_psbt_input;
                     }
                 }
             }
     
    -        self.update_psbt_with_descriptor(&mut psbt)?;
    +        self.update_psbt_with_descriptor(&mut psbt)?;
     
    -        Ok(psbt)
    +        Ok(psbt)
         }
     
    -    /// get the corresponding PSBT Input for a LocalUtxo
    -    pub fn get_psbt_input(
    +    /// get the corresponding PSBT Input for a LocalUtxo
    +    pub fn get_psbt_input(
             &self,
    -        utxo: LocalUtxo,
    -        sighash_type: Option<psbt::PsbtSighashType>,
    -        only_witness_utxo: bool,
    -    ) -> Result<psbt::Input, Error> {
    -        // Try to find the prev_script in our db to figure out if this is internal or external,
    -        // and the derivation index
    -        let (keychain, child) = self
    -            .database
    -            .borrow()
    -            .get_path_from_script_pubkey(&utxo.txout.script_pubkey)?
    -            .ok_or(Error::UnknownUtxo)?;
    -
    -        let mut psbt_input = psbt::Input {
    -            sighash_type,
    -            ..psbt::Input::default()
    +        utxo: LocalUtxo,
    +        sighash_type: Option<psbt::PsbtSighashType>,
    +        only_witness_utxo: bool,
    +    ) -> Result<psbt::Input, Error> {
    +        // Try to find the prev_script in our db to figure out if this is internal or external,
    +        // and the derivation index
    +        let (keychain, child) = self
    +            .database
    +            .borrow()
    +            .get_path_from_script_pubkey(&utxo.txout.script_pubkey)?
    +            .ok_or(Error::UnknownUtxo)?;
    +
    +        let mut psbt_input = psbt::Input {
    +            sighash_type,
    +            ..psbt::Input::default()
             };
     
    -        let desc = self.get_descriptor_for_keychain(keychain);
    -        let derived_descriptor = desc.at_derivation_index(child);
    +        let desc = self.get_descriptor_for_keychain(keychain);
    +        let derived_descriptor = desc.at_derivation_index(child);
     
    -        psbt_input
    -            .update_with_descriptor_unchecked(&derived_descriptor)
    -            .map_err(MiniscriptPsbtError::Conversion)?;
    +        psbt_input
    +            .update_with_descriptor_unchecked(&derived_descriptor)
    +            .map_err(MiniscriptPsbtError::Conversion)?;
     
    -        let prev_output = utxo.outpoint;
    -        if let Some(prev_tx) = self.database.borrow().get_raw_tx(&prev_output.txid)? {
    -            if desc.is_witness() || desc.is_taproot() {
    -                psbt_input.witness_utxo = Some(prev_tx.output[prev_output.vout as usize].clone());
    +        let prev_output = utxo.outpoint;
    +        if let Some(prev_tx) = self.database.borrow().get_raw_tx(&prev_output.txid)? {
    +            if desc.is_witness() || desc.is_taproot() {
    +                psbt_input.witness_utxo = Some(prev_tx.output[prev_output.vout as usize].clone());
                 }
    -            if !desc.is_taproot() && (!desc.is_witness() || !only_witness_utxo) {
    -                psbt_input.non_witness_utxo = Some(prev_tx);
    +            if !desc.is_taproot() && (!desc.is_witness() || !only_witness_utxo) {
    +                psbt_input.non_witness_utxo = Some(prev_tx);
                 }
             }
    -        Ok(psbt_input)
    +        Ok(psbt_input)
         }
     
    -    fn update_psbt_with_descriptor(
    +    fn update_psbt_with_descriptor(
             &self,
    -        psbt: &mut psbt::PartiallySignedTransaction,
    -    ) -> Result<(), Error> {
    -        // We need to borrow `psbt` mutably within the loops, so we have to allocate a vec for all
    -        // the input utxos and outputs
    -        //
    -        // Clippy complains that the collect is not required, but that's wrong
    -        #[allow(clippy::needless_collect)]
    -        let utxos = (0..psbt.inputs.len())
    -            .filter_map(|i| psbt.get_utxo_for(i).map(|utxo| (true, i, utxo)))
    -            .chain(
    -                psbt.unsigned_tx
    -                    .output
    -                    .iter()
    -                    .enumerate()
    -                    .map(|(i, out)| (false, i, out.clone())),
    +        psbt: &mut psbt::PartiallySignedTransaction,
    +    ) -> Result<(), Error> {
    +        // We need to borrow `psbt` mutably within the loops, so we have to allocate a vec for all
    +        // the input utxos and outputs
    +        //
    +        // Clippy complains that the collect is not required, but that's wrong
    +        #[allow(clippy::needless_collect)]
    +        let utxos = (0..psbt.inputs.len())
    +            .filter_map(|i| psbt.get_utxo_for(i).map(|utxo| (true, i, utxo)))
    +            .chain(
    +                psbt.unsigned_tx
    +                    .output
    +                    .iter()
    +                    .enumerate()
    +                    .map(|(i, out)| (false, i, out.clone())),
                 )
    -            .collect::<Vec<_>>();
    -
    -        // Try to figure out the keychain and derivation for every input and output
    -        for (is_input, index, out) in utxos.into_iter() {
    -            if let Some((keychain, child)) = self
    -                .database
    -                .borrow()
    -                .get_path_from_script_pubkey(&out.script_pubkey)?
    -            {
    +            .collect::<Vec<_>>();
    +
    +        // Try to figure out the keychain and derivation for every input and output
    +        for (is_input, index, out) in utxos.into_iter() {
    +            if let Some((keychain, child)) = self
    +                .database
    +                .borrow()
    +                .get_path_from_script_pubkey(&out.script_pubkey)?
    +            {
                     debug!(
                         "Found descriptor for input #{} {:?}/{}",
    -                    index, keychain, child
    +                    index, keychain, child
                     );
     
    -                let desc = self.get_descriptor_for_keychain(keychain);
    -                let desc = desc.at_derivation_index(child);
    +                let desc = self.get_descriptor_for_keychain(keychain);
    +                let desc = desc.at_derivation_index(child);
     
    -                if is_input {
    -                    psbt.update_input_with_descriptor(index, &desc)
    -                        .map_err(MiniscriptPsbtError::UtxoUpdate)?;
    -                } else {
    -                    psbt.update_output_with_descriptor(index, &desc)
    -                        .map_err(MiniscriptPsbtError::OutputUpdate)?;
    +                if is_input {
    +                    psbt.update_input_with_descriptor(index, &desc)
    +                        .map_err(MiniscriptPsbtError::UtxoUpdate)?;
    +                } else {
    +                    psbt.update_output_with_descriptor(index, &desc)
    +                        .map_err(MiniscriptPsbtError::OutputUpdate)?;
                     }
                 }
             }
    @@ -7272,3139 +7266,3139 @@
             Ok(())
         }
     
    -    /// Return an immutable reference to the internal database
    -    pub fn database(&self) -> impl std::ops::Deref<Target = D> + '_ {
    -        self.database.borrow()
    +    /// Return an immutable reference to the internal database
    +    pub fn database(&self) -> impl std::ops::Deref<Target = D> + '_ {
    +        self.database.borrow()
         }
     
    -    /// Sync the internal database with the blockchain
    -    #[maybe_async]
    -    pub fn sync<B: WalletSync + GetHeight>(
    +    /// Sync the internal database with the blockchain
    +    #[maybe_async]
    +    pub fn sync<B: WalletSync + GetHeight>(
             &self,
    -        blockchain: &B,
    -        sync_opts: SyncOptions,
    -    ) -> Result<(), Error> {
    +        blockchain: &B,
    +        sync_opts: SyncOptions,
    +    ) -> Result<(), Error> {
             debug!("Begin sync...");
     
    -        // TODO: for the next runs, we cannot reuse the `sync_opts.progress` object due to trait
    -        // restrictions
    -        let mut progress_iter = sync_opts.progress.into_iter();
    -        let mut new_progress = || {
    -            progress_iter
    -                .next()
    -                .unwrap_or_else(|| Box::new(NoopProgress))
    +        // TODO: for the next runs, we cannot reuse the `sync_opts.progress` object due to trait
    +        // restrictions
    +        let mut progress_iter = sync_opts.progress.into_iter();
    +        let mut new_progress = || {
    +            progress_iter
    +                .next()
    +                .unwrap_or_else(|| Box::new(NoopProgress))
             };
     
    -        let run_setup = self.ensure_addresses_cached(CACHE_ADDR_BATCH_SIZE)?;
    -        debug!("run_setup: {}", run_setup);
    -
    -        // TODO: what if i generate an address first and cache some addresses?
    -        // TODO: we should sync if generating an address triggers a new batch to be stored
    -
    -        // We need to ensure descriptor is derivable to fullfil "missing cache", otherwise we will
    -        // end up with an infinite loop
    -        let has_wildcard = self.descriptor.has_wildcard()
    -            && (self.change_descriptor.is_none()
    -                || self.change_descriptor.as_ref().unwrap().has_wildcard());
    -
    -        // Restrict max rounds in case of faulty "missing cache" implementation by blockchain
    -        let max_rounds = if has_wildcard { 100 } else { 1 };
    -
    -        for _ in 0..max_rounds {
    -            let sync_res =
    -                if run_setup {
    -                    maybe_await!(blockchain
    -                        .wallet_setup(self.database.borrow_mut().deref_mut(), new_progress()))
    -                } else {
    -                    maybe_await!(blockchain
    -                        .wallet_sync(self.database.borrow_mut().deref_mut(), new_progress()))
    +        let run_setup = self.ensure_addresses_cached(CACHE_ADDR_BATCH_SIZE)?;
    +        debug!("run_setup: {}", run_setup);
    +
    +        // TODO: what if i generate an address first and cache some addresses?
    +        // TODO: we should sync if generating an address triggers a new batch to be stored
    +
    +        // We need to ensure descriptor is derivable to fullfil "missing cache", otherwise we will
    +        // end up with an infinite loop
    +        let has_wildcard = self.descriptor.has_wildcard()
    +            && (self.change_descriptor.is_none()
    +                || self.change_descriptor.as_ref().unwrap().has_wildcard());
    +
    +        // Restrict max rounds in case of faulty "missing cache" implementation by blockchain
    +        let max_rounds = if has_wildcard { 100 } else { 1 };
    +
    +        for _ in 0..max_rounds {
    +            let sync_res =
    +                if run_setup {
    +                    maybe_await!(blockchain
    +                        .wallet_setup(self.database.borrow_mut().deref_mut(), new_progress()))
    +                } else {
    +                    maybe_await!(blockchain
    +                        .wallet_sync(self.database.borrow_mut().deref_mut(), new_progress()))
                     };
     
    -            // If the error is the special `MissingCachedScripts` error, we return the number of
    -            // scripts we should ensure cached.
    -            // On any other error, we should return the error.
    -            // On no error, we say `ensure_cache` is 0.
    -            let ensure_cache = sync_res.map_or_else(
    -                |e| match e {
    -                    Error::MissingCachedScripts(inner) => {
    -                        // each call to `WalletSync` is expensive, maximize on scripts to search for
    -                        let extra =
    -                            std::cmp::max(inner.missing_count as u32, CACHE_ADDR_BATCH_SIZE);
    -                        let last = inner.last_count as u32;
    -                        Ok(extra + last)
    +            // If the error is the special `MissingCachedScripts` error, we return the number of
    +            // scripts we should ensure cached.
    +            // On any other error, we should return the error.
    +            // On no error, we say `ensure_cache` is 0.
    +            let ensure_cache = sync_res.map_or_else(
    +                |e| match e {
    +                    Error::MissingCachedScripts(inner) => {
    +                        // each call to `WalletSync` is expensive, maximize on scripts to search for
    +                        let extra =
    +                            std::cmp::max(inner.missing_count as u32, CACHE_ADDR_BATCH_SIZE);
    +                        let last = inner.last_count as u32;
    +                        Ok(extra + last)
                         }
    -                    _ => Err(e),
    +                    _ => Err(e),
                     },
    -                |_| Ok(0_u32),
    +                |_| Ok(0_u32),
                 )?;
     
    -            // cache and try again, break when there is nothing to cache
    -            if !self.ensure_addresses_cached(ensure_cache)? {
    +            // cache and try again, break when there is nothing to cache
    +            if !self.ensure_addresses_cached(ensure_cache)? {
                     break;
                 }
             }
     
    -        let sync_time = SyncTime {
    -            block_time: BlockTime {
    -                height: maybe_await!(blockchain.get_height())?,
    -                timestamp: time::get_timestamp(),
    +        let sync_time = SyncTime {
    +            block_time: BlockTime {
    +                height: maybe_await!(blockchain.get_height())?,
    +                timestamp: time::get_timestamp(),
                 },
             };
    -        debug!("Saving `sync_time` = {:?}", sync_time);
    -        self.database.borrow_mut().set_sync_time(sync_time)?;
    +        debug!("Saving `sync_time` = {:?}", sync_time);
    +        self.database.borrow_mut().set_sync_time(sync_time)?;
     
             Ok(())
         }
     
    -    /// Return the checksum of the public descriptor associated to `keychain`
    -    ///
    -    /// Internally calls [`Self::get_descriptor_for_keychain`] to fetch the right descriptor
    -    pub fn descriptor_checksum(&self, keychain: KeychainKind) -> String {
    -        self.get_descriptor_for_keychain(keychain)
    -            .to_string()
    -            .split_once('#')
    -            .unwrap()
    -            .1
    -            .to_string()
    +    /// Return the checksum of the public descriptor associated to `keychain`
    +    ///
    +    /// Internally calls [`Self::get_descriptor_for_keychain`] to fetch the right descriptor
    +    pub fn descriptor_checksum(&self, keychain: KeychainKind) -> String {
    +        self.get_descriptor_for_keychain(keychain)
    +            .to_string()
    +            .split_once('#')
    +            .unwrap()
    +            .1
    +            .to_string()
         }
     }
     
    -/// Deterministically generate a unique name given the descriptors defining the wallet
    -///
    -/// Compatible with [`wallet_name_from_descriptor`]
    -pub fn wallet_name_from_descriptor<T>(
    -    descriptor: T,
    -    change_descriptor: Option<T>,
    -    network: Network,
    -    secp: &SecpCtx,
    -) -> Result<String, Error>
    -where
    -    T: IntoWalletDescriptor,
    +/// Deterministically generate a unique name given the descriptors defining the wallet
    +///
    +/// Compatible with [`wallet_name_from_descriptor`]
    +pub fn wallet_name_from_descriptor<T>(
    +    descriptor: T,
    +    change_descriptor: Option<T>,
    +    network: Network,
    +    secp: &SecpCtx,
    +) -> Result<String, Error>
    +where
    +    T: IntoWalletDescriptor,
     {
    -    //TODO check descriptors contains only public keys
    -    let descriptor = descriptor
    -        .into_wallet_descriptor(secp, network)?
    -        .0
    -        .to_string();
    -    let mut wallet_name = calc_checksum(&descriptor[..descriptor.find('#').unwrap()])?;
    -    if let Some(change_descriptor) = change_descriptor {
    -        let change_descriptor = change_descriptor
    -            .into_wallet_descriptor(secp, network)?
    -            .0
    -            .to_string();
    -        wallet_name.push_str(
    -            calc_checksum(&change_descriptor[..change_descriptor.find('#').unwrap()])?.as_str(),
    -        );
    -    }
    -
    -    Ok(wallet_name)
    +    //TODO check descriptors contains only public keys
    +    let descriptor = descriptor
    +        .into_wallet_descriptor(secp, network)?
    +        .0
    +        .to_string();
    +    let mut wallet_name = calc_checksum(&descriptor[..descriptor.find('#').unwrap()])?;
    +    if let Some(change_descriptor) = change_descriptor {
    +        let change_descriptor = change_descriptor
    +            .into_wallet_descriptor(secp, network)?
    +            .0
    +            .to_string();
    +        wallet_name.push_str(
    +            calc_checksum(&change_descriptor[..change_descriptor.find('#').unwrap()])?.as_str(),
    +        );
    +    }
    +
    +    Ok(wallet_name)
     }
     
    -/// Return a fake wallet that appears to be funded for testing.
    -pub fn get_funded_wallet(
    -    descriptor: &str,
    -) -> (Wallet<AnyDatabase>, (String, Option<String>), bitcoin::Txid) {
    -    let descriptors = testutils!(@descriptors (descriptor));
    -    let wallet = Wallet::new(
    -        &descriptors.0,
    +/// Return a fake wallet that appears to be funded for testing.
    +pub fn get_funded_wallet(
    +    descriptor: &str,
    +) -> (Wallet<AnyDatabase>, (String, Option<String>), bitcoin::Txid) {
    +    let descriptors = testutils!(@descriptors (descriptor));
    +    let wallet = Wallet::new(
    +        &descriptors.0,
             None,
    -        Network::Regtest,
    -        AnyDatabase::Memory(MemoryDatabase::new()),
    +        Network::Regtest,
    +        AnyDatabase::Memory(MemoryDatabase::new()),
         )
    -    .unwrap();
    +    .unwrap();
     
    -    let funding_address_kix = 0;
    +    let funding_address_kix = 0;
     
    -    let tx_meta = testutils! {
    -            @tx ( (@external descriptors, funding_address_kix) => 50_000 ) (@confirmations 1)
    +    let tx_meta = testutils! {
    +            @tx ( (@external descriptors, funding_address_kix) => 50_000 ) (@confirmations 1)
         };
     
    -    wallet
    -        .database
    -        .borrow_mut()
    -        .set_script_pubkey(
    -            &bitcoin::Address::from_str(&tx_meta.output.get(0).unwrap().to_address)
    -                .unwrap()
    -                .script_pubkey(),
    -            KeychainKind::External,
    -            funding_address_kix,
    +    wallet
    +        .database
    +        .borrow_mut()
    +        .set_script_pubkey(
    +            &bitcoin::Address::from_str(&tx_meta.output.get(0).unwrap().to_address)
    +                .unwrap()
    +                .script_pubkey(),
    +            KeychainKind::External,
    +            funding_address_kix,
             )
    -        .unwrap();
    -    wallet
    -        .database
    -        .borrow_mut()
    -        .set_last_index(KeychainKind::External, funding_address_kix)
    -        .unwrap();
    +        .unwrap();
    +    wallet
    +        .database
    +        .borrow_mut()
    +        .set_last_index(KeychainKind::External, funding_address_kix)
    +        .unwrap();
     
    -    let txid = crate::populate_test_db!(wallet.database.borrow_mut(), tx_meta, Some(100));
    +    let txid = crate::populate_test_db!(wallet.database.borrow_mut(), tx_meta, Some(100));
     
    -    (wallet, descriptors, txid)
    +    (wallet, descriptors, txid)
     }
     
    -#[cfg(test)]
    -pub(crate) mod test {
    -    use bitcoin::{util::psbt, Network, PackedLockTime, Sequence};
    -
    -    use crate::database::Database;
    -    use crate::types::KeychainKind;
    -
    -    use super::*;
    -    use crate::signer::{SignOptions, SignerError};
    -    use crate::wallet::AddressIndex::{LastUnused, New, Peek, Reset};
    -
    -    // The satisfaction size of a P2WPKH is 112 WU =
    -    // 1 (elements in witness) + 1 (OP_PUSH) + 33 (pk) + 1 (OP_PUSH) + 72 (signature + sighash) + 1*4 (script len)
    -    // On the witness itself, we have to push once for the pk (33WU) and once for signature + sighash (72WU), for
    -    // a total of 105 WU.
    -    // Here, we push just once for simplicity, so we have to add an extra byte for the missing
    -    // OP_PUSH.
    -    const P2WPKH_FAKE_WITNESS_SIZE: usize = 106;
    -
    -    #[test]
    -    fn test_descriptor_checksum() {
    -        let (wallet, _, _) = get_funded_wallet(get_test_wpkh());
    -        let checksum = wallet.descriptor_checksum(KeychainKind::External);
    -        assert_eq!(checksum.len(), 8);
    +#[cfg(test)]
    +pub(crate) mod test {
    +    use bitcoin::{util::psbt, Network, PackedLockTime, Sequence};
    +
    +    use crate::database::Database;
    +    use crate::types::KeychainKind;
    +
    +    use super::*;
    +    use crate::signer::{SignOptions, SignerError};
    +    use crate::wallet::AddressIndex::{LastUnused, New, Peek, Reset};
    +
    +    // The satisfaction size of a P2WPKH is 112 WU =
    +    // 1 (elements in witness) + 1 (OP_PUSH) + 33 (pk) + 1 (OP_PUSH) + 72 (signature + sighash) + 1*4 (script len)
    +    // On the witness itself, we have to push once for the pk (33WU) and once for signature + sighash (72WU), for
    +    // a total of 105 WU.
    +    // Here, we push just once for simplicity, so we have to add an extra byte for the missing
    +    // OP_PUSH.
    +    const P2WPKH_FAKE_WITNESS_SIZE: usize = 106;
    +
    +    #[test]
    +    fn test_descriptor_checksum() {
    +        let (wallet, _, _) = get_funded_wallet(get_test_wpkh());
    +        let checksum = wallet.descriptor_checksum(KeychainKind::External);
    +        assert_eq!(checksum.len(), 8);
             assert_eq!(
    -            calc_checksum(&wallet.descriptor.to_string()).unwrap(),
    -            checksum
    +            calc_checksum(&wallet.descriptor.to_string()).unwrap(),
    +            checksum
             );
         }
     
    -    #[test]
    -    fn test_db_checksum() {
    -        let (wallet, _, _) = get_funded_wallet(get_test_wpkh());
    -        let desc = wallet.descriptor.to_string();
    +    #[test]
    +    fn test_db_checksum() {
    +        let (wallet, _, _) = get_funded_wallet(get_test_wpkh());
    +        let desc = wallet.descriptor.to_string();
     
    -        let checksum = calc_checksum_bytes_internal(&desc, true).unwrap();
    -        let checksum_inception = calc_checksum_bytes_internal(&desc, false).unwrap();
    -        let checksum_invalid = [b'q'; 8];
    +        let checksum = calc_checksum_bytes_internal(&desc, true).unwrap();
    +        let checksum_inception = calc_checksum_bytes_internal(&desc, false).unwrap();
    +        let checksum_invalid = [b'q'; 8];
     
    -        let mut db = MemoryDatabase::new();
    -        db.check_descriptor_checksum(KeychainKind::External, checksum)
    -            .expect("failed to save actual checksum");
    -        Wallet::db_checksum(&mut db, &desc, KeychainKind::External)
    -            .expect("db that uses actual checksum should be supported");
    +        let mut db = MemoryDatabase::new();
    +        db.check_descriptor_checksum(KeychainKind::External, checksum)
    +            .expect("failed to save actual checksum");
    +        Wallet::db_checksum(&mut db, &desc, KeychainKind::External)
    +            .expect("db that uses actual checksum should be supported");
     
    -        let mut db = MemoryDatabase::new();
    -        db.check_descriptor_checksum(KeychainKind::External, checksum_inception)
    -            .expect("failed to save checksum inception");
    -        Wallet::db_checksum(&mut db, &desc, KeychainKind::External)
    -            .expect("db that uses checksum inception should be supported");
    +        let mut db = MemoryDatabase::new();
    +        db.check_descriptor_checksum(KeychainKind::External, checksum_inception)
    +            .expect("failed to save checksum inception");
    +        Wallet::db_checksum(&mut db, &desc, KeychainKind::External)
    +            .expect("db that uses checksum inception should be supported");
     
    -        let mut db = MemoryDatabase::new();
    -        db.check_descriptor_checksum(KeychainKind::External, checksum_invalid)
    -            .expect("failed to save invalid checksum");
    -        Wallet::db_checksum(&mut db, &desc, KeychainKind::External)
    -            .expect_err("db that uses invalid checksum should fail");
    +        let mut db = MemoryDatabase::new();
    +        db.check_descriptor_checksum(KeychainKind::External, checksum_invalid)
    +            .expect("failed to save invalid checksum");
    +        Wallet::db_checksum(&mut db, &desc, KeychainKind::External)
    +            .expect_err("db that uses invalid checksum should fail");
         }
     
    -    #[test]
    -    fn test_get_funded_wallet_balance() {
    -        let (wallet, _, _) = get_funded_wallet(get_test_wpkh());
    -        assert_eq!(wallet.get_balance().unwrap().confirmed, 50000);
    +    #[test]
    +    fn test_get_funded_wallet_balance() {
    +        let (wallet, _, _) = get_funded_wallet(get_test_wpkh());
    +        assert_eq!(wallet.get_balance().unwrap().confirmed, 50000);
         }
     
    -    #[test]
    -    fn test_cache_addresses_fixed() {
    -        let db = MemoryDatabase::new();
    -        let wallet = Wallet::new(
    +    #[test]
    +    fn test_cache_addresses_fixed() {
    +        let db = MemoryDatabase::new();
    +        let wallet = Wallet::new(
                 "wpkh(L5EZftvrYaSudiozVRzTqLcHLNDoVn7H5HSfM9BAN6tMJX8oTWz6)",
                 None,
    -            Network::Testnet,
    -            db,
    +            Network::Testnet,
    +            db,
             )
    -        .unwrap();
    +        .unwrap();
     
             assert_eq!(
    -            wallet.get_address(New).unwrap().to_string(),
    -            "tb1qj08ys4ct2hzzc2hcz6h2hgrvlmsjynaw43s835"
    -        );
    +            wallet.get_address(New).unwrap().to_string(),
    +            "tb1qj08ys4ct2hzzc2hcz6h2hgrvlmsjynaw43s835"
    +        );
             assert_eq!(
    -            wallet.get_address(New).unwrap().to_string(),
    -            "tb1qj08ys4ct2hzzc2hcz6h2hgrvlmsjynaw43s835"
    -        );
    -
    -        assert!(wallet
    -            .database
    -            .borrow_mut()
    -            .get_script_pubkey_from_path(KeychainKind::External, 0)
    -            .unwrap()
    -            .is_some());
    -        assert!(wallet
    -            .database
    -            .borrow_mut()
    -            .get_script_pubkey_from_path(KeychainKind::Internal, 0)
    -            .unwrap()
    -            .is_none());
    -    }
    -
    -    #[test]
    -    fn test_cache_addresses() {
    -        let db = MemoryDatabase::new();
    -        let wallet = Wallet::new("wpkh(tpubEBr4i6yk5nf5DAaJpsi9N2pPYBeJ7fZ5Z9rmN4977iYLCGco1VyjB9tvvuvYtfZzjD5A8igzgw3HeWeeKFmanHYqksqZXYXGsw5zjnj7KM9/*)", None, Network::Testnet, db).unwrap();
    +            wallet.get_address(New).unwrap().to_string(),
    +            "tb1qj08ys4ct2hzzc2hcz6h2hgrvlmsjynaw43s835"
    +        );
    +
    +        assert!(wallet
    +            .database
    +            .borrow_mut()
    +            .get_script_pubkey_from_path(KeychainKind::External, 0)
    +            .unwrap()
    +            .is_some());
    +        assert!(wallet
    +            .database
    +            .borrow_mut()
    +            .get_script_pubkey_from_path(KeychainKind::Internal, 0)
    +            .unwrap()
    +            .is_none());
    +    }
    +
    +    #[test]
    +    fn test_cache_addresses() {
    +        let db = MemoryDatabase::new();
    +        let wallet = Wallet::new("wpkh(tpubEBr4i6yk5nf5DAaJpsi9N2pPYBeJ7fZ5Z9rmN4977iYLCGco1VyjB9tvvuvYtfZzjD5A8igzgw3HeWeeKFmanHYqksqZXYXGsw5zjnj7KM9/*)", None, Network::Testnet, db).unwrap();
     
             assert_eq!(
    -            wallet.get_address(New).unwrap().to_string(),
    -            "tb1q6yn66vajcctph75pvylgkksgpp6nq04ppwct9a"
    -        );
    +            wallet.get_address(New).unwrap().to_string(),
    +            "tb1q6yn66vajcctph75pvylgkksgpp6nq04ppwct9a"
    +        );
             assert_eq!(
    -            wallet.get_address(New).unwrap().to_string(),
    -            "tb1q4er7kxx6sssz3q7qp7zsqsdx4erceahhax77d7"
    -        );
    -
    -        assert!(wallet
    -            .database
    -            .borrow_mut()
    -            .get_script_pubkey_from_path(KeychainKind::External, CACHE_ADDR_BATCH_SIZE - 1)
    -            .unwrap()
    -            .is_some());
    -        assert!(wallet
    -            .database
    -            .borrow_mut()
    -            .get_script_pubkey_from_path(KeychainKind::External, CACHE_ADDR_BATCH_SIZE)
    -            .unwrap()
    -            .is_none());
    -    }
    -
    -    #[test]
    -    fn test_cache_addresses_refill() {
    -        let db = MemoryDatabase::new();
    -        let wallet = Wallet::new("wpkh(tpubEBr4i6yk5nf5DAaJpsi9N2pPYBeJ7fZ5Z9rmN4977iYLCGco1VyjB9tvvuvYtfZzjD5A8igzgw3HeWeeKFmanHYqksqZXYXGsw5zjnj7KM9/*)", None, Network::Testnet, db).unwrap();
    +            wallet.get_address(New).unwrap().to_string(),
    +            "tb1q4er7kxx6sssz3q7qp7zsqsdx4erceahhax77d7"
    +        );
    +
    +        assert!(wallet
    +            .database
    +            .borrow_mut()
    +            .get_script_pubkey_from_path(KeychainKind::External, CACHE_ADDR_BATCH_SIZE - 1)
    +            .unwrap()
    +            .is_some());
    +        assert!(wallet
    +            .database
    +            .borrow_mut()
    +            .get_script_pubkey_from_path(KeychainKind::External, CACHE_ADDR_BATCH_SIZE)
    +            .unwrap()
    +            .is_none());
    +    }
    +
    +    #[test]
    +    fn test_cache_addresses_refill() {
    +        let db = MemoryDatabase::new();
    +        let wallet = Wallet::new("wpkh(tpubEBr4i6yk5nf5DAaJpsi9N2pPYBeJ7fZ5Z9rmN4977iYLCGco1VyjB9tvvuvYtfZzjD5A8igzgw3HeWeeKFmanHYqksqZXYXGsw5zjnj7KM9/*)", None, Network::Testnet, db).unwrap();
     
             assert_eq!(
    -            wallet.get_address(New).unwrap().to_string(),
    -            "tb1q6yn66vajcctph75pvylgkksgpp6nq04ppwct9a"
    -        );
    -        assert!(wallet
    -            .database
    -            .borrow_mut()
    -            .get_script_pubkey_from_path(KeychainKind::External, CACHE_ADDR_BATCH_SIZE - 1)
    -            .unwrap()
    -            .is_some());
    -
    -        for _ in 0..CACHE_ADDR_BATCH_SIZE {
    -            wallet.get_address(New).unwrap();
    +            wallet.get_address(New).unwrap().to_string(),
    +            "tb1q6yn66vajcctph75pvylgkksgpp6nq04ppwct9a"
    +        );
    +        assert!(wallet
    +            .database
    +            .borrow_mut()
    +            .get_script_pubkey_from_path(KeychainKind::External, CACHE_ADDR_BATCH_SIZE - 1)
    +            .unwrap()
    +            .is_some());
    +
    +        for _ in 0..CACHE_ADDR_BATCH_SIZE {
    +            wallet.get_address(New).unwrap();
             }
     
    -        assert!(wallet
    -            .database
    -            .borrow_mut()
    -            .get_script_pubkey_from_path(KeychainKind::External, CACHE_ADDR_BATCH_SIZE * 2 - 1)
    -            .unwrap()
    -            .is_some());
    -    }
    -
    -    pub(crate) fn get_test_wpkh() -> &'static str {
    -        "wpkh(cVpPVruEDdmutPzisEsYvtST1usBR3ntr8pXSyt6D2YYqXRyPcFW)"
    -    }
    -
    -    pub(crate) fn get_test_single_sig_csv() -> &'static str {
    -        // and(pk(Alice),older(6))
    -        "wsh(and_v(v:pk(cVpPVruEDdmutPzisEsYvtST1usBR3ntr8pXSyt6D2YYqXRyPcFW),older(6)))"
    -    }
    -
    -    pub(crate) fn get_test_a_or_b_plus_csv() -> &'static str {
    -        // or(pk(Alice),and(pk(Bob),older(144)))
    -        "wsh(or_d(pk(cRjo6jqfVNP33HhSS76UhXETZsGTZYx8FMFvR9kpbtCSV1PmdZdu),and_v(v:pk(cMnkdebixpXMPfkcNEjjGin7s94hiehAH4mLbYkZoh9KSiNNmqC8),older(144))))"
    -    }
    -
    -    pub(crate) fn get_test_single_sig_cltv() -> &'static str {
    -        // and(pk(Alice),after(100000))
    -        "wsh(and_v(v:pk(cVpPVruEDdmutPzisEsYvtST1usBR3ntr8pXSyt6D2YYqXRyPcFW),after(100000)))"
    -    }
    -
    -    pub(crate) fn get_test_tr_single_sig() -> &'static str {
    -        "tr(cNJmN3fH9DDbDt131fQNkVakkpzawJBSeybCUNmP1BovpmGQ45xG)"
    -    }
    -
    -    pub(crate) fn get_test_tr_with_taptree() -> &'static str {
    -        "tr(b511bd5771e47ee27558b1765e87b541668304ec567721c7b880edc0a010da55,{pk(cPZzKuNmpuUjD1e8jUU4PVzy2b5LngbSip8mBsxf4e7rSFZVb4Uh),pk(8aee2b8120a5f157f1223f72b5e62b825831a27a9fdf427db7cc697494d4a642)})"
    -    }
    -
    -    pub(crate) fn get_test_tr_with_taptree_both_priv() -> &'static str {
    -        "tr(b511bd5771e47ee27558b1765e87b541668304ec567721c7b880edc0a010da55,{pk(cPZzKuNmpuUjD1e8jUU4PVzy2b5LngbSip8mBsxf4e7rSFZVb4Uh),pk(cNaQCDwmmh4dS9LzCgVtyy1e1xjCJ21GUDHe9K98nzb689JvinGV)})"
    -    }
    -
    -    pub(crate) fn get_test_tr_repeated_key() -> &'static str {
    -        "tr(b511bd5771e47ee27558b1765e87b541668304ec567721c7b880edc0a010da55,{and_v(v:pk(cVpPVruEDdmutPzisEsYvtST1usBR3ntr8pXSyt6D2YYqXRyPcFW),after(100)),and_v(v:pk(cVpPVruEDdmutPzisEsYvtST1usBR3ntr8pXSyt6D2YYqXRyPcFW),after(200))})"
    -    }
    -
    -    pub(crate) fn get_test_tr_single_sig_xprv() -> &'static str {
    -        "tr(tprv8ZgxMBicQKsPdDArR4xSAECuVxeX1jwwSXR4ApKbkYgZiziDc4LdBy2WvJeGDfUSE4UT4hHhbgEwbdq8ajjUHiKDegkwrNU6V55CxcxonVN/*)"
    -    }
    -
    -    pub(crate) fn get_test_tr_with_taptree_xprv() -> &'static str {
    -        "tr(cNJmN3fH9DDbDt131fQNkVakkpzawJBSeybCUNmP1BovpmGQ45xG,{pk(tprv8ZgxMBicQKsPdDArR4xSAECuVxeX1jwwSXR4ApKbkYgZiziDc4LdBy2WvJeGDfUSE4UT4hHhbgEwbdq8ajjUHiKDegkwrNU6V55CxcxonVN/*),pk(8aee2b8120a5f157f1223f72b5e62b825831a27a9fdf427db7cc697494d4a642)})"
    -    }
    -
    -    pub(crate) fn get_test_tr_dup_keys() -> &'static str {
    -        "tr(cNJmN3fH9DDbDt131fQNkVakkpzawJBSeybCUNmP1BovpmGQ45xG,{pk(8aee2b8120a5f157f1223f72b5e62b825831a27a9fdf427db7cc697494d4a642),pk(8aee2b8120a5f157f1223f72b5e62b825831a27a9fdf427db7cc697494d4a642)})"
    -    }
    -
    -    macro_rules! assert_fee_rate {
    -        ($psbt:expr, $fees:expr, $fee_rate:expr $( ,@dust_change $( $dust_change:expr )* )* $( ,@add_signature $( $add_signature:expr )* )* ) => ({
    -            let psbt = $psbt.clone();
    -            #[allow(unused_mut)]
    -            let mut tx = $psbt.clone().extract_tx();
    +        assert!(wallet
    +            .database
    +            .borrow_mut()
    +            .get_script_pubkey_from_path(KeychainKind::External, CACHE_ADDR_BATCH_SIZE * 2 - 1)
    +            .unwrap()
    +            .is_some());
    +    }
    +
    +    pub(crate) fn get_test_wpkh() -> &'static str {
    +        "wpkh(cVpPVruEDdmutPzisEsYvtST1usBR3ntr8pXSyt6D2YYqXRyPcFW)"
    +    }
    +
    +    pub(crate) fn get_test_single_sig_csv() -> &'static str {
    +        // and(pk(Alice),older(6))
    +        "wsh(and_v(v:pk(cVpPVruEDdmutPzisEsYvtST1usBR3ntr8pXSyt6D2YYqXRyPcFW),older(6)))"
    +    }
    +
    +    pub(crate) fn get_test_a_or_b_plus_csv() -> &'static str {
    +        // or(pk(Alice),and(pk(Bob),older(144)))
    +        "wsh(or_d(pk(cRjo6jqfVNP33HhSS76UhXETZsGTZYx8FMFvR9kpbtCSV1PmdZdu),and_v(v:pk(cMnkdebixpXMPfkcNEjjGin7s94hiehAH4mLbYkZoh9KSiNNmqC8),older(144))))"
    +    }
    +
    +    pub(crate) fn get_test_single_sig_cltv() -> &'static str {
    +        // and(pk(Alice),after(100000))
    +        "wsh(and_v(v:pk(cVpPVruEDdmutPzisEsYvtST1usBR3ntr8pXSyt6D2YYqXRyPcFW),after(100000)))"
    +    }
    +
    +    pub(crate) fn get_test_tr_single_sig() -> &'static str {
    +        "tr(cNJmN3fH9DDbDt131fQNkVakkpzawJBSeybCUNmP1BovpmGQ45xG)"
    +    }
    +
    +    pub(crate) fn get_test_tr_with_taptree() -> &'static str {
    +        "tr(b511bd5771e47ee27558b1765e87b541668304ec567721c7b880edc0a010da55,{pk(cPZzKuNmpuUjD1e8jUU4PVzy2b5LngbSip8mBsxf4e7rSFZVb4Uh),pk(8aee2b8120a5f157f1223f72b5e62b825831a27a9fdf427db7cc697494d4a642)})"
    +    }
    +
    +    pub(crate) fn get_test_tr_with_taptree_both_priv() -> &'static str {
    +        "tr(b511bd5771e47ee27558b1765e87b541668304ec567721c7b880edc0a010da55,{pk(cPZzKuNmpuUjD1e8jUU4PVzy2b5LngbSip8mBsxf4e7rSFZVb4Uh),pk(cNaQCDwmmh4dS9LzCgVtyy1e1xjCJ21GUDHe9K98nzb689JvinGV)})"
    +    }
    +
    +    pub(crate) fn get_test_tr_repeated_key() -> &'static str {
    +        "tr(b511bd5771e47ee27558b1765e87b541668304ec567721c7b880edc0a010da55,{and_v(v:pk(cVpPVruEDdmutPzisEsYvtST1usBR3ntr8pXSyt6D2YYqXRyPcFW),after(100)),and_v(v:pk(cVpPVruEDdmutPzisEsYvtST1usBR3ntr8pXSyt6D2YYqXRyPcFW),after(200))})"
    +    }
    +
    +    pub(crate) fn get_test_tr_single_sig_xprv() -> &'static str {
    +        "tr(tprv8ZgxMBicQKsPdDArR4xSAECuVxeX1jwwSXR4ApKbkYgZiziDc4LdBy2WvJeGDfUSE4UT4hHhbgEwbdq8ajjUHiKDegkwrNU6V55CxcxonVN/*)"
    +    }
    +
    +    pub(crate) fn get_test_tr_with_taptree_xprv() -> &'static str {
    +        "tr(cNJmN3fH9DDbDt131fQNkVakkpzawJBSeybCUNmP1BovpmGQ45xG,{pk(tprv8ZgxMBicQKsPdDArR4xSAECuVxeX1jwwSXR4ApKbkYgZiziDc4LdBy2WvJeGDfUSE4UT4hHhbgEwbdq8ajjUHiKDegkwrNU6V55CxcxonVN/*),pk(8aee2b8120a5f157f1223f72b5e62b825831a27a9fdf427db7cc697494d4a642)})"
    +    }
    +
    +    pub(crate) fn get_test_tr_dup_keys() -> &'static str {
    +        "tr(cNJmN3fH9DDbDt131fQNkVakkpzawJBSeybCUNmP1BovpmGQ45xG,{pk(8aee2b8120a5f157f1223f72b5e62b825831a27a9fdf427db7cc697494d4a642),pk(8aee2b8120a5f157f1223f72b5e62b825831a27a9fdf427db7cc697494d4a642)})"
    +    }
    +
    +    macro_rules! assert_fee_rate {
    +        ($psbt:expr, $fees:expr, $fee_rate:expr $( ,@dust_change $( $dust_change:expr )* )* $( ,@add_signature $( $add_signature:expr )* )* ) => ({
    +            let psbt = $psbt.clone();
    +            #[allow(unused_mut)]
    +            let mut tx = $psbt.clone().extract_tx();
                 $(
    -                $( $add_signature )*
    -                for txin in &mut tx.input {
    -                    txin.witness.push([0x00; P2WPKH_FAKE_WITNESS_SIZE]); // fake signature
    -                }
    -            )*
    -
    -            #[allow(unused_mut)]
    -            #[allow(unused_assignments)]
    -            let mut dust_change = false;
    +                $( $add_signature )*
    +                for txin in &mut tx.input {
    +                    txin.witness.push([0x00; P2WPKH_FAKE_WITNESS_SIZE]); // fake signature
    +                }
    +            )*
    +
    +            #[allow(unused_mut)]
    +            #[allow(unused_assignments)]
    +            let mut dust_change = false;
                 $(
    -                $( $dust_change )*
    -                dust_change = true;
    -            )*
    -
    -            let fee_amount = psbt
    -                .inputs
    -                .iter()
    -                .fold(0, |acc, i| acc + i.witness_utxo.as_ref().unwrap().value)
    -                - psbt
    -                    .unsigned_tx
    -                    .output
    -                    .iter()
    -                    .fold(0, |acc, o| acc + o.value);
    -
    -            assert_eq!(fee_amount, $fees);
    -
    -            let tx_fee_rate = FeeRate::from_wu($fees, tx.weight());
    -            let fee_rate = $fee_rate;
    -
    -            if !dust_change {
    -                assert!(tx_fee_rate >= fee_rate && (tx_fee_rate - fee_rate).as_sat_per_vb().abs() < 0.5, "Expected fee rate of {:?}, the tx has {:?}", fee_rate, tx_fee_rate);
    -            } else {
    -                assert!(tx_fee_rate >= fee_rate, "Expected fee rate of at least {:?}, the tx has {:?}", fee_rate, tx_fee_rate);
    +                $( $dust_change )*
    +                dust_change = true;
    +            )*
    +
    +            let fee_amount = psbt
    +                .inputs
    +                .iter()
    +                .fold(0, |acc, i| acc + i.witness_utxo.as_ref().unwrap().value)
    +                - psbt
    +                    .unsigned_tx
    +                    .output
    +                    .iter()
    +                    .fold(0, |acc, o| acc + o.value);
    +
    +            assert_eq!(fee_amount, $fees);
    +
    +            let tx_fee_rate = FeeRate::from_wu($fees, tx.weight());
    +            let fee_rate = $fee_rate;
    +
    +            if !dust_change {
    +                assert!(tx_fee_rate >= fee_rate && (tx_fee_rate - fee_rate).as_sat_per_vb().abs() < 0.5, "Expected fee rate of {:?}, the tx has {:?}", fee_rate, tx_fee_rate);
    +            } else {
    +                assert!(tx_fee_rate >= fee_rate, "Expected fee rate of at least {:?}, the tx has {:?}", fee_rate, tx_fee_rate);
                 }
             });
         }
     
    -    macro_rules! from_str {
    -        ($e:expr, $t:ty) => {{
    -            use std::str::FromStr;
    -            <$t>::from_str($e).unwrap()
    +    macro_rules! from_str {
    +        ($e:expr, $t:ty) => {{
    +            use std::str::FromStr;
    +            <$t>::from_str($e).unwrap()
             }};
     
    -        ($e:expr) => {
    -            from_str!($e, _)
    +        ($e:expr) => {
    +            from_str!($e, _)
             };
         }
     
    -    #[test]
    -    #[should_panic(expected = "NoRecipients")]
    -    fn test_create_tx_empty_recipients() {
    -        let (wallet, _, _) = get_funded_wallet(get_test_wpkh());
    -        wallet.build_tx().finish().unwrap();
    -    }
    -
    -    #[test]
    -    #[should_panic(expected = "NoUtxosSelected")]
    -    fn test_create_tx_manually_selected_empty_utxos() {
    -        let (wallet, _, _) = get_funded_wallet(get_test_wpkh());
    -        let addr = wallet.get_address(New).unwrap();
    -        let mut builder = wallet.build_tx();
    -        builder
    -            .add_recipient(addr.script_pubkey(), 25_000)
    -            .manually_selected_only();
    -        builder.finish().unwrap();
    -    }
    -
    -    #[test]
    -    #[should_panic(expected = "Invalid version `0`")]
    -    fn test_create_tx_version_0() {
    -        let (wallet, _, _) = get_funded_wallet(get_test_wpkh());
    -        let addr = wallet.get_address(New).unwrap();
    -        let mut builder = wallet.build_tx();
    -        builder
    -            .add_recipient(addr.script_pubkey(), 25_000)
    -            .version(0);
    -        builder.finish().unwrap();
    -    }
    -
    -    #[test]
    -    #[should_panic(
    -        expected = "TxBuilder requested version `1`, but at least `2` is needed to use OP_CSV"
    -    )]
    -    fn test_create_tx_version_1_csv() {
    -        let (wallet, _, _) = get_funded_wallet(get_test_single_sig_csv());
    -        let addr = wallet.get_address(New).unwrap();
    -        let mut builder = wallet.build_tx();
    -        builder
    -            .add_recipient(addr.script_pubkey(), 25_000)
    -            .version(1);
    -        builder.finish().unwrap();
    -    }
    -
    -    #[test]
    -    fn test_create_tx_custom_version() {
    -        let (wallet, _, _) = get_funded_wallet(get_test_wpkh());
    -        let addr = wallet.get_address(New).unwrap();
    -        let mut builder = wallet.build_tx();
    -        builder
    -            .add_recipient(addr.script_pubkey(), 25_000)
    -            .version(42);
    -        let (psbt, _) = builder.finish().unwrap();
    -
    -        assert_eq!(psbt.unsigned_tx.version, 42);
    -    }
    -
    -    #[test]
    -    fn test_create_tx_default_locktime() {
    -        let descriptors = testutils!(@descriptors (get_test_wpkh()));
    -        let wallet = Wallet::new(
    -            &descriptors.0,
    +    #[test]
    +    #[should_panic(expected = "NoRecipients")]
    +    fn test_create_tx_empty_recipients() {
    +        let (wallet, _, _) = get_funded_wallet(get_test_wpkh());
    +        wallet.build_tx().finish().unwrap();
    +    }
    +
    +    #[test]
    +    #[should_panic(expected = "NoUtxosSelected")]
    +    fn test_create_tx_manually_selected_empty_utxos() {
    +        let (wallet, _, _) = get_funded_wallet(get_test_wpkh());
    +        let addr = wallet.get_address(New).unwrap();
    +        let mut builder = wallet.build_tx();
    +        builder
    +            .add_recipient(addr.script_pubkey(), 25_000)
    +            .manually_selected_only();
    +        builder.finish().unwrap();
    +    }
    +
    +    #[test]
    +    #[should_panic(expected = "Invalid version `0`")]
    +    fn test_create_tx_version_0() {
    +        let (wallet, _, _) = get_funded_wallet(get_test_wpkh());
    +        let addr = wallet.get_address(New).unwrap();
    +        let mut builder = wallet.build_tx();
    +        builder
    +            .add_recipient(addr.script_pubkey(), 25_000)
    +            .version(0);
    +        builder.finish().unwrap();
    +    }
    +
    +    #[test]
    +    #[should_panic(
    +        expected = "TxBuilder requested version `1`, but at least `2` is needed to use OP_CSV"
    +    )]
    +    fn test_create_tx_version_1_csv() {
    +        let (wallet, _, _) = get_funded_wallet(get_test_single_sig_csv());
    +        let addr = wallet.get_address(New).unwrap();
    +        let mut builder = wallet.build_tx();
    +        builder
    +            .add_recipient(addr.script_pubkey(), 25_000)
    +            .version(1);
    +        builder.finish().unwrap();
    +    }
    +
    +    #[test]
    +    fn test_create_tx_custom_version() {
    +        let (wallet, _, _) = get_funded_wallet(get_test_wpkh());
    +        let addr = wallet.get_address(New).unwrap();
    +        let mut builder = wallet.build_tx();
    +        builder
    +            .add_recipient(addr.script_pubkey(), 25_000)
    +            .version(42);
    +        let (psbt, _) = builder.finish().unwrap();
    +
    +        assert_eq!(psbt.unsigned_tx.version, 42);
    +    }
    +
    +    #[test]
    +    fn test_create_tx_default_locktime() {
    +        let descriptors = testutils!(@descriptors (get_test_wpkh()));
    +        let wallet = Wallet::new(
    +            &descriptors.0,
                 None,
    -            Network::Regtest,
    -            AnyDatabase::Memory(MemoryDatabase::new()),
    +            Network::Regtest,
    +            AnyDatabase::Memory(MemoryDatabase::new()),
             )
    -        .unwrap();
    +        .unwrap();
     
    -        let tx_meta = testutils! {
    -                @tx ( (@external descriptors, 0) => 50_000 )
    +        let tx_meta = testutils! {
    +                @tx ( (@external descriptors, 0) => 50_000 )
             };
     
    -        // Add the transaction to our db, but do not sync the db.
    -        crate::populate_test_db!(wallet.database.borrow_mut(), tx_meta, None);
    -
    -        let addr = wallet.get_address(New).unwrap();
    -        let mut builder = wallet.build_tx();
    -        builder.add_recipient(addr.script_pubkey(), 25_000);
    -        let (psbt, _) = builder.finish().unwrap();
    -
    -        // Since we never synced the wallet we don't have a last_sync_height
    -        // we could use to try to prevent fee sniping. We default to 0.
    -        assert_eq!(psbt.unsigned_tx.lock_time, PackedLockTime(0));
    -    }
    -
    -    #[test]
    -    fn test_create_tx_fee_sniping_locktime_provided_height() {
    -        let (wallet, _, _) = get_funded_wallet(get_test_wpkh());
    -        let addr = wallet.get_address(New).unwrap();
    -        let mut builder = wallet.build_tx();
    -        builder.add_recipient(addr.script_pubkey(), 25_000);
    -        let sync_time = SyncTime {
    -            block_time: BlockTime {
    -                height: 24,
    -                timestamp: 0,
    +        // Add the transaction to our db, but do not sync the db.
    +        crate::populate_test_db!(wallet.database.borrow_mut(), tx_meta, None);
    +
    +        let addr = wallet.get_address(New).unwrap();
    +        let mut builder = wallet.build_tx();
    +        builder.add_recipient(addr.script_pubkey(), 25_000);
    +        let (psbt, _) = builder.finish().unwrap();
    +
    +        // Since we never synced the wallet we don't have a last_sync_height
    +        // we could use to try to prevent fee sniping. We default to 0.
    +        assert_eq!(psbt.unsigned_tx.lock_time, PackedLockTime(0));
    +    }
    +
    +    #[test]
    +    fn test_create_tx_fee_sniping_locktime_provided_height() {
    +        let (wallet, _, _) = get_funded_wallet(get_test_wpkh());
    +        let addr = wallet.get_address(New).unwrap();
    +        let mut builder = wallet.build_tx();
    +        builder.add_recipient(addr.script_pubkey(), 25_000);
    +        let sync_time = SyncTime {
    +            block_time: BlockTime {
    +                height: 24,
    +                timestamp: 0,
                 },
             };
    -        wallet
    -            .database
    -            .borrow_mut()
    -            .set_sync_time(sync_time)
    -            .unwrap();
    -        let current_height = 25;
    -        builder.current_height(current_height);
    -        let (psbt, _) = builder.finish().unwrap();
    -
    -        // current_height will override the last sync height
    -        assert_eq!(psbt.unsigned_tx.lock_time, PackedLockTime(current_height));
    -    }
    -
    -    #[test]
    -    fn test_create_tx_fee_sniping_locktime_last_sync() {
    -        let (wallet, _, _) = get_funded_wallet(get_test_wpkh());
    -        let addr = wallet.get_address(New).unwrap();
    -        let mut builder = wallet.build_tx();
    -        builder.add_recipient(addr.script_pubkey(), 25_000);
    -        let sync_time = SyncTime {
    -            block_time: BlockTime {
    -                height: 25,
    -                timestamp: 0,
    +        wallet
    +            .database
    +            .borrow_mut()
    +            .set_sync_time(sync_time)
    +            .unwrap();
    +        let current_height = 25;
    +        builder.current_height(current_height);
    +        let (psbt, _) = builder.finish().unwrap();
    +
    +        // current_height will override the last sync height
    +        assert_eq!(psbt.unsigned_tx.lock_time, PackedLockTime(current_height));
    +    }
    +
    +    #[test]
    +    fn test_create_tx_fee_sniping_locktime_last_sync() {
    +        let (wallet, _, _) = get_funded_wallet(get_test_wpkh());
    +        let addr = wallet.get_address(New).unwrap();
    +        let mut builder = wallet.build_tx();
    +        builder.add_recipient(addr.script_pubkey(), 25_000);
    +        let sync_time = SyncTime {
    +            block_time: BlockTime {
    +                height: 25,
    +                timestamp: 0,
                 },
             };
    -        wallet
    -            .database
    -            .borrow_mut()
    -            .set_sync_time(sync_time.clone())
    -            .unwrap();
    -        let (psbt, _) = builder.finish().unwrap();
    -
    -        // If there's no current_height we're left with using the last sync height
    -        assert_eq!(
    -            psbt.unsigned_tx.lock_time,
    -            PackedLockTime(sync_time.block_time.height)
    -        );
    -    }
    -
    -    #[test]
    -    fn test_create_tx_default_locktime_cltv() {
    -        let (wallet, _, _) = get_funded_wallet(get_test_single_sig_cltv());
    -        let addr = wallet.get_address(New).unwrap();
    -        let mut builder = wallet.build_tx();
    -        builder.add_recipient(addr.script_pubkey(), 25_000);
    -        let (psbt, _) = builder.finish().unwrap();
    -
    -        assert_eq!(psbt.unsigned_tx.lock_time, PackedLockTime(100_000));
    -    }
    -
    -    #[test]
    -    fn test_create_tx_custom_locktime() {
    -        let (wallet, _, _) = get_funded_wallet(get_test_wpkh());
    -        let addr = wallet.get_address(New).unwrap();
    -        let mut builder = wallet.build_tx();
    -        builder
    -            .add_recipient(addr.script_pubkey(), 25_000)
    -            .current_height(630_001)
    -            .nlocktime(LockTime::from_height(630_000).unwrap());
    -        let (psbt, _) = builder.finish().unwrap();
    -
    -        // When we explicitly specify a nlocktime
    -        // we don't try any fee sniping prevention trick
    -        // (we ignore the current_height)
    -        assert_eq!(psbt.unsigned_tx.lock_time, PackedLockTime(630_000));
    -    }
    -
    -    #[test]
    -    fn test_create_tx_custom_locktime_compatible_with_cltv() {
    -        let (wallet, _, _) = get_funded_wallet(get_test_single_sig_cltv());
    -        let addr = wallet.get_address(New).unwrap();
    -        let mut builder = wallet.build_tx();
    -        builder
    -            .add_recipient(addr.script_pubkey(), 25_000)
    -            .nlocktime(LockTime::from_height(630_000).unwrap());
    -        let (psbt, _) = builder.finish().unwrap();
    -
    -        assert_eq!(psbt.unsigned_tx.lock_time, PackedLockTime(630_000));
    -    }
    -
    -    #[test]
    -    #[should_panic(
    -        expected = "TxBuilder requested timelock of `Blocks(Height(50000))`, but at least `Blocks(Height(100000))` is required to spend from this script"
    -    )]
    -    fn test_create_tx_custom_locktime_incompatible_with_cltv() {
    -        let (wallet, _, _) = get_funded_wallet(get_test_single_sig_cltv());
    -        let addr = wallet.get_address(New).unwrap();
    -        let mut builder = wallet.build_tx();
    -        builder
    -            .add_recipient(addr.script_pubkey(), 25_000)
    -            .nlocktime(LockTime::from_height(50000).unwrap());
    -        builder.finish().unwrap();
    -    }
    -
    -    #[test]
    -    fn test_create_tx_no_rbf_csv() {
    -        let (wallet, _, _) = get_funded_wallet(get_test_single_sig_csv());
    -        let addr = wallet.get_address(New).unwrap();
    -        let mut builder = wallet.build_tx();
    -        builder.add_recipient(addr.script_pubkey(), 25_000);
    -        let (psbt, _) = builder.finish().unwrap();
    -
    -        assert_eq!(psbt.unsigned_tx.input[0].sequence, Sequence(6));
    -    }
    -
    -    #[test]
    -    fn test_create_tx_with_default_rbf_csv() {
    -        let (wallet, _, _) = get_funded_wallet(get_test_single_sig_csv());
    -        let addr = wallet.get_address(New).unwrap();
    -        let mut builder = wallet.build_tx();
    -        builder
    -            .add_recipient(addr.script_pubkey(), 25_000)
    -            .enable_rbf();
    -        let (psbt, _) = builder.finish().unwrap();
    -        // When CSV is enabled it takes precedence over the rbf value (unless forced by the user).
    -        // It will be set to the OP_CSV value, in this case 6
    -        assert_eq!(psbt.unsigned_tx.input[0].sequence, Sequence(6));
    -    }
    -
    -    #[test]
    -    #[should_panic(
    -        expected = "Cannot enable RBF with nSequence `Sequence(3)` given a required OP_CSV of `Sequence(6)`"
    -    )]
    -    fn test_create_tx_with_custom_rbf_csv() {
    -        let (wallet, _, _) = get_funded_wallet(get_test_single_sig_csv());
    -        let addr = wallet.get_address(New).unwrap();
    -        let mut builder = wallet.build_tx();
    -        builder
    -            .add_recipient(addr.script_pubkey(), 25_000)
    -            .enable_rbf_with_sequence(Sequence(3));
    -        builder.finish().unwrap();
    -    }
    -
    -    #[test]
    -    fn test_create_tx_no_rbf_cltv() {
    -        let (wallet, _, _) = get_funded_wallet(get_test_single_sig_cltv());
    -        let addr = wallet.get_address(New).unwrap();
    -        let mut builder = wallet.build_tx();
    -        builder.add_recipient(addr.script_pubkey(), 25_000);
    -        let (psbt, _) = builder.finish().unwrap();
    -
    -        assert_eq!(psbt.unsigned_tx.input[0].sequence, Sequence(0xFFFFFFFE));
    -    }
    -
    -    #[test]
    -    #[should_panic(expected = "Cannot enable RBF with a nSequence >= 0xFFFFFFFE")]
    -    fn test_create_tx_invalid_rbf_sequence() {
    -        let (wallet, _, _) = get_funded_wallet(get_test_wpkh());
    -        let addr = wallet.get_address(New).unwrap();
    -        let mut builder = wallet.build_tx();
    -        builder
    -            .add_recipient(addr.script_pubkey(), 25_000)
    -            .enable_rbf_with_sequence(Sequence(0xFFFFFFFE));
    -        builder.finish().unwrap();
    -    }
    -
    -    #[test]
    -    fn test_create_tx_custom_rbf_sequence() {
    -        let (wallet, _, _) = get_funded_wallet(get_test_wpkh());
    -        let addr = wallet.get_address(New).unwrap();
    -        let mut builder = wallet.build_tx();
    -        builder
    -            .add_recipient(addr.script_pubkey(), 25_000)
    -            .enable_rbf_with_sequence(Sequence(0xDEADBEEF));
    -        let (psbt, _) = builder.finish().unwrap();
    -
    -        assert_eq!(psbt.unsigned_tx.input[0].sequence, Sequence(0xDEADBEEF));
    -    }
    -
    -    #[test]
    -    fn test_create_tx_default_sequence() {
    -        let descriptors = testutils!(@descriptors (get_test_wpkh()));
    -        let wallet = Wallet::new(
    -            &descriptors.0,
    +        wallet
    +            .database
    +            .borrow_mut()
    +            .set_sync_time(sync_time.clone())
    +            .unwrap();
    +        let (psbt, _) = builder.finish().unwrap();
    +
    +        // If there's no current_height we're left with using the last sync height
    +        assert_eq!(
    +            psbt.unsigned_tx.lock_time,
    +            PackedLockTime(sync_time.block_time.height)
    +        );
    +    }
    +
    +    #[test]
    +    fn test_create_tx_default_locktime_cltv() {
    +        let (wallet, _, _) = get_funded_wallet(get_test_single_sig_cltv());
    +        let addr = wallet.get_address(New).unwrap();
    +        let mut builder = wallet.build_tx();
    +        builder.add_recipient(addr.script_pubkey(), 25_000);
    +        let (psbt, _) = builder.finish().unwrap();
    +
    +        assert_eq!(psbt.unsigned_tx.lock_time, PackedLockTime(100_000));
    +    }
    +
    +    #[test]
    +    fn test_create_tx_custom_locktime() {
    +        let (wallet, _, _) = get_funded_wallet(get_test_wpkh());
    +        let addr = wallet.get_address(New).unwrap();
    +        let mut builder = wallet.build_tx();
    +        builder
    +            .add_recipient(addr.script_pubkey(), 25_000)
    +            .current_height(630_001)
    +            .nlocktime(LockTime::from_height(630_000).unwrap());
    +        let (psbt, _) = builder.finish().unwrap();
    +
    +        // When we explicitly specify a nlocktime
    +        // we don't try any fee sniping prevention trick
    +        // (we ignore the current_height)
    +        assert_eq!(psbt.unsigned_tx.lock_time, PackedLockTime(630_000));
    +    }
    +
    +    #[test]
    +    fn test_create_tx_custom_locktime_compatible_with_cltv() {
    +        let (wallet, _, _) = get_funded_wallet(get_test_single_sig_cltv());
    +        let addr = wallet.get_address(New).unwrap();
    +        let mut builder = wallet.build_tx();
    +        builder
    +            .add_recipient(addr.script_pubkey(), 25_000)
    +            .nlocktime(LockTime::from_height(630_000).unwrap());
    +        let (psbt, _) = builder.finish().unwrap();
    +
    +        assert_eq!(psbt.unsigned_tx.lock_time, PackedLockTime(630_000));
    +    }
    +
    +    #[test]
    +    #[should_panic(
    +        expected = "TxBuilder requested timelock of `Blocks(Height(50000))`, but at least `Blocks(Height(100000))` is required to spend from this script"
    +    )]
    +    fn test_create_tx_custom_locktime_incompatible_with_cltv() {
    +        let (wallet, _, _) = get_funded_wallet(get_test_single_sig_cltv());
    +        let addr = wallet.get_address(New).unwrap();
    +        let mut builder = wallet.build_tx();
    +        builder
    +            .add_recipient(addr.script_pubkey(), 25_000)
    +            .nlocktime(LockTime::from_height(50000).unwrap());
    +        builder.finish().unwrap();
    +    }
    +
    +    #[test]
    +    fn test_create_tx_no_rbf_csv() {
    +        let (wallet, _, _) = get_funded_wallet(get_test_single_sig_csv());
    +        let addr = wallet.get_address(New).unwrap();
    +        let mut builder = wallet.build_tx();
    +        builder.add_recipient(addr.script_pubkey(), 25_000);
    +        let (psbt, _) = builder.finish().unwrap();
    +
    +        assert_eq!(psbt.unsigned_tx.input[0].sequence, Sequence(6));
    +    }
    +
    +    #[test]
    +    fn test_create_tx_with_default_rbf_csv() {
    +        let (wallet, _, _) = get_funded_wallet(get_test_single_sig_csv());
    +        let addr = wallet.get_address(New).unwrap();
    +        let mut builder = wallet.build_tx();
    +        builder
    +            .add_recipient(addr.script_pubkey(), 25_000)
    +            .enable_rbf();
    +        let (psbt, _) = builder.finish().unwrap();
    +        // When CSV is enabled it takes precedence over the rbf value (unless forced by the user).
    +        // It will be set to the OP_CSV value, in this case 6
    +        assert_eq!(psbt.unsigned_tx.input[0].sequence, Sequence(6));
    +    }
    +
    +    #[test]
    +    #[should_panic(
    +        expected = "Cannot enable RBF with nSequence `Sequence(3)` given a required OP_CSV of `Sequence(6)`"
    +    )]
    +    fn test_create_tx_with_custom_rbf_csv() {
    +        let (wallet, _, _) = get_funded_wallet(get_test_single_sig_csv());
    +        let addr = wallet.get_address(New).unwrap();
    +        let mut builder = wallet.build_tx();
    +        builder
    +            .add_recipient(addr.script_pubkey(), 25_000)
    +            .enable_rbf_with_sequence(Sequence(3));
    +        builder.finish().unwrap();
    +    }
    +
    +    #[test]
    +    fn test_create_tx_no_rbf_cltv() {
    +        let (wallet, _, _) = get_funded_wallet(get_test_single_sig_cltv());
    +        let addr = wallet.get_address(New).unwrap();
    +        let mut builder = wallet.build_tx();
    +        builder.add_recipient(addr.script_pubkey(), 25_000);
    +        let (psbt, _) = builder.finish().unwrap();
    +
    +        assert_eq!(psbt.unsigned_tx.input[0].sequence, Sequence(0xFFFFFFFE));
    +    }
    +
    +    #[test]
    +    #[should_panic(expected = "Cannot enable RBF with a nSequence >= 0xFFFFFFFE")]
    +    fn test_create_tx_invalid_rbf_sequence() {
    +        let (wallet, _, _) = get_funded_wallet(get_test_wpkh());
    +        let addr = wallet.get_address(New).unwrap();
    +        let mut builder = wallet.build_tx();
    +        builder
    +            .add_recipient(addr.script_pubkey(), 25_000)
    +            .enable_rbf_with_sequence(Sequence(0xFFFFFFFE));
    +        builder.finish().unwrap();
    +    }
    +
    +    #[test]
    +    fn test_create_tx_custom_rbf_sequence() {
    +        let (wallet, _, _) = get_funded_wallet(get_test_wpkh());
    +        let addr = wallet.get_address(New).unwrap();
    +        let mut builder = wallet.build_tx();
    +        builder
    +            .add_recipient(addr.script_pubkey(), 25_000)
    +            .enable_rbf_with_sequence(Sequence(0xDEADBEEF));
    +        let (psbt, _) = builder.finish().unwrap();
    +
    +        assert_eq!(psbt.unsigned_tx.input[0].sequence, Sequence(0xDEADBEEF));
    +    }
    +
    +    #[test]
    +    fn test_create_tx_default_sequence() {
    +        let descriptors = testutils!(@descriptors (get_test_wpkh()));
    +        let wallet = Wallet::new(
    +            &descriptors.0,
                 None,
    -            Network::Regtest,
    -            AnyDatabase::Memory(MemoryDatabase::new()),
    +            Network::Regtest,
    +            AnyDatabase::Memory(MemoryDatabase::new()),
             )
    -        .unwrap();
    +        .unwrap();
     
    -        let tx_meta = testutils! {
    -                @tx ( (@external descriptors, 0) => 50_000 )
    +        let tx_meta = testutils! {
    +                @tx ( (@external descriptors, 0) => 50_000 )
             };
     
    -        // Add the transaction to our db, but do not sync the db. Unsynced db
    -        // should trigger the default sequence value for a new transaction as 0xFFFFFFFF
    -        crate::populate_test_db!(wallet.database.borrow_mut(), tx_meta, None);
    -
    -        let addr = wallet.get_address(New).unwrap();
    -        let mut builder = wallet.build_tx();
    -        builder.add_recipient(addr.script_pubkey(), 25_000);
    -        let (psbt, _) = builder.finish().unwrap();
    -
    -        assert_eq!(psbt.unsigned_tx.input[0].sequence, Sequence(0xFFFFFFFF));
    -    }
    -
    -    #[test]
    -    #[should_panic(
    -        expected = "The `change_policy` can be set only if the wallet has a change_descriptor"
    -    )]
    -    fn test_create_tx_change_policy_no_internal() {
    -        let (wallet, _, _) = get_funded_wallet(get_test_wpkh());
    -        let addr = wallet.get_address(New).unwrap();
    -        let mut builder = wallet.build_tx();
    -        builder
    -            .add_recipient(addr.script_pubkey(), 25_000)
    -            .do_not_spend_change();
    -        builder.finish().unwrap();
    -    }
    -
    -    #[test]
    -    fn test_create_tx_drain_wallet_and_drain_to() {
    -        let (wallet, _, _) = get_funded_wallet(get_test_wpkh());
    -        let addr = wallet.get_address(New).unwrap();
    -        let mut builder = wallet.build_tx();
    -        builder.drain_to(addr.script_pubkey()).drain_wallet();
    -        let (psbt, details) = builder.finish().unwrap();
    -
    -        assert_eq!(psbt.unsigned_tx.output.len(), 1);
    +        // Add the transaction to our db, but do not sync the db. Unsynced db
    +        // should trigger the default sequence value for a new transaction as 0xFFFFFFFF
    +        crate::populate_test_db!(wallet.database.borrow_mut(), tx_meta, None);
    +
    +        let addr = wallet.get_address(New).unwrap();
    +        let mut builder = wallet.build_tx();
    +        builder.add_recipient(addr.script_pubkey(), 25_000);
    +        let (psbt, _) = builder.finish().unwrap();
    +
    +        assert_eq!(psbt.unsigned_tx.input[0].sequence, Sequence(0xFFFFFFFF));
    +    }
    +
    +    #[test]
    +    #[should_panic(
    +        expected = "The `change_policy` can be set only if the wallet has a change_descriptor"
    +    )]
    +    fn test_create_tx_change_policy_no_internal() {
    +        let (wallet, _, _) = get_funded_wallet(get_test_wpkh());
    +        let addr = wallet.get_address(New).unwrap();
    +        let mut builder = wallet.build_tx();
    +        builder
    +            .add_recipient(addr.script_pubkey(), 25_000)
    +            .do_not_spend_change();
    +        builder.finish().unwrap();
    +    }
    +
    +    #[test]
    +    fn test_create_tx_drain_wallet_and_drain_to() {
    +        let (wallet, _, _) = get_funded_wallet(get_test_wpkh());
    +        let addr = wallet.get_address(New).unwrap();
    +        let mut builder = wallet.build_tx();
    +        builder.drain_to(addr.script_pubkey()).drain_wallet();
    +        let (psbt, details) = builder.finish().unwrap();
    +
    +        assert_eq!(psbt.unsigned_tx.output.len(), 1);
             assert_eq!(
    -            psbt.unsigned_tx.output[0].value,
    -            50_000 - details.fee.unwrap_or(0)
    -        );
    -    }
    -
    -    #[test]
    -    fn test_create_tx_drain_wallet_and_drain_to_and_with_recipient() {
    -        let (wallet, _, _) = get_funded_wallet(get_test_wpkh());
    -        let addr = Address::from_str("2N4eQYCbKUHCCTUjBJeHcJp9ok6J2GZsTDt").unwrap();
    -        let drain_addr = wallet.get_address(New).unwrap();
    -        let mut builder = wallet.build_tx();
    -        builder
    -            .add_recipient(addr.script_pubkey(), 20_000)
    -            .drain_to(drain_addr.script_pubkey())
    -            .drain_wallet();
    -        let (psbt, details) = builder.finish().unwrap();
    -        let outputs = psbt.unsigned_tx.output;
    -
    -        assert_eq!(outputs.len(), 2);
    -        let main_output = outputs
    -            .iter()
    -            .find(|x| x.script_pubkey == addr.script_pubkey())
    -            .unwrap();
    -        let drain_output = outputs
    -            .iter()
    -            .find(|x| x.script_pubkey == drain_addr.script_pubkey())
    -            .unwrap();
    -        assert_eq!(main_output.value, 20_000,);
    -        assert_eq!(drain_output.value, 30_000 - details.fee.unwrap_or(0));
    -    }
    -
    -    #[test]
    -    fn test_create_tx_drain_to_and_utxos() {
    -        let (wallet, _, _) = get_funded_wallet(get_test_wpkh());
    -        let addr = wallet.get_address(New).unwrap();
    -        let utxos: Vec<_> = wallet
    -            .get_available_utxos()
    -            .unwrap()
    -            .into_iter()
    -            .map(|(u, _)| u.outpoint)
    -            .collect();
    -        let mut builder = wallet.build_tx();
    -        builder
    -            .drain_to(addr.script_pubkey())
    -            .add_utxos(&utxos)
    -            .unwrap();
    -        let (psbt, details) = builder.finish().unwrap();
    -
    -        assert_eq!(psbt.unsigned_tx.output.len(), 1);
    +            psbt.unsigned_tx.output[0].value,
    +            50_000 - details.fee.unwrap_or(0)
    +        );
    +    }
    +
    +    #[test]
    +    fn test_create_tx_drain_wallet_and_drain_to_and_with_recipient() {
    +        let (wallet, _, _) = get_funded_wallet(get_test_wpkh());
    +        let addr = Address::from_str("2N4eQYCbKUHCCTUjBJeHcJp9ok6J2GZsTDt").unwrap();
    +        let drain_addr = wallet.get_address(New).unwrap();
    +        let mut builder = wallet.build_tx();
    +        builder
    +            .add_recipient(addr.script_pubkey(), 20_000)
    +            .drain_to(drain_addr.script_pubkey())
    +            .drain_wallet();
    +        let (psbt, details) = builder.finish().unwrap();
    +        let outputs = psbt.unsigned_tx.output;
    +
    +        assert_eq!(outputs.len(), 2);
    +        let main_output = outputs
    +            .iter()
    +            .find(|x| x.script_pubkey == addr.script_pubkey())
    +            .unwrap();
    +        let drain_output = outputs
    +            .iter()
    +            .find(|x| x.script_pubkey == drain_addr.script_pubkey())
    +            .unwrap();
    +        assert_eq!(main_output.value, 20_000,);
    +        assert_eq!(drain_output.value, 30_000 - details.fee.unwrap_or(0));
    +    }
    +
    +    #[test]
    +    fn test_create_tx_drain_to_and_utxos() {
    +        let (wallet, _, _) = get_funded_wallet(get_test_wpkh());
    +        let addr = wallet.get_address(New).unwrap();
    +        let utxos: Vec<_> = wallet
    +            .get_available_utxos()
    +            .unwrap()
    +            .into_iter()
    +            .map(|(u, _)| u.outpoint)
    +            .collect();
    +        let mut builder = wallet.build_tx();
    +        builder
    +            .drain_to(addr.script_pubkey())
    +            .add_utxos(&utxos)
    +            .unwrap();
    +        let (psbt, details) = builder.finish().unwrap();
    +
    +        assert_eq!(psbt.unsigned_tx.output.len(), 1);
             assert_eq!(
    -            psbt.unsigned_tx.output[0].value,
    -            50_000 - details.fee.unwrap_or(0)
    -        );
    -    }
    -
    -    #[test]
    -    #[should_panic(expected = "NoRecipients")]
    -    fn test_create_tx_drain_to_no_drain_wallet_no_utxos() {
    -        let (wallet, _, _) = get_funded_wallet(get_test_wpkh());
    -        let drain_addr = wallet.get_address(New).unwrap();
    -        let mut builder = wallet.build_tx();
    -        builder.drain_to(drain_addr.script_pubkey());
    -        builder.finish().unwrap();
    -    }
    -
    -    #[test]
    -    fn test_create_tx_default_fee_rate() {
    -        let (wallet, _, _) = get_funded_wallet(get_test_wpkh());
    -        let addr = wallet.get_address(New).unwrap();
    -        let mut builder = wallet.build_tx();
    -        builder.add_recipient(addr.script_pubkey(), 25_000);
    -        let (psbt, details) = builder.finish().unwrap();
    -
    -        assert_fee_rate!(psbt, details.fee.unwrap_or(0), FeeRate::default(), @add_signature);
    -    }
    -
    -    #[test]
    -    fn test_create_tx_custom_fee_rate() {
    -        let (wallet, _, _) = get_funded_wallet(get_test_wpkh());
    -        let addr = wallet.get_address(New).unwrap();
    -        let mut builder = wallet.build_tx();
    -        builder
    -            .add_recipient(addr.script_pubkey(), 25_000)
    -            .fee_rate(FeeRate::from_sat_per_vb(5.0));
    -        let (psbt, details) = builder.finish().unwrap();
    -
    -        assert_fee_rate!(psbt, details.fee.unwrap_or(0), FeeRate::from_sat_per_vb(5.0), @add_signature);
    -    }
    -
    -    #[test]
    -    fn test_create_tx_absolute_fee() {
    -        let (wallet, _, _) = get_funded_wallet(get_test_wpkh());
    -        let addr = wallet.get_address(New).unwrap();
    -        let mut builder = wallet.build_tx();
    -        builder
    -            .drain_to(addr.script_pubkey())
    -            .drain_wallet()
    -            .fee_absolute(100);
    -        let (psbt, details) = builder.finish().unwrap();
    -
    -        assert_eq!(details.fee.unwrap_or(0), 100);
    -        assert_eq!(psbt.unsigned_tx.output.len(), 1);
    +            psbt.unsigned_tx.output[0].value,
    +            50_000 - details.fee.unwrap_or(0)
    +        );
    +    }
    +
    +    #[test]
    +    #[should_panic(expected = "NoRecipients")]
    +    fn test_create_tx_drain_to_no_drain_wallet_no_utxos() {
    +        let (wallet, _, _) = get_funded_wallet(get_test_wpkh());
    +        let drain_addr = wallet.get_address(New).unwrap();
    +        let mut builder = wallet.build_tx();
    +        builder.drain_to(drain_addr.script_pubkey());
    +        builder.finish().unwrap();
    +    }
    +
    +    #[test]
    +    fn test_create_tx_default_fee_rate() {
    +        let (wallet, _, _) = get_funded_wallet(get_test_wpkh());
    +        let addr = wallet.get_address(New).unwrap();
    +        let mut builder = wallet.build_tx();
    +        builder.add_recipient(addr.script_pubkey(), 25_000);
    +        let (psbt, details) = builder.finish().unwrap();
    +
    +        assert_fee_rate!(psbt, details.fee.unwrap_or(0), FeeRate::default(), @add_signature);
    +    }
    +
    +    #[test]
    +    fn test_create_tx_custom_fee_rate() {
    +        let (wallet, _, _) = get_funded_wallet(get_test_wpkh());
    +        let addr = wallet.get_address(New).unwrap();
    +        let mut builder = wallet.build_tx();
    +        builder
    +            .add_recipient(addr.script_pubkey(), 25_000)
    +            .fee_rate(FeeRate::from_sat_per_vb(5.0));
    +        let (psbt, details) = builder.finish().unwrap();
    +
    +        assert_fee_rate!(psbt, details.fee.unwrap_or(0), FeeRate::from_sat_per_vb(5.0), @add_signature);
    +    }
    +
    +    #[test]
    +    fn test_create_tx_absolute_fee() {
    +        let (wallet, _, _) = get_funded_wallet(get_test_wpkh());
    +        let addr = wallet.get_address(New).unwrap();
    +        let mut builder = wallet.build_tx();
    +        builder
    +            .drain_to(addr.script_pubkey())
    +            .drain_wallet()
    +            .fee_absolute(100);
    +        let (psbt, details) = builder.finish().unwrap();
    +
    +        assert_eq!(details.fee.unwrap_or(0), 100);
    +        assert_eq!(psbt.unsigned_tx.output.len(), 1);
             assert_eq!(
    -            psbt.unsigned_tx.output[0].value,
    -            50_000 - details.fee.unwrap_or(0)
    +            psbt.unsigned_tx.output[0].value,
    +            50_000 - details.fee.unwrap_or(0)
             );
         }
     
    -    #[test]
    -    fn test_create_tx_absolute_zero_fee() {
    -        let (wallet, _, _) = get_funded_wallet(get_test_wpkh());
    -        let addr = wallet.get_address(New).unwrap();
    -        let mut builder = wallet.build_tx();
    -        builder
    -            .drain_to(addr.script_pubkey())
    -            .drain_wallet()
    -            .fee_absolute(0);
    -        let (psbt, details) = builder.finish().unwrap();
    +    #[test]
    +    fn test_create_tx_absolute_zero_fee() {
    +        let (wallet, _, _) = get_funded_wallet(get_test_wpkh());
    +        let addr = wallet.get_address(New).unwrap();
    +        let mut builder = wallet.build_tx();
    +        builder
    +            .drain_to(addr.script_pubkey())
    +            .drain_wallet()
    +            .fee_absolute(0);
    +        let (psbt, details) = builder.finish().unwrap();
     
    -        assert_eq!(details.fee.unwrap_or(0), 0);
    -        assert_eq!(psbt.unsigned_tx.output.len(), 1);
    +        assert_eq!(details.fee.unwrap_or(0), 0);
    +        assert_eq!(psbt.unsigned_tx.output.len(), 1);
             assert_eq!(
    -            psbt.unsigned_tx.output[0].value,
    -            50_000 - details.fee.unwrap_or(0)
    -        );
    -    }
    -
    -    #[test]
    -    #[should_panic(expected = "InsufficientFunds")]
    -    fn test_create_tx_absolute_high_fee() {
    -        let (wallet, _, _) = get_funded_wallet(get_test_wpkh());
    -        let addr = wallet.get_address(New).unwrap();
    -        let mut builder = wallet.build_tx();
    -        builder
    -            .drain_to(addr.script_pubkey())
    -            .drain_wallet()
    -            .fee_absolute(60_000);
    -        let (_psbt, _details) = builder.finish().unwrap();
    -    }
    -
    -    #[test]
    -    fn test_create_tx_add_change() {
    -        use super::tx_builder::TxOrdering;
    -
    -        let (wallet, _, _) = get_funded_wallet(get_test_wpkh());
    -        let addr = wallet.get_address(New).unwrap();
    -        let mut builder = wallet.build_tx();
    -        builder
    -            .add_recipient(addr.script_pubkey(), 25_000)
    -            .ordering(TxOrdering::Untouched);
    -        let (psbt, details) = builder.finish().unwrap();
    -
    -        assert_eq!(psbt.unsigned_tx.output.len(), 2);
    -        assert_eq!(psbt.unsigned_tx.output[0].value, 25_000);
    +            psbt.unsigned_tx.output[0].value,
    +            50_000 - details.fee.unwrap_or(0)
    +        );
    +    }
    +
    +    #[test]
    +    #[should_panic(expected = "InsufficientFunds")]
    +    fn test_create_tx_absolute_high_fee() {
    +        let (wallet, _, _) = get_funded_wallet(get_test_wpkh());
    +        let addr = wallet.get_address(New).unwrap();
    +        let mut builder = wallet.build_tx();
    +        builder
    +            .drain_to(addr.script_pubkey())
    +            .drain_wallet()
    +            .fee_absolute(60_000);
    +        let (_psbt, _details) = builder.finish().unwrap();
    +    }
    +
    +    #[test]
    +    fn test_create_tx_add_change() {
    +        use super::tx_builder::TxOrdering;
    +
    +        let (wallet, _, _) = get_funded_wallet(get_test_wpkh());
    +        let addr = wallet.get_address(New).unwrap();
    +        let mut builder = wallet.build_tx();
    +        builder
    +            .add_recipient(addr.script_pubkey(), 25_000)
    +            .ordering(TxOrdering::Untouched);
    +        let (psbt, details) = builder.finish().unwrap();
    +
    +        assert_eq!(psbt.unsigned_tx.output.len(), 2);
    +        assert_eq!(psbt.unsigned_tx.output[0].value, 25_000);
             assert_eq!(
    -            psbt.unsigned_tx.output[1].value,
    -            25_000 - details.fee.unwrap_or(0)
    -        );
    -    }
    -
    -    #[test]
    -    fn test_create_tx_skip_change_dust() {
    -        let (wallet, _, _) = get_funded_wallet(get_test_wpkh());
    -        let addr = wallet.get_address(New).unwrap();
    -        let mut builder = wallet.build_tx();
    -        builder.add_recipient(addr.script_pubkey(), 49_800);
    -        let (psbt, details) = builder.finish().unwrap();
    -
    -        assert_eq!(psbt.unsigned_tx.output.len(), 1);
    -        assert_eq!(psbt.unsigned_tx.output[0].value, 49_800);
    -        assert_eq!(details.fee.unwrap_or(0), 200);
    -    }
    -
    -    #[test]
    -    #[should_panic(expected = "InsufficientFunds")]
    -    fn test_create_tx_drain_to_dust_amount() {
    -        let (wallet, _, _) = get_funded_wallet(get_test_wpkh());
    -        let addr = wallet.get_address(New).unwrap();
    -        // very high fee rate, so that the only output would be below dust
    -        let mut builder = wallet.build_tx();
    -        builder
    -            .drain_to(addr.script_pubkey())
    -            .drain_wallet()
    -            .fee_rate(FeeRate::from_sat_per_vb(453.0));
    -        builder.finish().unwrap();
    -    }
    -
    -    #[test]
    -    fn test_create_tx_ordering_respected() {
    -        let (wallet, _, _) = get_funded_wallet(get_test_wpkh());
    -        let addr = wallet.get_address(New).unwrap();
    -        let mut builder = wallet.build_tx();
    -        builder
    -            .add_recipient(addr.script_pubkey(), 30_000)
    -            .add_recipient(addr.script_pubkey(), 10_000)
    -            .ordering(super::tx_builder::TxOrdering::Bip69Lexicographic);
    -        let (psbt, details) = builder.finish().unwrap();
    -
    -        assert_eq!(psbt.unsigned_tx.output.len(), 3);
    +            psbt.unsigned_tx.output[1].value,
    +            25_000 - details.fee.unwrap_or(0)
    +        );
    +    }
    +
    +    #[test]
    +    fn test_create_tx_skip_change_dust() {
    +        let (wallet, _, _) = get_funded_wallet(get_test_wpkh());
    +        let addr = wallet.get_address(New).unwrap();
    +        let mut builder = wallet.build_tx();
    +        builder.add_recipient(addr.script_pubkey(), 49_800);
    +        let (psbt, details) = builder.finish().unwrap();
    +
    +        assert_eq!(psbt.unsigned_tx.output.len(), 1);
    +        assert_eq!(psbt.unsigned_tx.output[0].value, 49_800);
    +        assert_eq!(details.fee.unwrap_or(0), 200);
    +    }
    +
    +    #[test]
    +    #[should_panic(expected = "InsufficientFunds")]
    +    fn test_create_tx_drain_to_dust_amount() {
    +        let (wallet, _, _) = get_funded_wallet(get_test_wpkh());
    +        let addr = wallet.get_address(New).unwrap();
    +        // very high fee rate, so that the only output would be below dust
    +        let mut builder = wallet.build_tx();
    +        builder
    +            .drain_to(addr.script_pubkey())
    +            .drain_wallet()
    +            .fee_rate(FeeRate::from_sat_per_vb(453.0));
    +        builder.finish().unwrap();
    +    }
    +
    +    #[test]
    +    fn test_create_tx_ordering_respected() {
    +        let (wallet, _, _) = get_funded_wallet(get_test_wpkh());
    +        let addr = wallet.get_address(New).unwrap();
    +        let mut builder = wallet.build_tx();
    +        builder
    +            .add_recipient(addr.script_pubkey(), 30_000)
    +            .add_recipient(addr.script_pubkey(), 10_000)
    +            .ordering(super::tx_builder::TxOrdering::Bip69Lexicographic);
    +        let (psbt, details) = builder.finish().unwrap();
    +
    +        assert_eq!(psbt.unsigned_tx.output.len(), 3);
             assert_eq!(
    -            psbt.unsigned_tx.output[0].value,
    -            10_000 - details.fee.unwrap_or(0)
    +            psbt.unsigned_tx.output[0].value,
    +            10_000 - details.fee.unwrap_or(0)
             );
    -        assert_eq!(psbt.unsigned_tx.output[1].value, 10_000);
    -        assert_eq!(psbt.unsigned_tx.output[2].value, 30_000);
    +        assert_eq!(psbt.unsigned_tx.output[1].value, 10_000);
    +        assert_eq!(psbt.unsigned_tx.output[2].value, 30_000);
         }
     
    -    #[test]
    -    fn test_create_tx_default_sighash() {
    -        let (wallet, _, _) = get_funded_wallet(get_test_wpkh());
    -        let addr = wallet.get_address(New).unwrap();
    -        let mut builder = wallet.build_tx();
    -        builder.add_recipient(addr.script_pubkey(), 30_000);
    -        let (psbt, _) = builder.finish().unwrap();
    +    #[test]
    +    fn test_create_tx_default_sighash() {
    +        let (wallet, _, _) = get_funded_wallet(get_test_wpkh());
    +        let addr = wallet.get_address(New).unwrap();
    +        let mut builder = wallet.build_tx();
    +        builder.add_recipient(addr.script_pubkey(), 30_000);
    +        let (psbt, _) = builder.finish().unwrap();
     
    -        assert_eq!(psbt.inputs[0].sighash_type, None);
    +        assert_eq!(psbt.inputs[0].sighash_type, None);
         }
     
    -    #[test]
    -    fn test_create_tx_custom_sighash() {
    -        let (wallet, _, _) = get_funded_wallet(get_test_wpkh());
    -        let addr = wallet.get_address(New).unwrap();
    -        let mut builder = wallet.build_tx();
    -        builder
    -            .add_recipient(addr.script_pubkey(), 30_000)
    -            .sighash(bitcoin::EcdsaSighashType::Single.into());
    -        let (psbt, _) = builder.finish().unwrap();
    +    #[test]
    +    fn test_create_tx_custom_sighash() {
    +        let (wallet, _, _) = get_funded_wallet(get_test_wpkh());
    +        let addr = wallet.get_address(New).unwrap();
    +        let mut builder = wallet.build_tx();
    +        builder
    +            .add_recipient(addr.script_pubkey(), 30_000)
    +            .sighash(bitcoin::EcdsaSighashType::Single.into());
    +        let (psbt, _) = builder.finish().unwrap();
     
             assert_eq!(
    -            psbt.inputs[0].sighash_type,
    -            Some(bitcoin::EcdsaSighashType::Single.into())
    +            psbt.inputs[0].sighash_type,
    +            Some(bitcoin::EcdsaSighashType::Single.into())
             );
         }
     
    -    #[test]
    -    fn test_create_tx_input_hd_keypaths() {
    -        use bitcoin::util::bip32::{DerivationPath, Fingerprint};
    -        use std::str::FromStr;
    +    #[test]
    +    fn test_create_tx_input_hd_keypaths() {
    +        use bitcoin::util::bip32::{DerivationPath, Fingerprint};
    +        use std::str::FromStr;
     
    -        let (wallet, _, _) = get_funded_wallet("wpkh([d34db33f/44'/0'/0']tpubDEnoLuPdBep9bzw5LoGYpsxUQYheRQ9gcgrJhJEcdKFB9cWQRyYmkCyRoTqeD4tJYiVVgt6A3rN6rWn9RYhR9sBsGxji29LYWHuKKbdb1ev/0/*)");
    -        let addr = wallet.get_address(New).unwrap();
    -        let mut builder = wallet.build_tx();
    -        builder.drain_to(addr.script_pubkey()).drain_wallet();
    -        let (psbt, _) = builder.finish().unwrap();
    +        let (wallet, _, _) = get_funded_wallet("wpkh([d34db33f/44'/0'/0']tpubDEnoLuPdBep9bzw5LoGYpsxUQYheRQ9gcgrJhJEcdKFB9cWQRyYmkCyRoTqeD4tJYiVVgt6A3rN6rWn9RYhR9sBsGxji29LYWHuKKbdb1ev/0/*)");
    +        let addr = wallet.get_address(New).unwrap();
    +        let mut builder = wallet.build_tx();
    +        builder.drain_to(addr.script_pubkey()).drain_wallet();
    +        let (psbt, _) = builder.finish().unwrap();
     
    -        assert_eq!(psbt.inputs[0].bip32_derivation.len(), 1);
    +        assert_eq!(psbt.inputs[0].bip32_derivation.len(), 1);
             assert_eq!(
    -            psbt.inputs[0].bip32_derivation.values().next().unwrap(),
    +            psbt.inputs[0].bip32_derivation.values().next().unwrap(),
                 &(
    -                Fingerprint::from_str("d34db33f").unwrap(),
    -                DerivationPath::from_str("m/44'/0'/0'/0/0").unwrap()
    +                Fingerprint::from_str("d34db33f").unwrap(),
    +                DerivationPath::from_str("m/44'/0'/0'/0/0").unwrap()
                 )
             );
         }
     
    -    #[test]
    -    fn test_create_tx_output_hd_keypaths() {
    -        use bitcoin::util::bip32::{DerivationPath, Fingerprint};
    -        use std::str::FromStr;
    +    #[test]
    +    fn test_create_tx_output_hd_keypaths() {
    +        use bitcoin::util::bip32::{DerivationPath, Fingerprint};
    +        use std::str::FromStr;
     
    -        let (wallet, descriptors, _) = get_funded_wallet("wpkh([d34db33f/44'/0'/0']tpubDEnoLuPdBep9bzw5LoGYpsxUQYheRQ9gcgrJhJEcdKFB9cWQRyYmkCyRoTqeD4tJYiVVgt6A3rN6rWn9RYhR9sBsGxji29LYWHuKKbdb1ev/0/*)");
    -        // cache some addresses
    -        wallet.get_address(New).unwrap();
    +        let (wallet, descriptors, _) = get_funded_wallet("wpkh([d34db33f/44'/0'/0']tpubDEnoLuPdBep9bzw5LoGYpsxUQYheRQ9gcgrJhJEcdKFB9cWQRyYmkCyRoTqeD4tJYiVVgt6A3rN6rWn9RYhR9sBsGxji29LYWHuKKbdb1ev/0/*)");
    +        // cache some addresses
    +        wallet.get_address(New).unwrap();
     
    -        let addr = testutils!(@external descriptors, 5);
    -        let mut builder = wallet.build_tx();
    -        builder.drain_to(addr.script_pubkey()).drain_wallet();
    -        let (psbt, _) = builder.finish().unwrap();
    +        let addr = testutils!(@external descriptors, 5);
    +        let mut builder = wallet.build_tx();
    +        builder.drain_to(addr.script_pubkey()).drain_wallet();
    +        let (psbt, _) = builder.finish().unwrap();
     
    -        assert_eq!(psbt.outputs[0].bip32_derivation.len(), 1);
    +        assert_eq!(psbt.outputs[0].bip32_derivation.len(), 1);
             assert_eq!(
    -            psbt.outputs[0].bip32_derivation.values().next().unwrap(),
    +            psbt.outputs[0].bip32_derivation.values().next().unwrap(),
                 &(
    -                Fingerprint::from_str("d34db33f").unwrap(),
    -                DerivationPath::from_str("m/44'/0'/0'/0/5").unwrap()
    +                Fingerprint::from_str("d34db33f").unwrap(),
    +                DerivationPath::from_str("m/44'/0'/0'/0/5").unwrap()
                 )
             );
         }
     
    -    #[test]
    -    fn test_create_tx_set_redeem_script_p2sh() {
    -        use bitcoin::hashes::hex::FromHex;
    +    #[test]
    +    fn test_create_tx_set_redeem_script_p2sh() {
    +        use bitcoin::hashes::hex::FromHex;
     
    -        let (wallet, _, _) =
    -            get_funded_wallet("sh(pk(cVpPVruEDdmutPzisEsYvtST1usBR3ntr8pXSyt6D2YYqXRyPcFW))");
    -        let addr = wallet.get_address(New).unwrap();
    -        let mut builder = wallet.build_tx();
    -        builder.drain_to(addr.script_pubkey()).drain_wallet();
    -        let (psbt, _) = builder.finish().unwrap();
    +        let (wallet, _, _) =
    +            get_funded_wallet("sh(pk(cVpPVruEDdmutPzisEsYvtST1usBR3ntr8pXSyt6D2YYqXRyPcFW))");
    +        let addr = wallet.get_address(New).unwrap();
    +        let mut builder = wallet.build_tx();
    +        builder.drain_to(addr.script_pubkey()).drain_wallet();
    +        let (psbt, _) = builder.finish().unwrap();
     
             assert_eq!(
    -            psbt.inputs[0].redeem_script,
    -            Some(Script::from(
    -                Vec::<u8>::from_hex(
    -                    "21032b0558078bec38694a84933d659303e2575dae7e91685911454115bfd64487e3ac"
    -                )
    -                .unwrap()
    +            psbt.inputs[0].redeem_script,
    +            Some(Script::from(
    +                Vec::<u8>::from_hex(
    +                    "21032b0558078bec38694a84933d659303e2575dae7e91685911454115bfd64487e3ac"
    +                )
    +                .unwrap()
                 ))
             );
    -        assert_eq!(psbt.inputs[0].witness_script, None);
    +        assert_eq!(psbt.inputs[0].witness_script, None);
         }
     
    -    #[test]
    -    fn test_create_tx_set_witness_script_p2wsh() {
    -        use bitcoin::hashes::hex::FromHex;
    +    #[test]
    +    fn test_create_tx_set_witness_script_p2wsh() {
    +        use bitcoin::hashes::hex::FromHex;
     
    -        let (wallet, _, _) =
    -            get_funded_wallet("wsh(pk(cVpPVruEDdmutPzisEsYvtST1usBR3ntr8pXSyt6D2YYqXRyPcFW))");
    -        let addr = wallet.get_address(New).unwrap();
    -        let mut builder = wallet.build_tx();
    -        builder.drain_to(addr.script_pubkey()).drain_wallet();
    -        let (psbt, _) = builder.finish().unwrap();
    +        let (wallet, _, _) =
    +            get_funded_wallet("wsh(pk(cVpPVruEDdmutPzisEsYvtST1usBR3ntr8pXSyt6D2YYqXRyPcFW))");
    +        let addr = wallet.get_address(New).unwrap();
    +        let mut builder = wallet.build_tx();
    +        builder.drain_to(addr.script_pubkey()).drain_wallet();
    +        let (psbt, _) = builder.finish().unwrap();
     
    -        assert_eq!(psbt.inputs[0].redeem_script, None);
    +        assert_eq!(psbt.inputs[0].redeem_script, None);
             assert_eq!(
    -            psbt.inputs[0].witness_script,
    -            Some(Script::from(
    -                Vec::<u8>::from_hex(
    -                    "21032b0558078bec38694a84933d659303e2575dae7e91685911454115bfd64487e3ac"
    -                )
    -                .unwrap()
    +            psbt.inputs[0].witness_script,
    +            Some(Script::from(
    +                Vec::<u8>::from_hex(
    +                    "21032b0558078bec38694a84933d659303e2575dae7e91685911454115bfd64487e3ac"
    +                )
    +                .unwrap()
                 ))
             );
         }
     
    -    #[test]
    -    fn test_create_tx_set_redeem_witness_script_p2wsh_p2sh() {
    -        use bitcoin::hashes::hex::FromHex;
    +    #[test]
    +    fn test_create_tx_set_redeem_witness_script_p2wsh_p2sh() {
    +        use bitcoin::hashes::hex::FromHex;
     
    -        let (wallet, _, _) =
    -            get_funded_wallet("sh(wsh(pk(cVpPVruEDdmutPzisEsYvtST1usBR3ntr8pXSyt6D2YYqXRyPcFW)))");
    -        let addr = wallet.get_address(New).unwrap();
    -        let mut builder = wallet.build_tx();
    -        builder.drain_to(addr.script_pubkey()).drain_wallet();
    -        let (psbt, _) = builder.finish().unwrap();
    +        let (wallet, _, _) =
    +            get_funded_wallet("sh(wsh(pk(cVpPVruEDdmutPzisEsYvtST1usBR3ntr8pXSyt6D2YYqXRyPcFW)))");
    +        let addr = wallet.get_address(New).unwrap();
    +        let mut builder = wallet.build_tx();
    +        builder.drain_to(addr.script_pubkey()).drain_wallet();
    +        let (psbt, _) = builder.finish().unwrap();
     
    -        let script = Script::from(
    -            Vec::<u8>::from_hex(
    +        let script = Script::from(
    +            Vec::<u8>::from_hex(
                     "21032b0558078bec38694a84933d659303e2575dae7e91685911454115bfd64487e3ac",
                 )
    -            .unwrap(),
    +            .unwrap(),
             );
     
    -        assert_eq!(psbt.inputs[0].redeem_script, Some(script.to_v0_p2wsh()));
    -        assert_eq!(psbt.inputs[0].witness_script, Some(script));
    -    }
    -
    -    #[test]
    -    fn test_create_tx_non_witness_utxo() {
    -        let (wallet, _, _) =
    -            get_funded_wallet("sh(pk(cVpPVruEDdmutPzisEsYvtST1usBR3ntr8pXSyt6D2YYqXRyPcFW))");
    -        let addr = wallet.get_address(New).unwrap();
    -        let mut builder = wallet.build_tx();
    -        builder.drain_to(addr.script_pubkey()).drain_wallet();
    -        let (psbt, _) = builder.finish().unwrap();
    -
    -        assert!(psbt.inputs[0].non_witness_utxo.is_some());
    -        assert!(psbt.inputs[0].witness_utxo.is_none());
    -    }
    -
    -    #[test]
    -    fn test_create_tx_only_witness_utxo() {
    -        let (wallet, _, _) =
    -            get_funded_wallet("wsh(pk(cVpPVruEDdmutPzisEsYvtST1usBR3ntr8pXSyt6D2YYqXRyPcFW))");
    -        let addr = wallet.get_address(New).unwrap();
    -        let mut builder = wallet.build_tx();
    -        builder
    -            .drain_to(addr.script_pubkey())
    -            .only_witness_utxo()
    -            .drain_wallet();
    -        let (psbt, _) = builder.finish().unwrap();
    -
    -        assert!(psbt.inputs[0].non_witness_utxo.is_none());
    -        assert!(psbt.inputs[0].witness_utxo.is_some());
    -    }
    -
    -    #[test]
    -    fn test_create_tx_shwpkh_has_witness_utxo() {
    -        let (wallet, _, _) =
    -            get_funded_wallet("sh(wpkh(cVpPVruEDdmutPzisEsYvtST1usBR3ntr8pXSyt6D2YYqXRyPcFW))");
    -        let addr = wallet.get_address(New).unwrap();
    -        let mut builder = wallet.build_tx();
    -        builder.drain_to(addr.script_pubkey()).drain_wallet();
    -        let (psbt, _) = builder.finish().unwrap();
    -
    -        assert!(psbt.inputs[0].witness_utxo.is_some());
    -    }
    -
    -    #[test]
    -    fn test_create_tx_both_non_witness_utxo_and_witness_utxo_default() {
    -        let (wallet, _, _) =
    -            get_funded_wallet("wsh(pk(cVpPVruEDdmutPzisEsYvtST1usBR3ntr8pXSyt6D2YYqXRyPcFW))");
    -        let addr = wallet.get_address(New).unwrap();
    -        let mut builder = wallet.build_tx();
    -        builder.drain_to(addr.script_pubkey()).drain_wallet();
    -        let (psbt, _) = builder.finish().unwrap();
    -
    -        assert!(psbt.inputs[0].non_witness_utxo.is_some());
    -        assert!(psbt.inputs[0].witness_utxo.is_some());
    -    }
    -
    -    #[test]
    -    fn test_create_tx_add_utxo() {
    -        let (wallet, descriptors, _) = get_funded_wallet(get_test_wpkh());
    -        let small_output_txid = crate::populate_test_db!(
    -            wallet.database.borrow_mut(),
    -            testutils! (@tx ( (@external descriptors, 0) => 25_000 ) (@confirmations 1)),
    +        assert_eq!(psbt.inputs[0].redeem_script, Some(script.to_v0_p2wsh()));
    +        assert_eq!(psbt.inputs[0].witness_script, Some(script));
    +    }
    +
    +    #[test]
    +    fn test_create_tx_non_witness_utxo() {
    +        let (wallet, _, _) =
    +            get_funded_wallet("sh(pk(cVpPVruEDdmutPzisEsYvtST1usBR3ntr8pXSyt6D2YYqXRyPcFW))");
    +        let addr = wallet.get_address(New).unwrap();
    +        let mut builder = wallet.build_tx();
    +        builder.drain_to(addr.script_pubkey()).drain_wallet();
    +        let (psbt, _) = builder.finish().unwrap();
    +
    +        assert!(psbt.inputs[0].non_witness_utxo.is_some());
    +        assert!(psbt.inputs[0].witness_utxo.is_none());
    +    }
    +
    +    #[test]
    +    fn test_create_tx_only_witness_utxo() {
    +        let (wallet, _, _) =
    +            get_funded_wallet("wsh(pk(cVpPVruEDdmutPzisEsYvtST1usBR3ntr8pXSyt6D2YYqXRyPcFW))");
    +        let addr = wallet.get_address(New).unwrap();
    +        let mut builder = wallet.build_tx();
    +        builder
    +            .drain_to(addr.script_pubkey())
    +            .only_witness_utxo()
    +            .drain_wallet();
    +        let (psbt, _) = builder.finish().unwrap();
    +
    +        assert!(psbt.inputs[0].non_witness_utxo.is_none());
    +        assert!(psbt.inputs[0].witness_utxo.is_some());
    +    }
    +
    +    #[test]
    +    fn test_create_tx_shwpkh_has_witness_utxo() {
    +        let (wallet, _, _) =
    +            get_funded_wallet("sh(wpkh(cVpPVruEDdmutPzisEsYvtST1usBR3ntr8pXSyt6D2YYqXRyPcFW))");
    +        let addr = wallet.get_address(New).unwrap();
    +        let mut builder = wallet.build_tx();
    +        builder.drain_to(addr.script_pubkey()).drain_wallet();
    +        let (psbt, _) = builder.finish().unwrap();
    +
    +        assert!(psbt.inputs[0].witness_utxo.is_some());
    +    }
    +
    +    #[test]
    +    fn test_create_tx_both_non_witness_utxo_and_witness_utxo_default() {
    +        let (wallet, _, _) =
    +            get_funded_wallet("wsh(pk(cVpPVruEDdmutPzisEsYvtST1usBR3ntr8pXSyt6D2YYqXRyPcFW))");
    +        let addr = wallet.get_address(New).unwrap();
    +        let mut builder = wallet.build_tx();
    +        builder.drain_to(addr.script_pubkey()).drain_wallet();
    +        let (psbt, _) = builder.finish().unwrap();
    +
    +        assert!(psbt.inputs[0].non_witness_utxo.is_some());
    +        assert!(psbt.inputs[0].witness_utxo.is_some());
    +    }
    +
    +    #[test]
    +    fn test_create_tx_add_utxo() {
    +        let (wallet, descriptors, _) = get_funded_wallet(get_test_wpkh());
    +        let small_output_txid = crate::populate_test_db!(
    +            wallet.database.borrow_mut(),
    +            testutils! (@tx ( (@external descriptors, 0) => 25_000 ) (@confirmations 1)),
                 Some(100),
             );
     
    -        let addr = Address::from_str("2N1Ffz3WaNzbeLFBb51xyFMHYSEUXcbiSoX").unwrap();
    -        let mut builder = wallet.build_tx();
    -        builder
    -            .add_recipient(addr.script_pubkey(), 30_000)
    -            .add_utxo(OutPoint {
    -                txid: small_output_txid,
    -                vout: 0,
    +        let addr = Address::from_str("2N1Ffz3WaNzbeLFBb51xyFMHYSEUXcbiSoX").unwrap();
    +        let mut builder = wallet.build_tx();
    +        builder
    +            .add_recipient(addr.script_pubkey(), 30_000)
    +            .add_utxo(OutPoint {
    +                txid: small_output_txid,
    +                vout: 0,
                 })
    -            .unwrap();
    -        let (psbt, details) = builder.finish().unwrap();
    +            .unwrap();
    +        let (psbt, details) = builder.finish().unwrap();
     
             assert_eq!(
    -            psbt.unsigned_tx.input.len(),
    +            psbt.unsigned_tx.input.len(),
                 2,
    -            "should add an additional input since 25_000 < 30_000"
    -        );
    -        assert_eq!(details.sent, 75_000, "total should be sum of both inputs");
    -    }
    -
    -    #[test]
    -    #[should_panic(expected = "InsufficientFunds")]
    -    fn test_create_tx_manually_selected_insufficient() {
    -        let (wallet, descriptors, _) = get_funded_wallet(get_test_wpkh());
    -        let small_output_txid = crate::populate_test_db!(
    -            wallet.database.borrow_mut(),
    -            testutils! (@tx ( (@external descriptors, 0) => 25_000 ) (@confirmations 1)),
    +            "should add an additional input since 25_000 < 30_000"
    +        );
    +        assert_eq!(details.sent, 75_000, "total should be sum of both inputs");
    +    }
    +
    +    #[test]
    +    #[should_panic(expected = "InsufficientFunds")]
    +    fn test_create_tx_manually_selected_insufficient() {
    +        let (wallet, descriptors, _) = get_funded_wallet(get_test_wpkh());
    +        let small_output_txid = crate::populate_test_db!(
    +            wallet.database.borrow_mut(),
    +            testutils! (@tx ( (@external descriptors, 0) => 25_000 ) (@confirmations 1)),
                 Some(100),
             );
     
    -        let addr = Address::from_str("2N1Ffz3WaNzbeLFBb51xyFMHYSEUXcbiSoX").unwrap();
    -        let mut builder = wallet.build_tx();
    -        builder
    -            .add_recipient(addr.script_pubkey(), 30_000)
    -            .add_utxo(OutPoint {
    -                txid: small_output_txid,
    -                vout: 0,
    +        let addr = Address::from_str("2N1Ffz3WaNzbeLFBb51xyFMHYSEUXcbiSoX").unwrap();
    +        let mut builder = wallet.build_tx();
    +        builder
    +            .add_recipient(addr.script_pubkey(), 30_000)
    +            .add_utxo(OutPoint {
    +                txid: small_output_txid,
    +                vout: 0,
                 })
    -            .unwrap()
    -            .manually_selected_only();
    -        builder.finish().unwrap();
    +            .unwrap()
    +            .manually_selected_only();
    +        builder.finish().unwrap();
         }
     
    -    #[test]
    -    #[should_panic(expected = "SpendingPolicyRequired(External)")]
    -    fn test_create_tx_policy_path_required() {
    -        let (wallet, _, _) = get_funded_wallet(get_test_a_or_b_plus_csv());
    +    #[test]
    +    #[should_panic(expected = "SpendingPolicyRequired(External)")]
    +    fn test_create_tx_policy_path_required() {
    +        let (wallet, _, _) = get_funded_wallet(get_test_a_or_b_plus_csv());
     
    -        let addr = Address::from_str("2N1Ffz3WaNzbeLFBb51xyFMHYSEUXcbiSoX").unwrap();
    -        let mut builder = wallet.build_tx();
    -        builder.add_recipient(addr.script_pubkey(), 30_000);
    -        builder.finish().unwrap();
    +        let addr = Address::from_str("2N1Ffz3WaNzbeLFBb51xyFMHYSEUXcbiSoX").unwrap();
    +        let mut builder = wallet.build_tx();
    +        builder.add_recipient(addr.script_pubkey(), 30_000);
    +        builder.finish().unwrap();
         }
     
    -    #[test]
    -    fn test_create_tx_policy_path_no_csv() {
    -        let descriptors = testutils!(@descriptors (get_test_wpkh()));
    -        let wallet = Wallet::new(
    -            &descriptors.0,
    +    #[test]
    +    fn test_create_tx_policy_path_no_csv() {
    +        let descriptors = testutils!(@descriptors (get_test_wpkh()));
    +        let wallet = Wallet::new(
    +            &descriptors.0,
                 None,
    -            Network::Regtest,
    -            AnyDatabase::Memory(MemoryDatabase::new()),
    +            Network::Regtest,
    +            AnyDatabase::Memory(MemoryDatabase::new()),
             )
    -        .unwrap();
    +        .unwrap();
     
    -        let tx_meta = testutils! {
    -                @tx ( (@external descriptors, 0) => 50_000 )
    +        let tx_meta = testutils! {
    +                @tx ( (@external descriptors, 0) => 50_000 )
             };
     
    -        // Add the transaction to our db, but do not sync the db. Unsynced db
    -        // should trigger the default sequence value for a new transaction as 0xFFFFFFFF
    -        crate::populate_test_db!(wallet.database.borrow_mut(), tx_meta, None);
    -
    -        let external_policy = wallet.policies(KeychainKind::External).unwrap().unwrap();
    -        let root_id = external_policy.id;
    -        // child #0 is just the key "A"
    -        let path = vec![(root_id, vec![0])].into_iter().collect();
    -
    -        let addr = Address::from_str("2N1Ffz3WaNzbeLFBb51xyFMHYSEUXcbiSoX").unwrap();
    -        let mut builder = wallet.build_tx();
    -        builder
    -            .add_recipient(addr.script_pubkey(), 30_000)
    -            .policy_path(path, KeychainKind::External);
    -        let (psbt, _) = builder.finish().unwrap();
    -
    -        assert_eq!(psbt.unsigned_tx.input[0].sequence, Sequence(0xFFFFFFFF));
    -    }
    -
    -    #[test]
    -    fn test_create_tx_policy_path_use_csv() {
    -        let (wallet, _, _) = get_funded_wallet(get_test_a_or_b_plus_csv());
    -
    -        let external_policy = wallet.policies(KeychainKind::External).unwrap().unwrap();
    -        let root_id = external_policy.id;
    -        // child #1 is or(pk(B),older(144))
    -        let path = vec![(root_id, vec![1])].into_iter().collect();
    -
    -        let addr = Address::from_str("2N1Ffz3WaNzbeLFBb51xyFMHYSEUXcbiSoX").unwrap();
    -        let mut builder = wallet.build_tx();
    -        builder
    -            .add_recipient(addr.script_pubkey(), 30_000)
    -            .policy_path(path, KeychainKind::External);
    -        let (psbt, _) = builder.finish().unwrap();
    -
    -        assert_eq!(psbt.unsigned_tx.input[0].sequence, Sequence(144));
    -    }
    -
    -    #[test]
    -    fn test_create_tx_global_xpubs_with_origin() {
    -        use bitcoin::hashes::hex::FromHex;
    -        use bitcoin::util::bip32;
    -
    -        let (wallet, _, _) = get_funded_wallet("wpkh([73756c7f/48'/0'/0'/2']tpubDCKxNyM3bLgbEX13Mcd8mYxbVg9ajDkWXMh29hMWBurKfVmBfWAM96QVP3zaUcN51HvkZ3ar4VwP82kC8JZhhux8vFQoJintSpVBwpFvyU3/0/*)");
    -        let addr = wallet.get_address(New).unwrap();
    -        let mut builder = wallet.build_tx();
    -        builder
    -            .add_recipient(addr.script_pubkey(), 25_000)
    -            .add_global_xpubs();
    -        let (psbt, _) = builder.finish().unwrap();
    -
    -        let key = bip32::ExtendedPubKey::from_str("tpubDCKxNyM3bLgbEX13Mcd8mYxbVg9ajDkWXMh29hMWBurKfVmBfWAM96QVP3zaUcN51HvkZ3ar4VwP82kC8JZhhux8vFQoJintSpVBwpFvyU3").unwrap();
    -        let fingerprint = bip32::Fingerprint::from_hex("73756c7f").unwrap();
    -        let path = bip32::DerivationPath::from_str("m/48'/0'/0'/2'").unwrap();
    -
    -        assert_eq!(psbt.xpub.len(), 1);
    -        assert_eq!(psbt.xpub.get(&key), Some(&(fingerprint, path)));
    -    }
    -
    -    #[test]
    -    fn test_add_foreign_utxo() {
    -        let (wallet1, _, _) = get_funded_wallet(get_test_wpkh());
    -        let (wallet2, _, _) =
    -            get_funded_wallet("wpkh(cVbZ8ovhye9AoAHFsqobCf7LxbXDAECy9Kb8TZdfsDYMZGBUyCnm)");
    -
    -        let addr = Address::from_str("2N1Ffz3WaNzbeLFBb51xyFMHYSEUXcbiSoX").unwrap();
    -        let utxo = wallet2.list_unspent().unwrap().remove(0);
    -        let foreign_utxo_satisfaction = wallet2
    -            .get_descriptor_for_keychain(KeychainKind::External)
    -            .max_satisfaction_weight()
    -            .unwrap();
    -
    -        let psbt_input = psbt::Input {
    -            witness_utxo: Some(utxo.txout.clone()),
    -            ..Default::default()
    +        // Add the transaction to our db, but do not sync the db. Unsynced db
    +        // should trigger the default sequence value for a new transaction as 0xFFFFFFFF
    +        crate::populate_test_db!(wallet.database.borrow_mut(), tx_meta, None);
    +
    +        let external_policy = wallet.policies(KeychainKind::External).unwrap().unwrap();
    +        let root_id = external_policy.id;
    +        // child #0 is just the key "A"
    +        let path = vec![(root_id, vec![0])].into_iter().collect();
    +
    +        let addr = Address::from_str("2N1Ffz3WaNzbeLFBb51xyFMHYSEUXcbiSoX").unwrap();
    +        let mut builder = wallet.build_tx();
    +        builder
    +            .add_recipient(addr.script_pubkey(), 30_000)
    +            .policy_path(path, KeychainKind::External);
    +        let (psbt, _) = builder.finish().unwrap();
    +
    +        assert_eq!(psbt.unsigned_tx.input[0].sequence, Sequence(0xFFFFFFFF));
    +    }
    +
    +    #[test]
    +    fn test_create_tx_policy_path_use_csv() {
    +        let (wallet, _, _) = get_funded_wallet(get_test_a_or_b_plus_csv());
    +
    +        let external_policy = wallet.policies(KeychainKind::External).unwrap().unwrap();
    +        let root_id = external_policy.id;
    +        // child #1 is or(pk(B),older(144))
    +        let path = vec![(root_id, vec![1])].into_iter().collect();
    +
    +        let addr = Address::from_str("2N1Ffz3WaNzbeLFBb51xyFMHYSEUXcbiSoX").unwrap();
    +        let mut builder = wallet.build_tx();
    +        builder
    +            .add_recipient(addr.script_pubkey(), 30_000)
    +            .policy_path(path, KeychainKind::External);
    +        let (psbt, _) = builder.finish().unwrap();
    +
    +        assert_eq!(psbt.unsigned_tx.input[0].sequence, Sequence(144));
    +    }
    +
    +    #[test]
    +    fn test_create_tx_global_xpubs_with_origin() {
    +        use bitcoin::hashes::hex::FromHex;
    +        use bitcoin::util::bip32;
    +
    +        let (wallet, _, _) = get_funded_wallet("wpkh([73756c7f/48'/0'/0'/2']tpubDCKxNyM3bLgbEX13Mcd8mYxbVg9ajDkWXMh29hMWBurKfVmBfWAM96QVP3zaUcN51HvkZ3ar4VwP82kC8JZhhux8vFQoJintSpVBwpFvyU3/0/*)");
    +        let addr = wallet.get_address(New).unwrap();
    +        let mut builder = wallet.build_tx();
    +        builder
    +            .add_recipient(addr.script_pubkey(), 25_000)
    +            .add_global_xpubs();
    +        let (psbt, _) = builder.finish().unwrap();
    +
    +        let key = bip32::ExtendedPubKey::from_str("tpubDCKxNyM3bLgbEX13Mcd8mYxbVg9ajDkWXMh29hMWBurKfVmBfWAM96QVP3zaUcN51HvkZ3ar4VwP82kC8JZhhux8vFQoJintSpVBwpFvyU3").unwrap();
    +        let fingerprint = bip32::Fingerprint::from_hex("73756c7f").unwrap();
    +        let path = bip32::DerivationPath::from_str("m/48'/0'/0'/2'").unwrap();
    +
    +        assert_eq!(psbt.xpub.len(), 1);
    +        assert_eq!(psbt.xpub.get(&key), Some(&(fingerprint, path)));
    +    }
    +
    +    #[test]
    +    fn test_add_foreign_utxo() {
    +        let (wallet1, _, _) = get_funded_wallet(get_test_wpkh());
    +        let (wallet2, _, _) =
    +            get_funded_wallet("wpkh(cVbZ8ovhye9AoAHFsqobCf7LxbXDAECy9Kb8TZdfsDYMZGBUyCnm)");
    +
    +        let addr = Address::from_str("2N1Ffz3WaNzbeLFBb51xyFMHYSEUXcbiSoX").unwrap();
    +        let utxo = wallet2.list_unspent().unwrap().remove(0);
    +        let foreign_utxo_satisfaction = wallet2
    +            .get_descriptor_for_keychain(KeychainKind::External)
    +            .max_satisfaction_weight()
    +            .unwrap();
    +
    +        let psbt_input = psbt::Input {
    +            witness_utxo: Some(utxo.txout.clone()),
    +            ..Default::default()
             };
     
    -        let mut builder = wallet1.build_tx();
    -        builder
    -            .add_recipient(addr.script_pubkey(), 60_000)
    -            .only_witness_utxo()
    -            .add_foreign_utxo(utxo.outpoint, psbt_input, foreign_utxo_satisfaction)
    -            .unwrap();
    -        let (mut psbt, details) = builder.finish().unwrap();
    +        let mut builder = wallet1.build_tx();
    +        builder
    +            .add_recipient(addr.script_pubkey(), 60_000)
    +            .only_witness_utxo()
    +            .add_foreign_utxo(utxo.outpoint, psbt_input, foreign_utxo_satisfaction)
    +            .unwrap();
    +        let (mut psbt, details) = builder.finish().unwrap();
     
             assert_eq!(
    -            details.sent - details.received,
    -            10_000 + details.fee.unwrap_or(0),
    -            "we should have only net spent ~10_000"
    -        );
    +            details.sent - details.received,
    +            10_000 + details.fee.unwrap_or(0),
    +            "we should have only net spent ~10_000"
    +        );
     
             assert!(
    -            psbt.unsigned_tx
    -                .input
    -                .iter()
    -                .any(|input| input.previous_output == utxo.outpoint),
    -            "foreign_utxo should be in there"
    -        );
    -
    -        let finished = wallet1
    -            .sign(
    -                &mut psbt,
    -                SignOptions {
    -                    trust_witness_utxo: true,
    -                    ..Default::default()
    +            psbt.unsigned_tx
    +                .input
    +                .iter()
    +                .any(|input| input.previous_output == utxo.outpoint),
    +            "foreign_utxo should be in there"
    +        );
    +
    +        let finished = wallet1
    +            .sign(
    +                &mut psbt,
    +                SignOptions {
    +                    trust_witness_utxo: true,
    +                    ..Default::default()
                     },
                 )
    -            .unwrap();
    +            .unwrap();
     
             assert!(
    -            !finished,
    -            "only one of the inputs should have been signed so far"
    -        );
    -
    -        let finished = wallet2
    -            .sign(
    -                &mut psbt,
    -                SignOptions {
    -                    trust_witness_utxo: true,
    -                    ..Default::default()
    +            !finished,
    +            "only one of the inputs should have been signed so far"
    +        );
    +
    +        let finished = wallet2
    +            .sign(
    +                &mut psbt,
    +                SignOptions {
    +                    trust_witness_utxo: true,
    +                    ..Default::default()
                     },
                 )
    -            .unwrap();
    -        assert!(finished, "all the inputs should have been signed now");
    -    }
    -
    -    #[test]
    -    #[should_panic(expected = "Generic(\"Foreign utxo missing witness_utxo or non_witness_utxo\")")]
    -    fn test_add_foreign_utxo_invalid_psbt_input() {
    -        let (wallet, _, _) = get_funded_wallet(get_test_wpkh());
    -        let mut builder = wallet.build_tx();
    -        let outpoint = wallet.list_unspent().unwrap()[0].outpoint;
    -        let foreign_utxo_satisfaction = wallet
    -            .get_descriptor_for_keychain(KeychainKind::External)
    -            .max_satisfaction_weight()
    -            .unwrap();
    -        builder
    -            .add_foreign_utxo(outpoint, psbt::Input::default(), foreign_utxo_satisfaction)
    -            .unwrap();
    -    }
    -
    -    #[test]
    -    fn test_add_foreign_utxo_where_outpoint_doesnt_match_psbt_input() {
    -        let (wallet1, _, txid1) = get_funded_wallet(get_test_wpkh());
    -        let (wallet2, _, txid2) =
    -            get_funded_wallet("wpkh(cVbZ8ovhye9AoAHFsqobCf7LxbXDAECy9Kb8TZdfsDYMZGBUyCnm)");
    -
    -        let utxo2 = wallet2.list_unspent().unwrap().remove(0);
    -        let tx1 = wallet1
    -            .database
    -            .borrow()
    -            .get_tx(&txid1, true)
    -            .unwrap()
    -            .unwrap()
    -            .transaction
    -            .unwrap();
    -        let tx2 = wallet2
    -            .database
    -            .borrow()
    -            .get_tx(&txid2, true)
    -            .unwrap()
    -            .unwrap()
    -            .transaction
    -            .unwrap();
    -
    -        let satisfaction_weight = wallet2
    -            .get_descriptor_for_keychain(KeychainKind::External)
    -            .max_satisfaction_weight()
    -            .unwrap();
    -
    -        let mut builder = wallet1.build_tx();
    +            .unwrap();
    +        assert!(finished, "all the inputs should have been signed now");
    +    }
    +
    +    #[test]
    +    #[should_panic(expected = "Generic(\"Foreign utxo missing witness_utxo or non_witness_utxo\")")]
    +    fn test_add_foreign_utxo_invalid_psbt_input() {
    +        let (wallet, _, _) = get_funded_wallet(get_test_wpkh());
    +        let mut builder = wallet.build_tx();
    +        let outpoint = wallet.list_unspent().unwrap()[0].outpoint;
    +        let foreign_utxo_satisfaction = wallet
    +            .get_descriptor_for_keychain(KeychainKind::External)
    +            .max_satisfaction_weight()
    +            .unwrap();
    +        builder
    +            .add_foreign_utxo(outpoint, psbt::Input::default(), foreign_utxo_satisfaction)
    +            .unwrap();
    +    }
    +
    +    #[test]
    +    fn test_add_foreign_utxo_where_outpoint_doesnt_match_psbt_input() {
    +        let (wallet1, _, txid1) = get_funded_wallet(get_test_wpkh());
    +        let (wallet2, _, txid2) =
    +            get_funded_wallet("wpkh(cVbZ8ovhye9AoAHFsqobCf7LxbXDAECy9Kb8TZdfsDYMZGBUyCnm)");
    +
    +        let utxo2 = wallet2.list_unspent().unwrap().remove(0);
    +        let tx1 = wallet1
    +            .database
    +            .borrow()
    +            .get_tx(&txid1, true)
    +            .unwrap()
    +            .unwrap()
    +            .transaction
    +            .unwrap();
    +        let tx2 = wallet2
    +            .database
    +            .borrow()
    +            .get_tx(&txid2, true)
    +            .unwrap()
    +            .unwrap()
    +            .transaction
    +            .unwrap();
    +
    +        let satisfaction_weight = wallet2
    +            .get_descriptor_for_keychain(KeychainKind::External)
    +            .max_satisfaction_weight()
    +            .unwrap();
    +
    +        let mut builder = wallet1.build_tx();
             assert!(
    -            builder
    -                .add_foreign_utxo(
    -                    utxo2.outpoint,
    -                    psbt::Input {
    -                        non_witness_utxo: Some(tx1),
    -                        ..Default::default()
    +            builder
    +                .add_foreign_utxo(
    +                    utxo2.outpoint,
    +                    psbt::Input {
    +                        non_witness_utxo: Some(tx1),
    +                        ..Default::default()
                         },
    -                    satisfaction_weight
    +                    satisfaction_weight
                     )
    -                .is_err(),
    -            "should fail when outpoint doesn't match psbt_input"
    -        );
    +                .is_err(),
    +            "should fail when outpoint doesn't match psbt_input"
    +        );
             assert!(
    -            builder
    -                .add_foreign_utxo(
    -                    utxo2.outpoint,
    -                    psbt::Input {
    -                        non_witness_utxo: Some(tx2),
    -                        ..Default::default()
    +            builder
    +                .add_foreign_utxo(
    +                    utxo2.outpoint,
    +                    psbt::Input {
    +                        non_witness_utxo: Some(tx2),
    +                        ..Default::default()
                         },
    -                    satisfaction_weight
    +                    satisfaction_weight
                     )
    -                .is_ok(),
    -            "shoulld be ok when outpoint does match psbt_input"
    -        );
    +                .is_ok(),
    +            "shoulld be ok when outpoint does match psbt_input"
    +        );
         }
     
    -    #[test]
    -    fn test_add_foreign_utxo_only_witness_utxo() {
    -        let (wallet1, _, _) = get_funded_wallet(get_test_wpkh());
    -        let (wallet2, _, txid2) =
    -            get_funded_wallet("wpkh(cVbZ8ovhye9AoAHFsqobCf7LxbXDAECy9Kb8TZdfsDYMZGBUyCnm)");
    -        let addr = Address::from_str("2N1Ffz3WaNzbeLFBb51xyFMHYSEUXcbiSoX").unwrap();
    -        let utxo2 = wallet2.list_unspent().unwrap().remove(0);
    +    #[test]
    +    fn test_add_foreign_utxo_only_witness_utxo() {
    +        let (wallet1, _, _) = get_funded_wallet(get_test_wpkh());
    +        let (wallet2, _, txid2) =
    +            get_funded_wallet("wpkh(cVbZ8ovhye9AoAHFsqobCf7LxbXDAECy9Kb8TZdfsDYMZGBUyCnm)");
    +        let addr = Address::from_str("2N1Ffz3WaNzbeLFBb51xyFMHYSEUXcbiSoX").unwrap();
    +        let utxo2 = wallet2.list_unspent().unwrap().remove(0);
     
    -        let satisfaction_weight = wallet2
    -            .get_descriptor_for_keychain(KeychainKind::External)
    -            .max_satisfaction_weight()
    -            .unwrap();
    +        let satisfaction_weight = wallet2
    +            .get_descriptor_for_keychain(KeychainKind::External)
    +            .max_satisfaction_weight()
    +            .unwrap();
     
    -        let mut builder = wallet1.build_tx();
    -        builder.add_recipient(addr.script_pubkey(), 60_000);
    +        let mut builder = wallet1.build_tx();
    +        builder.add_recipient(addr.script_pubkey(), 60_000);
     
             {
    -            let mut builder = builder.clone();
    -            let psbt_input = psbt::Input {
    -                witness_utxo: Some(utxo2.txout.clone()),
    -                ..Default::default()
    +            let mut builder = builder.clone();
    +            let psbt_input = psbt::Input {
    +                witness_utxo: Some(utxo2.txout.clone()),
    +                ..Default::default()
                 };
    -            builder
    -                .add_foreign_utxo(utxo2.outpoint, psbt_input, satisfaction_weight)
    -                .unwrap();
    +            builder
    +                .add_foreign_utxo(utxo2.outpoint, psbt_input, satisfaction_weight)
    +                .unwrap();
                 assert!(
    -                builder.finish().is_err(),
    -                "psbt_input with witness_utxo should fail with only witness_utxo"
    -            );
    +                builder.finish().is_err(),
    +                "psbt_input with witness_utxo should fail with only witness_utxo"
    +            );
             }
     
             {
    -            let mut builder = builder.clone();
    -            let psbt_input = psbt::Input {
    -                witness_utxo: Some(utxo2.txout.clone()),
    -                ..Default::default()
    +            let mut builder = builder.clone();
    +            let psbt_input = psbt::Input {
    +                witness_utxo: Some(utxo2.txout.clone()),
    +                ..Default::default()
                 };
    -            builder
    -                .only_witness_utxo()
    -                .add_foreign_utxo(utxo2.outpoint, psbt_input, satisfaction_weight)
    -                .unwrap();
    +            builder
    +                .only_witness_utxo()
    +                .add_foreign_utxo(utxo2.outpoint, psbt_input, satisfaction_weight)
    +                .unwrap();
                 assert!(
    -                builder.finish().is_ok(),
    -                "psbt_input with just witness_utxo should succeed when `only_witness_utxo` is enabled"
    -            );
    +                builder.finish().is_ok(),
    +                "psbt_input with just witness_utxo should succeed when `only_witness_utxo` is enabled"
    +            );
             }
     
             {
    -            let mut builder = builder.clone();
    -            let tx2 = wallet2
    -                .database
    -                .borrow()
    -                .get_tx(&txid2, true)
    -                .unwrap()
    -                .unwrap()
    -                .transaction
    -                .unwrap();
    -            let psbt_input = psbt::Input {
    -                non_witness_utxo: Some(tx2),
    -                ..Default::default()
    +            let mut builder = builder.clone();
    +            let tx2 = wallet2
    +                .database
    +                .borrow()
    +                .get_tx(&txid2, true)
    +                .unwrap()
    +                .unwrap()
    +                .transaction
    +                .unwrap();
    +            let psbt_input = psbt::Input {
    +                non_witness_utxo: Some(tx2),
    +                ..Default::default()
                 };
    -            builder
    -                .add_foreign_utxo(utxo2.outpoint, psbt_input, satisfaction_weight)
    -                .unwrap();
    +            builder
    +                .add_foreign_utxo(utxo2.outpoint, psbt_input, satisfaction_weight)
    +                .unwrap();
                 assert!(
    -                builder.finish().is_ok(),
    -                "psbt_input with non_witness_utxo should succeed by default"
    -            );
    +                builder.finish().is_ok(),
    +                "psbt_input with non_witness_utxo should succeed by default"
    +            );
             }
         }
     
    -    #[test]
    -    fn test_get_psbt_input() {
    -        // this should grab a known good utxo and set the input
    -        let (wallet, _, _) = get_funded_wallet(get_test_wpkh());
    -        for utxo in wallet.list_unspent().unwrap() {
    -            let psbt_input = wallet.get_psbt_input(utxo, None, false).unwrap();
    -            assert!(psbt_input.witness_utxo.is_some() || psbt_input.non_witness_utxo.is_some());
    +    #[test]
    +    fn test_get_psbt_input() {
    +        // this should grab a known good utxo and set the input
    +        let (wallet, _, _) = get_funded_wallet(get_test_wpkh());
    +        for utxo in wallet.list_unspent().unwrap() {
    +            let psbt_input = wallet.get_psbt_input(utxo, None, false).unwrap();
    +            assert!(psbt_input.witness_utxo.is_some() || psbt_input.non_witness_utxo.is_some());
             }
         }
     
    -    #[test]
    -    #[should_panic(
    -        expected = "MissingKeyOrigin(\"tpubDCKxNyM3bLgbEX13Mcd8mYxbVg9ajDkWXMh29hMWBurKfVmBfWAM96QVP3zaUcN51HvkZ3ar4VwP82kC8JZhhux8vFQoJintSpVBwpFvyU3\")"
    -    )]
    -    fn test_create_tx_global_xpubs_origin_missing() {
    -        let (wallet, _, _) = get_funded_wallet("wpkh(tpubDCKxNyM3bLgbEX13Mcd8mYxbVg9ajDkWXMh29hMWBurKfVmBfWAM96QVP3zaUcN51HvkZ3ar4VwP82kC8JZhhux8vFQoJintSpVBwpFvyU3/0/*)");
    -        let addr = wallet.get_address(New).unwrap();
    -        let mut builder = wallet.build_tx();
    -        builder
    -            .add_recipient(addr.script_pubkey(), 25_000)
    -            .add_global_xpubs();
    -        builder.finish().unwrap();
    -    }
    -
    -    #[test]
    -    fn test_create_tx_global_xpubs_master_without_origin() {
    -        use bitcoin::hashes::hex::FromHex;
    -        use bitcoin::util::bip32;
    -
    -        let (wallet, _, _) = get_funded_wallet("wpkh(tpubD6NzVbkrYhZ4Y55A58Gv9RSNF5hy84b5AJqYy7sCcjFrkcLpPre8kmgfit6kY1Zs3BLgeypTDBZJM222guPpdz7Cup5yzaMu62u7mYGbwFL/0/*)");
    -        let addr = wallet.get_address(New).unwrap();
    -        let mut builder = wallet.build_tx();
    -        builder
    -            .add_recipient(addr.script_pubkey(), 25_000)
    -            .add_global_xpubs();
    -        let (psbt, _) = builder.finish().unwrap();
    -
    -        let key = bip32::ExtendedPubKey::from_str("tpubD6NzVbkrYhZ4Y55A58Gv9RSNF5hy84b5AJqYy7sCcjFrkcLpPre8kmgfit6kY1Zs3BLgeypTDBZJM222guPpdz7Cup5yzaMu62u7mYGbwFL").unwrap();
    -        let fingerprint = bip32::Fingerprint::from_hex("997a323b").unwrap();
    -
    -        assert_eq!(psbt.xpub.len(), 1);
    +    #[test]
    +    #[should_panic(
    +        expected = "MissingKeyOrigin(\"tpubDCKxNyM3bLgbEX13Mcd8mYxbVg9ajDkWXMh29hMWBurKfVmBfWAM96QVP3zaUcN51HvkZ3ar4VwP82kC8JZhhux8vFQoJintSpVBwpFvyU3\")"
    +    )]
    +    fn test_create_tx_global_xpubs_origin_missing() {
    +        let (wallet, _, _) = get_funded_wallet("wpkh(tpubDCKxNyM3bLgbEX13Mcd8mYxbVg9ajDkWXMh29hMWBurKfVmBfWAM96QVP3zaUcN51HvkZ3ar4VwP82kC8JZhhux8vFQoJintSpVBwpFvyU3/0/*)");
    +        let addr = wallet.get_address(New).unwrap();
    +        let mut builder = wallet.build_tx();
    +        builder
    +            .add_recipient(addr.script_pubkey(), 25_000)
    +            .add_global_xpubs();
    +        builder.finish().unwrap();
    +    }
    +
    +    #[test]
    +    fn test_create_tx_global_xpubs_master_without_origin() {
    +        use bitcoin::hashes::hex::FromHex;
    +        use bitcoin::util::bip32;
    +
    +        let (wallet, _, _) = get_funded_wallet("wpkh(tpubD6NzVbkrYhZ4Y55A58Gv9RSNF5hy84b5AJqYy7sCcjFrkcLpPre8kmgfit6kY1Zs3BLgeypTDBZJM222guPpdz7Cup5yzaMu62u7mYGbwFL/0/*)");
    +        let addr = wallet.get_address(New).unwrap();
    +        let mut builder = wallet.build_tx();
    +        builder
    +            .add_recipient(addr.script_pubkey(), 25_000)
    +            .add_global_xpubs();
    +        let (psbt, _) = builder.finish().unwrap();
    +
    +        let key = bip32::ExtendedPubKey::from_str("tpubD6NzVbkrYhZ4Y55A58Gv9RSNF5hy84b5AJqYy7sCcjFrkcLpPre8kmgfit6kY1Zs3BLgeypTDBZJM222guPpdz7Cup5yzaMu62u7mYGbwFL").unwrap();
    +        let fingerprint = bip32::Fingerprint::from_hex("997a323b").unwrap();
    +
    +        assert_eq!(psbt.xpub.len(), 1);
             assert_eq!(
    -            psbt.xpub.get(&key),
    -            Some(&(fingerprint, bip32::DerivationPath::default()))
    -        );
    -    }
    -
    -    #[test]
    -    #[should_panic(expected = "IrreplaceableTransaction")]
    -    fn test_bump_fee_irreplaceable_tx() {
    -        let (wallet, _, _) = get_funded_wallet(get_test_wpkh());
    -        let addr = wallet.get_address(New).unwrap();
    -        let mut builder = wallet.build_tx();
    -        builder.add_recipient(addr.script_pubkey(), 25_000);
    -        let (psbt, mut details) = builder.finish().unwrap();
    -
    -        let tx = psbt.extract_tx();
    -        let txid = tx.txid();
    -        // skip saving the utxos, we know they can't be used anyways
    -        details.transaction = Some(tx);
    -        wallet.database.borrow_mut().set_tx(&details).unwrap();
    -
    -        wallet.build_fee_bump(txid).unwrap().finish().unwrap();
    -    }
    -
    -    #[test]
    -    #[should_panic(expected = "TransactionConfirmed")]
    -    fn test_bump_fee_confirmed_tx() {
    -        let (wallet, _, _) = get_funded_wallet(get_test_wpkh());
    -        let addr = wallet.get_address(New).unwrap();
    -        let mut builder = wallet.build_tx();
    -        builder.add_recipient(addr.script_pubkey(), 25_000);
    -        let (psbt, mut details) = builder.finish().unwrap();
    -
    -        let tx = psbt.extract_tx();
    -        let txid = tx.txid();
    -        // skip saving the utxos, we know they can't be used anyways
    -        details.transaction = Some(tx);
    -        details.confirmation_time = Some(BlockTime {
    -            timestamp: 12345678,
    -            height: 42,
    +            psbt.xpub.get(&key),
    +            Some(&(fingerprint, bip32::DerivationPath::default()))
    +        );
    +    }
    +
    +    #[test]
    +    #[should_panic(expected = "IrreplaceableTransaction")]
    +    fn test_bump_fee_irreplaceable_tx() {
    +        let (wallet, _, _) = get_funded_wallet(get_test_wpkh());
    +        let addr = wallet.get_address(New).unwrap();
    +        let mut builder = wallet.build_tx();
    +        builder.add_recipient(addr.script_pubkey(), 25_000);
    +        let (psbt, mut details) = builder.finish().unwrap();
    +
    +        let tx = psbt.extract_tx();
    +        let txid = tx.txid();
    +        // skip saving the utxos, we know they can't be used anyways
    +        details.transaction = Some(tx);
    +        wallet.database.borrow_mut().set_tx(&details).unwrap();
    +
    +        wallet.build_fee_bump(txid).unwrap().finish().unwrap();
    +    }
    +
    +    #[test]
    +    #[should_panic(expected = "TransactionConfirmed")]
    +    fn test_bump_fee_confirmed_tx() {
    +        let (wallet, _, _) = get_funded_wallet(get_test_wpkh());
    +        let addr = wallet.get_address(New).unwrap();
    +        let mut builder = wallet.build_tx();
    +        builder.add_recipient(addr.script_pubkey(), 25_000);
    +        let (psbt, mut details) = builder.finish().unwrap();
    +
    +        let tx = psbt.extract_tx();
    +        let txid = tx.txid();
    +        // skip saving the utxos, we know they can't be used anyways
    +        details.transaction = Some(tx);
    +        details.confirmation_time = Some(BlockTime {
    +            timestamp: 12345678,
    +            height: 42,
             });
    -        wallet.database.borrow_mut().set_tx(&details).unwrap();
    -
    -        wallet.build_fee_bump(txid).unwrap().finish().unwrap();
    -    }
    -
    -    #[test]
    -    #[should_panic(expected = "FeeRateTooLow")]
    -    fn test_bump_fee_low_fee_rate() {
    -        let (wallet, _, _) = get_funded_wallet(get_test_wpkh());
    -        let addr = wallet.get_address(New).unwrap();
    -        let mut builder = wallet.build_tx();
    -        builder
    -            .add_recipient(addr.script_pubkey(), 25_000)
    -            .enable_rbf();
    -        let (psbt, mut details) = builder.finish().unwrap();
    -
    -        let tx = psbt.extract_tx();
    -        let txid = tx.txid();
    -        // skip saving the utxos, we know they can't be used anyways
    -        details.transaction = Some(tx);
    -        wallet.database.borrow_mut().set_tx(&details).unwrap();
    -
    -        let mut builder = wallet.build_fee_bump(txid).unwrap();
    -        builder.fee_rate(FeeRate::from_sat_per_vb(1.0));
    -        builder.finish().unwrap();
    -    }
    -
    -    #[test]
    -    #[should_panic(expected = "FeeTooLow")]
    -    fn test_bump_fee_low_abs() {
    -        let (wallet, _, _) = get_funded_wallet(get_test_wpkh());
    -        let addr = wallet.get_address(New).unwrap();
    -        let mut builder = wallet.build_tx();
    -        builder
    -            .add_recipient(addr.script_pubkey(), 25_000)
    -            .enable_rbf();
    -        let (psbt, mut details) = builder.finish().unwrap();
    -
    -        let tx = psbt.extract_tx();
    -        let txid = tx.txid();
    -        // skip saving the utxos, we know they can't be used anyways
    -        details.transaction = Some(tx);
    -        wallet.database.borrow_mut().set_tx(&details).unwrap();
    -
    -        let mut builder = wallet.build_fee_bump(txid).unwrap();
    -        builder.fee_absolute(10);
    -        builder.finish().unwrap();
    -    }
    -
    -    #[test]
    -    #[should_panic(expected = "FeeTooLow")]
    -    fn test_bump_fee_zero_abs() {
    -        let (wallet, _, _) = get_funded_wallet(get_test_wpkh());
    -        let addr = wallet.get_address(New).unwrap();
    -        let mut builder = wallet.build_tx();
    -        builder
    -            .add_recipient(addr.script_pubkey(), 25_000)
    -            .enable_rbf();
    -        let (psbt, mut details) = builder.finish().unwrap();
    -
    -        let tx = psbt.extract_tx();
    -        let txid = tx.txid();
    -        // skip saving the utxos, we know they can't be used anyways
    -        details.transaction = Some(tx);
    -        wallet.database.borrow_mut().set_tx(&details).unwrap();
    -
    -        let mut builder = wallet.build_fee_bump(txid).unwrap();
    -        builder.fee_absolute(0);
    -        builder.finish().unwrap();
    -    }
    -
    -    #[test]
    -    fn test_bump_fee_reduce_change() {
    -        let (wallet, _, _) = get_funded_wallet(get_test_wpkh());
    -        let addr = Address::from_str("2N1Ffz3WaNzbeLFBb51xyFMHYSEUXcbiSoX").unwrap();
    -        let mut builder = wallet.build_tx();
    -        builder
    -            .add_recipient(addr.script_pubkey(), 25_000)
    -            .enable_rbf();
    -        let (psbt, mut original_details) = builder.finish().unwrap();
    -        let mut tx = psbt.extract_tx();
    -        let txid = tx.txid();
    -        // skip saving the new utxos, we know they can't be used anyways
    -        for txin in &mut tx.input {
    -            txin.witness.push([0x00; P2WPKH_FAKE_WITNESS_SIZE]); // fake signature
    -            wallet
    -                .database
    -                .borrow_mut()
    -                .del_utxo(&txin.previous_output)
    -                .unwrap();
    +        wallet.database.borrow_mut().set_tx(&details).unwrap();
    +
    +        wallet.build_fee_bump(txid).unwrap().finish().unwrap();
    +    }
    +
    +    #[test]
    +    #[should_panic(expected = "FeeRateTooLow")]
    +    fn test_bump_fee_low_fee_rate() {
    +        let (wallet, _, _) = get_funded_wallet(get_test_wpkh());
    +        let addr = wallet.get_address(New).unwrap();
    +        let mut builder = wallet.build_tx();
    +        builder
    +            .add_recipient(addr.script_pubkey(), 25_000)
    +            .enable_rbf();
    +        let (psbt, mut details) = builder.finish().unwrap();
    +
    +        let tx = psbt.extract_tx();
    +        let txid = tx.txid();
    +        // skip saving the utxos, we know they can't be used anyways
    +        details.transaction = Some(tx);
    +        wallet.database.borrow_mut().set_tx(&details).unwrap();
    +
    +        let mut builder = wallet.build_fee_bump(txid).unwrap();
    +        builder.fee_rate(FeeRate::from_sat_per_vb(1.0));
    +        builder.finish().unwrap();
    +    }
    +
    +    #[test]
    +    #[should_panic(expected = "FeeTooLow")]
    +    fn test_bump_fee_low_abs() {
    +        let (wallet, _, _) = get_funded_wallet(get_test_wpkh());
    +        let addr = wallet.get_address(New).unwrap();
    +        let mut builder = wallet.build_tx();
    +        builder
    +            .add_recipient(addr.script_pubkey(), 25_000)
    +            .enable_rbf();
    +        let (psbt, mut details) = builder.finish().unwrap();
    +
    +        let tx = psbt.extract_tx();
    +        let txid = tx.txid();
    +        // skip saving the utxos, we know they can't be used anyways
    +        details.transaction = Some(tx);
    +        wallet.database.borrow_mut().set_tx(&details).unwrap();
    +
    +        let mut builder = wallet.build_fee_bump(txid).unwrap();
    +        builder.fee_absolute(10);
    +        builder.finish().unwrap();
    +    }
    +
    +    #[test]
    +    #[should_panic(expected = "FeeTooLow")]
    +    fn test_bump_fee_zero_abs() {
    +        let (wallet, _, _) = get_funded_wallet(get_test_wpkh());
    +        let addr = wallet.get_address(New).unwrap();
    +        let mut builder = wallet.build_tx();
    +        builder
    +            .add_recipient(addr.script_pubkey(), 25_000)
    +            .enable_rbf();
    +        let (psbt, mut details) = builder.finish().unwrap();
    +
    +        let tx = psbt.extract_tx();
    +        let txid = tx.txid();
    +        // skip saving the utxos, we know they can't be used anyways
    +        details.transaction = Some(tx);
    +        wallet.database.borrow_mut().set_tx(&details).unwrap();
    +
    +        let mut builder = wallet.build_fee_bump(txid).unwrap();
    +        builder.fee_absolute(0);
    +        builder.finish().unwrap();
    +    }
    +
    +    #[test]
    +    fn test_bump_fee_reduce_change() {
    +        let (wallet, _, _) = get_funded_wallet(get_test_wpkh());
    +        let addr = Address::from_str("2N1Ffz3WaNzbeLFBb51xyFMHYSEUXcbiSoX").unwrap();
    +        let mut builder = wallet.build_tx();
    +        builder
    +            .add_recipient(addr.script_pubkey(), 25_000)
    +            .enable_rbf();
    +        let (psbt, mut original_details) = builder.finish().unwrap();
    +        let mut tx = psbt.extract_tx();
    +        let txid = tx.txid();
    +        // skip saving the new utxos, we know they can't be used anyways
    +        for txin in &mut tx.input {
    +            txin.witness.push([0x00; P2WPKH_FAKE_WITNESS_SIZE]); // fake signature
    +            wallet
    +                .database
    +                .borrow_mut()
    +                .del_utxo(&txin.previous_output)
    +                .unwrap();
             }
    -        original_details.transaction = Some(tx);
    -        wallet
    -            .database
    -            .borrow_mut()
    -            .set_tx(&original_details)
    -            .unwrap();
    -
    -        let mut builder = wallet.build_fee_bump(txid).unwrap();
    -        builder.fee_rate(FeeRate::from_sat_per_vb(2.5)).enable_rbf();
    -        let (psbt, details) = builder.finish().unwrap();
    -
    -        assert_eq!(details.sent, original_details.sent);
    +        original_details.transaction = Some(tx);
    +        wallet
    +            .database
    +            .borrow_mut()
    +            .set_tx(&original_details)
    +            .unwrap();
    +
    +        let mut builder = wallet.build_fee_bump(txid).unwrap();
    +        builder.fee_rate(FeeRate::from_sat_per_vb(2.5)).enable_rbf();
    +        let (psbt, details) = builder.finish().unwrap();
    +
    +        assert_eq!(details.sent, original_details.sent);
             assert_eq!(
    -            details.received + details.fee.unwrap_or(0),
    -            original_details.received + original_details.fee.unwrap_or(0)
    +            details.received + details.fee.unwrap_or(0),
    +            original_details.received + original_details.fee.unwrap_or(0)
             );
    -        assert!(details.fee.unwrap_or(0) > original_details.fee.unwrap_or(0));
    +        assert!(details.fee.unwrap_or(0) > original_details.fee.unwrap_or(0));
     
    -        let tx = &psbt.unsigned_tx;
    -        assert_eq!(tx.output.len(), 2);
    +        let tx = &psbt.unsigned_tx;
    +        assert_eq!(tx.output.len(), 2);
             assert_eq!(
    -            tx.output
    -                .iter()
    -                .find(|txout| txout.script_pubkey == addr.script_pubkey())
    -                .unwrap()
    -                .value,
    -            25_000
    -        );
    +            tx.output
    +                .iter()
    +                .find(|txout| txout.script_pubkey == addr.script_pubkey())
    +                .unwrap()
    +                .value,
    +            25_000
    +        );
             assert_eq!(
    -            tx.output
    -                .iter()
    -                .find(|txout| txout.script_pubkey != addr.script_pubkey())
    -                .unwrap()
    -                .value,
    -            details.received
    -        );
    -
    -        assert_fee_rate!(psbt, details.fee.unwrap_or(0), FeeRate::from_sat_per_vb(2.5), @add_signature);
    -    }
    -
    -    #[test]
    -    fn test_bump_fee_absolute_reduce_change() {
    -        let (wallet, _, _) = get_funded_wallet(get_test_wpkh());
    -        let addr = Address::from_str("2N1Ffz3WaNzbeLFBb51xyFMHYSEUXcbiSoX").unwrap();
    -        let mut builder = wallet.build_tx();
    -        builder
    -            .add_recipient(addr.script_pubkey(), 25_000)
    -            .enable_rbf();
    -        let (psbt, mut original_details) = builder.finish().unwrap();
    -        let mut tx = psbt.extract_tx();
    -        let txid = tx.txid();
    -        // skip saving the new utxos, we know they can't be used anyways
    -        for txin in &mut tx.input {
    -            txin.witness.push([0x00; P2WPKH_FAKE_WITNESS_SIZE]); // fake signature
    -            wallet
    -                .database
    -                .borrow_mut()
    -                .del_utxo(&txin.previous_output)
    -                .unwrap();
    +            tx.output
    +                .iter()
    +                .find(|txout| txout.script_pubkey != addr.script_pubkey())
    +                .unwrap()
    +                .value,
    +            details.received
    +        );
    +
    +        assert_fee_rate!(psbt, details.fee.unwrap_or(0), FeeRate::from_sat_per_vb(2.5), @add_signature);
    +    }
    +
    +    #[test]
    +    fn test_bump_fee_absolute_reduce_change() {
    +        let (wallet, _, _) = get_funded_wallet(get_test_wpkh());
    +        let addr = Address::from_str("2N1Ffz3WaNzbeLFBb51xyFMHYSEUXcbiSoX").unwrap();
    +        let mut builder = wallet.build_tx();
    +        builder
    +            .add_recipient(addr.script_pubkey(), 25_000)
    +            .enable_rbf();
    +        let (psbt, mut original_details) = builder.finish().unwrap();
    +        let mut tx = psbt.extract_tx();
    +        let txid = tx.txid();
    +        // skip saving the new utxos, we know they can't be used anyways
    +        for txin in &mut tx.input {
    +            txin.witness.push([0x00; P2WPKH_FAKE_WITNESS_SIZE]); // fake signature
    +            wallet
    +                .database
    +                .borrow_mut()
    +                .del_utxo(&txin.previous_output)
    +                .unwrap();
             }
    -        original_details.transaction = Some(tx);
    -        wallet
    -            .database
    -            .borrow_mut()
    -            .set_tx(&original_details)
    -            .unwrap();
    -
    -        let mut builder = wallet.build_fee_bump(txid).unwrap();
    -        builder.fee_absolute(200);
    -        builder.enable_rbf();
    -        let (psbt, details) = builder.finish().unwrap();
    -
    -        assert_eq!(details.sent, original_details.sent);
    +        original_details.transaction = Some(tx);
    +        wallet
    +            .database
    +            .borrow_mut()
    +            .set_tx(&original_details)
    +            .unwrap();
    +
    +        let mut builder = wallet.build_fee_bump(txid).unwrap();
    +        builder.fee_absolute(200);
    +        builder.enable_rbf();
    +        let (psbt, details) = builder.finish().unwrap();
    +
    +        assert_eq!(details.sent, original_details.sent);
             assert_eq!(
    -            details.received + details.fee.unwrap_or(0),
    -            original_details.received + original_details.fee.unwrap_or(0)
    +            details.received + details.fee.unwrap_or(0),
    +            original_details.received + original_details.fee.unwrap_or(0)
             );
             assert!(
    -            details.fee.unwrap_or(0) > original_details.fee.unwrap_or(0),
    +            details.fee.unwrap_or(0) > original_details.fee.unwrap_or(0),
                 "{} > {}",
    -            details.fee.unwrap_or(0),
    -            original_details.fee.unwrap_or(0)
    +            details.fee.unwrap_or(0),
    +            original_details.fee.unwrap_or(0)
             );
     
    -        let tx = &psbt.unsigned_tx;
    -        assert_eq!(tx.output.len(), 2);
    +        let tx = &psbt.unsigned_tx;
    +        assert_eq!(tx.output.len(), 2);
             assert_eq!(
    -            tx.output
    -                .iter()
    -                .find(|txout| txout.script_pubkey == addr.script_pubkey())
    -                .unwrap()
    -                .value,
    -            25_000
    -        );
    +            tx.output
    +                .iter()
    +                .find(|txout| txout.script_pubkey == addr.script_pubkey())
    +                .unwrap()
    +                .value,
    +            25_000
    +        );
             assert_eq!(
    -            tx.output
    -                .iter()
    -                .find(|txout| txout.script_pubkey != addr.script_pubkey())
    -                .unwrap()
    -                .value,
    -            details.received
    -        );
    -
    -        assert_eq!(details.fee.unwrap_or(0), 200);
    -    }
    -
    -    #[test]
    -    fn test_bump_fee_reduce_single_recipient() {
    -        let (wallet, _, _) = get_funded_wallet(get_test_wpkh());
    -        let addr = Address::from_str("2N1Ffz3WaNzbeLFBb51xyFMHYSEUXcbiSoX").unwrap();
    -        let mut builder = wallet.build_tx();
    -        builder
    -            .drain_to(addr.script_pubkey())
    -            .drain_wallet()
    -            .enable_rbf();
    -        let (psbt, mut original_details) = builder.finish().unwrap();
    -        let mut tx = psbt.extract_tx();
    -        let txid = tx.txid();
    -        for txin in &mut tx.input {
    -            txin.witness.push([0x00; P2WPKH_FAKE_WITNESS_SIZE]); // fake signature
    -            wallet
    -                .database
    -                .borrow_mut()
    -                .del_utxo(&txin.previous_output)
    -                .unwrap();
    +            tx.output
    +                .iter()
    +                .find(|txout| txout.script_pubkey != addr.script_pubkey())
    +                .unwrap()
    +                .value,
    +            details.received
    +        );
    +
    +        assert_eq!(details.fee.unwrap_or(0), 200);
    +    }
    +
    +    #[test]
    +    fn test_bump_fee_reduce_single_recipient() {
    +        let (wallet, _, _) = get_funded_wallet(get_test_wpkh());
    +        let addr = Address::from_str("2N1Ffz3WaNzbeLFBb51xyFMHYSEUXcbiSoX").unwrap();
    +        let mut builder = wallet.build_tx();
    +        builder
    +            .drain_to(addr.script_pubkey())
    +            .drain_wallet()
    +            .enable_rbf();
    +        let (psbt, mut original_details) = builder.finish().unwrap();
    +        let mut tx = psbt.extract_tx();
    +        let txid = tx.txid();
    +        for txin in &mut tx.input {
    +            txin.witness.push([0x00; P2WPKH_FAKE_WITNESS_SIZE]); // fake signature
    +            wallet
    +                .database
    +                .borrow_mut()
    +                .del_utxo(&txin.previous_output)
    +                .unwrap();
             }
    -        original_details.transaction = Some(tx);
    -        wallet
    -            .database
    -            .borrow_mut()
    -            .set_tx(&original_details)
    -            .unwrap();
    -
    -        let mut builder = wallet.build_fee_bump(txid).unwrap();
    -        builder
    -            .fee_rate(FeeRate::from_sat_per_vb(2.5))
    -            .allow_shrinking(addr.script_pubkey())
    -            .unwrap();
    -        let (psbt, details) = builder.finish().unwrap();
    -
    -        assert_eq!(details.sent, original_details.sent);
    -        assert!(details.fee.unwrap_or(0) > original_details.fee.unwrap_or(0));
    -
    -        let tx = &psbt.unsigned_tx;
    -        assert_eq!(tx.output.len(), 1);
    -        assert_eq!(tx.output[0].value + details.fee.unwrap_or(0), details.sent);
    -
    -        assert_fee_rate!(psbt, details.fee.unwrap_or(0), FeeRate::from_sat_per_vb(2.5), @add_signature);
    -    }
    -
    -    #[test]
    -    fn test_bump_fee_absolute_reduce_single_recipient() {
    -        let (wallet, _, _) = get_funded_wallet(get_test_wpkh());
    -        let addr = Address::from_str("2N1Ffz3WaNzbeLFBb51xyFMHYSEUXcbiSoX").unwrap();
    -        let mut builder = wallet.build_tx();
    -        builder
    -            .drain_to(addr.script_pubkey())
    -            .drain_wallet()
    -            .enable_rbf();
    -        let (psbt, mut original_details) = builder.finish().unwrap();
    -        let mut tx = psbt.extract_tx();
    -        let txid = tx.txid();
    -        for txin in &mut tx.input {
    -            txin.witness.push([0x00; P2WPKH_FAKE_WITNESS_SIZE]); // fake signature
    -            wallet
    -                .database
    -                .borrow_mut()
    -                .del_utxo(&txin.previous_output)
    -                .unwrap();
    +        original_details.transaction = Some(tx);
    +        wallet
    +            .database
    +            .borrow_mut()
    +            .set_tx(&original_details)
    +            .unwrap();
    +
    +        let mut builder = wallet.build_fee_bump(txid).unwrap();
    +        builder
    +            .fee_rate(FeeRate::from_sat_per_vb(2.5))
    +            .allow_shrinking(addr.script_pubkey())
    +            .unwrap();
    +        let (psbt, details) = builder.finish().unwrap();
    +
    +        assert_eq!(details.sent, original_details.sent);
    +        assert!(details.fee.unwrap_or(0) > original_details.fee.unwrap_or(0));
    +
    +        let tx = &psbt.unsigned_tx;
    +        assert_eq!(tx.output.len(), 1);
    +        assert_eq!(tx.output[0].value + details.fee.unwrap_or(0), details.sent);
    +
    +        assert_fee_rate!(psbt, details.fee.unwrap_or(0), FeeRate::from_sat_per_vb(2.5), @add_signature);
    +    }
    +
    +    #[test]
    +    fn test_bump_fee_absolute_reduce_single_recipient() {
    +        let (wallet, _, _) = get_funded_wallet(get_test_wpkh());
    +        let addr = Address::from_str("2N1Ffz3WaNzbeLFBb51xyFMHYSEUXcbiSoX").unwrap();
    +        let mut builder = wallet.build_tx();
    +        builder
    +            .drain_to(addr.script_pubkey())
    +            .drain_wallet()
    +            .enable_rbf();
    +        let (psbt, mut original_details) = builder.finish().unwrap();
    +        let mut tx = psbt.extract_tx();
    +        let txid = tx.txid();
    +        for txin in &mut tx.input {
    +            txin.witness.push([0x00; P2WPKH_FAKE_WITNESS_SIZE]); // fake signature
    +            wallet
    +                .database
    +                .borrow_mut()
    +                .del_utxo(&txin.previous_output)
    +                .unwrap();
             }
    -        original_details.transaction = Some(tx);
    -        wallet
    -            .database
    -            .borrow_mut()
    -            .set_tx(&original_details)
    -            .unwrap();
    -
    -        let mut builder = wallet.build_fee_bump(txid).unwrap();
    -        builder
    -            .allow_shrinking(addr.script_pubkey())
    -            .unwrap()
    -            .fee_absolute(300);
    -        let (psbt, details) = builder.finish().unwrap();
    -
    -        assert_eq!(details.sent, original_details.sent);
    -        assert!(details.fee.unwrap_or(0) > original_details.fee.unwrap_or(0));
    -
    -        let tx = &psbt.unsigned_tx;
    -        assert_eq!(tx.output.len(), 1);
    -        assert_eq!(tx.output[0].value + details.fee.unwrap_or(0), details.sent);
    -
    -        assert_eq!(details.fee.unwrap_or(0), 300);
    -    }
    -
    -    #[test]
    -    fn test_bump_fee_drain_wallet() {
    -        let (wallet, descriptors, _) = get_funded_wallet(get_test_wpkh());
    -        // receive an extra tx so that our wallet has two utxos.
    -        let incoming_txid = crate::populate_test_db!(
    -            wallet.database.borrow_mut(),
    -            testutils! (@tx ( (@external descriptors, 0) => 25_000 ) (@confirmations 1)),
    +        original_details.transaction = Some(tx);
    +        wallet
    +            .database
    +            .borrow_mut()
    +            .set_tx(&original_details)
    +            .unwrap();
    +
    +        let mut builder = wallet.build_fee_bump(txid).unwrap();
    +        builder
    +            .allow_shrinking(addr.script_pubkey())
    +            .unwrap()
    +            .fee_absolute(300);
    +        let (psbt, details) = builder.finish().unwrap();
    +
    +        assert_eq!(details.sent, original_details.sent);
    +        assert!(details.fee.unwrap_or(0) > original_details.fee.unwrap_or(0));
    +
    +        let tx = &psbt.unsigned_tx;
    +        assert_eq!(tx.output.len(), 1);
    +        assert_eq!(tx.output[0].value + details.fee.unwrap_or(0), details.sent);
    +
    +        assert_eq!(details.fee.unwrap_or(0), 300);
    +    }
    +
    +    #[test]
    +    fn test_bump_fee_drain_wallet() {
    +        let (wallet, descriptors, _) = get_funded_wallet(get_test_wpkh());
    +        // receive an extra tx so that our wallet has two utxos.
    +        let incoming_txid = crate::populate_test_db!(
    +            wallet.database.borrow_mut(),
    +            testutils! (@tx ( (@external descriptors, 0) => 25_000 ) (@confirmations 1)),
                 Some(100),
             );
    -        let outpoint = OutPoint {
    -            txid: incoming_txid,
    -            vout: 0,
    +        let outpoint = OutPoint {
    +            txid: incoming_txid,
    +            vout: 0,
             };
    -        let addr = Address::from_str("2N1Ffz3WaNzbeLFBb51xyFMHYSEUXcbiSoX").unwrap();
    -        let mut builder = wallet.build_tx();
    -        builder
    -            .drain_to(addr.script_pubkey())
    -            .add_utxo(outpoint)
    -            .unwrap()
    -            .manually_selected_only()
    -            .enable_rbf();
    -        let (psbt, mut original_details) = builder.finish().unwrap();
    -        let mut tx = psbt.extract_tx();
    -        let txid = tx.txid();
    -        for txin in &mut tx.input {
    -            txin.witness.push([0x00; P2WPKH_FAKE_WITNESS_SIZE]); // fake signature
    -            wallet
    -                .database
    -                .borrow_mut()
    -                .del_utxo(&txin.previous_output)
    -                .unwrap();
    +        let addr = Address::from_str("2N1Ffz3WaNzbeLFBb51xyFMHYSEUXcbiSoX").unwrap();
    +        let mut builder = wallet.build_tx();
    +        builder
    +            .drain_to(addr.script_pubkey())
    +            .add_utxo(outpoint)
    +            .unwrap()
    +            .manually_selected_only()
    +            .enable_rbf();
    +        let (psbt, mut original_details) = builder.finish().unwrap();
    +        let mut tx = psbt.extract_tx();
    +        let txid = tx.txid();
    +        for txin in &mut tx.input {
    +            txin.witness.push([0x00; P2WPKH_FAKE_WITNESS_SIZE]); // fake signature
    +            wallet
    +                .database
    +                .borrow_mut()
    +                .del_utxo(&txin.previous_output)
    +                .unwrap();
             }
    -        original_details.transaction = Some(tx);
    -        wallet
    -            .database
    -            .borrow_mut()
    -            .set_tx(&original_details)
    -            .unwrap();
    -        assert_eq!(original_details.sent, 25_000);
    -
    -        // for the new feerate, it should be enough to reduce the output, but since we specify
    -        // `drain_wallet` we expect to spend everything
    -        let mut builder = wallet.build_fee_bump(txid).unwrap();
    -        builder
    -            .drain_wallet()
    -            .allow_shrinking(addr.script_pubkey())
    -            .unwrap()
    -            .fee_rate(FeeRate::from_sat_per_vb(5.0));
    -        let (_, details) = builder.finish().unwrap();
    -        assert_eq!(details.sent, 75_000);
    -    }
    -
    -    #[test]
    -    #[should_panic(expected = "InsufficientFunds")]
    -    fn test_bump_fee_remove_output_manually_selected_only() {
    -        let (wallet, descriptors, _) = get_funded_wallet(get_test_wpkh());
    -        // receive an extra tx so that our wallet has two utxos. then we manually pick only one of
    -        // them, and make sure that `bump_fee` doesn't try to add more. This fails because we've
    -        // told the wallet it's not allowed to add more inputs AND it can't reduce the value of the
    -        // existing output. In other words, bump_fee + manually_selected_only is always an error
    -        // unless you've also set "allow_shrinking" OR there is a change output.
    -        let incoming_txid = crate::populate_test_db!(
    -            wallet.database.borrow_mut(),
    -            testutils! (@tx ( (@external descriptors, 0) => 25_000 ) (@confirmations 1)),
    +        original_details.transaction = Some(tx);
    +        wallet
    +            .database
    +            .borrow_mut()
    +            .set_tx(&original_details)
    +            .unwrap();
    +        assert_eq!(original_details.sent, 25_000);
    +
    +        // for the new feerate, it should be enough to reduce the output, but since we specify
    +        // `drain_wallet` we expect to spend everything
    +        let mut builder = wallet.build_fee_bump(txid).unwrap();
    +        builder
    +            .drain_wallet()
    +            .allow_shrinking(addr.script_pubkey())
    +            .unwrap()
    +            .fee_rate(FeeRate::from_sat_per_vb(5.0));
    +        let (_, details) = builder.finish().unwrap();
    +        assert_eq!(details.sent, 75_000);
    +    }
    +
    +    #[test]
    +    #[should_panic(expected = "InsufficientFunds")]
    +    fn test_bump_fee_remove_output_manually_selected_only() {
    +        let (wallet, descriptors, _) = get_funded_wallet(get_test_wpkh());
    +        // receive an extra tx so that our wallet has two utxos. then we manually pick only one of
    +        // them, and make sure that `bump_fee` doesn't try to add more. This fails because we've
    +        // told the wallet it's not allowed to add more inputs AND it can't reduce the value of the
    +        // existing output. In other words, bump_fee + manually_selected_only is always an error
    +        // unless you've also set "allow_shrinking" OR there is a change output.
    +        let incoming_txid = crate::populate_test_db!(
    +            wallet.database.borrow_mut(),
    +            testutils! (@tx ( (@external descriptors, 0) => 25_000 ) (@confirmations 1)),
                 Some(100),
             );
    -        let outpoint = OutPoint {
    -            txid: incoming_txid,
    -            vout: 0,
    +        let outpoint = OutPoint {
    +            txid: incoming_txid,
    +            vout: 0,
             };
    -        let addr = Address::from_str("2N1Ffz3WaNzbeLFBb51xyFMHYSEUXcbiSoX").unwrap();
    -        let mut builder = wallet.build_tx();
    -        builder
    -            .drain_to(addr.script_pubkey())
    -            .add_utxo(outpoint)
    -            .unwrap()
    -            .manually_selected_only()
    -            .enable_rbf();
    -        let (psbt, mut original_details) = builder.finish().unwrap();
    -        let mut tx = psbt.extract_tx();
    -        let txid = tx.txid();
    -        for txin in &mut tx.input {
    -            txin.witness.push([0x00; P2WPKH_FAKE_WITNESS_SIZE]); // fake signature
    -            wallet
    -                .database
    -                .borrow_mut()
    -                .del_utxo(&txin.previous_output)
    -                .unwrap();
    +        let addr = Address::from_str("2N1Ffz3WaNzbeLFBb51xyFMHYSEUXcbiSoX").unwrap();
    +        let mut builder = wallet.build_tx();
    +        builder
    +            .drain_to(addr.script_pubkey())
    +            .add_utxo(outpoint)
    +            .unwrap()
    +            .manually_selected_only()
    +            .enable_rbf();
    +        let (psbt, mut original_details) = builder.finish().unwrap();
    +        let mut tx = psbt.extract_tx();
    +        let txid = tx.txid();
    +        for txin in &mut tx.input {
    +            txin.witness.push([0x00; P2WPKH_FAKE_WITNESS_SIZE]); // fake signature
    +            wallet
    +                .database
    +                .borrow_mut()
    +                .del_utxo(&txin.previous_output)
    +                .unwrap();
             }
    -        original_details.transaction = Some(tx);
    -        wallet
    -            .database
    -            .borrow_mut()
    -            .set_tx(&original_details)
    -            .unwrap();
    -        assert_eq!(original_details.sent, 25_000);
    -
    -        let mut builder = wallet.build_fee_bump(txid).unwrap();
    -        builder
    -            .manually_selected_only()
    -            .fee_rate(FeeRate::from_sat_per_vb(255.0));
    -        builder.finish().unwrap();
    -    }
    -
    -    #[test]
    -    fn test_bump_fee_add_input() {
    -        let (wallet, descriptors, _) = get_funded_wallet(get_test_wpkh());
    +        original_details.transaction = Some(tx);
    +        wallet
    +            .database
    +            .borrow_mut()
    +            .set_tx(&original_details)
    +            .unwrap();
    +        assert_eq!(original_details.sent, 25_000);
    +
    +        let mut builder = wallet.build_fee_bump(txid).unwrap();
    +        builder
    +            .manually_selected_only()
    +            .fee_rate(FeeRate::from_sat_per_vb(255.0));
    +        builder.finish().unwrap();
    +    }
    +
    +    #[test]
    +    fn test_bump_fee_add_input() {
    +        let (wallet, descriptors, _) = get_funded_wallet(get_test_wpkh());
             crate::populate_test_db!(
    -            wallet.database.borrow_mut(),
    -            testutils! (@tx ( (@external descriptors, 0) => 25_000 ) (@confirmations 1)),
    +            wallet.database.borrow_mut(),
    +            testutils! (@tx ( (@external descriptors, 0) => 25_000 ) (@confirmations 1)),
                 Some(100),
             );
     
    -        let addr = Address::from_str("2N1Ffz3WaNzbeLFBb51xyFMHYSEUXcbiSoX").unwrap();
    -        let mut builder = wallet.build_tx();
    -        builder
    -            .add_recipient(addr.script_pubkey(), 45_000)
    -            .enable_rbf();
    -        let (psbt, mut original_details) = builder.finish().unwrap();
    -        let mut tx = psbt.extract_tx();
    -        let txid = tx.txid();
    -        // skip saving the new utxos, we know they can't be used anyways
    -        for txin in &mut tx.input {
    -            txin.witness.push([0x00; P2WPKH_FAKE_WITNESS_SIZE]); // fake signature
    -            wallet
    -                .database
    -                .borrow_mut()
    -                .del_utxo(&txin.previous_output)
    -                .unwrap();
    +        let addr = Address::from_str("2N1Ffz3WaNzbeLFBb51xyFMHYSEUXcbiSoX").unwrap();
    +        let mut builder = wallet.build_tx();
    +        builder
    +            .add_recipient(addr.script_pubkey(), 45_000)
    +            .enable_rbf();
    +        let (psbt, mut original_details) = builder.finish().unwrap();
    +        let mut tx = psbt.extract_tx();
    +        let txid = tx.txid();
    +        // skip saving the new utxos, we know they can't be used anyways
    +        for txin in &mut tx.input {
    +            txin.witness.push([0x00; P2WPKH_FAKE_WITNESS_SIZE]); // fake signature
    +            wallet
    +                .database
    +                .borrow_mut()
    +                .del_utxo(&txin.previous_output)
    +                .unwrap();
             }
    -        original_details.transaction = Some(tx);
    -        wallet
    -            .database
    -            .borrow_mut()
    -            .set_tx(&original_details)
    -            .unwrap();
    -
    -        let mut builder = wallet.build_fee_bump(txid).unwrap();
    -        builder.fee_rate(FeeRate::from_sat_per_vb(50.0));
    -        let (psbt, details) = builder.finish().unwrap();
    -
    -        assert_eq!(details.sent, original_details.sent + 25_000);
    -        assert_eq!(details.fee.unwrap_or(0) + details.received, 30_000);
    -
    -        let tx = &psbt.unsigned_tx;
    -        assert_eq!(tx.input.len(), 2);
    -        assert_eq!(tx.output.len(), 2);
    +        original_details.transaction = Some(tx);
    +        wallet
    +            .database
    +            .borrow_mut()
    +            .set_tx(&original_details)
    +            .unwrap();
    +
    +        let mut builder = wallet.build_fee_bump(txid).unwrap();
    +        builder.fee_rate(FeeRate::from_sat_per_vb(50.0));
    +        let (psbt, details) = builder.finish().unwrap();
    +
    +        assert_eq!(details.sent, original_details.sent + 25_000);
    +        assert_eq!(details.fee.unwrap_or(0) + details.received, 30_000);
    +
    +        let tx = &psbt.unsigned_tx;
    +        assert_eq!(tx.input.len(), 2);
    +        assert_eq!(tx.output.len(), 2);
             assert_eq!(
    -            tx.output
    -                .iter()
    -                .find(|txout| txout.script_pubkey == addr.script_pubkey())
    -                .unwrap()
    -                .value,
    -            45_000
    -        );
    +            tx.output
    +                .iter()
    +                .find(|txout| txout.script_pubkey == addr.script_pubkey())
    +                .unwrap()
    +                .value,
    +            45_000
    +        );
             assert_eq!(
    -            tx.output
    -                .iter()
    -                .find(|txout| txout.script_pubkey != addr.script_pubkey())
    -                .unwrap()
    -                .value,
    -            details.received
    +            tx.output
    +                .iter()
    +                .find(|txout| txout.script_pubkey != addr.script_pubkey())
    +                .unwrap()
    +                .value,
    +            details.received
             );
     
    -        assert_fee_rate!(psbt, details.fee.unwrap_or(0), FeeRate::from_sat_per_vb(50.0), @add_signature);
    +        assert_fee_rate!(psbt, details.fee.unwrap_or(0), FeeRate::from_sat_per_vb(50.0), @add_signature);
         }
     
    -    #[test]
    -    fn test_bump_fee_absolute_add_input() {
    -        let (wallet, descriptors, _) = get_funded_wallet(get_test_wpkh());
    +    #[test]
    +    fn test_bump_fee_absolute_add_input() {
    +        let (wallet, descriptors, _) = get_funded_wallet(get_test_wpkh());
             crate::populate_test_db!(
    -            wallet.database.borrow_mut(),
    -            testutils! (@tx ( (@external descriptors, 0) => 25_000 ) (@confirmations 1)),
    +            wallet.database.borrow_mut(),
    +            testutils! (@tx ( (@external descriptors, 0) => 25_000 ) (@confirmations 1)),
                 Some(100),
             );
     
    -        let addr = Address::from_str("2N1Ffz3WaNzbeLFBb51xyFMHYSEUXcbiSoX").unwrap();
    -        let mut builder = wallet.build_tx();
    -        builder
    -            .add_recipient(addr.script_pubkey(), 45_000)
    -            .enable_rbf();
    -        let (psbt, mut original_details) = builder.finish().unwrap();
    -        let mut tx = psbt.extract_tx();
    -        let txid = tx.txid();
    -        // skip saving the new utxos, we know they can't be used anyways
    -        for txin in &mut tx.input {
    -            txin.witness.push([0x00; P2WPKH_FAKE_WITNESS_SIZE]); // fake signature
    -            wallet
    -                .database
    -                .borrow_mut()
    -                .del_utxo(&txin.previous_output)
    -                .unwrap();
    +        let addr = Address::from_str("2N1Ffz3WaNzbeLFBb51xyFMHYSEUXcbiSoX").unwrap();
    +        let mut builder = wallet.build_tx();
    +        builder
    +            .add_recipient(addr.script_pubkey(), 45_000)
    +            .enable_rbf();
    +        let (psbt, mut original_details) = builder.finish().unwrap();
    +        let mut tx = psbt.extract_tx();
    +        let txid = tx.txid();
    +        // skip saving the new utxos, we know they can't be used anyways
    +        for txin in &mut tx.input {
    +            txin.witness.push([0x00; P2WPKH_FAKE_WITNESS_SIZE]); // fake signature
    +            wallet
    +                .database
    +                .borrow_mut()
    +                .del_utxo(&txin.previous_output)
    +                .unwrap();
             }
    -        original_details.transaction = Some(tx);
    -        wallet
    -            .database
    -            .borrow_mut()
    -            .set_tx(&original_details)
    -            .unwrap();
    -
    -        let mut builder = wallet.build_fee_bump(txid).unwrap();
    -        builder.fee_absolute(6_000);
    -        let (psbt, details) = builder.finish().unwrap();
    -
    -        assert_eq!(details.sent, original_details.sent + 25_000);
    -        assert_eq!(details.fee.unwrap_or(0) + details.received, 30_000);
    -
    -        let tx = &psbt.unsigned_tx;
    -        assert_eq!(tx.input.len(), 2);
    -        assert_eq!(tx.output.len(), 2);
    +        original_details.transaction = Some(tx);
    +        wallet
    +            .database
    +            .borrow_mut()
    +            .set_tx(&original_details)
    +            .unwrap();
    +
    +        let mut builder = wallet.build_fee_bump(txid).unwrap();
    +        builder.fee_absolute(6_000);
    +        let (psbt, details) = builder.finish().unwrap();
    +
    +        assert_eq!(details.sent, original_details.sent + 25_000);
    +        assert_eq!(details.fee.unwrap_or(0) + details.received, 30_000);
    +
    +        let tx = &psbt.unsigned_tx;
    +        assert_eq!(tx.input.len(), 2);
    +        assert_eq!(tx.output.len(), 2);
             assert_eq!(
    -            tx.output
    -                .iter()
    -                .find(|txout| txout.script_pubkey == addr.script_pubkey())
    -                .unwrap()
    -                .value,
    -            45_000
    -        );
    +            tx.output
    +                .iter()
    +                .find(|txout| txout.script_pubkey == addr.script_pubkey())
    +                .unwrap()
    +                .value,
    +            45_000
    +        );
             assert_eq!(
    -            tx.output
    -                .iter()
    -                .find(|txout| txout.script_pubkey != addr.script_pubkey())
    -                .unwrap()
    -                .value,
    -            details.received
    +            tx.output
    +                .iter()
    +                .find(|txout| txout.script_pubkey != addr.script_pubkey())
    +                .unwrap()
    +                .value,
    +            details.received
             );
     
    -        assert_eq!(details.fee.unwrap_or(0), 6_000);
    +        assert_eq!(details.fee.unwrap_or(0), 6_000);
         }
     
    -    #[test]
    -    fn test_bump_fee_no_change_add_input_and_change() {
    -        let (wallet, descriptors, _) = get_funded_wallet(get_test_wpkh());
    -        let incoming_txid = crate::populate_test_db!(
    -            wallet.database.borrow_mut(),
    -            testutils! (@tx ( (@external descriptors, 0) => 25_000 ) (@confirmations 1)),
    +    #[test]
    +    fn test_bump_fee_no_change_add_input_and_change() {
    +        let (wallet, descriptors, _) = get_funded_wallet(get_test_wpkh());
    +        let incoming_txid = crate::populate_test_db!(
    +            wallet.database.borrow_mut(),
    +            testutils! (@tx ( (@external descriptors, 0) => 25_000 ) (@confirmations 1)),
                 Some(100),
             );
     
    -        // initially make a tx without change by using `drain_to`
    -        let addr = Address::from_str("2N1Ffz3WaNzbeLFBb51xyFMHYSEUXcbiSoX").unwrap();
    -        let mut builder = wallet.build_tx();
    -        builder
    -            .drain_to(addr.script_pubkey())
    -            .add_utxo(OutPoint {
    -                txid: incoming_txid,
    -                vout: 0,
    +        // initially make a tx without change by using `drain_to`
    +        let addr = Address::from_str("2N1Ffz3WaNzbeLFBb51xyFMHYSEUXcbiSoX").unwrap();
    +        let mut builder = wallet.build_tx();
    +        builder
    +            .drain_to(addr.script_pubkey())
    +            .add_utxo(OutPoint {
    +                txid: incoming_txid,
    +                vout: 0,
                 })
    -            .unwrap()
    -            .manually_selected_only()
    -            .enable_rbf();
    -        let (psbt, mut original_details) = builder.finish().unwrap();
    -
    -        let mut tx = psbt.extract_tx();
    -        let txid = tx.txid();
    -        // skip saving the new utxos, we know they can't be used anyways
    -        for txin in &mut tx.input {
    -            txin.witness.push([0x00; P2WPKH_FAKE_WITNESS_SIZE]); // fake signature
    -            wallet
    -                .database
    -                .borrow_mut()
    -                .del_utxo(&txin.previous_output)
    -                .unwrap();
    +            .unwrap()
    +            .manually_selected_only()
    +            .enable_rbf();
    +        let (psbt, mut original_details) = builder.finish().unwrap();
    +
    +        let mut tx = psbt.extract_tx();
    +        let txid = tx.txid();
    +        // skip saving the new utxos, we know they can't be used anyways
    +        for txin in &mut tx.input {
    +            txin.witness.push([0x00; P2WPKH_FAKE_WITNESS_SIZE]); // fake signature
    +            wallet
    +                .database
    +                .borrow_mut()
    +                .del_utxo(&txin.previous_output)
    +                .unwrap();
             }
    -        original_details.transaction = Some(tx);
    -        wallet
    -            .database
    -            .borrow_mut()
    -            .set_tx(&original_details)
    -            .unwrap();
    -
    -        // now bump the fees without using `allow_shrinking`. the wallet should add an
    -        // extra input and a change output, and leave the original output untouched
    -        let mut builder = wallet.build_fee_bump(txid).unwrap();
    -        builder.fee_rate(FeeRate::from_sat_per_vb(50.0));
    -        let (psbt, details) = builder.finish().unwrap();
    -
    -        let original_send_all_amount = original_details.sent - original_details.fee.unwrap_or(0);
    -        assert_eq!(details.sent, original_details.sent + 50_000);
    +        original_details.transaction = Some(tx);
    +        wallet
    +            .database
    +            .borrow_mut()
    +            .set_tx(&original_details)
    +            .unwrap();
    +
    +        // now bump the fees without using `allow_shrinking`. the wallet should add an
    +        // extra input and a change output, and leave the original output untouched
    +        let mut builder = wallet.build_fee_bump(txid).unwrap();
    +        builder.fee_rate(FeeRate::from_sat_per_vb(50.0));
    +        let (psbt, details) = builder.finish().unwrap();
    +
    +        let original_send_all_amount = original_details.sent - original_details.fee.unwrap_or(0);
    +        assert_eq!(details.sent, original_details.sent + 50_000);
             assert_eq!(
    -            details.received,
    -            75_000 - original_send_all_amount - details.fee.unwrap_or(0)
    +            details.received,
    +            75_000 - original_send_all_amount - details.fee.unwrap_or(0)
             );
     
    -        let tx = &psbt.unsigned_tx;
    -        assert_eq!(tx.input.len(), 2);
    -        assert_eq!(tx.output.len(), 2);
    +        let tx = &psbt.unsigned_tx;
    +        assert_eq!(tx.input.len(), 2);
    +        assert_eq!(tx.output.len(), 2);
             assert_eq!(
    -            tx.output
    -                .iter()
    -                .find(|txout| txout.script_pubkey == addr.script_pubkey())
    -                .unwrap()
    -                .value,
    -            original_send_all_amount
    +            tx.output
    +                .iter()
    +                .find(|txout| txout.script_pubkey == addr.script_pubkey())
    +                .unwrap()
    +                .value,
    +            original_send_all_amount
             );
             assert_eq!(
    -            tx.output
    -                .iter()
    -                .find(|txout| txout.script_pubkey != addr.script_pubkey())
    -                .unwrap()
    -                .value,
    -            75_000 - original_send_all_amount - details.fee.unwrap_or(0)
    +            tx.output
    +                .iter()
    +                .find(|txout| txout.script_pubkey != addr.script_pubkey())
    +                .unwrap()
    +                .value,
    +            75_000 - original_send_all_amount - details.fee.unwrap_or(0)
             );
     
    -        assert_fee_rate!(psbt, details.fee.unwrap_or(0), FeeRate::from_sat_per_vb(50.0), @add_signature);
    +        assert_fee_rate!(psbt, details.fee.unwrap_or(0), FeeRate::from_sat_per_vb(50.0), @add_signature);
         }
     
    -    #[test]
    -    fn test_bump_fee_add_input_change_dust() {
    -        let (wallet, descriptors, _) = get_funded_wallet(get_test_wpkh());
    +    #[test]
    +    fn test_bump_fee_add_input_change_dust() {
    +        let (wallet, descriptors, _) = get_funded_wallet(get_test_wpkh());
             crate::populate_test_db!(
    -            wallet.database.borrow_mut(),
    -            testutils! (@tx ( (@external descriptors, 0) => 25_000 ) (@confirmations 1)),
    +            wallet.database.borrow_mut(),
    +            testutils! (@tx ( (@external descriptors, 0) => 25_000 ) (@confirmations 1)),
                 Some(100),
             );
     
    -        let addr = Address::from_str("2N1Ffz3WaNzbeLFBb51xyFMHYSEUXcbiSoX").unwrap();
    -        let mut builder = wallet.build_tx();
    -        builder
    -            .add_recipient(addr.script_pubkey(), 45_000)
    -            .enable_rbf();
    -        let (psbt, mut original_details) = builder.finish().unwrap();
    -        let mut tx = psbt.extract_tx();
    -        assert_eq!(tx.input.len(), 1);
    -        assert_eq!(tx.output.len(), 2);
    -        let txid = tx.txid();
    -        // skip saving the new utxos, we know they can't be used anyways
    -        for txin in &mut tx.input {
    -            txin.witness.push([0x00; P2WPKH_FAKE_WITNESS_SIZE]); // fake signature
    -            wallet
    -                .database
    -                .borrow_mut()
    -                .del_utxo(&txin.previous_output)
    -                .unwrap();
    +        let addr = Address::from_str("2N1Ffz3WaNzbeLFBb51xyFMHYSEUXcbiSoX").unwrap();
    +        let mut builder = wallet.build_tx();
    +        builder
    +            .add_recipient(addr.script_pubkey(), 45_000)
    +            .enable_rbf();
    +        let (psbt, mut original_details) = builder.finish().unwrap();
    +        let mut tx = psbt.extract_tx();
    +        assert_eq!(tx.input.len(), 1);
    +        assert_eq!(tx.output.len(), 2);
    +        let txid = tx.txid();
    +        // skip saving the new utxos, we know they can't be used anyways
    +        for txin in &mut tx.input {
    +            txin.witness.push([0x00; P2WPKH_FAKE_WITNESS_SIZE]); // fake signature
    +            wallet
    +                .database
    +                .borrow_mut()
    +                .del_utxo(&txin.previous_output)
    +                .unwrap();
             }
    -        let original_tx_weight = tx.weight();
    -        original_details.transaction = Some(tx);
    -        wallet
    -            .database
    -            .borrow_mut()
    -            .set_tx(&original_details)
    -            .unwrap();
    -
    -        let mut builder = wallet.build_fee_bump(txid).unwrap();
    -        // We set a fee high enough that during rbf we are forced to add
    -        // a new input and also that we have to remove the change
    -        // that we had previously
    -
    -        // We calculate the new weight as:
    -        //   original weight
    -        // + extra input weight: 160 WU = (32 (prevout) + 4 (vout) + 4 (nsequence)) * 4
    -        // + input satisfaction weight: 112 WU = 106 (witness) + 2 (witness len) + (1 (script len)) * 4
    -        // - change output weight: 124 WU = (8 (value) + 1 (script len) + 22 (script)) * 4
    -        let new_tx_weight = original_tx_weight + 160 + 112 - 124;
    -        // two inputs (50k, 25k) and one output (45k) - epsilon
    -        // We use epsilon here to avoid asking for a slightly too high feerate
    -        let fee_abs = 50_000 + 25_000 - 45_000 - 10;
    -        builder.fee_rate(FeeRate::from_wu(fee_abs, new_tx_weight));
    -        let (psbt, details) = builder.finish().unwrap();
    +        let original_tx_weight = tx.weight();
    +        original_details.transaction = Some(tx);
    +        wallet
    +            .database
    +            .borrow_mut()
    +            .set_tx(&original_details)
    +            .unwrap();
    +
    +        let mut builder = wallet.build_fee_bump(txid).unwrap();
    +        // We set a fee high enough that during rbf we are forced to add
    +        // a new input and also that we have to remove the change
    +        // that we had previously
    +
    +        // We calculate the new weight as:
    +        //   original weight
    +        // + extra input weight: 160 WU = (32 (prevout) + 4 (vout) + 4 (nsequence)) * 4
    +        // + input satisfaction weight: 112 WU = 106 (witness) + 2 (witness len) + (1 (script len)) * 4
    +        // - change output weight: 124 WU = (8 (value) + 1 (script len) + 22 (script)) * 4
    +        let new_tx_weight = original_tx_weight + 160 + 112 - 124;
    +        // two inputs (50k, 25k) and one output (45k) - epsilon
    +        // We use epsilon here to avoid asking for a slightly too high feerate
    +        let fee_abs = 50_000 + 25_000 - 45_000 - 10;
    +        builder.fee_rate(FeeRate::from_wu(fee_abs, new_tx_weight));
    +        let (psbt, details) = builder.finish().unwrap();
     
             assert_eq!(
    -            original_details.received,
    -            5_000 - original_details.fee.unwrap_or(0)
    +            original_details.received,
    +            5_000 - original_details.fee.unwrap_or(0)
             );
     
    -        assert_eq!(details.sent, original_details.sent + 25_000);
    -        assert_eq!(details.fee.unwrap_or(0), 30_000);
    -        assert_eq!(details.received, 0);
    +        assert_eq!(details.sent, original_details.sent + 25_000);
    +        assert_eq!(details.fee.unwrap_or(0), 30_000);
    +        assert_eq!(details.received, 0);
     
    -        let tx = &psbt.unsigned_tx;
    -        assert_eq!(tx.input.len(), 2);
    -        assert_eq!(tx.output.len(), 1);
    +        let tx = &psbt.unsigned_tx;
    +        assert_eq!(tx.input.len(), 2);
    +        assert_eq!(tx.output.len(), 1);
             assert_eq!(
    -            tx.output
    -                .iter()
    -                .find(|txout| txout.script_pubkey == addr.script_pubkey())
    -                .unwrap()
    -                .value,
    -            45_000
    -        );
    -
    -        assert_fee_rate!(psbt, details.fee.unwrap_or(0), FeeRate::from_sat_per_vb(140.0), @dust_change, @add_signature);
    -    }
    -
    -    #[test]
    -    fn test_bump_fee_force_add_input() {
    -        let (wallet, descriptors, _) = get_funded_wallet(get_test_wpkh());
    -        let incoming_txid = crate::populate_test_db!(
    -            wallet.database.borrow_mut(),
    -            testutils! (@tx ( (@external descriptors, 0) => 25_000 ) (@confirmations 1)),
    +            tx.output
    +                .iter()
    +                .find(|txout| txout.script_pubkey == addr.script_pubkey())
    +                .unwrap()
    +                .value,
    +            45_000
    +        );
    +
    +        assert_fee_rate!(psbt, details.fee.unwrap_or(0), FeeRate::from_sat_per_vb(140.0), @dust_change, @add_signature);
    +    }
    +
    +    #[test]
    +    fn test_bump_fee_force_add_input() {
    +        let (wallet, descriptors, _) = get_funded_wallet(get_test_wpkh());
    +        let incoming_txid = crate::populate_test_db!(
    +            wallet.database.borrow_mut(),
    +            testutils! (@tx ( (@external descriptors, 0) => 25_000 ) (@confirmations 1)),
                 Some(100),
             );
     
    -        let addr = Address::from_str("2N1Ffz3WaNzbeLFBb51xyFMHYSEUXcbiSoX").unwrap();
    -        let mut builder = wallet.build_tx();
    -        builder
    -            .add_recipient(addr.script_pubkey(), 45_000)
    -            .enable_rbf();
    -        let (psbt, mut original_details) = builder.finish().unwrap();
    -        let mut tx = psbt.extract_tx();
    -        let txid = tx.txid();
    -        // skip saving the new utxos, we know they can't be used anyways
    -        for txin in &mut tx.input {
    -            txin.witness.push([0x00; P2WPKH_FAKE_WITNESS_SIZE]); // fake signature
    -            wallet
    -                .database
    -                .borrow_mut()
    -                .del_utxo(&txin.previous_output)
    -                .unwrap();
    +        let addr = Address::from_str("2N1Ffz3WaNzbeLFBb51xyFMHYSEUXcbiSoX").unwrap();
    +        let mut builder = wallet.build_tx();
    +        builder
    +            .add_recipient(addr.script_pubkey(), 45_000)
    +            .enable_rbf();
    +        let (psbt, mut original_details) = builder.finish().unwrap();
    +        let mut tx = psbt.extract_tx();
    +        let txid = tx.txid();
    +        // skip saving the new utxos, we know they can't be used anyways
    +        for txin in &mut tx.input {
    +            txin.witness.push([0x00; P2WPKH_FAKE_WITNESS_SIZE]); // fake signature
    +            wallet
    +                .database
    +                .borrow_mut()
    +                .del_utxo(&txin.previous_output)
    +                .unwrap();
             }
    -        original_details.transaction = Some(tx);
    -        wallet
    -            .database
    -            .borrow_mut()
    -            .set_tx(&original_details)
    -            .unwrap();
    -
    -        // the new fee_rate is low enough that just reducing the change would be fine, but we force
    -        // the addition of an extra input with `add_utxo()`
    -        let mut builder = wallet.build_fee_bump(txid).unwrap();
    -        builder
    -            .add_utxo(OutPoint {
    -                txid: incoming_txid,
    -                vout: 0,
    +        original_details.transaction = Some(tx);
    +        wallet
    +            .database
    +            .borrow_mut()
    +            .set_tx(&original_details)
    +            .unwrap();
    +
    +        // the new fee_rate is low enough that just reducing the change would be fine, but we force
    +        // the addition of an extra input with `add_utxo()`
    +        let mut builder = wallet.build_fee_bump(txid).unwrap();
    +        builder
    +            .add_utxo(OutPoint {
    +                txid: incoming_txid,
    +                vout: 0,
                 })
    -            .unwrap()
    -            .fee_rate(FeeRate::from_sat_per_vb(5.0));
    -        let (psbt, details) = builder.finish().unwrap();
    +            .unwrap()
    +            .fee_rate(FeeRate::from_sat_per_vb(5.0));
    +        let (psbt, details) = builder.finish().unwrap();
     
    -        assert_eq!(details.sent, original_details.sent + 25_000);
    -        assert_eq!(details.fee.unwrap_or(0) + details.received, 30_000);
    +        assert_eq!(details.sent, original_details.sent + 25_000);
    +        assert_eq!(details.fee.unwrap_or(0) + details.received, 30_000);
     
    -        let tx = &psbt.unsigned_tx;
    -        assert_eq!(tx.input.len(), 2);
    -        assert_eq!(tx.output.len(), 2);
    +        let tx = &psbt.unsigned_tx;
    +        assert_eq!(tx.input.len(), 2);
    +        assert_eq!(tx.output.len(), 2);
             assert_eq!(
    -            tx.output
    -                .iter()
    -                .find(|txout| txout.script_pubkey == addr.script_pubkey())
    -                .unwrap()
    -                .value,
    -            45_000
    -        );
    +            tx.output
    +                .iter()
    +                .find(|txout| txout.script_pubkey == addr.script_pubkey())
    +                .unwrap()
    +                .value,
    +            45_000
    +        );
             assert_eq!(
    -            tx.output
    -                .iter()
    -                .find(|txout| txout.script_pubkey != addr.script_pubkey())
    -                .unwrap()
    -                .value,
    -            details.received
    +            tx.output
    +                .iter()
    +                .find(|txout| txout.script_pubkey != addr.script_pubkey())
    +                .unwrap()
    +                .value,
    +            details.received
             );
     
    -        assert_fee_rate!(psbt, details.fee.unwrap_or(0), FeeRate::from_sat_per_vb(5.0), @add_signature);
    +        assert_fee_rate!(psbt, details.fee.unwrap_or(0), FeeRate::from_sat_per_vb(5.0), @add_signature);
         }
     
    -    #[test]
    -    fn test_bump_fee_absolute_force_add_input() {
    -        let (wallet, descriptors, _) = get_funded_wallet(get_test_wpkh());
    -        let incoming_txid = crate::populate_test_db!(
    -            wallet.database.borrow_mut(),
    -            testutils! (@tx ( (@external descriptors, 0) => 25_000 ) (@confirmations 1)),
    +    #[test]
    +    fn test_bump_fee_absolute_force_add_input() {
    +        let (wallet, descriptors, _) = get_funded_wallet(get_test_wpkh());
    +        let incoming_txid = crate::populate_test_db!(
    +            wallet.database.borrow_mut(),
    +            testutils! (@tx ( (@external descriptors, 0) => 25_000 ) (@confirmations 1)),
                 Some(100),
             );
     
    -        let addr = Address::from_str("2N1Ffz3WaNzbeLFBb51xyFMHYSEUXcbiSoX").unwrap();
    -        let mut builder = wallet.build_tx();
    -        builder
    -            .add_recipient(addr.script_pubkey(), 45_000)
    -            .enable_rbf();
    -        let (psbt, mut original_details) = builder.finish().unwrap();
    -        let mut tx = psbt.extract_tx();
    -        let txid = tx.txid();
    -        // skip saving the new utxos, we know they can't be used anyways
    -        for txin in &mut tx.input {
    -            txin.witness.push([0x00; P2WPKH_FAKE_WITNESS_SIZE]); // fake signature
    -            wallet
    -                .database
    -                .borrow_mut()
    -                .del_utxo(&txin.previous_output)
    -                .unwrap();
    +        let addr = Address::from_str("2N1Ffz3WaNzbeLFBb51xyFMHYSEUXcbiSoX").unwrap();
    +        let mut builder = wallet.build_tx();
    +        builder
    +            .add_recipient(addr.script_pubkey(), 45_000)
    +            .enable_rbf();
    +        let (psbt, mut original_details) = builder.finish().unwrap();
    +        let mut tx = psbt.extract_tx();
    +        let txid = tx.txid();
    +        // skip saving the new utxos, we know they can't be used anyways
    +        for txin in &mut tx.input {
    +            txin.witness.push([0x00; P2WPKH_FAKE_WITNESS_SIZE]); // fake signature
    +            wallet
    +                .database
    +                .borrow_mut()
    +                .del_utxo(&txin.previous_output)
    +                .unwrap();
             }
    -        original_details.transaction = Some(tx);
    -        wallet
    -            .database
    -            .borrow_mut()
    -            .set_tx(&original_details)
    -            .unwrap();
    -
    -        // the new fee_rate is low enough that just reducing the change would be fine, but we force
    -        // the addition of an extra input with `add_utxo()`
    -        let mut builder = wallet.build_fee_bump(txid).unwrap();
    -        builder
    -            .add_utxo(OutPoint {
    -                txid: incoming_txid,
    -                vout: 0,
    +        original_details.transaction = Some(tx);
    +        wallet
    +            .database
    +            .borrow_mut()
    +            .set_tx(&original_details)
    +            .unwrap();
    +
    +        // the new fee_rate is low enough that just reducing the change would be fine, but we force
    +        // the addition of an extra input with `add_utxo()`
    +        let mut builder = wallet.build_fee_bump(txid).unwrap();
    +        builder
    +            .add_utxo(OutPoint {
    +                txid: incoming_txid,
    +                vout: 0,
                 })
    -            .unwrap()
    -            .fee_absolute(250);
    -        let (psbt, details) = builder.finish().unwrap();
    +            .unwrap()
    +            .fee_absolute(250);
    +        let (psbt, details) = builder.finish().unwrap();
     
    -        assert_eq!(details.sent, original_details.sent + 25_000);
    -        assert_eq!(details.fee.unwrap_or(0) + details.received, 30_000);
    +        assert_eq!(details.sent, original_details.sent + 25_000);
    +        assert_eq!(details.fee.unwrap_or(0) + details.received, 30_000);
     
    -        let tx = &psbt.unsigned_tx;
    -        assert_eq!(tx.input.len(), 2);
    -        assert_eq!(tx.output.len(), 2);
    +        let tx = &psbt.unsigned_tx;
    +        assert_eq!(tx.input.len(), 2);
    +        assert_eq!(tx.output.len(), 2);
             assert_eq!(
    -            tx.output
    -                .iter()
    -                .find(|txout| txout.script_pubkey == addr.script_pubkey())
    -                .unwrap()
    -                .value,
    -            45_000
    -        );
    +            tx.output
    +                .iter()
    +                .find(|txout| txout.script_pubkey == addr.script_pubkey())
    +                .unwrap()
    +                .value,
    +            45_000
    +        );
             assert_eq!(
    -            tx.output
    -                .iter()
    -                .find(|txout| txout.script_pubkey != addr.script_pubkey())
    -                .unwrap()
    -                .value,
    -            details.received
    -        );
    -
    -        assert_eq!(details.fee.unwrap_or(0), 250);
    -    }
    -
    -    #[test]
    -    #[should_panic(expected = "InsufficientFunds")]
    -    fn test_bump_fee_unconfirmed_inputs_only() {
    -        // We try to bump the fee, but:
    -        // - We can't reduce the change, as we have no change
    -        // - All our UTXOs are unconfirmed
    -        // So, we fail with "InsufficientFunds", as per RBF rule 2:
    -        // The replacement transaction may only include an unconfirmed input
    -        // if that input was included in one of the original transactions.
    -        let (wallet, descriptors, _) = get_funded_wallet(get_test_wpkh());
    -        let addr = Address::from_str("2N1Ffz3WaNzbeLFBb51xyFMHYSEUXcbiSoX").unwrap();
    -        let mut builder = wallet.build_tx();
    -        builder
    -            .drain_wallet()
    -            .drain_to(addr.script_pubkey())
    -            .enable_rbf();
    -        let (psbt, mut original_details) = builder.finish().unwrap();
    -        // Now we receive one transaction with 0 confirmations. We won't be able to use that for
    -        // fee bumping, as it's still unconfirmed!
    -        crate::populate_test_db!(
    -            wallet.database.borrow_mut(),
    -            testutils! (@tx ( (@external descriptors, 0) => 25_000 ) (@confirmations 0)),
    +            tx.output
    +                .iter()
    +                .find(|txout| txout.script_pubkey != addr.script_pubkey())
    +                .unwrap()
    +                .value,
    +            details.received
    +        );
    +
    +        assert_eq!(details.fee.unwrap_or(0), 250);
    +    }
    +
    +    #[test]
    +    #[should_panic(expected = "InsufficientFunds")]
    +    fn test_bump_fee_unconfirmed_inputs_only() {
    +        // We try to bump the fee, but:
    +        // - We can't reduce the change, as we have no change
    +        // - All our UTXOs are unconfirmed
    +        // So, we fail with "InsufficientFunds", as per RBF rule 2:
    +        // The replacement transaction may only include an unconfirmed input
    +        // if that input was included in one of the original transactions.
    +        let (wallet, descriptors, _) = get_funded_wallet(get_test_wpkh());
    +        let addr = Address::from_str("2N1Ffz3WaNzbeLFBb51xyFMHYSEUXcbiSoX").unwrap();
    +        let mut builder = wallet.build_tx();
    +        builder
    +            .drain_wallet()
    +            .drain_to(addr.script_pubkey())
    +            .enable_rbf();
    +        let (psbt, mut original_details) = builder.finish().unwrap();
    +        // Now we receive one transaction with 0 confirmations. We won't be able to use that for
    +        // fee bumping, as it's still unconfirmed!
    +        crate::populate_test_db!(
    +            wallet.database.borrow_mut(),
    +            testutils! (@tx ( (@external descriptors, 0) => 25_000 ) (@confirmations 0)),
                 Some(100),
             );
    -        let mut tx = psbt.extract_tx();
    -        let txid = tx.txid();
    -        for txin in &mut tx.input {
    -            txin.witness.push([0x00; P2WPKH_FAKE_WITNESS_SIZE]); // fake signature
    -            wallet
    -                .database
    -                .borrow_mut()
    -                .del_utxo(&txin.previous_output)
    -                .unwrap();
    +        let mut tx = psbt.extract_tx();
    +        let txid = tx.txid();
    +        for txin in &mut tx.input {
    +            txin.witness.push([0x00; P2WPKH_FAKE_WITNESS_SIZE]); // fake signature
    +            wallet
    +                .database
    +                .borrow_mut()
    +                .del_utxo(&txin.previous_output)
    +                .unwrap();
             }
    -        original_details.transaction = Some(tx);
    -        wallet
    -            .database
    -            .borrow_mut()
    -            .set_tx(&original_details)
    -            .unwrap();
    -
    -        let mut builder = wallet.build_fee_bump(txid).unwrap();
    -        builder.fee_rate(FeeRate::from_sat_per_vb(25.0));
    -        builder.finish().unwrap();
    -    }
    -
    -    #[test]
    -    fn test_bump_fee_unconfirmed_input() {
    -        // We create a tx draining the wallet and spending one confirmed
    -        // and one unconfirmed UTXO. We check that we can fee bump normally
    -        // (BIP125 rule 2 only apply to newly added unconfirmed input, you can
    -        // always fee bump with an unconfirmed input if it was included in the
    -        // original transaction)
    -        let (wallet, descriptors, _) = get_funded_wallet(get_test_wpkh());
    -        let addr = Address::from_str("2N1Ffz3WaNzbeLFBb51xyFMHYSEUXcbiSoX").unwrap();
    -        // We receive a tx with 0 confirmations, which will be used as an input
    -        // in the drain tx.
    -        crate::populate_test_db!(
    -            wallet.database.borrow_mut(),
    -            testutils! (@tx ( (@external descriptors, 0) => 25_000 ) (@confirmations 0)),
    +        original_details.transaction = Some(tx);
    +        wallet
    +            .database
    +            .borrow_mut()
    +            .set_tx(&original_details)
    +            .unwrap();
    +
    +        let mut builder = wallet.build_fee_bump(txid).unwrap();
    +        builder.fee_rate(FeeRate::from_sat_per_vb(25.0));
    +        builder.finish().unwrap();
    +    }
    +
    +    #[test]
    +    fn test_bump_fee_unconfirmed_input() {
    +        // We create a tx draining the wallet and spending one confirmed
    +        // and one unconfirmed UTXO. We check that we can fee bump normally
    +        // (BIP125 rule 2 only apply to newly added unconfirmed input, you can
    +        // always fee bump with an unconfirmed input if it was included in the
    +        // original transaction)
    +        let (wallet, descriptors, _) = get_funded_wallet(get_test_wpkh());
    +        let addr = Address::from_str("2N1Ffz3WaNzbeLFBb51xyFMHYSEUXcbiSoX").unwrap();
    +        // We receive a tx with 0 confirmations, which will be used as an input
    +        // in the drain tx.
    +        crate::populate_test_db!(
    +            wallet.database.borrow_mut(),
    +            testutils! (@tx ( (@external descriptors, 0) => 25_000 ) (@confirmations 0)),
                 Some(100),
             );
    -        let mut builder = wallet.build_tx();
    -        builder
    -            .drain_wallet()
    -            .drain_to(addr.script_pubkey())
    -            .enable_rbf();
    -        let (psbt, mut original_details) = builder.finish().unwrap();
    -        let mut tx = psbt.extract_tx();
    -        let txid = tx.txid();
    -        for txin in &mut tx.input {
    -            txin.witness.push([0x00; P2WPKH_FAKE_WITNESS_SIZE]); // fake signature
    -            wallet
    -                .database
    -                .borrow_mut()
    -                .del_utxo(&txin.previous_output)
    -                .unwrap();
    +        let mut builder = wallet.build_tx();
    +        builder
    +            .drain_wallet()
    +            .drain_to(addr.script_pubkey())
    +            .enable_rbf();
    +        let (psbt, mut original_details) = builder.finish().unwrap();
    +        let mut tx = psbt.extract_tx();
    +        let txid = tx.txid();
    +        for txin in &mut tx.input {
    +            txin.witness.push([0x00; P2WPKH_FAKE_WITNESS_SIZE]); // fake signature
    +            wallet
    +                .database
    +                .borrow_mut()
    +                .del_utxo(&txin.previous_output)
    +                .unwrap();
             }
    -        original_details.transaction = Some(tx);
    -        wallet
    -            .database
    -            .borrow_mut()
    -            .set_tx(&original_details)
    -            .unwrap();
    -
    -        let mut builder = wallet.build_fee_bump(txid).unwrap();
    -        builder
    -            .fee_rate(FeeRate::from_sat_per_vb(15.0))
    -            .allow_shrinking(addr.script_pubkey())
    -            .unwrap();
    -        builder.finish().unwrap();
    -    }
    -
    -    #[test]
    -    fn test_fee_amount_negative_drain_val() {
    -        // While building the transaction, bdk would calculate the drain_value
    -        // as
    -        // current_delta - fee_amount - drain_fee
    -        // using saturating_sub, meaning that if the result would end up negative,
    -        // it'll remain to zero instead.
    -        // This caused a bug in master where we would calculate the wrong fee
    -        // for a transaction.
    -        // See https://github.com/bitcoindevkit/bdk/issues/660
    -        let (wallet, descriptors, _) = get_funded_wallet(get_test_wpkh());
    -        let send_to = Address::from_str("tb1ql7w62elx9ucw4pj5lgw4l028hmuw80sndtntxt").unwrap();
    -        let fee_rate = FeeRate::from_sat_per_vb(2.01);
    -        let incoming_txid = crate::populate_test_db!(
    -            wallet.database.borrow_mut(),
    -            testutils! (@tx ( (@external descriptors, 0) => 8859 ) (@confirmations 1)),
    +        original_details.transaction = Some(tx);
    +        wallet
    +            .database
    +            .borrow_mut()
    +            .set_tx(&original_details)
    +            .unwrap();
    +
    +        let mut builder = wallet.build_fee_bump(txid).unwrap();
    +        builder
    +            .fee_rate(FeeRate::from_sat_per_vb(15.0))
    +            .allow_shrinking(addr.script_pubkey())
    +            .unwrap();
    +        builder.finish().unwrap();
    +    }
    +
    +    #[test]
    +    fn test_fee_amount_negative_drain_val() {
    +        // While building the transaction, bdk would calculate the drain_value
    +        // as
    +        // current_delta - fee_amount - drain_fee
    +        // using saturating_sub, meaning that if the result would end up negative,
    +        // it'll remain to zero instead.
    +        // This caused a bug in master where we would calculate the wrong fee
    +        // for a transaction.
    +        // See https://github.com/bitcoindevkit/bdk/issues/660
    +        let (wallet, descriptors, _) = get_funded_wallet(get_test_wpkh());
    +        let send_to = Address::from_str("tb1ql7w62elx9ucw4pj5lgw4l028hmuw80sndtntxt").unwrap();
    +        let fee_rate = FeeRate::from_sat_per_vb(2.01);
    +        let incoming_txid = crate::populate_test_db!(
    +            wallet.database.borrow_mut(),
    +            testutils! (@tx ( (@external descriptors, 0) => 8859 ) (@confirmations 1)),
                 Some(100),
             );
     
    -        let mut builder = wallet.build_tx();
    -        builder
    -            .add_recipient(send_to.script_pubkey(), 8630)
    -            .add_utxo(OutPoint::new(incoming_txid, 0))
    -            .unwrap()
    -            .enable_rbf()
    -            .fee_rate(fee_rate);
    -        let (psbt, details) = builder.finish().unwrap();
    +        let mut builder = wallet.build_tx();
    +        builder
    +            .add_recipient(send_to.script_pubkey(), 8630)
    +            .add_utxo(OutPoint::new(incoming_txid, 0))
    +            .unwrap()
    +            .enable_rbf()
    +            .fee_rate(fee_rate);
    +        let (psbt, details) = builder.finish().unwrap();
     
    -        assert!(psbt.inputs.len() == 1);
    -        assert_fee_rate!(psbt, details.fee.unwrap_or(0), fee_rate, @add_signature);
    +        assert!(psbt.inputs.len() == 1);
    +        assert_fee_rate!(psbt, details.fee.unwrap_or(0), fee_rate, @add_signature);
         }
     
    -    #[test]
    -    fn test_sign_single_xprv() {
    -        let (wallet, _, _) = get_funded_wallet("wpkh(tprv8ZgxMBicQKsPd3EupYiPRhaMooHKUHJxNsTfYuScep13go8QFfHdtkG9nRkFGb7busX4isf6X9dURGCoKgitaApQ6MupRhZMcELAxTBRJgS/*)");
    -        let addr = wallet.get_address(New).unwrap();
    -        let mut builder = wallet.build_tx();
    -        builder.drain_to(addr.script_pubkey()).drain_wallet();
    -        let (mut psbt, _) = builder.finish().unwrap();
    +    #[test]
    +    fn test_sign_single_xprv() {
    +        let (wallet, _, _) = get_funded_wallet("wpkh(tprv8ZgxMBicQKsPd3EupYiPRhaMooHKUHJxNsTfYuScep13go8QFfHdtkG9nRkFGb7busX4isf6X9dURGCoKgitaApQ6MupRhZMcELAxTBRJgS/*)");
    +        let addr = wallet.get_address(New).unwrap();
    +        let mut builder = wallet.build_tx();
    +        builder.drain_to(addr.script_pubkey()).drain_wallet();
    +        let (mut psbt, _) = builder.finish().unwrap();
     
    -        let finalized = wallet.sign(&mut psbt, Default::default()).unwrap();
    -        assert!(finalized);
    +        let finalized = wallet.sign(&mut psbt, Default::default()).unwrap();
    +        assert!(finalized);
     
    -        let extracted = psbt.extract_tx();
    -        assert_eq!(extracted.input[0].witness.len(), 2);
    +        let extracted = psbt.extract_tx();
    +        assert_eq!(extracted.input[0].witness.len(), 2);
         }
     
    -    #[test]
    -    fn test_sign_single_xprv_with_master_fingerprint_and_path() {
    -        let (wallet, _, _) = get_funded_wallet("wpkh([d34db33f/84h/1h/0h]tprv8ZgxMBicQKsPd3EupYiPRhaMooHKUHJxNsTfYuScep13go8QFfHdtkG9nRkFGb7busX4isf6X9dURGCoKgitaApQ6MupRhZMcELAxTBRJgS/*)");
    -        let addr = wallet.get_address(New).unwrap();
    -        let mut builder = wallet.build_tx();
    -        builder.drain_to(addr.script_pubkey()).drain_wallet();
    -        let (mut psbt, _) = builder.finish().unwrap();
    -
    -        let finalized = wallet.sign(&mut psbt, Default::default()).unwrap();
    -        assert!(finalized);
    -
    -        let extracted = psbt.extract_tx();
    -        assert_eq!(extracted.input[0].witness.len(), 2);
    -    }
    -
    -    #[test]
    -    fn test_sign_single_xprv_bip44_path() {
    -        let (wallet, _, _) = get_funded_wallet("wpkh(tprv8ZgxMBicQKsPd3EupYiPRhaMooHKUHJxNsTfYuScep13go8QFfHdtkG9nRkFGb7busX4isf6X9dURGCoKgitaApQ6MupRhZMcELAxTBRJgS/44'/0'/0'/0/*)");
    -        let addr = wallet.get_address(New).unwrap();
    -        let mut builder = wallet.build_tx();
    -        builder.drain_to(addr.script_pubkey()).drain_wallet();
    -        let (mut psbt, _) = builder.finish().unwrap();
    -
    -        let finalized = wallet.sign(&mut psbt, Default::default()).unwrap();
    -        assert!(finalized);
    -
    -        let extracted = psbt.extract_tx();
    -        assert_eq!(extracted.input[0].witness.len(), 2);
    -    }
    -
    -    #[test]
    -    fn test_sign_single_xprv_sh_wpkh() {
    -        let (wallet, _, _) = get_funded_wallet("sh(wpkh(tprv8ZgxMBicQKsPd3EupYiPRhaMooHKUHJxNsTfYuScep13go8QFfHdtkG9nRkFGb7busX4isf6X9dURGCoKgitaApQ6MupRhZMcELAxTBRJgS/*))");
    -        let addr = wallet.get_address(New).unwrap();
    -        let mut builder = wallet.build_tx();
    -        builder.drain_to(addr.script_pubkey()).drain_wallet();
    -        let (mut psbt, _) = builder.finish().unwrap();
    -
    -        let finalized = wallet.sign(&mut psbt, Default::default()).unwrap();
    -        assert!(finalized);
    -
    -        let extracted = psbt.extract_tx();
    -        assert_eq!(extracted.input[0].witness.len(), 2);
    -    }
    -
    -    #[test]
    -    fn test_sign_single_wif() {
    -        let (wallet, _, _) =
    -            get_funded_wallet("wpkh(cVpPVruEDdmutPzisEsYvtST1usBR3ntr8pXSyt6D2YYqXRyPcFW)");
    -        let addr = wallet.get_address(New).unwrap();
    -        let mut builder = wallet.build_tx();
    -        builder.drain_to(addr.script_pubkey()).drain_wallet();
    -        let (mut psbt, _) = builder.finish().unwrap();
    -
    -        let finalized = wallet.sign(&mut psbt, Default::default()).unwrap();
    -        assert!(finalized);
    -
    -        let extracted = psbt.extract_tx();
    -        assert_eq!(extracted.input[0].witness.len(), 2);
    -    }
    -
    -    #[test]
    -    fn test_sign_single_xprv_no_hd_keypaths() {
    -        let (wallet, _, _) = get_funded_wallet("wpkh(tprv8ZgxMBicQKsPd3EupYiPRhaMooHKUHJxNsTfYuScep13go8QFfHdtkG9nRkFGb7busX4isf6X9dURGCoKgitaApQ6MupRhZMcELAxTBRJgS/*)");
    -        let addr = wallet.get_address(New).unwrap();
    -        let mut builder = wallet.build_tx();
    -        builder.drain_to(addr.script_pubkey()).drain_wallet();
    -        let (mut psbt, _) = builder.finish().unwrap();
    -
    -        psbt.inputs[0].bip32_derivation.clear();
    -        assert_eq!(psbt.inputs[0].bip32_derivation.len(), 0);
    -
    -        let finalized = wallet.sign(&mut psbt, Default::default()).unwrap();
    -        assert!(finalized);
    -
    -        let extracted = psbt.extract_tx();
    -        assert_eq!(extracted.input[0].witness.len(), 2);
    -    }
    -
    -    #[test]
    -    fn test_include_output_redeem_witness_script() {
    -        let (wallet, _, _) = get_funded_wallet("sh(wsh(multi(1,cVpPVruEDdmutPzisEsYvtST1usBR3ntr8pXSyt6D2YYqXRyPcFW,cRjo6jqfVNP33HhSS76UhXETZsGTZYx8FMFvR9kpbtCSV1PmdZdu)))");
    -        let addr = Address::from_str("2N1Ffz3WaNzbeLFBb51xyFMHYSEUXcbiSoX").unwrap();
    -        let mut builder = wallet.build_tx();
    -        builder
    -            .add_recipient(addr.script_pubkey(), 45_000)
    -            .include_output_redeem_witness_script();
    -        let (psbt, _) = builder.finish().unwrap();
    -
    -        // p2sh-p2wsh transaction should contain both witness and redeem scripts
    -        assert!(psbt
    -            .outputs
    -            .iter()
    -            .any(|output| output.redeem_script.is_some() && output.witness_script.is_some()));
    -    }
    -
    -    #[test]
    -    fn test_signing_only_one_of_multiple_inputs() {
    -        let (wallet, _, _) = get_funded_wallet(get_test_wpkh());
    -        let addr = Address::from_str("2N1Ffz3WaNzbeLFBb51xyFMHYSEUXcbiSoX").unwrap();
    -        let mut builder = wallet.build_tx();
    -        builder
    -            .add_recipient(addr.script_pubkey(), 45_000)
    -            .include_output_redeem_witness_script();
    -        let (mut psbt, _) = builder.finish().unwrap();
    -
    -        // add another input to the psbt that is at least passable.
    -        let dud_input = bitcoin::util::psbt::Input {
    -            witness_utxo: Some(TxOut {
    -                value: 100_000,
    -                script_pubkey: miniscript::Descriptor::<bitcoin::PublicKey>::from_str(
    +    #[test]
    +    fn test_sign_single_xprv_with_master_fingerprint_and_path() {
    +        let (wallet, _, _) = get_funded_wallet("wpkh([d34db33f/84h/1h/0h]tprv8ZgxMBicQKsPd3EupYiPRhaMooHKUHJxNsTfYuScep13go8QFfHdtkG9nRkFGb7busX4isf6X9dURGCoKgitaApQ6MupRhZMcELAxTBRJgS/*)");
    +        let addr = wallet.get_address(New).unwrap();
    +        let mut builder = wallet.build_tx();
    +        builder.drain_to(addr.script_pubkey()).drain_wallet();
    +        let (mut psbt, _) = builder.finish().unwrap();
    +
    +        let finalized = wallet.sign(&mut psbt, Default::default()).unwrap();
    +        assert!(finalized);
    +
    +        let extracted = psbt.extract_tx();
    +        assert_eq!(extracted.input[0].witness.len(), 2);
    +    }
    +
    +    #[test]
    +    fn test_sign_single_xprv_bip44_path() {
    +        let (wallet, _, _) = get_funded_wallet("wpkh(tprv8ZgxMBicQKsPd3EupYiPRhaMooHKUHJxNsTfYuScep13go8QFfHdtkG9nRkFGb7busX4isf6X9dURGCoKgitaApQ6MupRhZMcELAxTBRJgS/44'/0'/0'/0/*)");
    +        let addr = wallet.get_address(New).unwrap();
    +        let mut builder = wallet.build_tx();
    +        builder.drain_to(addr.script_pubkey()).drain_wallet();
    +        let (mut psbt, _) = builder.finish().unwrap();
    +
    +        let finalized = wallet.sign(&mut psbt, Default::default()).unwrap();
    +        assert!(finalized);
    +
    +        let extracted = psbt.extract_tx();
    +        assert_eq!(extracted.input[0].witness.len(), 2);
    +    }
    +
    +    #[test]
    +    fn test_sign_single_xprv_sh_wpkh() {
    +        let (wallet, _, _) = get_funded_wallet("sh(wpkh(tprv8ZgxMBicQKsPd3EupYiPRhaMooHKUHJxNsTfYuScep13go8QFfHdtkG9nRkFGb7busX4isf6X9dURGCoKgitaApQ6MupRhZMcELAxTBRJgS/*))");
    +        let addr = wallet.get_address(New).unwrap();
    +        let mut builder = wallet.build_tx();
    +        builder.drain_to(addr.script_pubkey()).drain_wallet();
    +        let (mut psbt, _) = builder.finish().unwrap();
    +
    +        let finalized = wallet.sign(&mut psbt, Default::default()).unwrap();
    +        assert!(finalized);
    +
    +        let extracted = psbt.extract_tx();
    +        assert_eq!(extracted.input[0].witness.len(), 2);
    +    }
    +
    +    #[test]
    +    fn test_sign_single_wif() {
    +        let (wallet, _, _) =
    +            get_funded_wallet("wpkh(cVpPVruEDdmutPzisEsYvtST1usBR3ntr8pXSyt6D2YYqXRyPcFW)");
    +        let addr = wallet.get_address(New).unwrap();
    +        let mut builder = wallet.build_tx();
    +        builder.drain_to(addr.script_pubkey()).drain_wallet();
    +        let (mut psbt, _) = builder.finish().unwrap();
    +
    +        let finalized = wallet.sign(&mut psbt, Default::default()).unwrap();
    +        assert!(finalized);
    +
    +        let extracted = psbt.extract_tx();
    +        assert_eq!(extracted.input[0].witness.len(), 2);
    +    }
    +
    +    #[test]
    +    fn test_sign_single_xprv_no_hd_keypaths() {
    +        let (wallet, _, _) = get_funded_wallet("wpkh(tprv8ZgxMBicQKsPd3EupYiPRhaMooHKUHJxNsTfYuScep13go8QFfHdtkG9nRkFGb7busX4isf6X9dURGCoKgitaApQ6MupRhZMcELAxTBRJgS/*)");
    +        let addr = wallet.get_address(New).unwrap();
    +        let mut builder = wallet.build_tx();
    +        builder.drain_to(addr.script_pubkey()).drain_wallet();
    +        let (mut psbt, _) = builder.finish().unwrap();
    +
    +        psbt.inputs[0].bip32_derivation.clear();
    +        assert_eq!(psbt.inputs[0].bip32_derivation.len(), 0);
    +
    +        let finalized = wallet.sign(&mut psbt, Default::default()).unwrap();
    +        assert!(finalized);
    +
    +        let extracted = psbt.extract_tx();
    +        assert_eq!(extracted.input[0].witness.len(), 2);
    +    }
    +
    +    #[test]
    +    fn test_include_output_redeem_witness_script() {
    +        let (wallet, _, _) = get_funded_wallet("sh(wsh(multi(1,cVpPVruEDdmutPzisEsYvtST1usBR3ntr8pXSyt6D2YYqXRyPcFW,cRjo6jqfVNP33HhSS76UhXETZsGTZYx8FMFvR9kpbtCSV1PmdZdu)))");
    +        let addr = Address::from_str("2N1Ffz3WaNzbeLFBb51xyFMHYSEUXcbiSoX").unwrap();
    +        let mut builder = wallet.build_tx();
    +        builder
    +            .add_recipient(addr.script_pubkey(), 45_000)
    +            .include_output_redeem_witness_script();
    +        let (psbt, _) = builder.finish().unwrap();
    +
    +        // p2sh-p2wsh transaction should contain both witness and redeem scripts
    +        assert!(psbt
    +            .outputs
    +            .iter()
    +            .any(|output| output.redeem_script.is_some() && output.witness_script.is_some()));
    +    }
    +
    +    #[test]
    +    fn test_signing_only_one_of_multiple_inputs() {
    +        let (wallet, _, _) = get_funded_wallet(get_test_wpkh());
    +        let addr = Address::from_str("2N1Ffz3WaNzbeLFBb51xyFMHYSEUXcbiSoX").unwrap();
    +        let mut builder = wallet.build_tx();
    +        builder
    +            .add_recipient(addr.script_pubkey(), 45_000)
    +            .include_output_redeem_witness_script();
    +        let (mut psbt, _) = builder.finish().unwrap();
    +
    +        // add another input to the psbt that is at least passable.
    +        let dud_input = bitcoin::util::psbt::Input {
    +            witness_utxo: Some(TxOut {
    +                value: 100_000,
    +                script_pubkey: miniscript::Descriptor::<bitcoin::PublicKey>::from_str(
                         "wpkh(025476c2e83188368da1ff3e292e7acafcdb3566bb0ad253f62fc70f07aeee6357)",
                     )
    -                .unwrap()
    -                .script_pubkey(),
    +                .unwrap()
    +                .script_pubkey(),
                 }),
    -            ..Default::default()
    +            ..Default::default()
             };
     
    -        psbt.inputs.push(dud_input);
    -        psbt.unsigned_tx.input.push(bitcoin::TxIn::default());
    -        let is_final = wallet
    -            .sign(
    -                &mut psbt,
    -                SignOptions {
    -                    trust_witness_utxo: true,
    -                    ..Default::default()
    +        psbt.inputs.push(dud_input);
    +        psbt.unsigned_tx.input.push(bitcoin::TxIn::default());
    +        let is_final = wallet
    +            .sign(
    +                &mut psbt,
    +                SignOptions {
    +                    trust_witness_utxo: true,
    +                    ..Default::default()
                     },
                 )
    -            .unwrap();
    +            .unwrap();
             assert!(
    -            !is_final,
    -            "shouldn't be final since we can't sign one of the inputs"
    -        );
    +            !is_final,
    +            "shouldn't be final since we can't sign one of the inputs"
    +        );
             assert!(
    -            psbt.inputs[0].final_script_witness.is_some(),
    -            "should finalized input it signed"
    -        )
    -    }
    -
    -    #[test]
    -    fn test_remove_partial_sigs_after_finalize_sign_option() {
    -        let (wallet, _, _) = get_funded_wallet("wpkh(tprv8ZgxMBicQKsPd3EupYiPRhaMooHKUHJxNsTfYuScep13go8QFfHdtkG9nRkFGb7busX4isf6X9dURGCoKgitaApQ6MupRhZMcELAxTBRJgS/*)");
    -
    -        for remove_partial_sigs in &[true, false] {
    -            let addr = wallet.get_address(New).unwrap();
    -            let mut builder = wallet.build_tx();
    -            builder.drain_to(addr.script_pubkey()).drain_wallet();
    -            let mut psbt = builder.finish().unwrap().0;
    -
    -            assert!(wallet
    -                .sign(
    -                    &mut psbt,
    -                    SignOptions {
    -                        remove_partial_sigs: *remove_partial_sigs,
    -                        ..Default::default()
    +            psbt.inputs[0].final_script_witness.is_some(),
    +            "should finalized input it signed"
    +        )
    +    }
    +
    +    #[test]
    +    fn test_remove_partial_sigs_after_finalize_sign_option() {
    +        let (wallet, _, _) = get_funded_wallet("wpkh(tprv8ZgxMBicQKsPd3EupYiPRhaMooHKUHJxNsTfYuScep13go8QFfHdtkG9nRkFGb7busX4isf6X9dURGCoKgitaApQ6MupRhZMcELAxTBRJgS/*)");
    +
    +        for remove_partial_sigs in &[true, false] {
    +            let addr = wallet.get_address(New).unwrap();
    +            let mut builder = wallet.build_tx();
    +            builder.drain_to(addr.script_pubkey()).drain_wallet();
    +            let mut psbt = builder.finish().unwrap().0;
    +
    +            assert!(wallet
    +                .sign(
    +                    &mut psbt,
    +                    SignOptions {
    +                        remove_partial_sigs: *remove_partial_sigs,
    +                        ..Default::default()
                         },
                     )
    -                .unwrap());
    +                .unwrap());
     
    -            psbt.inputs.iter().for_each(|input| {
    -                if *remove_partial_sigs {
    -                    assert!(input.partial_sigs.is_empty())
    -                } else {
    -                    assert!(!input.partial_sigs.is_empty())
    +            psbt.inputs.iter().for_each(|input| {
    +                if *remove_partial_sigs {
    +                    assert!(input.partial_sigs.is_empty())
    +                } else {
    +                    assert!(!input.partial_sigs.is_empty())
                     }
                 });
             }
         }
     
    -    #[test]
    -    fn test_try_finalize_sign_option() {
    -        let (wallet, _, _) = get_funded_wallet("wpkh(tprv8ZgxMBicQKsPd3EupYiPRhaMooHKUHJxNsTfYuScep13go8QFfHdtkG9nRkFGb7busX4isf6X9dURGCoKgitaApQ6MupRhZMcELAxTBRJgS/*)");
    +    #[test]
    +    fn test_try_finalize_sign_option() {
    +        let (wallet, _, _) = get_funded_wallet("wpkh(tprv8ZgxMBicQKsPd3EupYiPRhaMooHKUHJxNsTfYuScep13go8QFfHdtkG9nRkFGb7busX4isf6X9dURGCoKgitaApQ6MupRhZMcELAxTBRJgS/*)");
     
    -        for try_finalize in &[true, false] {
    -            let addr = wallet.get_address(New).unwrap();
    -            let mut builder = wallet.build_tx();
    -            builder.drain_to(addr.script_pubkey()).drain_wallet();
    -            let mut psbt = builder.finish().unwrap().0;
    +        for try_finalize in &[true, false] {
    +            let addr = wallet.get_address(New).unwrap();
    +            let mut builder = wallet.build_tx();
    +            builder.drain_to(addr.script_pubkey()).drain_wallet();
    +            let mut psbt = builder.finish().unwrap().0;
     
    -            let finalized = wallet
    -                .sign(
    -                    &mut psbt,
    -                    SignOptions {
    -                        try_finalize: *try_finalize,
    -                        ..Default::default()
    +            let finalized = wallet
    +                .sign(
    +                    &mut psbt,
    +                    SignOptions {
    +                        try_finalize: *try_finalize,
    +                        ..Default::default()
                         },
                     )
    -                .unwrap();
    -
    -            psbt.inputs.iter().for_each(|input| {
    -                if *try_finalize {
    -                    assert!(finalized);
    -                    assert!(input.final_script_sig.is_some());
    -                    assert!(input.final_script_witness.is_some());
    -                } else {
    -                    assert!(!finalized);
    -                    assert!(input.final_script_sig.is_none());
    -                    assert!(input.final_script_witness.is_none());
    +                .unwrap();
    +
    +            psbt.inputs.iter().for_each(|input| {
    +                if *try_finalize {
    +                    assert!(finalized);
    +                    assert!(input.final_script_sig.is_some());
    +                    assert!(input.final_script_witness.is_some());
    +                } else {
    +                    assert!(!finalized);
    +                    assert!(input.final_script_sig.is_none());
    +                    assert!(input.final_script_witness.is_none());
                     }
                 });
             }
         }
     
    -    #[test]
    -    fn test_sign_nonstandard_sighash() {
    -        let sighash = EcdsaSighashType::NonePlusAnyoneCanPay;
    +    #[test]
    +    fn test_sign_nonstandard_sighash() {
    +        let sighash = EcdsaSighashType::NonePlusAnyoneCanPay;
     
    -        let (wallet, _, _) = get_funded_wallet("wpkh(tprv8ZgxMBicQKsPd3EupYiPRhaMooHKUHJxNsTfYuScep13go8QFfHdtkG9nRkFGb7busX4isf6X9dURGCoKgitaApQ6MupRhZMcELAxTBRJgS/*)");
    -        let addr = wallet.get_address(New).unwrap();
    -        let mut builder = wallet.build_tx();
    -        builder
    -            .drain_to(addr.script_pubkey())
    -            .sighash(sighash.into())
    -            .drain_wallet();
    -        let (mut psbt, _) = builder.finish().unwrap();
    +        let (wallet, _, _) = get_funded_wallet("wpkh(tprv8ZgxMBicQKsPd3EupYiPRhaMooHKUHJxNsTfYuScep13go8QFfHdtkG9nRkFGb7busX4isf6X9dURGCoKgitaApQ6MupRhZMcELAxTBRJgS/*)");
    +        let addr = wallet.get_address(New).unwrap();
    +        let mut builder = wallet.build_tx();
    +        builder
    +            .drain_to(addr.script_pubkey())
    +            .sighash(sighash.into())
    +            .drain_wallet();
    +        let (mut psbt, _) = builder.finish().unwrap();
     
    -        let result = wallet.sign(&mut psbt, Default::default());
    +        let result = wallet.sign(&mut psbt, Default::default());
             assert!(
    -            result.is_err(),
    -            "Signing should have failed because the TX uses non-standard sighashes"
    -        );
    +            result.is_err(),
    +            "Signing should have failed because the TX uses non-standard sighashes"
    +        );
             assert!(
                 matches!(
    -                result.unwrap_err(),
    -                Error::Signer(SignerError::NonStandardSighash)
    +                result.unwrap_err(),
    +                Error::Signer(SignerError::NonStandardSighash)
                 ),
    -            "Signing failed with the wrong error type"
    -        );
    -
    -        // try again after opting-in
    -        let result = wallet.sign(
    -            &mut psbt,
    -            SignOptions {
    -                allow_all_sighashes: true,
    -                ..Default::default()
    +            "Signing failed with the wrong error type"
    +        );
    +
    +        // try again after opting-in
    +        let result = wallet.sign(
    +            &mut psbt,
    +            SignOptions {
    +                allow_all_sighashes: true,
    +                ..Default::default()
                 },
             );
    -        assert!(result.is_ok(), "Signing should have worked");
    +        assert!(result.is_ok(), "Signing should have worked");
             assert!(
    -            result.unwrap(),
    -            "Should finalize the input since we can produce signatures"
    -        );
    +            result.unwrap(),
    +            "Should finalize the input since we can produce signatures"
    +        );
     
    -        let extracted = psbt.extract_tx();
    +        let extracted = psbt.extract_tx();
             assert_eq!(
    -            *extracted.input[0].witness.to_vec()[0].last().unwrap(),
    -            sighash.to_u32() as u8,
    -            "The signature should have been made with the right sighash"
    -        );
    +            *extracted.input[0].witness.to_vec()[0].last().unwrap(),
    +            sighash.to_u32() as u8,
    +            "The signature should have been made with the right sighash"
    +        );
         }
     
    -    #[test]
    -    fn test_unused_address() {
    -        let db = MemoryDatabase::new();
    -        let wallet = Wallet::new("wpkh(tpubEBr4i6yk5nf5DAaJpsi9N2pPYBeJ7fZ5Z9rmN4977iYLCGco1VyjB9tvvuvYtfZzjD5A8igzgw3HeWeeKFmanHYqksqZXYXGsw5zjnj7KM9/*)",
    -                                         None, Network::Testnet, db).unwrap();
    +    #[test]
    +    fn test_unused_address() {
    +        let db = MemoryDatabase::new();
    +        let wallet = Wallet::new("wpkh(tpubEBr4i6yk5nf5DAaJpsi9N2pPYBeJ7fZ5Z9rmN4977iYLCGco1VyjB9tvvuvYtfZzjD5A8igzgw3HeWeeKFmanHYqksqZXYXGsw5zjnj7KM9/*)",
    +                                         None, Network::Testnet, db).unwrap();
     
             assert_eq!(
    -            wallet.get_address(LastUnused).unwrap().to_string(),
    -            "tb1q6yn66vajcctph75pvylgkksgpp6nq04ppwct9a"
    -        );
    +            wallet.get_address(LastUnused).unwrap().to_string(),
    +            "tb1q6yn66vajcctph75pvylgkksgpp6nq04ppwct9a"
    +        );
             assert_eq!(
    -            wallet.get_address(LastUnused).unwrap().to_string(),
    -            "tb1q6yn66vajcctph75pvylgkksgpp6nq04ppwct9a"
    -        );
    +            wallet.get_address(LastUnused).unwrap().to_string(),
    +            "tb1q6yn66vajcctph75pvylgkksgpp6nq04ppwct9a"
    +        );
         }
     
    -    #[test]
    -    fn test_next_unused_address() {
    -        let descriptor = "wpkh(tpubEBr4i6yk5nf5DAaJpsi9N2pPYBeJ7fZ5Z9rmN4977iYLCGco1VyjB9tvvuvYtfZzjD5A8igzgw3HeWeeKFmanHYqksqZXYXGsw5zjnj7KM9/*)";
    -        let descriptors = testutils!(@descriptors (descriptor));
    -        let wallet = Wallet::new(
    -            &descriptors.0,
    +    #[test]
    +    fn test_next_unused_address() {
    +        let descriptor = "wpkh(tpubEBr4i6yk5nf5DAaJpsi9N2pPYBeJ7fZ5Z9rmN4977iYLCGco1VyjB9tvvuvYtfZzjD5A8igzgw3HeWeeKFmanHYqksqZXYXGsw5zjnj7KM9/*)";
    +        let descriptors = testutils!(@descriptors (descriptor));
    +        let wallet = Wallet::new(
    +            &descriptors.0,
                 None,
    -            Network::Testnet,
    -            MemoryDatabase::new(),
    +            Network::Testnet,
    +            MemoryDatabase::new(),
             )
    -        .unwrap();
    +        .unwrap();
     
             assert_eq!(
    -            wallet.get_address(LastUnused).unwrap().to_string(),
    -            "tb1q6yn66vajcctph75pvylgkksgpp6nq04ppwct9a"
    -        );
    -
    -        // use the above address
    -        crate::populate_test_db!(
    -            wallet.database.borrow_mut(),
    -            testutils! (@tx ( (@external descriptors, 0) => 25_000 ) (@confirmations 1)),
    +            wallet.get_address(LastUnused).unwrap().to_string(),
    +            "tb1q6yn66vajcctph75pvylgkksgpp6nq04ppwct9a"
    +        );
    +
    +        // use the above address
    +        crate::populate_test_db!(
    +            wallet.database.borrow_mut(),
    +            testutils! (@tx ( (@external descriptors, 0) => 25_000 ) (@confirmations 1)),
                 Some(100),
             );
     
             assert_eq!(
    -            wallet.get_address(LastUnused).unwrap().to_string(),
    -            "tb1q4er7kxx6sssz3q7qp7zsqsdx4erceahhax77d7"
    -        );
    +            wallet.get_address(LastUnused).unwrap().to_string(),
    +            "tb1q4er7kxx6sssz3q7qp7zsqsdx4erceahhax77d7"
    +        );
         }
     
    -    #[test]
    -    fn test_peek_address_at_index() {
    -        let db = MemoryDatabase::new();
    -        let wallet = Wallet::new("wpkh(tpubEBr4i6yk5nf5DAaJpsi9N2pPYBeJ7fZ5Z9rmN4977iYLCGco1VyjB9tvvuvYtfZzjD5A8igzgw3HeWeeKFmanHYqksqZXYXGsw5zjnj7KM9/*)",
    -                                         None, Network::Testnet, db).unwrap();
    +    #[test]
    +    fn test_peek_address_at_index() {
    +        let db = MemoryDatabase::new();
    +        let wallet = Wallet::new("wpkh(tpubEBr4i6yk5nf5DAaJpsi9N2pPYBeJ7fZ5Z9rmN4977iYLCGco1VyjB9tvvuvYtfZzjD5A8igzgw3HeWeeKFmanHYqksqZXYXGsw5zjnj7KM9/*)",
    +                                         None, Network::Testnet, db).unwrap();
     
             assert_eq!(
    -            wallet.get_address(Peek(1)).unwrap().to_string(),
    -            "tb1q4er7kxx6sssz3q7qp7zsqsdx4erceahhax77d7"
    -        );
    +            wallet.get_address(Peek(1)).unwrap().to_string(),
    +            "tb1q4er7kxx6sssz3q7qp7zsqsdx4erceahhax77d7"
    +        );
     
             assert_eq!(
    -            wallet.get_address(Peek(0)).unwrap().to_string(),
    -            "tb1q6yn66vajcctph75pvylgkksgpp6nq04ppwct9a"
    -        );
    -
    -        assert_eq!(
    -            wallet.get_address(Peek(2)).unwrap().to_string(),
    -            "tb1qzntf2mqex4ehwkjlfdyy3ewdlk08qkvkvrz7x2"
    -        );
    -
    -        // current new address is not affected
    -        assert_eq!(
    -            wallet.get_address(New).unwrap().to_string(),
    -            "tb1q6yn66vajcctph75pvylgkksgpp6nq04ppwct9a"
    -        );
    -
    -        assert_eq!(
    -            wallet.get_address(New).unwrap().to_string(),
    -            "tb1q4er7kxx6sssz3q7qp7zsqsdx4erceahhax77d7"
    -        );
    -    }
    -
    -    #[test]
    -    fn test_peek_address_at_index_not_derivable() {
    -        let db = MemoryDatabase::new();
    -        let wallet = Wallet::new("wpkh(tpubEBr4i6yk5nf5DAaJpsi9N2pPYBeJ7fZ5Z9rmN4977iYLCGco1VyjB9tvvuvYtfZzjD5A8igzgw3HeWeeKFmanHYqksqZXYXGsw5zjnj7KM9/1)",
    -                                         None, Network::Testnet, db).unwrap();
    +            wallet.get_address(Peek(0)).unwrap().to_string(),
    +            "tb1q6yn66vajcctph75pvylgkksgpp6nq04ppwct9a"
    +        );
     
             assert_eq!(
    -            wallet.get_address(Peek(1)).unwrap().to_string(),
    -            "tb1q4er7kxx6sssz3q7qp7zsqsdx4erceahhax77d7"
    -        );
    +            wallet.get_address(Peek(2)).unwrap().to_string(),
    +            "tb1qzntf2mqex4ehwkjlfdyy3ewdlk08qkvkvrz7x2"
    +        );
     
    -        assert_eq!(
    -            wallet.get_address(Peek(0)).unwrap().to_string(),
    -            "tb1q4er7kxx6sssz3q7qp7zsqsdx4erceahhax77d7"
    -        );
    +        // current new address is not affected
    +        assert_eq!(
    +            wallet.get_address(New).unwrap().to_string(),
    +            "tb1q6yn66vajcctph75pvylgkksgpp6nq04ppwct9a"
    +        );
     
             assert_eq!(
    -            wallet.get_address(Peek(2)).unwrap().to_string(),
    -            "tb1q4er7kxx6sssz3q7qp7zsqsdx4erceahhax77d7"
    -        );
    +            wallet.get_address(New).unwrap().to_string(),
    +            "tb1q4er7kxx6sssz3q7qp7zsqsdx4erceahhax77d7"
    +        );
         }
     
    -    #[test]
    -    fn test_reset_address_index() {
    -        let db = MemoryDatabase::new();
    -        let wallet = Wallet::new("wpkh(tpubEBr4i6yk5nf5DAaJpsi9N2pPYBeJ7fZ5Z9rmN4977iYLCGco1VyjB9tvvuvYtfZzjD5A8igzgw3HeWeeKFmanHYqksqZXYXGsw5zjnj7KM9/*)",
    -                                         None, Network::Testnet, db).unwrap();
    -
    -        // new index 0
    -        assert_eq!(
    -            wallet.get_address(New).unwrap().to_string(),
    -            "tb1q6yn66vajcctph75pvylgkksgpp6nq04ppwct9a"
    -        );
    -
    -        // new index 1
    -        assert_eq!(
    -            wallet.get_address(New).unwrap().to_string(),
    -            "tb1q4er7kxx6sssz3q7qp7zsqsdx4erceahhax77d7"
    -        );
    +    #[test]
    +    fn test_peek_address_at_index_not_derivable() {
    +        let db = MemoryDatabase::new();
    +        let wallet = Wallet::new("wpkh(tpubEBr4i6yk5nf5DAaJpsi9N2pPYBeJ7fZ5Z9rmN4977iYLCGco1VyjB9tvvuvYtfZzjD5A8igzgw3HeWeeKFmanHYqksqZXYXGsw5zjnj7KM9/1)",
    +                                         None, Network::Testnet, db).unwrap();
     
    -        // new index 2
             assert_eq!(
    -            wallet.get_address(New).unwrap().to_string(),
    -            "tb1qzntf2mqex4ehwkjlfdyy3ewdlk08qkvkvrz7x2"
    -        );
    +            wallet.get_address(Peek(1)).unwrap().to_string(),
    +            "tb1q4er7kxx6sssz3q7qp7zsqsdx4erceahhax77d7"
    +        );
     
    -        //  reset index 1 again
             assert_eq!(
    -            wallet.get_address(Reset(1)).unwrap().to_string(),
    -            "tb1q4er7kxx6sssz3q7qp7zsqsdx4erceahhax77d7"
    -        );
    +            wallet.get_address(Peek(0)).unwrap().to_string(),
    +            "tb1q4er7kxx6sssz3q7qp7zsqsdx4erceahhax77d7"
    +        );
     
    -        // new index 2 again
             assert_eq!(
    -            wallet.get_address(New).unwrap().to_string(),
    -            "tb1qzntf2mqex4ehwkjlfdyy3ewdlk08qkvkvrz7x2"
    -        );
    -    }
    -
    -    #[test]
    -    fn test_returns_index_and_address() {
    -        let db = MemoryDatabase::new();
    -        let wallet = Wallet::new("wpkh(tpubEBr4i6yk5nf5DAaJpsi9N2pPYBeJ7fZ5Z9rmN4977iYLCGco1VyjB9tvvuvYtfZzjD5A8igzgw3HeWeeKFmanHYqksqZXYXGsw5zjnj7KM9/*)",
    -                                         None, Network::Testnet, db).unwrap();
    -
    -        // new index 0
    -        assert_eq!(
    -            wallet.get_address(New).unwrap(),
    -            AddressInfo {
    -                index: 0,
    -                address: Address::from_str("tb1q6yn66vajcctph75pvylgkksgpp6nq04ppwct9a").unwrap(),
    -                keychain: KeychainKind::External,
    +            wallet.get_address(Peek(2)).unwrap().to_string(),
    +            "tb1q4er7kxx6sssz3q7qp7zsqsdx4erceahhax77d7"
    +        );
    +    }
    +
    +    #[test]
    +    fn test_reset_address_index() {
    +        let db = MemoryDatabase::new();
    +        let wallet = Wallet::new("wpkh(tpubEBr4i6yk5nf5DAaJpsi9N2pPYBeJ7fZ5Z9rmN4977iYLCGco1VyjB9tvvuvYtfZzjD5A8igzgw3HeWeeKFmanHYqksqZXYXGsw5zjnj7KM9/*)",
    +                                         None, Network::Testnet, db).unwrap();
    +
    +        // new index 0
    +        assert_eq!(
    +            wallet.get_address(New).unwrap().to_string(),
    +            "tb1q6yn66vajcctph75pvylgkksgpp6nq04ppwct9a"
    +        );
    +
    +        // new index 1
    +        assert_eq!(
    +            wallet.get_address(New).unwrap().to_string(),
    +            "tb1q4er7kxx6sssz3q7qp7zsqsdx4erceahhax77d7"
    +        );
    +
    +        // new index 2
    +        assert_eq!(
    +            wallet.get_address(New).unwrap().to_string(),
    +            "tb1qzntf2mqex4ehwkjlfdyy3ewdlk08qkvkvrz7x2"
    +        );
    +
    +        //  reset index 1 again
    +        assert_eq!(
    +            wallet.get_address(Reset(1)).unwrap().to_string(),
    +            "tb1q4er7kxx6sssz3q7qp7zsqsdx4erceahhax77d7"
    +        );
    +
    +        // new index 2 again
    +        assert_eq!(
    +            wallet.get_address(New).unwrap().to_string(),
    +            "tb1qzntf2mqex4ehwkjlfdyy3ewdlk08qkvkvrz7x2"
    +        );
    +    }
    +
    +    #[test]
    +    fn test_returns_index_and_address() {
    +        let db = MemoryDatabase::new();
    +        let wallet = Wallet::new("wpkh(tpubEBr4i6yk5nf5DAaJpsi9N2pPYBeJ7fZ5Z9rmN4977iYLCGco1VyjB9tvvuvYtfZzjD5A8igzgw3HeWeeKFmanHYqksqZXYXGsw5zjnj7KM9/*)",
    +                                         None, Network::Testnet, db).unwrap();
    +
    +        // new index 0
    +        assert_eq!(
    +            wallet.get_address(New).unwrap(),
    +            AddressInfo {
    +                index: 0,
    +                address: Address::from_str("tb1q6yn66vajcctph75pvylgkksgpp6nq04ppwct9a").unwrap(),
    +                keychain: KeychainKind::External,
                 }
             );
     
    -        // new index 1
    -        assert_eq!(
    -            wallet.get_address(New).unwrap(),
    -            AddressInfo {
    -                index: 1,
    -                address: Address::from_str("tb1q4er7kxx6sssz3q7qp7zsqsdx4erceahhax77d7").unwrap(),
    -                keychain: KeychainKind::External,
    +        // new index 1
    +        assert_eq!(
    +            wallet.get_address(New).unwrap(),
    +            AddressInfo {
    +                index: 1,
    +                address: Address::from_str("tb1q4er7kxx6sssz3q7qp7zsqsdx4erceahhax77d7").unwrap(),
    +                keychain: KeychainKind::External,
                 }
             );
     
    -        // peek index 25
    -        assert_eq!(
    -            wallet.get_address(Peek(25)).unwrap(),
    -            AddressInfo {
    -                index: 25,
    -                address: Address::from_str("tb1qsp7qu0knx3sl6536dzs0703u2w2ag6ppl9d0c2").unwrap(),
    -                keychain: KeychainKind::External,
    +        // peek index 25
    +        assert_eq!(
    +            wallet.get_address(Peek(25)).unwrap(),
    +            AddressInfo {
    +                index: 25,
    +                address: Address::from_str("tb1qsp7qu0knx3sl6536dzs0703u2w2ag6ppl9d0c2").unwrap(),
    +                keychain: KeychainKind::External,
                 }
             );
     
    -        // new index 2
    -        assert_eq!(
    -            wallet.get_address(New).unwrap(),
    -            AddressInfo {
    -                index: 2,
    -                address: Address::from_str("tb1qzntf2mqex4ehwkjlfdyy3ewdlk08qkvkvrz7x2").unwrap(),
    -                keychain: KeychainKind::External,
    +        // new index 2
    +        assert_eq!(
    +            wallet.get_address(New).unwrap(),
    +            AddressInfo {
    +                index: 2,
    +                address: Address::from_str("tb1qzntf2mqex4ehwkjlfdyy3ewdlk08qkvkvrz7x2").unwrap(),
    +                keychain: KeychainKind::External,
                 }
             );
     
    -        //  reset index 1 again
    -        assert_eq!(
    -            wallet.get_address(Reset(1)).unwrap(),
    -            AddressInfo {
    -                index: 1,
    -                address: Address::from_str("tb1q4er7kxx6sssz3q7qp7zsqsdx4erceahhax77d7").unwrap(),
    -                keychain: KeychainKind::External,
    +        //  reset index 1 again
    +        assert_eq!(
    +            wallet.get_address(Reset(1)).unwrap(),
    +            AddressInfo {
    +                index: 1,
    +                address: Address::from_str("tb1q4er7kxx6sssz3q7qp7zsqsdx4erceahhax77d7").unwrap(),
    +                keychain: KeychainKind::External,
                 }
             );
     
    -        // new index 2 again
    -        assert_eq!(
    -            wallet.get_address(New).unwrap(),
    -            AddressInfo {
    -                index: 2,
    -                address: Address::from_str("tb1qzntf2mqex4ehwkjlfdyy3ewdlk08qkvkvrz7x2").unwrap(),
    -                keychain: KeychainKind::External,
    +        // new index 2 again
    +        assert_eq!(
    +            wallet.get_address(New).unwrap(),
    +            AddressInfo {
    +                index: 2,
    +                address: Address::from_str("tb1qzntf2mqex4ehwkjlfdyy3ewdlk08qkvkvrz7x2").unwrap(),
    +                keychain: KeychainKind::External,
                 }
             );
         }
     
    -    #[test]
    -    fn test_sending_to_bip350_bech32m_address() {
    -        let (wallet, _, _) = get_funded_wallet(get_test_wpkh());
    -        let addr =
    -            Address::from_str("tb1pqqqqp399et2xygdj5xreqhjjvcmzhxw4aywxecjdzew6hylgvsesf3hn0c")
    -                .unwrap();
    -        let mut builder = wallet.build_tx();
    -        builder.add_recipient(addr.script_pubkey(), 45_000);
    -        builder.finish().unwrap();
    -    }
    -
    -    #[test]
    -    fn test_get_address() {
    -        use crate::descriptor::template::Bip84;
    -        let key = bitcoin::util::bip32::ExtendedPrivKey::from_str("tprv8ZgxMBicQKsPcx5nBGsR63Pe8KnRUqmbJNENAfGftF3yuXoMMoVJJcYeUw5eVkm9WBPjWYt6HMWYJNesB5HaNVBaFc1M6dRjWSYnmewUMYy").unwrap();
    -        let wallet = Wallet::new(
    -            Bip84(key, KeychainKind::External),
    -            Some(Bip84(key, KeychainKind::Internal)),
    -            Network::Regtest,
    -            MemoryDatabase::default(),
    +    #[test]
    +    fn test_sending_to_bip350_bech32m_address() {
    +        let (wallet, _, _) = get_funded_wallet(get_test_wpkh());
    +        let addr =
    +            Address::from_str("tb1pqqqqp399et2xygdj5xreqhjjvcmzhxw4aywxecjdzew6hylgvsesf3hn0c")
    +                .unwrap();
    +        let mut builder = wallet.build_tx();
    +        builder.add_recipient(addr.script_pubkey(), 45_000);
    +        builder.finish().unwrap();
    +    }
    +
    +    #[test]
    +    fn test_get_address() {
    +        use crate::descriptor::template::Bip84;
    +        let key = bitcoin::util::bip32::ExtendedPrivKey::from_str("tprv8ZgxMBicQKsPcx5nBGsR63Pe8KnRUqmbJNENAfGftF3yuXoMMoVJJcYeUw5eVkm9WBPjWYt6HMWYJNesB5HaNVBaFc1M6dRjWSYnmewUMYy").unwrap();
    +        let wallet = Wallet::new(
    +            Bip84(key, KeychainKind::External),
    +            Some(Bip84(key, KeychainKind::Internal)),
    +            Network::Regtest,
    +            MemoryDatabase::default(),
             )
    -        .unwrap();
    +        .unwrap();
     
             assert_eq!(
    -            wallet.get_address(AddressIndex::New).unwrap(),
    -            AddressInfo {
    -                index: 0,
    -                address: Address::from_str("bcrt1qrhgaqu0zvf5q2d0gwwz04w0dh0cuehhqvzpp4w").unwrap(),
    -                keychain: KeychainKind::External,
    +            wallet.get_address(AddressIndex::New).unwrap(),
    +            AddressInfo {
    +                index: 0,
    +                address: Address::from_str("bcrt1qrhgaqu0zvf5q2d0gwwz04w0dh0cuehhqvzpp4w").unwrap(),
    +                keychain: KeychainKind::External,
                 }
             );
     
             assert_eq!(
    -            wallet.get_internal_address(AddressIndex::New).unwrap(),
    -            AddressInfo {
    -                index: 0,
    -                address: Address::from_str("bcrt1q0ue3s5y935tw7v3gmnh36c5zzsaw4n9c9smq79").unwrap(),
    -                keychain: KeychainKind::Internal,
    +            wallet.get_internal_address(AddressIndex::New).unwrap(),
    +            AddressInfo {
    +                index: 0,
    +                address: Address::from_str("bcrt1q0ue3s5y935tw7v3gmnh36c5zzsaw4n9c9smq79").unwrap(),
    +                keychain: KeychainKind::Internal,
                 }
             );
     
    -        let wallet = Wallet::new(
    -            Bip84(key, KeychainKind::External),
    +        let wallet = Wallet::new(
    +            Bip84(key, KeychainKind::External),
                 None,
    -            Network::Regtest,
    -            MemoryDatabase::default(),
    +            Network::Regtest,
    +            MemoryDatabase::default(),
             )
    -        .unwrap();
    +        .unwrap();
     
             assert_eq!(
    -            wallet.get_internal_address(AddressIndex::New).unwrap(),
    -            AddressInfo {
    -                index: 0,
    -                address: Address::from_str("bcrt1qrhgaqu0zvf5q2d0gwwz04w0dh0cuehhqvzpp4w").unwrap(),
    -                keychain: KeychainKind::Internal,
    +            wallet.get_internal_address(AddressIndex::New).unwrap(),
    +            AddressInfo {
    +                index: 0,
    +                address: Address::from_str("bcrt1qrhgaqu0zvf5q2d0gwwz04w0dh0cuehhqvzpp4w").unwrap(),
    +                keychain: KeychainKind::Internal,
                 },
    -            "when there's no internal descriptor it should just use external"
    -        );
    +            "when there's no internal descriptor it should just use external"
    +        );
         }
     
    -    #[test]
    -    fn test_get_address_no_reuse_single_descriptor() {
    -        use crate::descriptor::template::Bip84;
    -        use std::collections::HashSet;
    +    #[test]
    +    fn test_get_address_no_reuse_single_descriptor() {
    +        use crate::descriptor::template::Bip84;
    +        use std::collections::HashSet;
     
    -        let key = bitcoin::util::bip32::ExtendedPrivKey::from_str("tprv8ZgxMBicQKsPcx5nBGsR63Pe8KnRUqmbJNENAfGftF3yuXoMMoVJJcYeUw5eVkm9WBPjWYt6HMWYJNesB5HaNVBaFc1M6dRjWSYnmewUMYy").unwrap();
    -        let wallet = Wallet::new(
    -            Bip84(key, KeychainKind::External),
    +        let key = bitcoin::util::bip32::ExtendedPrivKey::from_str("tprv8ZgxMBicQKsPcx5nBGsR63Pe8KnRUqmbJNENAfGftF3yuXoMMoVJJcYeUw5eVkm9WBPjWYt6HMWYJNesB5HaNVBaFc1M6dRjWSYnmewUMYy").unwrap();
    +        let wallet = Wallet::new(
    +            Bip84(key, KeychainKind::External),
                 None,
    -            Network::Regtest,
    -            MemoryDatabase::default(),
    +            Network::Regtest,
    +            MemoryDatabase::default(),
             )
    -        .unwrap();
    +        .unwrap();
     
    -        let mut used_set = HashSet::new();
    +        let mut used_set = HashSet::new();
     
    -        (0..3).for_each(|_| {
    -            let external_addr = wallet.get_address(AddressIndex::New).unwrap().address;
    -            assert!(used_set.insert(external_addr));
    +        (0..3).for_each(|_| {
    +            let external_addr = wallet.get_address(AddressIndex::New).unwrap().address;
    +            assert!(used_set.insert(external_addr));
     
    -            let internal_addr = wallet
    -                .get_internal_address(AddressIndex::New)
    -                .unwrap()
    -                .address;
    -            assert!(used_set.insert(internal_addr));
    +            let internal_addr = wallet
    +                .get_internal_address(AddressIndex::New)
    +                .unwrap()
    +                .address;
    +            assert!(used_set.insert(internal_addr));
             });
         }
     
    -    #[test]
    -    fn test_taproot_psbt_populate_tap_key_origins() {
    -        let (wallet, _, _) = get_funded_wallet(get_test_tr_single_sig_xprv());
    -        let addr = wallet.get_address(AddressIndex::New).unwrap();
    +    #[test]
    +    fn test_taproot_psbt_populate_tap_key_origins() {
    +        let (wallet, _, _) = get_funded_wallet(get_test_tr_single_sig_xprv());
    +        let addr = wallet.get_address(AddressIndex::New).unwrap();
     
    -        let mut builder = wallet.build_tx();
    -        builder.add_recipient(addr.script_pubkey(), 25_000);
    -        let (psbt, _) = builder.finish().unwrap();
    +        let mut builder = wallet.build_tx();
    +        builder.add_recipient(addr.script_pubkey(), 25_000);
    +        let (psbt, _) = builder.finish().unwrap();
     
             assert_eq!(
    -            psbt.inputs[0]
    -                .tap_key_origins
    -                .clone()
    -                .into_iter()
    -                .collect::<Vec<_>>(),
    +            psbt.inputs[0]
    +                .tap_key_origins
    +                .clone()
    +                .into_iter()
    +                .collect::<Vec<_>>(),
                 vec![(
                     from_str!("b96d3a3dc76a4fc74e976511b23aecb78e0754c23c0ed7a6513e18cbbc7178e9"),
                     (vec![], (from_str!("f6a5cb8b"), from_str!("m/0")))
                 )],
    -            "Wrong input tap_key_origins"
    -        );
    +            "Wrong input tap_key_origins"
    +        );
             assert_eq!(
    -            psbt.outputs[0]
    -                .tap_key_origins
    -                .clone()
    -                .into_iter()
    -                .collect::<Vec<_>>(),
    +            psbt.outputs[0]
    +                .tap_key_origins
    +                .clone()
    +                .into_iter()
    +                .collect::<Vec<_>>(),
                 vec![(
                     from_str!("e9b03068cf4a2621d4f81e68f6c4216e6bd260fe6edf6acc55c8d8ae5aeff0a8"),
                     (vec![], (from_str!("f6a5cb8b"), from_str!("m/1")))
                 )],
    -            "Wrong output tap_key_origins"
    -        );
    +            "Wrong output tap_key_origins"
    +        );
         }
     
    -    #[test]
    -    fn test_taproot_psbt_populate_tap_key_origins_repeated_key() {
    -        let (wallet, _, _) = get_funded_wallet(get_test_tr_repeated_key());
    -        let addr = wallet.get_address(AddressIndex::New).unwrap();
    +    #[test]
    +    fn test_taproot_psbt_populate_tap_key_origins_repeated_key() {
    +        let (wallet, _, _) = get_funded_wallet(get_test_tr_repeated_key());
    +        let addr = wallet.get_address(AddressIndex::New).unwrap();
     
    -        let path = vec![("e5mmg3xh".to_string(), vec![0])]
    -            .into_iter()
    -            .collect();
    +        let path = vec![("e5mmg3xh".to_string(), vec![0])]
    +            .into_iter()
    +            .collect();
     
    -        let mut builder = wallet.build_tx();
    -        builder
    -            .add_recipient(addr.script_pubkey(), 25_000)
    -            .policy_path(path, KeychainKind::External);
    -        let (psbt, _) = builder.finish().unwrap();
    +        let mut builder = wallet.build_tx();
    +        builder
    +            .add_recipient(addr.script_pubkey(), 25_000)
    +            .policy_path(path, KeychainKind::External);
    +        let (psbt, _) = builder.finish().unwrap();
     
    -        let mut input_key_origins = psbt.inputs[0]
    -            .tap_key_origins
    -            .clone()
    -            .into_iter()
    -            .collect::<Vec<_>>();
    -        input_key_origins.sort();
    +        let mut input_key_origins = psbt.inputs[0]
    +            .tap_key_origins
    +            .clone()
    +            .into_iter()
    +            .collect::<Vec<_>>();
    +        input_key_origins.sort();
     
             assert_eq!(
    -            input_key_origins,
    +            input_key_origins,
                 vec![
                     (
                         from_str!("b511bd5771e47ee27558b1765e87b541668304ec567721c7b880edc0a010da55"),
                         (
                             vec![],
    -                        (FromStr::from_str("871fd295").unwrap(), vec![].into())
    +                        (FromStr::from_str("871fd295").unwrap(), vec![].into())
                         )
                     ),
                     (
    @@ -10412,769 +10406,768 @@
                         (
                             vec![
                                 from_str!(
    -                                "858ad7a7d7f270e2c490c4d6ba00c499e46b18fdd59ea3c2c47d20347110271e"
    -                            ),
    +                                "858ad7a7d7f270e2c490c4d6ba00c499e46b18fdd59ea3c2c47d20347110271e"
    +                            ),
                                 from_str!(
    -                                "f6e927ad4492c051fe325894a4f5f14538333b55a35f099876be42009ec8f903"
    -                            ),
    +                                "f6e927ad4492c051fe325894a4f5f14538333b55a35f099876be42009ec8f903"
    +                            ),
                             ],
    -                        (FromStr::from_str("ece52657").unwrap(), vec![].into())
    +                        (FromStr::from_str("ece52657").unwrap(), vec![].into())
                         )
                     )
                 ],
    -            "Wrong input tap_key_origins"
    -        );
    +            "Wrong input tap_key_origins"
    +        );
     
    -        let mut output_key_origins = psbt.outputs[0]
    -            .tap_key_origins
    -            .clone()
    -            .into_iter()
    -            .collect::<Vec<_>>();
    -        output_key_origins.sort();
    +        let mut output_key_origins = psbt.outputs[0]
    +            .tap_key_origins
    +            .clone()
    +            .into_iter()
    +            .collect::<Vec<_>>();
    +        output_key_origins.sort();
     
             assert_eq!(
    -            input_key_origins, output_key_origins,
    -            "Wrong output tap_key_origins"
    -        );
    +            input_key_origins, output_key_origins,
    +            "Wrong output tap_key_origins"
    +        );
         }
     
    -    #[test]
    -    fn test_taproot_psbt_input_tap_tree() {
    -        use crate::bitcoin::psbt::serialize::Deserialize;
    -        use crate::bitcoin::psbt::TapTree;
    -        use bitcoin::hashes::hex::FromHex;
    -        use bitcoin::util::taproot;
    +    #[test]
    +    fn test_taproot_psbt_input_tap_tree() {
    +        use crate::bitcoin::psbt::serialize::Deserialize;
    +        use crate::bitcoin::psbt::TapTree;
    +        use bitcoin::hashes::hex::FromHex;
    +        use bitcoin::util::taproot;
     
    -        let (wallet, _, _) = get_funded_wallet(get_test_tr_with_taptree());
    -        let addr = wallet.get_address(AddressIndex::Peek(0)).unwrap();
    +        let (wallet, _, _) = get_funded_wallet(get_test_tr_with_taptree());
    +        let addr = wallet.get_address(AddressIndex::Peek(0)).unwrap();
     
    -        let mut builder = wallet.build_tx();
    -        builder.drain_to(addr.script_pubkey()).drain_wallet();
    -        let (psbt, _) = builder.finish().unwrap();
    +        let mut builder = wallet.build_tx();
    +        builder.drain_to(addr.script_pubkey()).drain_wallet();
    +        let (psbt, _) = builder.finish().unwrap();
     
             assert_eq!(
    -            psbt.inputs[0].tap_merkle_root,
    +            psbt.inputs[0].tap_merkle_root,
                 Some(
    -                FromHex::from_hex(
    -                    "61f81509635053e52d9d1217545916167394490da2287aca4693606e43851986"
    -                )
    -                .unwrap()
    +                FromHex::from_hex(
    +                    "61f81509635053e52d9d1217545916167394490da2287aca4693606e43851986"
    +                )
    +                .unwrap()
                 ),
             );
             assert_eq!(
    -            psbt.inputs[0].tap_scripts.clone().into_iter().collect::<Vec<_>>(),
    +            psbt.inputs[0].tap_scripts.clone().into_iter().collect::<Vec<_>>(),
                 vec![
    -                (taproot::ControlBlock::from_slice(&Vec::<u8>::from_hex("c0b511bd5771e47ee27558b1765e87b541668304ec567721c7b880edc0a010da55b7ef769a745e625ed4b9a4982a4dc08274c59187e73e6f07171108f455081cb2").unwrap()).unwrap(), (from_str!("208aee2b8120a5f157f1223f72b5e62b825831a27a9fdf427db7cc697494d4a642ac"), taproot::LeafVersion::TapScript)),
    -                (taproot::ControlBlock::from_slice(&Vec::<u8>::from_hex("c0b511bd5771e47ee27558b1765e87b541668304ec567721c7b880edc0a010da55b9a515f7be31a70186e3c5937ee4a70cc4b4e1efe876c1d38e408222ffc64834").unwrap()).unwrap(), (from_str!("2051494dc22e24a32fe9dcfbd7e85faf345fa1df296fb49d156e859ef345201295ac"), taproot::LeafVersion::TapScript)),
    +                (taproot::ControlBlock::from_slice(&Vec::<u8>::from_hex("c0b511bd5771e47ee27558b1765e87b541668304ec567721c7b880edc0a010da55b7ef769a745e625ed4b9a4982a4dc08274c59187e73e6f07171108f455081cb2").unwrap()).unwrap(), (from_str!("208aee2b8120a5f157f1223f72b5e62b825831a27a9fdf427db7cc697494d4a642ac"), taproot::LeafVersion::TapScript)),
    +                (taproot::ControlBlock::from_slice(&Vec::<u8>::from_hex("c0b511bd5771e47ee27558b1765e87b541668304ec567721c7b880edc0a010da55b9a515f7be31a70186e3c5937ee4a70cc4b4e1efe876c1d38e408222ffc64834").unwrap()).unwrap(), (from_str!("2051494dc22e24a32fe9dcfbd7e85faf345fa1df296fb49d156e859ef345201295ac"), taproot::LeafVersion::TapScript)),
                 ],
             );
             assert_eq!(
    -            psbt.inputs[0].tap_internal_key,
    +            psbt.inputs[0].tap_internal_key,
                 Some(from_str!(
    -                "b511bd5771e47ee27558b1765e87b541668304ec567721c7b880edc0a010da55"
    -            ))
    +                "b511bd5771e47ee27558b1765e87b541668304ec567721c7b880edc0a010da55"
    +            ))
             );
     
    -        // Since we are creating an output to the same address as the input, assert that the
    -        // internal_key is the same
    -        assert_eq!(
    -            psbt.inputs[0].tap_internal_key,
    -            psbt.outputs[0].tap_internal_key
    +        // Since we are creating an output to the same address as the input, assert that the
    +        // internal_key is the same
    +        assert_eq!(
    +            psbt.inputs[0].tap_internal_key,
    +            psbt.outputs[0].tap_internal_key
             );
     
             assert_eq!(
    -            psbt.outputs[0].tap_tree,
    -            Some(TapTree::deserialize(&Vec::<u8>::from_hex("01c022208aee2b8120a5f157f1223f72b5e62b825831a27a9fdf427db7cc697494d4a642ac01c0222051494dc22e24a32fe9dcfbd7e85faf345fa1df296fb49d156e859ef345201295ac",).unwrap()).unwrap())
    +            psbt.outputs[0].tap_tree,
    +            Some(TapTree::deserialize(&Vec::<u8>::from_hex("01c022208aee2b8120a5f157f1223f72b5e62b825831a27a9fdf427db7cc697494d4a642ac01c0222051494dc22e24a32fe9dcfbd7e85faf345fa1df296fb49d156e859ef345201295ac",).unwrap()).unwrap())
             );
         }
     
    -    #[test]
    -    fn test_taproot_sign_missing_witness_utxo() {
    -        let (wallet, _, _) = get_funded_wallet(get_test_tr_single_sig());
    -        let addr = wallet.get_address(New).unwrap();
    -        let mut builder = wallet.build_tx();
    -        builder.drain_to(addr.script_pubkey()).drain_wallet();
    -        let (mut psbt, _) = builder.finish().unwrap();
    -        let witness_utxo = psbt.inputs[0].witness_utxo.take();
    -
    -        let result = wallet.sign(
    -            &mut psbt,
    -            SignOptions {
    -                allow_all_sighashes: true,
    -                ..Default::default()
    +    #[test]
    +    fn test_taproot_sign_missing_witness_utxo() {
    +        let (wallet, _, _) = get_funded_wallet(get_test_tr_single_sig());
    +        let addr = wallet.get_address(New).unwrap();
    +        let mut builder = wallet.build_tx();
    +        builder.drain_to(addr.script_pubkey()).drain_wallet();
    +        let (mut psbt, _) = builder.finish().unwrap();
    +        let witness_utxo = psbt.inputs[0].witness_utxo.take();
    +
    +        let result = wallet.sign(
    +            &mut psbt,
    +            SignOptions {
    +                allow_all_sighashes: true,
    +                ..Default::default()
                 },
             );
             assert!(
    -            result.is_err(),
    -            "Signing should have failed because the witness_utxo is missing"
    -        );
    +            result.is_err(),
    +            "Signing should have failed because the witness_utxo is missing"
    +        );
             assert!(
                 matches!(
    -                result.unwrap_err(),
    -                Error::Signer(SignerError::MissingWitnessUtxo)
    +                result.unwrap_err(),
    +                Error::Signer(SignerError::MissingWitnessUtxo)
                 ),
    -            "Signing failed with the wrong error type"
    -        );
    +            "Signing failed with the wrong error type"
    +        );
     
    -        // restore the witness_utxo
    -        psbt.inputs[0].witness_utxo = witness_utxo;
    +        // restore the witness_utxo
    +        psbt.inputs[0].witness_utxo = witness_utxo;
     
    -        let result = wallet.sign(
    -            &mut psbt,
    -            SignOptions {
    -                allow_all_sighashes: true,
    -                ..Default::default()
    +        let result = wallet.sign(
    +            &mut psbt,
    +            SignOptions {
    +                allow_all_sighashes: true,
    +                ..Default::default()
                 },
             );
     
    -        assert!(result.is_ok(), "Signing should have worked");
    +        assert!(result.is_ok(), "Signing should have worked");
             assert!(
    -            result.unwrap(),
    -            "Should finalize the input since we can produce signatures"
    -        );
    +            result.unwrap(),
    +            "Should finalize the input since we can produce signatures"
    +        );
         }
     
    -    #[test]
    -    fn test_taproot_sign_using_non_witness_utxo() {
    -        let (wallet, _, prev_txid) = get_funded_wallet(get_test_tr_single_sig());
    -        let addr = wallet.get_address(New).unwrap();
    -        let mut builder = wallet.build_tx();
    -        builder.drain_to(addr.script_pubkey()).drain_wallet();
    -        let (mut psbt, _) = builder.finish().unwrap();
    +    #[test]
    +    fn test_taproot_sign_using_non_witness_utxo() {
    +        let (wallet, _, prev_txid) = get_funded_wallet(get_test_tr_single_sig());
    +        let addr = wallet.get_address(New).unwrap();
    +        let mut builder = wallet.build_tx();
    +        builder.drain_to(addr.script_pubkey()).drain_wallet();
    +        let (mut psbt, _) = builder.finish().unwrap();
     
    -        psbt.inputs[0].witness_utxo = None;
    -        psbt.inputs[0].non_witness_utxo = wallet.database().get_raw_tx(&prev_txid).unwrap();
    +        psbt.inputs[0].witness_utxo = None;
    +        psbt.inputs[0].non_witness_utxo = wallet.database().get_raw_tx(&prev_txid).unwrap();
             assert!(
    -            psbt.inputs[0].non_witness_utxo.is_some(),
    -            "Previous tx should be present in the database"
    -        );
    +            psbt.inputs[0].non_witness_utxo.is_some(),
    +            "Previous tx should be present in the database"
    +        );
     
    -        let result = wallet.sign(&mut psbt, Default::default());
    -        assert!(result.is_ok(), "Signing should have worked");
    +        let result = wallet.sign(&mut psbt, Default::default());
    +        assert!(result.is_ok(), "Signing should have worked");
             assert!(
    -            result.unwrap(),
    -            "Should finalize the input since we can produce signatures"
    -        );
    +            result.unwrap(),
    +            "Should finalize the input since we can produce signatures"
    +        );
         }
     
    -    #[test]
    -    fn test_taproot_foreign_utxo() {
    -        let (wallet1, _, _) = get_funded_wallet(get_test_wpkh());
    -        let (wallet2, _, _) = get_funded_wallet(get_test_tr_single_sig());
    +    #[test]
    +    fn test_taproot_foreign_utxo() {
    +        let (wallet1, _, _) = get_funded_wallet(get_test_wpkh());
    +        let (wallet2, _, _) = get_funded_wallet(get_test_tr_single_sig());
     
    -        let addr = Address::from_str("2N1Ffz3WaNzbeLFBb51xyFMHYSEUXcbiSoX").unwrap();
    -        let utxo = wallet2.list_unspent().unwrap().remove(0);
    -        let psbt_input = wallet2.get_psbt_input(utxo.clone(), None, false).unwrap();
    -        let foreign_utxo_satisfaction = wallet2
    -            .get_descriptor_for_keychain(KeychainKind::External)
    -            .max_satisfaction_weight()
    -            .unwrap();
    +        let addr = Address::from_str("2N1Ffz3WaNzbeLFBb51xyFMHYSEUXcbiSoX").unwrap();
    +        let utxo = wallet2.list_unspent().unwrap().remove(0);
    +        let psbt_input = wallet2.get_psbt_input(utxo.clone(), None, false).unwrap();
    +        let foreign_utxo_satisfaction = wallet2
    +            .get_descriptor_for_keychain(KeychainKind::External)
    +            .max_satisfaction_weight()
    +            .unwrap();
     
             assert!(
    -            psbt_input.non_witness_utxo.is_none(),
    -            "`non_witness_utxo` should never be populated for taproot"
    -        );
    +            psbt_input.non_witness_utxo.is_none(),
    +            "`non_witness_utxo` should never be populated for taproot"
    +        );
     
    -        let mut builder = wallet1.build_tx();
    -        builder
    -            .add_recipient(addr.script_pubkey(), 60_000)
    -            .add_foreign_utxo(utxo.outpoint, psbt_input, foreign_utxo_satisfaction)
    -            .unwrap();
    -        let (psbt, details) = builder.finish().unwrap();
    +        let mut builder = wallet1.build_tx();
    +        builder
    +            .add_recipient(addr.script_pubkey(), 60_000)
    +            .add_foreign_utxo(utxo.outpoint, psbt_input, foreign_utxo_satisfaction)
    +            .unwrap();
    +        let (psbt, details) = builder.finish().unwrap();
     
             assert_eq!(
    -            details.sent - details.received,
    -            10_000 + details.fee.unwrap_or(0),
    -            "we should have only net spent ~10_000"
    -        );
    +            details.sent - details.received,
    +            10_000 + details.fee.unwrap_or(0),
    +            "we should have only net spent ~10_000"
    +        );
     
             assert!(
    -            psbt.unsigned_tx
    -                .input
    -                .iter()
    -                .any(|input| input.previous_output == utxo.outpoint),
    -            "foreign_utxo should be in there"
    -        );
    +            psbt.unsigned_tx
    +                .input
    +                .iter()
    +                .any(|input| input.previous_output == utxo.outpoint),
    +            "foreign_utxo should be in there"
    +        );
         }
     
    -    fn test_spend_from_wallet(wallet: Wallet<AnyDatabase>) {
    -        let addr = wallet.get_address(AddressIndex::New).unwrap();
    +    fn test_spend_from_wallet(wallet: Wallet<AnyDatabase>) {
    +        let addr = wallet.get_address(AddressIndex::New).unwrap();
     
    -        let mut builder = wallet.build_tx();
    -        builder.add_recipient(addr.script_pubkey(), 25_000);
    -        let (mut psbt, _) = builder.finish().unwrap();
    +        let mut builder = wallet.build_tx();
    +        builder.add_recipient(addr.script_pubkey(), 25_000);
    +        let (mut psbt, _) = builder.finish().unwrap();
     
             assert!(
    -            wallet.sign(&mut psbt, Default::default()).unwrap(),
    -            "Unable to finalize tx"
    -        );
    +            wallet.sign(&mut psbt, Default::default()).unwrap(),
    +            "Unable to finalize tx"
    +        );
         }
     
    -    #[test]
    -    fn test_taproot_key_spend() {
    -        let (wallet, _, _) = get_funded_wallet(get_test_tr_single_sig());
    -        test_spend_from_wallet(wallet);
    +    #[test]
    +    fn test_taproot_key_spend() {
    +        let (wallet, _, _) = get_funded_wallet(get_test_tr_single_sig());
    +        test_spend_from_wallet(wallet);
     
    -        let (wallet, _, _) = get_funded_wallet(get_test_tr_single_sig_xprv());
    -        test_spend_from_wallet(wallet);
    +        let (wallet, _, _) = get_funded_wallet(get_test_tr_single_sig_xprv());
    +        test_spend_from_wallet(wallet);
         }
     
    -    #[test]
    -    fn test_taproot_no_key_spend() {
    -        let (wallet, _, _) = get_funded_wallet(get_test_tr_with_taptree_both_priv());
    -        let addr = wallet.get_address(AddressIndex::New).unwrap();
    +    #[test]
    +    fn test_taproot_no_key_spend() {
    +        let (wallet, _, _) = get_funded_wallet(get_test_tr_with_taptree_both_priv());
    +        let addr = wallet.get_address(AddressIndex::New).unwrap();
     
    -        let mut builder = wallet.build_tx();
    -        builder.add_recipient(addr.script_pubkey(), 25_000);
    -        let (mut psbt, _) = builder.finish().unwrap();
    +        let mut builder = wallet.build_tx();
    +        builder.add_recipient(addr.script_pubkey(), 25_000);
    +        let (mut psbt, _) = builder.finish().unwrap();
     
             assert!(
    -            wallet
    -                .sign(
    -                    &mut psbt,
    -                    SignOptions {
    -                        sign_with_tap_internal_key: false,
    -                        ..Default::default()
    +            wallet
    +                .sign(
    +                    &mut psbt,
    +                    SignOptions {
    +                        sign_with_tap_internal_key: false,
    +                        ..Default::default()
                         },
                     )
    -                .unwrap(),
    -            "Unable to finalize tx"
    -        );
    +                .unwrap(),
    +            "Unable to finalize tx"
    +        );
     
    -        assert!(psbt.inputs.iter().all(|i| i.tap_key_sig.is_none()));
    +        assert!(psbt.inputs.iter().all(|i| i.tap_key_sig.is_none()));
         }
     
    -    #[test]
    -    fn test_taproot_script_spend() {
    -        let (wallet, _, _) = get_funded_wallet(get_test_tr_with_taptree());
    -        test_spend_from_wallet(wallet);
    +    #[test]
    +    fn test_taproot_script_spend() {
    +        let (wallet, _, _) = get_funded_wallet(get_test_tr_with_taptree());
    +        test_spend_from_wallet(wallet);
     
    -        let (wallet, _, _) = get_funded_wallet(get_test_tr_with_taptree_xprv());
    -        test_spend_from_wallet(wallet);
    +        let (wallet, _, _) = get_funded_wallet(get_test_tr_with_taptree_xprv());
    +        test_spend_from_wallet(wallet);
         }
     
    -    #[test]
    -    fn test_taproot_script_spend_sign_all_leaves() {
    -        use crate::signer::TapLeavesOptions;
    -        let (wallet, _, _) = get_funded_wallet(get_test_tr_with_taptree_both_priv());
    -        let addr = wallet.get_address(AddressIndex::New).unwrap();
    +    #[test]
    +    fn test_taproot_script_spend_sign_all_leaves() {
    +        use crate::signer::TapLeavesOptions;
    +        let (wallet, _, _) = get_funded_wallet(get_test_tr_with_taptree_both_priv());
    +        let addr = wallet.get_address(AddressIndex::New).unwrap();
     
    -        let mut builder = wallet.build_tx();
    -        builder.add_recipient(addr.script_pubkey(), 25_000);
    -        let (mut psbt, _) = builder.finish().unwrap();
    +        let mut builder = wallet.build_tx();
    +        builder.add_recipient(addr.script_pubkey(), 25_000);
    +        let (mut psbt, _) = builder.finish().unwrap();
     
             assert!(
    -            wallet
    -                .sign(
    -                    &mut psbt,
    -                    SignOptions {
    -                        tap_leaves_options: TapLeavesOptions::All,
    -                        ..Default::default()
    +            wallet
    +                .sign(
    +                    &mut psbt,
    +                    SignOptions {
    +                        tap_leaves_options: TapLeavesOptions::All,
    +                        ..Default::default()
                         },
                     )
    -                .unwrap(),
    -            "Unable to finalize tx"
    -        );
    -
    -        assert!(psbt
    -            .inputs
    -            .iter()
    -            .all(|i| i.tap_script_sigs.len() == i.tap_scripts.len()));
    -    }
    -
    -    #[test]
    -    fn test_taproot_script_spend_sign_include_some_leaves() {
    -        use crate::signer::TapLeavesOptions;
    -        use bitcoin::util::taproot::TapLeafHash;
    -
    -        let (wallet, _, _) = get_funded_wallet(get_test_tr_with_taptree_both_priv());
    -        let addr = wallet.get_address(AddressIndex::New).unwrap();
    -
    -        let mut builder = wallet.build_tx();
    -        builder.add_recipient(addr.script_pubkey(), 25_000);
    -        let (mut psbt, _) = builder.finish().unwrap();
    -        let mut script_leaves: Vec<_> = psbt.inputs[0]
    -            .tap_scripts
    -            .clone()
    -            .values()
    -            .map(|(script, version)| TapLeafHash::from_script(script, *version))
    -            .collect();
    -        let included_script_leaves = vec![script_leaves.pop().unwrap()];
    -        let excluded_script_leaves = script_leaves;
    +                .unwrap(),
    +            "Unable to finalize tx"
    +        );
    +
    +        assert!(psbt
    +            .inputs
    +            .iter()
    +            .all(|i| i.tap_script_sigs.len() == i.tap_scripts.len()));
    +    }
    +
    +    #[test]
    +    fn test_taproot_script_spend_sign_include_some_leaves() {
    +        use crate::signer::TapLeavesOptions;
    +        use bitcoin::util::taproot::TapLeafHash;
    +
    +        let (wallet, _, _) = get_funded_wallet(get_test_tr_with_taptree_both_priv());
    +        let addr = wallet.get_address(AddressIndex::New).unwrap();
    +
    +        let mut builder = wallet.build_tx();
    +        builder.add_recipient(addr.script_pubkey(), 25_000);
    +        let (mut psbt, _) = builder.finish().unwrap();
    +        let mut script_leaves: Vec<_> = psbt.inputs[0]
    +            .tap_scripts
    +            .clone()
    +            .values()
    +            .map(|(script, version)| TapLeafHash::from_script(script, *version))
    +            .collect();
    +        let included_script_leaves = vec![script_leaves.pop().unwrap()];
    +        let excluded_script_leaves = script_leaves;
     
             assert!(
    -            wallet
    -                .sign(
    -                    &mut psbt,
    -                    SignOptions {
    -                        tap_leaves_options: TapLeavesOptions::Include(
    -                            included_script_leaves.clone()
    +            wallet
    +                .sign(
    +                    &mut psbt,
    +                    SignOptions {
    +                        tap_leaves_options: TapLeavesOptions::Include(
    +                            included_script_leaves.clone()
                             ),
    -                        ..Default::default()
    +                        ..Default::default()
                         },
                     )
    -                .unwrap(),
    -            "Unable to finalize tx"
    -        );
    -
    -        assert!(psbt.inputs[0]
    -            .tap_script_sigs
    -            .iter()
    -            .all(|s| included_script_leaves.contains(&s.0 .1)
    -                && !excluded_script_leaves.contains(&s.0 .1)));
    -    }
    -
    -    #[test]
    -    fn test_taproot_script_spend_sign_exclude_some_leaves() {
    -        use crate::signer::TapLeavesOptions;
    -        use bitcoin::util::taproot::TapLeafHash;
    -
    -        let (wallet, _, _) = get_funded_wallet(get_test_tr_with_taptree_both_priv());
    -        let addr = wallet.get_address(AddressIndex::New).unwrap();
    -
    -        let mut builder = wallet.build_tx();
    -        builder.add_recipient(addr.script_pubkey(), 25_000);
    -        let (mut psbt, _) = builder.finish().unwrap();
    -        let mut script_leaves: Vec<_> = psbt.inputs[0]
    -            .tap_scripts
    -            .clone()
    -            .values()
    -            .map(|(script, version)| TapLeafHash::from_script(script, *version))
    -            .collect();
    -        let included_script_leaves = vec![script_leaves.pop().unwrap()];
    -        let excluded_script_leaves = script_leaves;
    +                .unwrap(),
    +            "Unable to finalize tx"
    +        );
    +
    +        assert!(psbt.inputs[0]
    +            .tap_script_sigs
    +            .iter()
    +            .all(|s| included_script_leaves.contains(&s.0 .1)
    +                && !excluded_script_leaves.contains(&s.0 .1)));
    +    }
    +
    +    #[test]
    +    fn test_taproot_script_spend_sign_exclude_some_leaves() {
    +        use crate::signer::TapLeavesOptions;
    +        use bitcoin::util::taproot::TapLeafHash;
    +
    +        let (wallet, _, _) = get_funded_wallet(get_test_tr_with_taptree_both_priv());
    +        let addr = wallet.get_address(AddressIndex::New).unwrap();
    +
    +        let mut builder = wallet.build_tx();
    +        builder.add_recipient(addr.script_pubkey(), 25_000);
    +        let (mut psbt, _) = builder.finish().unwrap();
    +        let mut script_leaves: Vec<_> = psbt.inputs[0]
    +            .tap_scripts
    +            .clone()
    +            .values()
    +            .map(|(script, version)| TapLeafHash::from_script(script, *version))
    +            .collect();
    +        let included_script_leaves = vec![script_leaves.pop().unwrap()];
    +        let excluded_script_leaves = script_leaves;
     
             assert!(
    -            wallet
    -                .sign(
    -                    &mut psbt,
    -                    SignOptions {
    -                        tap_leaves_options: TapLeavesOptions::Exclude(
    -                            excluded_script_leaves.clone()
    +            wallet
    +                .sign(
    +                    &mut psbt,
    +                    SignOptions {
    +                        tap_leaves_options: TapLeavesOptions::Exclude(
    +                            excluded_script_leaves.clone()
                             ),
    -                        ..Default::default()
    +                        ..Default::default()
                         },
                     )
    -                .unwrap(),
    -            "Unable to finalize tx"
    -        );
    -
    -        assert!(psbt.inputs[0]
    -            .tap_script_sigs
    -            .iter()
    -            .all(|s| included_script_leaves.contains(&s.0 .1)
    -                && !excluded_script_leaves.contains(&s.0 .1)));
    -    }
    -
    -    #[test]
    -    fn test_taproot_script_spend_sign_no_leaves() {
    -        use crate::signer::TapLeavesOptions;
    -        let (wallet, _, _) = get_funded_wallet(get_test_tr_with_taptree_both_priv());
    -        let addr = wallet.get_address(AddressIndex::New).unwrap();
    -
    -        let mut builder = wallet.build_tx();
    -        builder.add_recipient(addr.script_pubkey(), 25_000);
    -        let (mut psbt, _) = builder.finish().unwrap();
    -
    -        wallet
    -            .sign(
    -                &mut psbt,
    -                SignOptions {
    -                    tap_leaves_options: TapLeavesOptions::None,
    -                    ..Default::default()
    +                .unwrap(),
    +            "Unable to finalize tx"
    +        );
    +
    +        assert!(psbt.inputs[0]
    +            .tap_script_sigs
    +            .iter()
    +            .all(|s| included_script_leaves.contains(&s.0 .1)
    +                && !excluded_script_leaves.contains(&s.0 .1)));
    +    }
    +
    +    #[test]
    +    fn test_taproot_script_spend_sign_no_leaves() {
    +        use crate::signer::TapLeavesOptions;
    +        let (wallet, _, _) = get_funded_wallet(get_test_tr_with_taptree_both_priv());
    +        let addr = wallet.get_address(AddressIndex::New).unwrap();
    +
    +        let mut builder = wallet.build_tx();
    +        builder.add_recipient(addr.script_pubkey(), 25_000);
    +        let (mut psbt, _) = builder.finish().unwrap();
    +
    +        wallet
    +            .sign(
    +                &mut psbt,
    +                SignOptions {
    +                    tap_leaves_options: TapLeavesOptions::None,
    +                    ..Default::default()
                     },
                 )
    -            .unwrap();
    +            .unwrap();
     
    -        assert!(psbt.inputs.iter().all(|i| i.tap_script_sigs.is_empty()));
    +        assert!(psbt.inputs.iter().all(|i| i.tap_script_sigs.is_empty()));
         }
     
    -    #[test]
    -    fn test_taproot_sign_derive_index_from_psbt() {
    -        let (wallet, _, _) = get_funded_wallet(get_test_tr_single_sig_xprv());
    +    #[test]
    +    fn test_taproot_sign_derive_index_from_psbt() {
    +        let (wallet, _, _) = get_funded_wallet(get_test_tr_single_sig_xprv());
     
    -        let addr = wallet.get_address(AddressIndex::New).unwrap();
    +        let addr = wallet.get_address(AddressIndex::New).unwrap();
     
    -        let mut builder = wallet.build_tx();
    -        builder.add_recipient(addr.script_pubkey(), 25_000);
    -        let (mut psbt, _) = builder.finish().unwrap();
    +        let mut builder = wallet.build_tx();
    +        builder.add_recipient(addr.script_pubkey(), 25_000);
    +        let (mut psbt, _) = builder.finish().unwrap();
     
    -        // re-create the wallet with an empty db
    -        let wallet_empty = Wallet::new(
    -            get_test_tr_single_sig_xprv(),
    +        // re-create the wallet with an empty db
    +        let wallet_empty = Wallet::new(
    +            get_test_tr_single_sig_xprv(),
                 None,
    -            Network::Regtest,
    -            AnyDatabase::Memory(MemoryDatabase::new()),
    +            Network::Regtest,
    +            AnyDatabase::Memory(MemoryDatabase::new()),
             )
    -        .unwrap();
    -
    -        // signing with an empty db means that we will only look at the psbt to infer the
    -        // derivation index
    +        .unwrap();
    +
    +        // signing with an empty db means that we will only look at the psbt to infer the
    +        // derivation index
    +        assert!(
    +            wallet_empty.sign(&mut psbt, Default::default()).unwrap(),
    +            "Unable to finalize tx"
    +        );
    +    }
    +
    +    #[test]
    +    fn test_taproot_sign_explicit_sighash_all() {
    +        let (wallet, _, _) = get_funded_wallet(get_test_tr_single_sig());
    +        let addr = wallet.get_address(New).unwrap();
    +        let mut builder = wallet.build_tx();
    +        builder
    +            .drain_to(addr.script_pubkey())
    +            .sighash(SchnorrSighashType::All.into())
    +            .drain_wallet();
    +        let (mut psbt, _) = builder.finish().unwrap();
    +
    +        let result = wallet.sign(&mut psbt, Default::default());
             assert!(
    -            wallet_empty.sign(&mut psbt, Default::default()).unwrap(),
    -            "Unable to finalize tx"
    -        );
    -    }
    -
    -    #[test]
    -    fn test_taproot_sign_explicit_sighash_all() {
    -        let (wallet, _, _) = get_funded_wallet(get_test_tr_single_sig());
    -        let addr = wallet.get_address(New).unwrap();
    -        let mut builder = wallet.build_tx();
    -        builder
    -            .drain_to(addr.script_pubkey())
    -            .sighash(SchnorrSighashType::All.into())
    -            .drain_wallet();
    -        let (mut psbt, _) = builder.finish().unwrap();
    -
    -        let result = wallet.sign(&mut psbt, Default::default());
    -        assert!(
    -            result.is_ok(),
    -            "Signing should work because SIGHASH_ALL is safe"
    -        )
    +            result.is_ok(),
    +            "Signing should work because SIGHASH_ALL is safe"
    +        )
         }
     
    -    #[test]
    -    fn test_taproot_sign_non_default_sighash() {
    -        let sighash = SchnorrSighashType::NonePlusAnyoneCanPay;
    +    #[test]
    +    fn test_taproot_sign_non_default_sighash() {
    +        let sighash = SchnorrSighashType::NonePlusAnyoneCanPay;
     
    -        let (wallet, _, _) = get_funded_wallet(get_test_tr_single_sig());
    -        let addr = wallet.get_address(New).unwrap();
    -        let mut builder = wallet.build_tx();
    -        builder
    -            .drain_to(addr.script_pubkey())
    -            .sighash(sighash.into())
    -            .drain_wallet();
    -        let (mut psbt, _) = builder.finish().unwrap();
    +        let (wallet, _, _) = get_funded_wallet(get_test_tr_single_sig());
    +        let addr = wallet.get_address(New).unwrap();
    +        let mut builder = wallet.build_tx();
    +        builder
    +            .drain_to(addr.script_pubkey())
    +            .sighash(sighash.into())
    +            .drain_wallet();
    +        let (mut psbt, _) = builder.finish().unwrap();
     
    -        let witness_utxo = psbt.inputs[0].witness_utxo.take();
    +        let witness_utxo = psbt.inputs[0].witness_utxo.take();
     
    -        let result = wallet.sign(&mut psbt, Default::default());
    +        let result = wallet.sign(&mut psbt, Default::default());
             assert!(
    -            result.is_err(),
    -            "Signing should have failed because the TX uses non-standard sighashes"
    -        );
    +            result.is_err(),
    +            "Signing should have failed because the TX uses non-standard sighashes"
    +        );
             assert!(
                 matches!(
    -                result.unwrap_err(),
    -                Error::Signer(SignerError::NonStandardSighash)
    +                result.unwrap_err(),
    +                Error::Signer(SignerError::NonStandardSighash)
                 ),
    -            "Signing failed with the wrong error type"
    -        );
    -
    -        // try again after opting-in
    -        let result = wallet.sign(
    -            &mut psbt,
    -            SignOptions {
    -                allow_all_sighashes: true,
    -                ..Default::default()
    +            "Signing failed with the wrong error type"
    +        );
    +
    +        // try again after opting-in
    +        let result = wallet.sign(
    +            &mut psbt,
    +            SignOptions {
    +                allow_all_sighashes: true,
    +                ..Default::default()
                 },
             );
             assert!(
    -            result.is_err(),
    -            "Signing should have failed because the witness_utxo is missing"
    -        );
    +            result.is_err(),
    +            "Signing should have failed because the witness_utxo is missing"
    +        );
             assert!(
                 matches!(
    -                result.unwrap_err(),
    -                Error::Signer(SignerError::MissingWitnessUtxo)
    +                result.unwrap_err(),
    +                Error::Signer(SignerError::MissingWitnessUtxo)
                 ),
    -            "Signing failed with the wrong error type"
    -        );
    +            "Signing failed with the wrong error type"
    +        );
     
    -        // restore the witness_utxo
    -        psbt.inputs[0].witness_utxo = witness_utxo;
    +        // restore the witness_utxo
    +        psbt.inputs[0].witness_utxo = witness_utxo;
     
    -        let result = wallet.sign(
    -            &mut psbt,
    -            SignOptions {
    -                allow_all_sighashes: true,
    -                ..Default::default()
    +        let result = wallet.sign(
    +            &mut psbt,
    +            SignOptions {
    +                allow_all_sighashes: true,
    +                ..Default::default()
                 },
             );
     
    -        assert!(result.is_ok(), "Signing should have worked");
    +        assert!(result.is_ok(), "Signing should have worked");
             assert!(
    -            result.unwrap(),
    -            "Should finalize the input since we can produce signatures"
    -        );
    +            result.unwrap(),
    +            "Should finalize the input since we can produce signatures"
    +        );
     
    -        let extracted = psbt.extract_tx();
    +        let extracted = psbt.extract_tx();
             assert_eq!(
    -            *extracted.input[0].witness.to_vec()[0].last().unwrap(),
    -            sighash as u8,
    -            "The signature should have been made with the right sighash"
    -        );
    +            *extracted.input[0].witness.to_vec()[0].last().unwrap(),
    +            sighash as u8,
    +            "The signature should have been made with the right sighash"
    +        );
         }
     
    -    #[test]
    -    fn test_spend_coinbase() {
    -        let descriptors = testutils!(@descriptors (get_test_wpkh()));
    -        let wallet = Wallet::new(
    -            &descriptors.0,
    +    #[test]
    +    fn test_spend_coinbase() {
    +        let descriptors = testutils!(@descriptors (get_test_wpkh()));
    +        let wallet = Wallet::new(
    +            &descriptors.0,
                 None,
    -            Network::Regtest,
    -            AnyDatabase::Memory(MemoryDatabase::new()),
    +            Network::Regtest,
    +            AnyDatabase::Memory(MemoryDatabase::new()),
             )
    -        .unwrap();
    +        .unwrap();
     
    -        let confirmation_time = 5;
    +        let confirmation_time = 5;
     
             crate::populate_test_db!(
    -            wallet.database.borrow_mut(),
    -            testutils! (@tx ( (@external descriptors, 0) => 25_000 ) (@confirmations 1)),
    -            Some(confirmation_time),
    -            (@coinbase true)
    -        );
    -        let sync_time = SyncTime {
    -            block_time: BlockTime {
    -                height: confirmation_time,
    -                timestamp: 0,
    +            wallet.database.borrow_mut(),
    +            testutils! (@tx ( (@external descriptors, 0) => 25_000 ) (@confirmations 1)),
    +            Some(confirmation_time),
    +            (@coinbase true)
    +        );
    +        let sync_time = SyncTime {
    +            block_time: BlockTime {
    +                height: confirmation_time,
    +                timestamp: 0,
                 },
             };
    -        wallet
    -            .database
    -            .borrow_mut()
    -            .set_sync_time(sync_time)
    -            .unwrap();
    +        wallet
    +            .database
    +            .borrow_mut()
    +            .set_sync_time(sync_time)
    +            .unwrap();
     
    -        let not_yet_mature_time = confirmation_time + COINBASE_MATURITY - 1;
    -        let maturity_time = confirmation_time + COINBASE_MATURITY;
    +        let not_yet_mature_time = confirmation_time + COINBASE_MATURITY - 1;
    +        let maturity_time = confirmation_time + COINBASE_MATURITY;
     
    -        let balance = wallet.get_balance().unwrap();
    +        let balance = wallet.get_balance().unwrap();
             assert_eq!(
    -            balance,
    -            Balance {
    -                immature: 25_000,
    -                trusted_pending: 0,
    -                untrusted_pending: 0,
    -                confirmed: 0
    -            }
    -        );
    -
    -        // We try to create a transaction, only to notice that all
    -        // our funds are unspendable
    -        let addr = Address::from_str("2N1Ffz3WaNzbeLFBb51xyFMHYSEUXcbiSoX").unwrap();
    -        let mut builder = wallet.build_tx();
    -        builder
    -            .add_recipient(addr.script_pubkey(), balance.immature / 2)
    -            .current_height(confirmation_time);
    +            balance,
    +            Balance {
    +                immature: 25_000,
    +                trusted_pending: 0,
    +                untrusted_pending: 0,
    +                confirmed: 0
    +            }
    +        );
    +
    +        // We try to create a transaction, only to notice that all
    +        // our funds are unspendable
    +        let addr = Address::from_str("2N1Ffz3WaNzbeLFBb51xyFMHYSEUXcbiSoX").unwrap();
    +        let mut builder = wallet.build_tx();
    +        builder
    +            .add_recipient(addr.script_pubkey(), balance.immature / 2)
    +            .current_height(confirmation_time);
             assert!(matches!(
    -            builder.finish().unwrap_err(),
    -            Error::InsufficientFunds {
    -                needed: _,
    -                available: 0
    -            }
    +            builder.finish().unwrap_err(),
    +            Error::InsufficientFunds {
    +                needed: _,
    +                available: 0
    +            }
             ));
     
    -        // Still unspendable...
    -        let mut builder = wallet.build_tx();
    -        builder
    -            .add_recipient(addr.script_pubkey(), balance.immature / 2)
    -            .current_height(not_yet_mature_time);
    +        // Still unspendable...
    +        let mut builder = wallet.build_tx();
    +        builder
    +            .add_recipient(addr.script_pubkey(), balance.immature / 2)
    +            .current_height(not_yet_mature_time);
             assert!(matches!(
    -            builder.finish().unwrap_err(),
    -            Error::InsufficientFunds {
    -                needed: _,
    -                available: 0
    -            }
    +            builder.finish().unwrap_err(),
    +            Error::InsufficientFunds {
    +                needed: _,
    +                available: 0
    +            }
             ));
     
    -        // ...Now the coinbase is mature :)
    -        let sync_time = SyncTime {
    -            block_time: BlockTime {
    -                height: maturity_time,
    -                timestamp: 0,
    +        // ...Now the coinbase is mature :)
    +        let sync_time = SyncTime {
    +            block_time: BlockTime {
    +                height: maturity_time,
    +                timestamp: 0,
                 },
             };
    -        wallet
    -            .database
    -            .borrow_mut()
    -            .set_sync_time(sync_time)
    -            .unwrap();
    +        wallet
    +            .database
    +            .borrow_mut()
    +            .set_sync_time(sync_time)
    +            .unwrap();
     
    -        let balance = wallet.get_balance().unwrap();
    +        let balance = wallet.get_balance().unwrap();
             assert_eq!(
    -            balance,
    -            Balance {
    -                immature: 0,
    -                trusted_pending: 0,
    -                untrusted_pending: 0,
    -                confirmed: 25_000
    -            }
    +            balance,
    +            Balance {
    +                immature: 0,
    +                trusted_pending: 0,
    +                untrusted_pending: 0,
    +                confirmed: 25_000
    +            }
             );
    -        let mut builder = wallet.build_tx();
    -        builder
    -            .add_recipient(addr.script_pubkey(), balance.confirmed / 2)
    -            .current_height(maturity_time);
    -        builder.finish().unwrap();
    +        let mut builder = wallet.build_tx();
    +        builder
    +            .add_recipient(addr.script_pubkey(), balance.confirmed / 2)
    +            .current_height(maturity_time);
    +        builder.finish().unwrap();
         }
     
    -    #[test]
    -    fn test_allow_dust_limit() {
    -        let (wallet, _, _) = get_funded_wallet(get_test_single_sig_cltv());
    +    #[test]
    +    fn test_allow_dust_limit() {
    +        let (wallet, _, _) = get_funded_wallet(get_test_single_sig_cltv());
     
    -        let addr = wallet.get_address(New).unwrap();
    +        let addr = wallet.get_address(New).unwrap();
     
    -        let mut builder = wallet.build_tx();
    +        let mut builder = wallet.build_tx();
     
    -        builder.add_recipient(addr.script_pubkey(), 0);
    +        builder.add_recipient(addr.script_pubkey(), 0);
     
             assert!(matches!(
    -            builder.finish().unwrap_err(),
    -            Error::OutputBelowDustLimit(0)
    +            builder.finish().unwrap_err(),
    +            Error::OutputBelowDustLimit(0)
             ));
     
    -        let mut builder = wallet.build_tx();
    -
    -        builder
    -            .allow_dust(true)
    -            .add_recipient(addr.script_pubkey(), 0);
    -
    -        assert!(builder.finish().is_ok());
    -    }
    -
    -    #[test]
    -    fn test_fee_rate_sign_no_grinding_high_r() {
    -        // Our goal is to obtain a transaction with a signature with high-R (71 bytes
    -        // instead of 70). We then check that our fee rate and fee calculation is
    -        // alright.
    -        let (wallet, _, _) = get_funded_wallet("wpkh(tprv8ZgxMBicQKsPd3EupYiPRhaMooHKUHJxNsTfYuScep13go8QFfHdtkG9nRkFGb7busX4isf6X9dURGCoKgitaApQ6MupRhZMcELAxTBRJgS/*)");
    -        let addr = wallet.get_address(New).unwrap();
    -        let fee_rate = FeeRate::from_sat_per_vb(1.0);
    -        let mut builder = wallet.build_tx();
    -        let mut data = vec![0];
    -        builder
    -            .drain_to(addr.script_pubkey())
    -            .drain_wallet()
    -            .fee_rate(fee_rate)
    -            .add_data(&data);
    -        let (mut psbt, details) = builder.finish().unwrap();
    -        let (op_return_vout, _) = psbt
    -            .unsigned_tx
    -            .output
    -            .iter()
    -            .enumerate()
    -            .find(|(_n, i)| i.script_pubkey.is_op_return())
    -            .unwrap();
    -
    -        let mut sig_len: usize = 0;
    -        // We try to sign many different times until we find a longer signature (71 bytes)
    -        while sig_len < 71 {
    -            // Changing the OP_RETURN data will make the signature change (but not the fee, until
    -            // data[0] is small enough)
    -            data[0] += 1;
    -            psbt.unsigned_tx.output[op_return_vout].script_pubkey = Script::new_op_return(&data);
    -            // Clearing the previous signature
    -            psbt.inputs[0].partial_sigs.clear();
    -            // Signing
    -            wallet
    -                .sign(
    -                    &mut psbt,
    -                    SignOptions {
    -                        remove_partial_sigs: false,
    -                        try_finalize: false,
    -                        allow_grinding: false,
    -                        ..Default::default()
    +        let mut builder = wallet.build_tx();
    +
    +        builder
    +            .allow_dust(true)
    +            .add_recipient(addr.script_pubkey(), 0);
    +
    +        assert!(builder.finish().is_ok());
    +    }
    +
    +    #[test]
    +    fn test_fee_rate_sign_no_grinding_high_r() {
    +        // Our goal is to obtain a transaction with a signature with high-R (71 bytes
    +        // instead of 70). We then check that our fee rate and fee calculation is
    +        // alright.
    +        let (wallet, _, _) = get_funded_wallet("wpkh(tprv8ZgxMBicQKsPd3EupYiPRhaMooHKUHJxNsTfYuScep13go8QFfHdtkG9nRkFGb7busX4isf6X9dURGCoKgitaApQ6MupRhZMcELAxTBRJgS/*)");
    +        let addr = wallet.get_address(New).unwrap();
    +        let fee_rate = FeeRate::from_sat_per_vb(1.0);
    +        let mut builder = wallet.build_tx();
    +        let mut data = vec![0];
    +        builder
    +            .drain_to(addr.script_pubkey())
    +            .drain_wallet()
    +            .fee_rate(fee_rate)
    +            .add_data(&data);
    +        let (mut psbt, details) = builder.finish().unwrap();
    +        let (op_return_vout, _) = psbt
    +            .unsigned_tx
    +            .output
    +            .iter()
    +            .enumerate()
    +            .find(|(_n, i)| i.script_pubkey.is_op_return())
    +            .unwrap();
    +
    +        let mut sig_len: usize = 0;
    +        // We try to sign many different times until we find a longer signature (71 bytes)
    +        while sig_len < 71 {
    +            // Changing the OP_RETURN data will make the signature change (but not the fee, until
    +            // data[0] is small enough)
    +            data[0] += 1;
    +            psbt.unsigned_tx.output[op_return_vout].script_pubkey = Script::new_op_return(&data);
    +            // Clearing the previous signature
    +            psbt.inputs[0].partial_sigs.clear();
    +            // Signing
    +            wallet
    +                .sign(
    +                    &mut psbt,
    +                    SignOptions {
    +                        remove_partial_sigs: false,
    +                        try_finalize: false,
    +                        allow_grinding: false,
    +                        ..Default::default()
                         },
                     )
    -                .unwrap();
    -            // We only have one key in the partial_sigs map, this is a trick to retrieve it
    -            let key = psbt.inputs[0].partial_sigs.keys().next().unwrap();
    -            sig_len = psbt.inputs[0].partial_sigs[key].sig.serialize_der().len();
    +                .unwrap();
    +            // We only have one key in the partial_sigs map, this is a trick to retrieve it
    +            let key = psbt.inputs[0].partial_sigs.keys().next().unwrap();
    +            sig_len = psbt.inputs[0].partial_sigs[key].sig.serialize_der().len();
             }
    -        // Actually finalizing the transaction...
    -        wallet
    -            .sign(
    -                &mut psbt,
    -                SignOptions {
    -                    remove_partial_sigs: false,
    -                    allow_grinding: false,
    -                    ..Default::default()
    +        // Actually finalizing the transaction...
    +        wallet
    +            .sign(
    +                &mut psbt,
    +                SignOptions {
    +                    remove_partial_sigs: false,
    +                    allow_grinding: false,
    +                    ..Default::default()
                     },
                 )
    -            .unwrap();
    -        // ...and checking that everything is fine
    -        assert_fee_rate!(psbt, details.fee.unwrap_or(0), fee_rate);
    -    }
    -
    -    #[test]
    -    fn test_fee_rate_sign_grinding_low_r() {
    -        // Our goal is to obtain a transaction with a signature with low-R (70 bytes)
    -        // by setting the `allow_grinding` signing option as true.
    -        // We then check that our fee rate and fee calculation is alright and that our
    -        // signature is 70 bytes.
    -        let (wallet, _, _) = get_funded_wallet("wpkh(tprv8ZgxMBicQKsPd3EupYiPRhaMooHKUHJxNsTfYuScep13go8QFfHdtkG9nRkFGb7busX4isf6X9dURGCoKgitaApQ6MupRhZMcELAxTBRJgS/*)");
    -        let addr = wallet.get_address(New).unwrap();
    -        let fee_rate = FeeRate::from_sat_per_vb(1.0);
    -        let mut builder = wallet.build_tx();
    -        builder
    -            .drain_to(addr.script_pubkey())
    -            .drain_wallet()
    -            .fee_rate(fee_rate);
    -        let (mut psbt, details) = builder.finish().unwrap();
    -
    -        wallet
    -            .sign(
    -                &mut psbt,
    -                SignOptions {
    -                    remove_partial_sigs: false,
    -                    allow_grinding: true,
    -                    ..Default::default()
    +            .unwrap();
    +        // ...and checking that everything is fine
    +        assert_fee_rate!(psbt, details.fee.unwrap_or(0), fee_rate);
    +    }
    +
    +    #[test]
    +    fn test_fee_rate_sign_grinding_low_r() {
    +        // Our goal is to obtain a transaction with a signature with low-R (70 bytes)
    +        // by setting the `allow_grinding` signing option as true.
    +        // We then check that our fee rate and fee calculation is alright and that our
    +        // signature is 70 bytes.
    +        let (wallet, _, _) = get_funded_wallet("wpkh(tprv8ZgxMBicQKsPd3EupYiPRhaMooHKUHJxNsTfYuScep13go8QFfHdtkG9nRkFGb7busX4isf6X9dURGCoKgitaApQ6MupRhZMcELAxTBRJgS/*)");
    +        let addr = wallet.get_address(New).unwrap();
    +        let fee_rate = FeeRate::from_sat_per_vb(1.0);
    +        let mut builder = wallet.build_tx();
    +        builder
    +            .drain_to(addr.script_pubkey())
    +            .drain_wallet()
    +            .fee_rate(fee_rate);
    +        let (mut psbt, details) = builder.finish().unwrap();
    +
    +        wallet
    +            .sign(
    +                &mut psbt,
    +                SignOptions {
    +                    remove_partial_sigs: false,
    +                    allow_grinding: true,
    +                    ..Default::default()
                     },
                 )
    -            .unwrap();
    -
    -        let key = psbt.inputs[0].partial_sigs.keys().next().unwrap();
    -        let sig_len = psbt.inputs[0].partial_sigs[key].sig.serialize_der().len();
    -        assert_eq!(sig_len, 70);
    -        assert_fee_rate!(psbt, details.fee.unwrap_or(0), fee_rate);
    -    }
    -
    -    #[cfg(feature = "test-hardware-signer")]
    -    #[test]
    -    fn test_create_signer() {
    -        use crate::wallet::hardwaresigner::HWISigner;
    -        use hwi::types::HWIChain;
    -        use hwi::HWIClient;
    -
    -        let devices = HWIClient::enumerate().unwrap();
    -        let device = devices.first().expect("No devices found");
    -        let client = HWIClient::get_client(device, true, HWIChain::Regtest).unwrap();
    -        let descriptors = client.get_descriptors(None).unwrap();
    -        let custom_signer = HWISigner::from_device(device, HWIChain::Regtest).unwrap();
    -
    -        let (mut wallet, _, _) = get_funded_wallet(&descriptors.internal[0]);
    -        wallet.add_signer(
    -            KeychainKind::External,
    -            SignerOrdering(200),
    -            Arc::new(custom_signer),
    +            .unwrap();
    +
    +        let key = psbt.inputs[0].partial_sigs.keys().next().unwrap();
    +        let sig_len = psbt.inputs[0].partial_sigs[key].sig.serialize_der().len();
    +        assert_eq!(sig_len, 70);
    +        assert_fee_rate!(psbt, details.fee.unwrap_or(0), fee_rate);
    +    }
    +
    +    #[cfg(feature = "test-hardware-signer")]
    +    #[test]
    +    fn test_create_signer() {
    +        use crate::wallet::hardwaresigner::HWISigner;
    +        use hwi::types::HWIChain;
    +        use hwi::HWIClient;
    +
    +        let devices = HWIClient::enumerate().unwrap();
    +        let device = devices.first().expect("No devices found");
    +        let client = HWIClient::get_client(device, true, HWIChain::Regtest).unwrap();
    +        let descriptors = client.get_descriptors(None).unwrap();
    +        let custom_signer = HWISigner::from_device(device, HWIChain::Regtest).unwrap();
    +
    +        let (mut wallet, _, _) = get_funded_wallet(&descriptors.internal[0]);
    +        wallet.add_signer(
    +            KeychainKind::External,
    +            SignerOrdering(200),
    +            Arc::new(custom_signer),
             );
     
    -        let addr = wallet.get_address(LastUnused).unwrap();
    -        let mut builder = wallet.build_tx();
    -        builder.drain_to(addr.script_pubkey()).drain_wallet();
    -        let (mut psbt, _) = builder.finish().unwrap();
    +        let addr = wallet.get_address(LastUnused).unwrap();
    +        let mut builder = wallet.build_tx();
    +        builder.drain_to(addr.script_pubkey()).drain_wallet();
    +        let (mut psbt, _) = builder.finish().unwrap();
     
    -        let finalized = wallet.sign(&mut psbt, Default::default()).unwrap();
    -        assert!(finalized);
    +        let finalized = wallet.sign(&mut psbt, Default::default()).unwrap();
    +        assert!(finalized);
         }
     
    -    #[test]
    -    fn test_taproot_load_descriptor_duplicated_keys() {
    -        // Added after issue https://github.com/bitcoindevkit/bdk/issues/760
    -        //
    -        // Having the same key in multiple taproot leaves is safe and should be accepted by BDK
    +    #[test]
    +    fn test_taproot_load_descriptor_duplicated_keys() {
    +        // Added after issue https://github.com/bitcoindevkit/bdk/issues/760
    +        //
    +        // Having the same key in multiple taproot leaves is safe and should be accepted by BDK
     
    -        let (wallet, _, _) = get_funded_wallet(get_test_tr_dup_keys());
    -        let addr = wallet.get_address(New).unwrap();
    +        let (wallet, _, _) = get_funded_wallet(get_test_tr_dup_keys());
    +        let addr = wallet.get_address(New).unwrap();
     
             assert_eq!(
    -            addr.to_string(),
    -            "bcrt1pvysh4nmh85ysrkpwtrr8q8gdadhgdejpy6f9v424a8v9htjxjhyqw9c5s5"
    -        );
    +            addr.to_string(),
    +            "bcrt1pvysh4nmh85ysrkpwtrr8q8gdadhgdejpy6f9v424a8v9htjxjhyqw9c5s5"
    +        );
         }
     }
     
    -
    - \ No newline at end of file +
    \ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/src/bdk/wallet/signer.rs.html b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/src/bdk/wallet/signer.rs.html index a9cfd8ceed..0e12a977d9 100644 --- a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/src/bdk/wallet/signer.rs.html +++ b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/src/bdk/wallet/signer.rs.html @@ -1,2256 +1,2249 @@ -signer.rs - source - -
       1
    -   2
    -   3
    -   4
    -   5
    -   6
    -   7
    -   8
    -   9
    -  10
    -  11
    -  12
    -  13
    -  14
    -  15
    -  16
    -  17
    -  18
    -  19
    -  20
    -  21
    -  22
    -  23
    -  24
    -  25
    -  26
    -  27
    -  28
    -  29
    -  30
    -  31
    -  32
    -  33
    -  34
    -  35
    -  36
    -  37
    -  38
    -  39
    -  40
    -  41
    -  42
    -  43
    -  44
    -  45
    -  46
    -  47
    -  48
    -  49
    -  50
    -  51
    -  52
    -  53
    -  54
    -  55
    -  56
    -  57
    -  58
    -  59
    -  60
    -  61
    -  62
    -  63
    -  64
    -  65
    -  66
    -  67
    -  68
    -  69
    -  70
    -  71
    -  72
    -  73
    -  74
    -  75
    -  76
    -  77
    -  78
    -  79
    -  80
    -  81
    -  82
    -  83
    -  84
    -  85
    -  86
    -  87
    -  88
    -  89
    -  90
    -  91
    -  92
    -  93
    -  94
    -  95
    -  96
    -  97
    -  98
    -  99
    - 100
    - 101
    - 102
    - 103
    - 104
    - 105
    - 106
    - 107
    - 108
    - 109
    - 110
    - 111
    - 112
    - 113
    - 114
    - 115
    - 116
    - 117
    - 118
    - 119
    - 120
    - 121
    - 122
    - 123
    - 124
    - 125
    - 126
    - 127
    - 128
    - 129
    - 130
    - 131
    - 132
    - 133
    - 134
    - 135
    - 136
    - 137
    - 138
    - 139
    - 140
    - 141
    - 142
    - 143
    - 144
    - 145
    - 146
    - 147
    - 148
    - 149
    - 150
    - 151
    - 152
    - 153
    - 154
    - 155
    - 156
    - 157
    - 158
    - 159
    - 160
    - 161
    - 162
    - 163
    - 164
    - 165
    - 166
    - 167
    - 168
    - 169
    - 170
    - 171
    - 172
    - 173
    - 174
    - 175
    - 176
    - 177
    - 178
    - 179
    - 180
    - 181
    - 182
    - 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
    - 245
    - 246
    - 247
    - 248
    - 249
    - 250
    - 251
    - 252
    - 253
    - 254
    - 255
    - 256
    - 257
    - 258
    - 259
    - 260
    - 261
    - 262
    - 263
    - 264
    - 265
    - 266
    - 267
    - 268
    - 269
    - 270
    - 271
    - 272
    - 273
    - 274
    - 275
    - 276
    - 277
    - 278
    - 279
    - 280
    - 281
    - 282
    - 283
    - 284
    - 285
    - 286
    - 287
    - 288
    - 289
    - 290
    - 291
    - 292
    - 293
    - 294
    - 295
    - 296
    - 297
    - 298
    - 299
    - 300
    - 301
    - 302
    - 303
    - 304
    - 305
    - 306
    - 307
    - 308
    - 309
    - 310
    - 311
    - 312
    - 313
    - 314
    - 315
    - 316
    - 317
    - 318
    - 319
    - 320
    - 321
    - 322
    - 323
    - 324
    - 325
    - 326
    - 327
    - 328
    - 329
    - 330
    - 331
    - 332
    - 333
    - 334
    - 335
    - 336
    - 337
    - 338
    - 339
    - 340
    - 341
    - 342
    - 343
    - 344
    - 345
    - 346
    - 347
    - 348
    - 349
    - 350
    - 351
    - 352
    - 353
    - 354
    - 355
    - 356
    - 357
    - 358
    - 359
    - 360
    - 361
    - 362
    - 363
    - 364
    - 365
    - 366
    - 367
    - 368
    - 369
    - 370
    - 371
    - 372
    - 373
    - 374
    - 375
    - 376
    - 377
    - 378
    - 379
    - 380
    - 381
    - 382
    - 383
    - 384
    - 385
    - 386
    - 387
    - 388
    - 389
    - 390
    - 391
    - 392
    - 393
    - 394
    - 395
    - 396
    - 397
    - 398
    - 399
    - 400
    - 401
    - 402
    - 403
    - 404
    - 405
    - 406
    - 407
    - 408
    - 409
    - 410
    - 411
    - 412
    - 413
    - 414
    - 415
    - 416
    - 417
    - 418
    - 419
    - 420
    - 421
    - 422
    - 423
    - 424
    - 425
    - 426
    - 427
    - 428
    - 429
    - 430
    - 431
    - 432
    - 433
    - 434
    - 435
    - 436
    - 437
    - 438
    - 439
    - 440
    - 441
    - 442
    - 443
    - 444
    - 445
    - 446
    - 447
    - 448
    - 449
    - 450
    - 451
    - 452
    - 453
    - 454
    - 455
    - 456
    - 457
    - 458
    - 459
    - 460
    - 461
    - 462
    - 463
    - 464
    - 465
    - 466
    - 467
    - 468
    - 469
    - 470
    - 471
    - 472
    - 473
    - 474
    - 475
    - 476
    - 477
    - 478
    - 479
    - 480
    - 481
    - 482
    - 483
    - 484
    - 485
    - 486
    - 487
    - 488
    - 489
    - 490
    - 491
    - 492
    - 493
    - 494
    - 495
    - 496
    - 497
    - 498
    - 499
    - 500
    - 501
    - 502
    - 503
    - 504
    - 505
    - 506
    - 507
    - 508
    - 509
    - 510
    - 511
    - 512
    - 513
    - 514
    - 515
    - 516
    - 517
    - 518
    - 519
    - 520
    - 521
    - 522
    - 523
    - 524
    - 525
    - 526
    - 527
    - 528
    - 529
    - 530
    - 531
    - 532
    - 533
    - 534
    - 535
    - 536
    - 537
    - 538
    - 539
    - 540
    - 541
    - 542
    - 543
    - 544
    - 545
    - 546
    - 547
    - 548
    - 549
    - 550
    - 551
    - 552
    - 553
    - 554
    - 555
    - 556
    - 557
    - 558
    - 559
    - 560
    - 561
    - 562
    - 563
    - 564
    - 565
    - 566
    - 567
    - 568
    - 569
    - 570
    - 571
    - 572
    - 573
    - 574
    - 575
    - 576
    - 577
    - 578
    - 579
    - 580
    - 581
    - 582
    - 583
    - 584
    - 585
    - 586
    - 587
    - 588
    - 589
    - 590
    - 591
    - 592
    - 593
    - 594
    - 595
    - 596
    - 597
    - 598
    - 599
    - 600
    - 601
    - 602
    - 603
    - 604
    - 605
    - 606
    - 607
    - 608
    - 609
    - 610
    - 611
    - 612
    - 613
    - 614
    - 615
    - 616
    - 617
    - 618
    - 619
    - 620
    - 621
    - 622
    - 623
    - 624
    - 625
    - 626
    - 627
    - 628
    - 629
    - 630
    - 631
    - 632
    - 633
    - 634
    - 635
    - 636
    - 637
    - 638
    - 639
    - 640
    - 641
    - 642
    - 643
    - 644
    - 645
    - 646
    - 647
    - 648
    - 649
    - 650
    - 651
    - 652
    - 653
    - 654
    - 655
    - 656
    - 657
    - 658
    - 659
    - 660
    - 661
    - 662
    - 663
    - 664
    - 665
    - 666
    - 667
    - 668
    - 669
    - 670
    - 671
    - 672
    - 673
    - 674
    - 675
    - 676
    - 677
    - 678
    - 679
    - 680
    - 681
    - 682
    - 683
    - 684
    - 685
    - 686
    - 687
    - 688
    - 689
    - 690
    - 691
    - 692
    - 693
    - 694
    - 695
    - 696
    - 697
    - 698
    - 699
    - 700
    - 701
    - 702
    - 703
    - 704
    - 705
    - 706
    - 707
    - 708
    - 709
    - 710
    - 711
    - 712
    - 713
    - 714
    - 715
    - 716
    - 717
    - 718
    - 719
    - 720
    - 721
    - 722
    - 723
    - 724
    - 725
    - 726
    - 727
    - 728
    - 729
    - 730
    - 731
    - 732
    - 733
    - 734
    - 735
    - 736
    - 737
    - 738
    - 739
    - 740
    - 741
    - 742
    - 743
    - 744
    - 745
    - 746
    - 747
    - 748
    - 749
    - 750
    - 751
    - 752
    - 753
    - 754
    - 755
    - 756
    - 757
    - 758
    - 759
    - 760
    - 761
    - 762
    - 763
    - 764
    - 765
    - 766
    - 767
    - 768
    - 769
    - 770
    - 771
    - 772
    - 773
    - 774
    - 775
    - 776
    - 777
    - 778
    - 779
    - 780
    - 781
    - 782
    - 783
    - 784
    - 785
    - 786
    - 787
    - 788
    - 789
    - 790
    - 791
    - 792
    - 793
    - 794
    - 795
    - 796
    - 797
    - 798
    - 799
    - 800
    - 801
    - 802
    - 803
    - 804
    - 805
    - 806
    - 807
    - 808
    - 809
    - 810
    - 811
    - 812
    - 813
    - 814
    - 815
    - 816
    - 817
    - 818
    - 819
    - 820
    - 821
    - 822
    - 823
    - 824
    - 825
    - 826
    - 827
    - 828
    - 829
    - 830
    - 831
    - 832
    - 833
    - 834
    - 835
    - 836
    - 837
    - 838
    - 839
    - 840
    - 841
    - 842
    - 843
    - 844
    - 845
    - 846
    - 847
    - 848
    - 849
    - 850
    - 851
    - 852
    - 853
    - 854
    - 855
    - 856
    - 857
    - 858
    - 859
    - 860
    - 861
    - 862
    - 863
    - 864
    - 865
    - 866
    - 867
    - 868
    - 869
    - 870
    - 871
    - 872
    - 873
    - 874
    - 875
    - 876
    - 877
    - 878
    - 879
    - 880
    - 881
    - 882
    - 883
    - 884
    - 885
    - 886
    - 887
    - 888
    - 889
    - 890
    - 891
    - 892
    - 893
    - 894
    - 895
    - 896
    - 897
    - 898
    - 899
    - 900
    - 901
    - 902
    - 903
    - 904
    - 905
    - 906
    - 907
    - 908
    - 909
    - 910
    - 911
    - 912
    - 913
    - 914
    - 915
    - 916
    - 917
    - 918
    - 919
    - 920
    - 921
    - 922
    - 923
    - 924
    - 925
    - 926
    - 927
    - 928
    - 929
    - 930
    - 931
    - 932
    - 933
    - 934
    - 935
    - 936
    - 937
    - 938
    - 939
    - 940
    - 941
    - 942
    - 943
    - 944
    - 945
    - 946
    - 947
    - 948
    - 949
    - 950
    - 951
    - 952
    - 953
    - 954
    - 955
    - 956
    - 957
    - 958
    - 959
    - 960
    - 961
    - 962
    - 963
    - 964
    - 965
    - 966
    - 967
    - 968
    - 969
    - 970
    - 971
    - 972
    - 973
    - 974
    - 975
    - 976
    - 977
    - 978
    - 979
    - 980
    - 981
    - 982
    - 983
    - 984
    - 985
    - 986
    - 987
    - 988
    - 989
    - 990
    - 991
    - 992
    - 993
    - 994
    - 995
    - 996
    - 997
    - 998
    - 999
    -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
    -1028
    -1029
    -1030
    -1031
    -1032
    -1033
    -1034
    -1035
    -1036
    -1037
    -1038
    -1039
    -1040
    -1041
    -1042
    -1043
    -1044
    -1045
    -1046
    -1047
    -1048
    -1049
    -1050
    -1051
    -1052
    -1053
    -1054
    -1055
    -1056
    -1057
    -1058
    -1059
    -1060
    -1061
    -1062
    -1063
    -1064
    -1065
    -1066
    -1067
    -1068
    -1069
    -1070
    -1071
    -1072
    -1073
    -1074
    -1075
    -1076
    -1077
    -1078
    -1079
    -1080
    -1081
    -1082
    -1083
    -1084
    -1085
    -1086
    -1087
    -1088
    -1089
    -1090
    -1091
    -1092
    -1093
    -1094
    -1095
    -1096
    -1097
    -1098
    -1099
    -1100
    -1101
    -1102
    -1103
    -1104
    -1105
    -1106
    -1107
    -1108
    -1109
    -1110
    -1111
    -1112
    -1113
    -1114
    -1115
    -1116
    -1117
    -1118
    -1119
    -1120
    -1121
    -1122
    -1123
    -
    // Bitcoin Dev Kit
    -// Written in 2020 by Alekos Filini <alekos.filini@gmail.com>
    -//
    -// Copyright (c) 2020-2021 Bitcoin Dev Kit Developers
    -//
    -// This file is licensed under the Apache License, Version 2.0 <LICENSE-APACHE
    -// or http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
    -// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your option.
    -// You may not use this file except in accordance with one or both of these
    -// licenses.
    -
    -//! Generalized signers
    -//!
    -//! This module provides the ability to add customized signers to a [`Wallet`](super::Wallet)
    -//! through the [`Wallet::add_signer`](super::Wallet::add_signer) function.
    -//!
    -//! ```
    -//! # use std::sync::Arc;
    -//! # use std::str::FromStr;
    -//! # use bitcoin::secp256k1::{Secp256k1, All};
    -//! # use bitcoin::*;
    -//! # use bitcoin::util::psbt;
    -//! # use bdk::signer::*;
    -//! # use bdk::database::*;
    -//! # use bdk::*;
    -//! # #[derive(Debug)]
    -//! # struct CustomHSM;
    -//! # impl CustomHSM {
    -//! #     fn hsm_sign_input(&self, _psbt: &mut psbt::PartiallySignedTransaction, _input: usize) -> Result<(), SignerError> {
    -//! #         Ok(())
    -//! #     }
    -//! #     fn connect() -> Self {
    -//! #         CustomHSM
    -//! #     }
    -//! #     fn get_id(&self) -> SignerId {
    -//! #         SignerId::Dummy(0)
    -//! #     }
    -//! # }
    -//! #[derive(Debug)]
    -//! struct CustomSigner {
    -//!     device: CustomHSM,
    -//! }
    -//!
    -//! impl CustomSigner {
    -//!     fn connect() -> Self {
    -//!         CustomSigner { device: CustomHSM::connect() }
    -//!     }
    -//! }
    -//!
    -//! impl SignerCommon for CustomSigner {
    -//!     fn id(&self, _secp: &Secp256k1<All>) -> SignerId {
    -//!         self.device.get_id()
    -//!     }
    -//! }
    -//!
    -//! impl InputSigner for CustomSigner {
    -//!     fn sign_input(
    -//!         &self,
    -//!         psbt: &mut psbt::PartiallySignedTransaction,
    -//!         input_index: usize,
    -//!         _sign_options: &SignOptions,
    -//!         _secp: &Secp256k1<All>,
    -//!     ) -> Result<(), SignerError> {
    -//!         self.device.hsm_sign_input(psbt, input_index)?;
    -//!
    -//!         Ok(())
    -//!     }
    -//! }
    -//!
    -//! let custom_signer = CustomSigner::connect();
    -//!
    -//! let descriptor = "wpkh(tpubD6NzVbkrYhZ4Xferm7Pz4VnjdcDPFyjVu5K4iZXQ4pVN8Cks4pHVowTBXBKRhX64pkRyJZJN5xAKj4UDNnLPb5p2sSKXhewoYx5GbTdUFWq/*)";
    -//! let mut wallet = Wallet::new(descriptor, None, Network::Testnet, MemoryDatabase::default())?;
    -//! wallet.add_signer(
    -//!     KeychainKind::External,
    -//!     SignerOrdering(200),
    -//!     Arc::new(custom_signer)
    -//! );
    -//!
    -//! # Ok::<_, bdk::Error>(())
    -//! ```
    -
    -use std::cmp::Ordering;
    -use std::collections::BTreeMap;
    -use std::fmt;
    -use std::ops::{Bound::Included, Deref};
    -use std::sync::Arc;
    -
    -use bitcoin::blockdata::opcodes;
    -use bitcoin::blockdata::script::Builder as ScriptBuilder;
    -use bitcoin::hashes::{hash160, Hash};
    -use bitcoin::secp256k1::Message;
    -use bitcoin::util::bip32::{ChildNumber, DerivationPath, ExtendedPrivKey, Fingerprint};
    -use bitcoin::util::{ecdsa, psbt, schnorr, sighash, taproot};
    -use bitcoin::{secp256k1, XOnlyPublicKey};
    -use bitcoin::{EcdsaSighashType, PrivateKey, PublicKey, SchnorrSighashType, Script};
    -
    -use miniscript::descriptor::{
    -    Descriptor, DescriptorPublicKey, DescriptorSecretKey, DescriptorXKey, KeyMap, SinglePriv,
    -    SinglePubKey,
    +signer.rs - source
    1
    +2
    +3
    +4
    +5
    +6
    +7
    +8
    +9
    +10
    +11
    +12
    +13
    +14
    +15
    +16
    +17
    +18
    +19
    +20
    +21
    +22
    +23
    +24
    +25
    +26
    +27
    +28
    +29
    +30
    +31
    +32
    +33
    +34
    +35
    +36
    +37
    +38
    +39
    +40
    +41
    +42
    +43
    +44
    +45
    +46
    +47
    +48
    +49
    +50
    +51
    +52
    +53
    +54
    +55
    +56
    +57
    +58
    +59
    +60
    +61
    +62
    +63
    +64
    +65
    +66
    +67
    +68
    +69
    +70
    +71
    +72
    +73
    +74
    +75
    +76
    +77
    +78
    +79
    +80
    +81
    +82
    +83
    +84
    +85
    +86
    +87
    +88
    +89
    +90
    +91
    +92
    +93
    +94
    +95
    +96
    +97
    +98
    +99
    +100
    +101
    +102
    +103
    +104
    +105
    +106
    +107
    +108
    +109
    +110
    +111
    +112
    +113
    +114
    +115
    +116
    +117
    +118
    +119
    +120
    +121
    +122
    +123
    +124
    +125
    +126
    +127
    +128
    +129
    +130
    +131
    +132
    +133
    +134
    +135
    +136
    +137
    +138
    +139
    +140
    +141
    +142
    +143
    +144
    +145
    +146
    +147
    +148
    +149
    +150
    +151
    +152
    +153
    +154
    +155
    +156
    +157
    +158
    +159
    +160
    +161
    +162
    +163
    +164
    +165
    +166
    +167
    +168
    +169
    +170
    +171
    +172
    +173
    +174
    +175
    +176
    +177
    +178
    +179
    +180
    +181
    +182
    +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
    +245
    +246
    +247
    +248
    +249
    +250
    +251
    +252
    +253
    +254
    +255
    +256
    +257
    +258
    +259
    +260
    +261
    +262
    +263
    +264
    +265
    +266
    +267
    +268
    +269
    +270
    +271
    +272
    +273
    +274
    +275
    +276
    +277
    +278
    +279
    +280
    +281
    +282
    +283
    +284
    +285
    +286
    +287
    +288
    +289
    +290
    +291
    +292
    +293
    +294
    +295
    +296
    +297
    +298
    +299
    +300
    +301
    +302
    +303
    +304
    +305
    +306
    +307
    +308
    +309
    +310
    +311
    +312
    +313
    +314
    +315
    +316
    +317
    +318
    +319
    +320
    +321
    +322
    +323
    +324
    +325
    +326
    +327
    +328
    +329
    +330
    +331
    +332
    +333
    +334
    +335
    +336
    +337
    +338
    +339
    +340
    +341
    +342
    +343
    +344
    +345
    +346
    +347
    +348
    +349
    +350
    +351
    +352
    +353
    +354
    +355
    +356
    +357
    +358
    +359
    +360
    +361
    +362
    +363
    +364
    +365
    +366
    +367
    +368
    +369
    +370
    +371
    +372
    +373
    +374
    +375
    +376
    +377
    +378
    +379
    +380
    +381
    +382
    +383
    +384
    +385
    +386
    +387
    +388
    +389
    +390
    +391
    +392
    +393
    +394
    +395
    +396
    +397
    +398
    +399
    +400
    +401
    +402
    +403
    +404
    +405
    +406
    +407
    +408
    +409
    +410
    +411
    +412
    +413
    +414
    +415
    +416
    +417
    +418
    +419
    +420
    +421
    +422
    +423
    +424
    +425
    +426
    +427
    +428
    +429
    +430
    +431
    +432
    +433
    +434
    +435
    +436
    +437
    +438
    +439
    +440
    +441
    +442
    +443
    +444
    +445
    +446
    +447
    +448
    +449
    +450
    +451
    +452
    +453
    +454
    +455
    +456
    +457
    +458
    +459
    +460
    +461
    +462
    +463
    +464
    +465
    +466
    +467
    +468
    +469
    +470
    +471
    +472
    +473
    +474
    +475
    +476
    +477
    +478
    +479
    +480
    +481
    +482
    +483
    +484
    +485
    +486
    +487
    +488
    +489
    +490
    +491
    +492
    +493
    +494
    +495
    +496
    +497
    +498
    +499
    +500
    +501
    +502
    +503
    +504
    +505
    +506
    +507
    +508
    +509
    +510
    +511
    +512
    +513
    +514
    +515
    +516
    +517
    +518
    +519
    +520
    +521
    +522
    +523
    +524
    +525
    +526
    +527
    +528
    +529
    +530
    +531
    +532
    +533
    +534
    +535
    +536
    +537
    +538
    +539
    +540
    +541
    +542
    +543
    +544
    +545
    +546
    +547
    +548
    +549
    +550
    +551
    +552
    +553
    +554
    +555
    +556
    +557
    +558
    +559
    +560
    +561
    +562
    +563
    +564
    +565
    +566
    +567
    +568
    +569
    +570
    +571
    +572
    +573
    +574
    +575
    +576
    +577
    +578
    +579
    +580
    +581
    +582
    +583
    +584
    +585
    +586
    +587
    +588
    +589
    +590
    +591
    +592
    +593
    +594
    +595
    +596
    +597
    +598
    +599
    +600
    +601
    +602
    +603
    +604
    +605
    +606
    +607
    +608
    +609
    +610
    +611
    +612
    +613
    +614
    +615
    +616
    +617
    +618
    +619
    +620
    +621
    +622
    +623
    +624
    +625
    +626
    +627
    +628
    +629
    +630
    +631
    +632
    +633
    +634
    +635
    +636
    +637
    +638
    +639
    +640
    +641
    +642
    +643
    +644
    +645
    +646
    +647
    +648
    +649
    +650
    +651
    +652
    +653
    +654
    +655
    +656
    +657
    +658
    +659
    +660
    +661
    +662
    +663
    +664
    +665
    +666
    +667
    +668
    +669
    +670
    +671
    +672
    +673
    +674
    +675
    +676
    +677
    +678
    +679
    +680
    +681
    +682
    +683
    +684
    +685
    +686
    +687
    +688
    +689
    +690
    +691
    +692
    +693
    +694
    +695
    +696
    +697
    +698
    +699
    +700
    +701
    +702
    +703
    +704
    +705
    +706
    +707
    +708
    +709
    +710
    +711
    +712
    +713
    +714
    +715
    +716
    +717
    +718
    +719
    +720
    +721
    +722
    +723
    +724
    +725
    +726
    +727
    +728
    +729
    +730
    +731
    +732
    +733
    +734
    +735
    +736
    +737
    +738
    +739
    +740
    +741
    +742
    +743
    +744
    +745
    +746
    +747
    +748
    +749
    +750
    +751
    +752
    +753
    +754
    +755
    +756
    +757
    +758
    +759
    +760
    +761
    +762
    +763
    +764
    +765
    +766
    +767
    +768
    +769
    +770
    +771
    +772
    +773
    +774
    +775
    +776
    +777
    +778
    +779
    +780
    +781
    +782
    +783
    +784
    +785
    +786
    +787
    +788
    +789
    +790
    +791
    +792
    +793
    +794
    +795
    +796
    +797
    +798
    +799
    +800
    +801
    +802
    +803
    +804
    +805
    +806
    +807
    +808
    +809
    +810
    +811
    +812
    +813
    +814
    +815
    +816
    +817
    +818
    +819
    +820
    +821
    +822
    +823
    +824
    +825
    +826
    +827
    +828
    +829
    +830
    +831
    +832
    +833
    +834
    +835
    +836
    +837
    +838
    +839
    +840
    +841
    +842
    +843
    +844
    +845
    +846
    +847
    +848
    +849
    +850
    +851
    +852
    +853
    +854
    +855
    +856
    +857
    +858
    +859
    +860
    +861
    +862
    +863
    +864
    +865
    +866
    +867
    +868
    +869
    +870
    +871
    +872
    +873
    +874
    +875
    +876
    +877
    +878
    +879
    +880
    +881
    +882
    +883
    +884
    +885
    +886
    +887
    +888
    +889
    +890
    +891
    +892
    +893
    +894
    +895
    +896
    +897
    +898
    +899
    +900
    +901
    +902
    +903
    +904
    +905
    +906
    +907
    +908
    +909
    +910
    +911
    +912
    +913
    +914
    +915
    +916
    +917
    +918
    +919
    +920
    +921
    +922
    +923
    +924
    +925
    +926
    +927
    +928
    +929
    +930
    +931
    +932
    +933
    +934
    +935
    +936
    +937
    +938
    +939
    +940
    +941
    +942
    +943
    +944
    +945
    +946
    +947
    +948
    +949
    +950
    +951
    +952
    +953
    +954
    +955
    +956
    +957
    +958
    +959
    +960
    +961
    +962
    +963
    +964
    +965
    +966
    +967
    +968
    +969
    +970
    +971
    +972
    +973
    +974
    +975
    +976
    +977
    +978
    +979
    +980
    +981
    +982
    +983
    +984
    +985
    +986
    +987
    +988
    +989
    +990
    +991
    +992
    +993
    +994
    +995
    +996
    +997
    +998
    +999
    +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
    +1028
    +1029
    +1030
    +1031
    +1032
    +1033
    +1034
    +1035
    +1036
    +1037
    +1038
    +1039
    +1040
    +1041
    +1042
    +1043
    +1044
    +1045
    +1046
    +1047
    +1048
    +1049
    +1050
    +1051
    +1052
    +1053
    +1054
    +1055
    +1056
    +1057
    +1058
    +1059
    +1060
    +1061
    +1062
    +1063
    +1064
    +1065
    +1066
    +1067
    +1068
    +1069
    +1070
    +1071
    +1072
    +1073
    +1074
    +1075
    +1076
    +1077
    +1078
    +1079
    +1080
    +1081
    +1082
    +1083
    +1084
    +1085
    +1086
    +1087
    +1088
    +1089
    +1090
    +1091
    +1092
    +1093
    +1094
    +1095
    +1096
    +1097
    +1098
    +1099
    +1100
    +1101
    +1102
    +1103
    +1104
    +1105
    +1106
    +1107
    +1108
    +1109
    +1110
    +1111
    +1112
    +1113
    +1114
    +1115
    +1116
    +1117
    +1118
    +1119
    +1120
    +1121
    +1122
    +1123
    +
    // Bitcoin Dev Kit
    +// Written in 2020 by Alekos Filini <alekos.filini@gmail.com>
    +//
    +// Copyright (c) 2020-2021 Bitcoin Dev Kit Developers
    +//
    +// This file is licensed under the Apache License, Version 2.0 <LICENSE-APACHE
    +// or http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
    +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your option.
    +// You may not use this file except in accordance with one or both of these
    +// licenses.
    +
    +//! Generalized signers
    +//!
    +//! This module provides the ability to add customized signers to a [`Wallet`](super::Wallet)
    +//! through the [`Wallet::add_signer`](super::Wallet::add_signer) function.
    +//!
    +//! ```
    +//! # use std::sync::Arc;
    +//! # use std::str::FromStr;
    +//! # use bitcoin::secp256k1::{Secp256k1, All};
    +//! # use bitcoin::*;
    +//! # use bitcoin::util::psbt;
    +//! # use bdk::signer::*;
    +//! # use bdk::database::*;
    +//! # use bdk::*;
    +//! # #[derive(Debug)]
    +//! # struct CustomHSM;
    +//! # impl CustomHSM {
    +//! #     fn hsm_sign_input(&self, _psbt: &mut psbt::PartiallySignedTransaction, _input: usize) -> Result<(), SignerError> {
    +//! #         Ok(())
    +//! #     }
    +//! #     fn connect() -> Self {
    +//! #         CustomHSM
    +//! #     }
    +//! #     fn get_id(&self) -> SignerId {
    +//! #         SignerId::Dummy(0)
    +//! #     }
    +//! # }
    +//! #[derive(Debug)]
    +//! struct CustomSigner {
    +//!     device: CustomHSM,
    +//! }
    +//!
    +//! impl CustomSigner {
    +//!     fn connect() -> Self {
    +//!         CustomSigner { device: CustomHSM::connect() }
    +//!     }
    +//! }
    +//!
    +//! impl SignerCommon for CustomSigner {
    +//!     fn id(&self, _secp: &Secp256k1<All>) -> SignerId {
    +//!         self.device.get_id()
    +//!     }
    +//! }
    +//!
    +//! impl InputSigner for CustomSigner {
    +//!     fn sign_input(
    +//!         &self,
    +//!         psbt: &mut psbt::PartiallySignedTransaction,
    +//!         input_index: usize,
    +//!         _sign_options: &SignOptions,
    +//!         _secp: &Secp256k1<All>,
    +//!     ) -> Result<(), SignerError> {
    +//!         self.device.hsm_sign_input(psbt, input_index)?;
    +//!
    +//!         Ok(())
    +//!     }
    +//! }
    +//!
    +//! let custom_signer = CustomSigner::connect();
    +//!
    +//! let descriptor = "wpkh(tpubD6NzVbkrYhZ4Xferm7Pz4VnjdcDPFyjVu5K4iZXQ4pVN8Cks4pHVowTBXBKRhX64pkRyJZJN5xAKj4UDNnLPb5p2sSKXhewoYx5GbTdUFWq/*)";
    +//! let mut wallet = Wallet::new(descriptor, None, Network::Testnet, MemoryDatabase::default())?;
    +//! wallet.add_signer(
    +//!     KeychainKind::External,
    +//!     SignerOrdering(200),
    +//!     Arc::new(custom_signer)
    +//! );
    +//!
    +//! # Ok::<_, bdk::Error>(())
    +//! ```
    +
    +use std::cmp::Ordering;
    +use std::collections::BTreeMap;
    +use std::fmt;
    +use std::ops::{Bound::Included, Deref};
    +use std::sync::Arc;
    +
    +use bitcoin::blockdata::opcodes;
    +use bitcoin::blockdata::script::Builder as ScriptBuilder;
    +use bitcoin::hashes::{hash160, Hash};
    +use bitcoin::secp256k1::Message;
    +use bitcoin::util::bip32::{ChildNumber, DerivationPath, ExtendedPrivKey, Fingerprint};
    +use bitcoin::util::{ecdsa, psbt, schnorr, sighash, taproot};
    +use bitcoin::{secp256k1, XOnlyPublicKey};
    +use bitcoin::{EcdsaSighashType, PrivateKey, PublicKey, SchnorrSighashType, Script};
    +
    +use miniscript::descriptor::{
    +    Descriptor, DescriptorPublicKey, DescriptorSecretKey, DescriptorXKey, KeyMap, SinglePriv,
    +    SinglePubKey,
     };
    -use miniscript::{Legacy, Segwitv0, SigType, Tap, ToPublicKey};
    -
    -use super::utils::SecpCtx;
    -use crate::descriptor::{DescriptorMeta, XKeyUtils};
    -use crate::psbt::PsbtUtils;
    -
    -/// Identifier of a signer in the `SignersContainers`. Used as a key to find the right signer among
    -/// multiple of them
    -#[derive(Debug, Clone, Ord, PartialOrd, PartialEq, Eq, Hash)]
    -pub enum SignerId {
    -    /// Bitcoin HASH160 (RIPEMD160 after SHA256) hash of an ECDSA public key
    -    PkHash(hash160::Hash),
    -    /// The fingerprint of a BIP32 extended key
    -    Fingerprint(Fingerprint),
    -    /// Dummy identifier
    -    Dummy(u64),
    +use miniscript::{Legacy, Segwitv0, SigType, Tap, ToPublicKey};
    +
    +use super::utils::SecpCtx;
    +use crate::descriptor::{DescriptorMeta, XKeyUtils};
    +use crate::psbt::PsbtUtils;
    +
    +/// Identifier of a signer in the `SignersContainers`. Used as a key to find the right signer among
    +/// multiple of them
    +#[derive(Debug, Clone, Ord, PartialOrd, PartialEq, Eq, Hash)]
    +pub enum SignerId {
    +    /// Bitcoin HASH160 (RIPEMD160 after SHA256) hash of an ECDSA public key
    +    PkHash(hash160::Hash),
    +    /// The fingerprint of a BIP32 extended key
    +    Fingerprint(Fingerprint),
    +    /// Dummy identifier
    +    Dummy(u64),
     }
     
    -impl From<hash160::Hash> for SignerId {
    -    fn from(hash: hash160::Hash) -> SignerId {
    -        SignerId::PkHash(hash)
    +impl From<hash160::Hash> for SignerId {
    +    fn from(hash: hash160::Hash) -> SignerId {
    +        SignerId::PkHash(hash)
         }
     }
     
    -impl From<Fingerprint> for SignerId {
    -    fn from(fing: Fingerprint) -> SignerId {
    -        SignerId::Fingerprint(fing)
    +impl From<Fingerprint> for SignerId {
    +    fn from(fing: Fingerprint) -> SignerId {
    +        SignerId::Fingerprint(fing)
         }
     }
     
    -/// Signing error
    -#[derive(Debug, PartialEq, Eq, Clone)]
    -pub enum SignerError {
    -    /// The private key is missing for the required public key
    -    MissingKey,
    -    /// The private key in use has the right fingerprint but derives differently than expected
    -    InvalidKey,
    -    /// The user canceled the operation
    -    UserCanceled,
    -    /// Input index is out of range
    -    InputIndexOutOfRange,
    -    /// The `non_witness_utxo` field of the transaction is required to sign this input
    -    MissingNonWitnessUtxo,
    -    /// The `non_witness_utxo` specified is invalid
    -    InvalidNonWitnessUtxo,
    -    /// The `witness_utxo` field of the transaction is required to sign this input
    -    MissingWitnessUtxo,
    -    /// The `witness_script` field of the transaction is required to sign this input
    -    MissingWitnessScript,
    -    /// The fingerprint and derivation path are missing from the psbt input
    -    MissingHdKeypath,
    -    /// The psbt contains a non-`SIGHASH_ALL` sighash in one of its input and the user hasn't
    -    /// explicitly allowed them
    -    ///
    -    /// To enable signing transactions with non-standard sighashes set
    -    /// [`SignOptions::allow_all_sighashes`] to `true`.
    -    NonStandardSighash,
    -    /// Invalid SIGHASH for the signing context in use
    -    InvalidSighash,
    -    /// Error while computing the hash to sign
    -    SighashError(sighash::Error),
    -    /// Error while signing using hardware wallets
    -    #[cfg(feature = "hardware-signer")]
    -    HWIError(hwi::error::Error),
    +/// Signing error
    +#[derive(Debug, PartialEq, Eq, Clone)]
    +pub enum SignerError {
    +    /// The private key is missing for the required public key
    +    MissingKey,
    +    /// The private key in use has the right fingerprint but derives differently than expected
    +    InvalidKey,
    +    /// The user canceled the operation
    +    UserCanceled,
    +    /// Input index is out of range
    +    InputIndexOutOfRange,
    +    /// The `non_witness_utxo` field of the transaction is required to sign this input
    +    MissingNonWitnessUtxo,
    +    /// The `non_witness_utxo` specified is invalid
    +    InvalidNonWitnessUtxo,
    +    /// The `witness_utxo` field of the transaction is required to sign this input
    +    MissingWitnessUtxo,
    +    /// The `witness_script` field of the transaction is required to sign this input
    +    MissingWitnessScript,
    +    /// The fingerprint and derivation path are missing from the psbt input
    +    MissingHdKeypath,
    +    /// The psbt contains a non-`SIGHASH_ALL` sighash in one of its input and the user hasn't
    +    /// explicitly allowed them
    +    ///
    +    /// To enable signing transactions with non-standard sighashes set
    +    /// [`SignOptions::allow_all_sighashes`] to `true`.
    +    NonStandardSighash,
    +    /// Invalid SIGHASH for the signing context in use
    +    InvalidSighash,
    +    /// Error while computing the hash to sign
    +    SighashError(sighash::Error),
    +    /// Error while signing using hardware wallets
    +    #[cfg(feature = "hardware-signer")]
    +    HWIError(hwi::error::Error),
     }
     
    -#[cfg(feature = "hardware-signer")]
    -impl From<hwi::error::Error> for SignerError {
    -    fn from(e: hwi::error::Error) -> Self {
    -        SignerError::HWIError(e)
    +#[cfg(feature = "hardware-signer")]
    +impl From<hwi::error::Error> for SignerError {
    +    fn from(e: hwi::error::Error) -> Self {
    +        SignerError::HWIError(e)
         }
     }
     
    -impl From<sighash::Error> for SignerError {
    -    fn from(e: sighash::Error) -> Self {
    -        SignerError::SighashError(e)
    +impl From<sighash::Error> for SignerError {
    +    fn from(e: sighash::Error) -> Self {
    +        SignerError::SighashError(e)
         }
     }
     
    -impl fmt::Display for SignerError {
    -    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
    -        write!(f, "{:?}", self)
    +impl fmt::Display for SignerError {
    +    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
    +        write!(f, "{:?}", self)
         }
     }
     
    -impl std::error::Error for SignerError {}
    -
    -/// Signing context
    -///
    -/// Used by our software signers to determine the type of signatures to make
    -#[derive(Debug, Clone, Copy, PartialEq, Eq)]
    -pub enum SignerContext {
    -    /// Legacy context
    -    Legacy,
    -    /// Segwit v0 context (BIP 143)
    -    Segwitv0,
    -    /// Taproot context (BIP 340)
    -    Tap {
    -        /// Whether the signer can sign for the internal key or not
    -        is_internal_key: bool,
    +impl std::error::Error for SignerError {}
    +
    +/// Signing context
    +///
    +/// Used by our software signers to determine the type of signatures to make
    +#[derive(Debug, Clone, Copy, PartialEq, Eq)]
    +pub enum SignerContext {
    +    /// Legacy context
    +    Legacy,
    +    /// Segwit v0 context (BIP 143)
    +    Segwitv0,
    +    /// Taproot context (BIP 340)
    +    Tap {
    +        /// Whether the signer can sign for the internal key or not
    +        is_internal_key: bool,
         },
     }
     
    -/// Wrapper structure to pair a signer with its context
    -#[derive(Debug, Clone)]
    -pub struct SignerWrapper<S: Sized + fmt::Debug + Clone> {
    -    signer: S,
    -    ctx: SignerContext,
    +/// Wrapper structure to pair a signer with its context
    +#[derive(Debug, Clone)]
    +pub struct SignerWrapper<S: Sized + fmt::Debug + Clone> {
    +    signer: S,
    +    ctx: SignerContext,
     }
     
    -impl<S: Sized + fmt::Debug + Clone> SignerWrapper<S> {
    -    /// Create a wrapped signer from a signer and a context
    -    pub fn new(signer: S, ctx: SignerContext) -> Self {
    -        SignerWrapper { signer, ctx }
    +impl<S: Sized + fmt::Debug + Clone> SignerWrapper<S> {
    +    /// Create a wrapped signer from a signer and a context
    +    pub fn new(signer: S, ctx: SignerContext) -> Self {
    +        SignerWrapper { signer, ctx }
         }
     }
     
    -impl<S: Sized + fmt::Debug + Clone> Deref for SignerWrapper<S> {
    -    type Target = S;
    +impl<S: Sized + fmt::Debug + Clone> Deref for SignerWrapper<S> {
    +    type Target = S;
     
    -    fn deref(&self) -> &Self::Target {
    -        &self.signer
    +    fn deref(&self) -> &Self::Target {
    +        &self.signer
         }
     }
     
    -/// Common signer methods
    -pub trait SignerCommon: fmt::Debug + Send + Sync {
    -    /// Return the [`SignerId`] for this signer
    -    ///
    -    /// The [`SignerId`] can be used to lookup a signer in the [`Wallet`](crate::Wallet)'s signers map or to
    -    /// compare two signers.
    -    fn id(&self, secp: &SecpCtx) -> SignerId;
    -
    -    /// Return the secret key for the signer
    -    ///
    -    /// This is used internally to reconstruct the original descriptor that may contain secrets.
    -    /// External signers that are meant to keep key isolated should just return `None` here (which
    -    /// is the default for this method, if not overridden).
    -    fn descriptor_secret_key(&self) -> Option<DescriptorSecretKey> {
    -        None
    -    }
    +/// Common signer methods
    +pub trait SignerCommon: fmt::Debug + Send + Sync {
    +    /// Return the [`SignerId`] for this signer
    +    ///
    +    /// The [`SignerId`] can be used to lookup a signer in the [`Wallet`](crate::Wallet)'s signers map or to
    +    /// compare two signers.
    +    fn id(&self, secp: &SecpCtx) -> SignerId;
    +
    +    /// Return the secret key for the signer
    +    ///
    +    /// This is used internally to reconstruct the original descriptor that may contain secrets.
    +    /// External signers that are meant to keep key isolated should just return `None` here (which
    +    /// is the default for this method, if not overridden).
    +    fn descriptor_secret_key(&self) -> Option<DescriptorSecretKey> {
    +        None
    +    }
     }
     
    -/// PSBT Input signer
    -///
    -/// This trait can be implemented to provide custom signers to the wallet. If the signer supports signing
    -/// individual inputs, this trait should be implemented and BDK will provide automatically an implementation
    -/// for [`TransactionSigner`].
    -pub trait InputSigner: SignerCommon {
    -    /// Sign a single psbt input
    -    fn sign_input(
    +/// PSBT Input signer
    +///
    +/// This trait can be implemented to provide custom signers to the wallet. If the signer supports signing
    +/// individual inputs, this trait should be implemented and BDK will provide automatically an implementation
    +/// for [`TransactionSigner`].
    +pub trait InputSigner: SignerCommon {
    +    /// Sign a single psbt input
    +    fn sign_input(
             &self,
    -        psbt: &mut psbt::PartiallySignedTransaction,
    -        input_index: usize,
    -        sign_options: &SignOptions,
    -        secp: &SecpCtx,
    -    ) -> Result<(), SignerError>;
    +        psbt: &mut psbt::PartiallySignedTransaction,
    +        input_index: usize,
    +        sign_options: &SignOptions,
    +        secp: &SecpCtx,
    +    ) -> Result<(), SignerError>;
     }
     
    -/// PSBT signer
    -///
    -/// This trait can be implemented when the signer can't sign inputs individually, but signs the whole transaction
    -/// at once.
    -pub trait TransactionSigner: SignerCommon {
    -    /// Sign all the inputs of the psbt
    -    fn sign_transaction(
    +/// PSBT signer
    +///
    +/// This trait can be implemented when the signer can't sign inputs individually, but signs the whole transaction
    +/// at once.
    +pub trait TransactionSigner: SignerCommon {
    +    /// Sign all the inputs of the psbt
    +    fn sign_transaction(
             &self,
    -        psbt: &mut psbt::PartiallySignedTransaction,
    -        sign_options: &SignOptions,
    -        secp: &SecpCtx,
    -    ) -> Result<(), SignerError>;
    +        psbt: &mut psbt::PartiallySignedTransaction,
    +        sign_options: &SignOptions,
    +        secp: &SecpCtx,
    +    ) -> Result<(), SignerError>;
     }
     
    -impl<T: InputSigner> TransactionSigner for T {
    -    fn sign_transaction(
    +impl<T: InputSigner> TransactionSigner for T {
    +    fn sign_transaction(
             &self,
    -        psbt: &mut psbt::PartiallySignedTransaction,
    -        sign_options: &SignOptions,
    -        secp: &SecpCtx,
    -    ) -> Result<(), SignerError> {
    -        for input_index in 0..psbt.inputs.len() {
    -            self.sign_input(psbt, input_index, sign_options, secp)?;
    +        psbt: &mut psbt::PartiallySignedTransaction,
    +        sign_options: &SignOptions,
    +        secp: &SecpCtx,
    +    ) -> Result<(), SignerError> {
    +        for input_index in 0..psbt.inputs.len() {
    +            self.sign_input(psbt, input_index, sign_options, secp)?;
             }
     
             Ok(())
         }
     }
     
    -impl SignerCommon for SignerWrapper<DescriptorXKey<ExtendedPrivKey>> {
    -    fn id(&self, secp: &SecpCtx) -> SignerId {
    -        SignerId::from(self.root_fingerprint(secp))
    +impl SignerCommon for SignerWrapper<DescriptorXKey<ExtendedPrivKey>> {
    +    fn id(&self, secp: &SecpCtx) -> SignerId {
    +        SignerId::from(self.root_fingerprint(secp))
         }
     
    -    fn descriptor_secret_key(&self) -> Option<DescriptorSecretKey> {
    -        Some(DescriptorSecretKey::XPrv(self.signer.clone()))
    +    fn descriptor_secret_key(&self) -> Option<DescriptorSecretKey> {
    +        Some(DescriptorSecretKey::XPrv(self.signer.clone()))
         }
     }
     
    -impl InputSigner for SignerWrapper<DescriptorXKey<ExtendedPrivKey>> {
    -    fn sign_input(
    +impl InputSigner for SignerWrapper<DescriptorXKey<ExtendedPrivKey>> {
    +    fn sign_input(
             &self,
    -        psbt: &mut psbt::PartiallySignedTransaction,
    -        input_index: usize,
    -        sign_options: &SignOptions,
    -        secp: &SecpCtx,
    -    ) -> Result<(), SignerError> {
    -        if input_index >= psbt.inputs.len() {
    -            return Err(SignerError::InputIndexOutOfRange);
    +        psbt: &mut psbt::PartiallySignedTransaction,
    +        input_index: usize,
    +        sign_options: &SignOptions,
    +        secp: &SecpCtx,
    +    ) -> Result<(), SignerError> {
    +        if input_index >= psbt.inputs.len() {
    +            return Err(SignerError::InputIndexOutOfRange);
             }
     
    -        if psbt.inputs[input_index].final_script_sig.is_some()
    -            || psbt.inputs[input_index].final_script_witness.is_some()
    +        if psbt.inputs[input_index].final_script_sig.is_some()
    +            || psbt.inputs[input_index].final_script_witness.is_some()
             {
    -            return Ok(());
    +            return Ok(());
             }
     
    -        let tap_key_origins = psbt.inputs[input_index]
    -            .tap_key_origins
    -            .iter()
    -            .map(|(pk, (_, keysource))| (SinglePubKey::XOnly(*pk), keysource));
    -        let (public_key, full_path) = match psbt.inputs[input_index]
    -            .bip32_derivation
    -            .iter()
    -            .map(|(pk, keysource)| (SinglePubKey::FullKey(PublicKey::new(*pk)), keysource))
    -            .chain(tap_key_origins)
    -            .find_map(|(pk, keysource)| {
    -                if self.matches(keysource, secp).is_some() {
    -                    Some((pk, keysource.1.clone()))
    -                } else {
    -                    None
    -                }
    +        let tap_key_origins = psbt.inputs[input_index]
    +            .tap_key_origins
    +            .iter()
    +            .map(|(pk, (_, keysource))| (SinglePubKey::XOnly(*pk), keysource));
    +        let (public_key, full_path) = match psbt.inputs[input_index]
    +            .bip32_derivation
    +            .iter()
    +            .map(|(pk, keysource)| (SinglePubKey::FullKey(PublicKey::new(*pk)), keysource))
    +            .chain(tap_key_origins)
    +            .find_map(|(pk, keysource)| {
    +                if self.matches(keysource, secp).is_some() {
    +                    Some((pk, keysource.1.clone()))
    +                } else {
    +                    None
    +                }
                 }) {
    -            Some((pk, full_path)) => (pk, full_path),
    -            None => return Ok(()),
    +            Some((pk, full_path)) => (pk, full_path),
    +            None => return Ok(()),
             };
     
    -        let derived_key = match self.origin.clone() {
    -            Some((_fingerprint, origin_path)) => {
    -                let deriv_path = DerivationPath::from(
    -                    &full_path.into_iter().cloned().collect::<Vec<ChildNumber>>()
    -                        [origin_path.len()..],
    +        let derived_key = match self.origin.clone() {
    +            Some((_fingerprint, origin_path)) => {
    +                let deriv_path = DerivationPath::from(
    +                    &full_path.into_iter().cloned().collect::<Vec<ChildNumber>>()
    +                        [origin_path.len()..],
                     );
    -                self.xkey.derive_priv(secp, &deriv_path).unwrap()
    +                self.xkey.derive_priv(secp, &deriv_path).unwrap()
                 }
    -            None => self.xkey.derive_priv(secp, &full_path).unwrap(),
    +            None => self.xkey.derive_priv(secp, &full_path).unwrap(),
             };
     
    -        let computed_pk = secp256k1::PublicKey::from_secret_key(secp, &derived_key.private_key);
    -        let valid_key = match public_key {
    -            SinglePubKey::FullKey(pk) if pk.inner == computed_pk => true,
    -            SinglePubKey::XOnly(x_only) if XOnlyPublicKey::from(computed_pk) == x_only => true,
    -            _ => false,
    +        let computed_pk = secp256k1::PublicKey::from_secret_key(secp, &derived_key.private_key);
    +        let valid_key = match public_key {
    +            SinglePubKey::FullKey(pk) if pk.inner == computed_pk => true,
    +            SinglePubKey::XOnly(x_only) if XOnlyPublicKey::from(computed_pk) == x_only => true,
    +            _ => false,
             };
    -        if !valid_key {
    -            Err(SignerError::InvalidKey)
    -        } else {
    -            // HD wallets imply compressed keys
    -            let priv_key = PrivateKey {
    -                compressed: true,
    -                network: self.xkey.network,
    -                inner: derived_key.private_key,
    +        if !valid_key {
    +            Err(SignerError::InvalidKey)
    +        } else {
    +            // HD wallets imply compressed keys
    +            let priv_key = PrivateKey {
    +                compressed: true,
    +                network: self.xkey.network,
    +                inner: derived_key.private_key,
                 };
     
    -            SignerWrapper::new(priv_key, self.ctx).sign_input(psbt, input_index, sign_options, secp)
    +            SignerWrapper::new(priv_key, self.ctx).sign_input(psbt, input_index, sign_options, secp)
             }
         }
     }
     
    -impl SignerCommon for SignerWrapper<PrivateKey> {
    -    fn id(&self, secp: &SecpCtx) -> SignerId {
    -        SignerId::from(self.public_key(secp).to_pubkeyhash(SigType::Ecdsa))
    +impl SignerCommon for SignerWrapper<PrivateKey> {
    +    fn id(&self, secp: &SecpCtx) -> SignerId {
    +        SignerId::from(self.public_key(secp).to_pubkeyhash(SigType::Ecdsa))
         }
     
    -    fn descriptor_secret_key(&self) -> Option<DescriptorSecretKey> {
    -        Some(DescriptorSecretKey::Single(SinglePriv {
    -            key: self.signer,
    -            origin: None,
    +    fn descriptor_secret_key(&self) -> Option<DescriptorSecretKey> {
    +        Some(DescriptorSecretKey::Single(SinglePriv {
    +            key: self.signer,
    +            origin: None,
             }))
         }
     }
     
    -impl InputSigner for SignerWrapper<PrivateKey> {
    -    fn sign_input(
    +impl InputSigner for SignerWrapper<PrivateKey> {
    +    fn sign_input(
             &self,
    -        psbt: &mut psbt::PartiallySignedTransaction,
    -        input_index: usize,
    -        sign_options: &SignOptions,
    -        secp: &SecpCtx,
    -    ) -> Result<(), SignerError> {
    -        if input_index >= psbt.inputs.len() || input_index >= psbt.unsigned_tx.input.len() {
    -            return Err(SignerError::InputIndexOutOfRange);
    +        psbt: &mut psbt::PartiallySignedTransaction,
    +        input_index: usize,
    +        sign_options: &SignOptions,
    +        secp: &SecpCtx,
    +    ) -> Result<(), SignerError> {
    +        if input_index >= psbt.inputs.len() || input_index >= psbt.unsigned_tx.input.len() {
    +            return Err(SignerError::InputIndexOutOfRange);
             }
     
    -        if psbt.inputs[input_index].final_script_sig.is_some()
    -            || psbt.inputs[input_index].final_script_witness.is_some()
    +        if psbt.inputs[input_index].final_script_sig.is_some()
    +            || psbt.inputs[input_index].final_script_witness.is_some()
             {
    -            return Ok(());
    +            return Ok(());
             }
     
    -        let pubkey = PublicKey::from_private_key(secp, self);
    -        let x_only_pubkey = XOnlyPublicKey::from(pubkey.inner);
    +        let pubkey = PublicKey::from_private_key(secp, self);
    +        let x_only_pubkey = XOnlyPublicKey::from(pubkey.inner);
     
    -        if let SignerContext::Tap { is_internal_key } = self.ctx {
    -            if is_internal_key
    -                && psbt.inputs[input_index].tap_key_sig.is_none()
    -                && sign_options.sign_with_tap_internal_key
    +        if let SignerContext::Tap { is_internal_key } = self.ctx {
    +            if is_internal_key
    +                && psbt.inputs[input_index].tap_key_sig.is_none()
    +                && sign_options.sign_with_tap_internal_key
                 {
    -                let (hash, hash_ty) = Tap::sighash(psbt, input_index, None)?;
    -                sign_psbt_schnorr(
    -                    &self.inner,
    -                    x_only_pubkey,
    +                let (hash, hash_ty) = Tap::sighash(psbt, input_index, None)?;
    +                sign_psbt_schnorr(
    +                    &self.inner,
    +                    x_only_pubkey,
                         None,
    -                    &mut psbt.inputs[input_index],
    -                    hash,
    -                    hash_ty,
    -                    secp,
    +                    &mut psbt.inputs[input_index],
    +                    hash,
    +                    hash_ty,
    +                    secp,
                     );
                 }
     
    -            if let Some((leaf_hashes, _)) =
    -                psbt.inputs[input_index].tap_key_origins.get(&x_only_pubkey)
    +            if let Some((leaf_hashes, _)) =
    +                psbt.inputs[input_index].tap_key_origins.get(&x_only_pubkey)
                 {
    -                let leaf_hashes = leaf_hashes
    -                    .iter()
    -                    .filter(|lh| {
    -                        // Removing the leaves we shouldn't sign for
    -                        let should_sign = match &sign_options.tap_leaves_options {
    -                            TapLeavesOptions::All => true,
    -                            TapLeavesOptions::Include(v) => v.contains(lh),
    -                            TapLeavesOptions::Exclude(v) => !v.contains(lh),
    -                            TapLeavesOptions::None => false,
    +                let leaf_hashes = leaf_hashes
    +                    .iter()
    +                    .filter(|lh| {
    +                        // Removing the leaves we shouldn't sign for
    +                        let should_sign = match &sign_options.tap_leaves_options {
    +                            TapLeavesOptions::All => true,
    +                            TapLeavesOptions::Include(v) => v.contains(lh),
    +                            TapLeavesOptions::Exclude(v) => !v.contains(lh),
    +                            TapLeavesOptions::None => false,
                             };
    -                        // Filtering out the leaves without our key
    -                        should_sign
    -                            && !psbt.inputs[input_index]
    -                                .tap_script_sigs
    -                                .contains_key(&(x_only_pubkey, **lh))
    +                        // Filtering out the leaves without our key
    +                        should_sign
    +                            && !psbt.inputs[input_index]
    +                                .tap_script_sigs
    +                                .contains_key(&(x_only_pubkey, **lh))
                         })
    -                    .cloned()
    -                    .collect::<Vec<_>>();
    -                for lh in leaf_hashes {
    -                    let (hash, hash_ty) = Tap::sighash(psbt, input_index, Some(lh))?;
    -                    sign_psbt_schnorr(
    -                        &self.inner,
    -                        x_only_pubkey,
    -                        Some(lh),
    -                        &mut psbt.inputs[input_index],
    -                        hash,
    -                        hash_ty,
    -                        secp,
    +                    .cloned()
    +                    .collect::<Vec<_>>();
    +                for lh in leaf_hashes {
    +                    let (hash, hash_ty) = Tap::sighash(psbt, input_index, Some(lh))?;
    +                    sign_psbt_schnorr(
    +                        &self.inner,
    +                        x_only_pubkey,
    +                        Some(lh),
    +                        &mut psbt.inputs[input_index],
    +                        hash,
    +                        hash_ty,
    +                        secp,
                         );
                     }
                 }
     
    -            return Ok(());
    +            return Ok(());
             }
     
    -        if psbt.inputs[input_index].partial_sigs.contains_key(&pubkey) {
    -            return Ok(());
    +        if psbt.inputs[input_index].partial_sigs.contains_key(&pubkey) {
    +            return Ok(());
             }
     
    -        let (hash, hash_ty) = match self.ctx {
    -            SignerContext::Segwitv0 => Segwitv0::sighash(psbt, input_index, ())?,
    -            SignerContext::Legacy => Legacy::sighash(psbt, input_index, ())?,
    -            _ => return Ok(()), // handled above
    -        };
    -        sign_psbt_ecdsa(
    -            &self.inner,
    -            pubkey,
    -            &mut psbt.inputs[input_index],
    -            hash,
    -            hash_ty,
    -            secp,
    -            sign_options.allow_grinding,
    +        let (hash, hash_ty) = match self.ctx {
    +            SignerContext::Segwitv0 => Segwitv0::sighash(psbt, input_index, ())?,
    +            SignerContext::Legacy => Legacy::sighash(psbt, input_index, ())?,
    +            _ => return Ok(()), // handled above
    +        };
    +        sign_psbt_ecdsa(
    +            &self.inner,
    +            pubkey,
    +            &mut psbt.inputs[input_index],
    +            hash,
    +            hash_ty,
    +            secp,
    +            sign_options.allow_grinding,
             );
     
             Ok(())
         }
     }
     
    -fn sign_psbt_ecdsa(
    -    secret_key: &secp256k1::SecretKey,
    -    pubkey: PublicKey,
    -    psbt_input: &mut psbt::Input,
    -    hash: bitcoin::Sighash,
    -    hash_ty: EcdsaSighashType,
    -    secp: &SecpCtx,
    -    allow_grinding: bool,
    +fn sign_psbt_ecdsa(
    +    secret_key: &secp256k1::SecretKey,
    +    pubkey: PublicKey,
    +    psbt_input: &mut psbt::Input,
    +    hash: bitcoin::Sighash,
    +    hash_ty: EcdsaSighashType,
    +    secp: &SecpCtx,
    +    allow_grinding: bool,
     ) {
    -    let msg = &Message::from_slice(&hash.into_inner()[..]).unwrap();
    -    let sig = if allow_grinding {
    -        secp.sign_ecdsa_low_r(msg, secret_key)
    -    } else {
    -        secp.sign_ecdsa(msg, secret_key)
    +    let msg = &Message::from_slice(&hash.into_inner()[..]).unwrap();
    +    let sig = if allow_grinding {
    +        secp.sign_ecdsa_low_r(msg, secret_key)
    +    } else {
    +        secp.sign_ecdsa(msg, secret_key)
         };
    -    secp.verify_ecdsa(msg, &sig, &pubkey.inner)
    -        .expect("invalid or corrupted ecdsa signature");
    +    secp.verify_ecdsa(msg, &sig, &pubkey.inner)
    +        .expect("invalid or corrupted ecdsa signature");
     
    -    let final_signature = ecdsa::EcdsaSig { sig, hash_ty };
    -    psbt_input.partial_sigs.insert(pubkey, final_signature);
    +    let final_signature = ecdsa::EcdsaSig { sig, hash_ty };
    +    psbt_input.partial_sigs.insert(pubkey, final_signature);
     }
     
    -// Calling this with `leaf_hash` = `None` will sign for key-spend
    -fn sign_psbt_schnorr(
    -    secret_key: &secp256k1::SecretKey,
    -    pubkey: XOnlyPublicKey,
    -    leaf_hash: Option<taproot::TapLeafHash>,
    -    psbt_input: &mut psbt::Input,
    -    hash: taproot::TapSighashHash,
    -    hash_ty: SchnorrSighashType,
    -    secp: &SecpCtx,
    +// Calling this with `leaf_hash` = `None` will sign for key-spend
    +fn sign_psbt_schnorr(
    +    secret_key: &secp256k1::SecretKey,
    +    pubkey: XOnlyPublicKey,
    +    leaf_hash: Option<taproot::TapLeafHash>,
    +    psbt_input: &mut psbt::Input,
    +    hash: taproot::TapSighashHash,
    +    hash_ty: SchnorrSighashType,
    +    secp: &SecpCtx,
     ) {
    -    use schnorr::TapTweak;
    -
    -    let keypair = secp256k1::KeyPair::from_seckey_slice(secp, secret_key.as_ref()).unwrap();
    -    let keypair = match leaf_hash {
    -        None => keypair
    -            .tap_tweak(secp, psbt_input.tap_merkle_root)
    -            .to_inner(),
    -        Some(_) => keypair, // no tweak for script spend
    -    };
    -
    -    let msg = &Message::from_slice(&hash.into_inner()[..]).unwrap();
    -    let sig = secp.sign_schnorr(msg, &keypair);
    -    secp.verify_schnorr(&sig, msg, &XOnlyPublicKey::from_keypair(&keypair).0)
    -        .expect("invalid or corrupted schnorr signature");
    -
    -    let final_signature = schnorr::SchnorrSig { sig, hash_ty };
    -
    -    if let Some(lh) = leaf_hash {
    -        psbt_input
    -            .tap_script_sigs
    -            .insert((pubkey, lh), final_signature);
    -    } else {
    -        psbt_input.tap_key_sig = Some(final_signature);
    +    use schnorr::TapTweak;
    +
    +    let keypair = secp256k1::KeyPair::from_seckey_slice(secp, secret_key.as_ref()).unwrap();
    +    let keypair = match leaf_hash {
    +        None => keypair
    +            .tap_tweak(secp, psbt_input.tap_merkle_root)
    +            .to_inner(),
    +        Some(_) => keypair, // no tweak for script spend
    +    };
    +
    +    let msg = &Message::from_slice(&hash.into_inner()[..]).unwrap();
    +    let sig = secp.sign_schnorr(msg, &keypair);
    +    secp.verify_schnorr(&sig, msg, &XOnlyPublicKey::from_keypair(&keypair).0)
    +        .expect("invalid or corrupted schnorr signature");
    +
    +    let final_signature = schnorr::SchnorrSig { sig, hash_ty };
    +
    +    if let Some(lh) = leaf_hash {
    +        psbt_input
    +            .tap_script_sigs
    +            .insert((pubkey, lh), final_signature);
    +    } else {
    +        psbt_input.tap_key_sig = Some(final_signature);
         }
     }
     
    -/// Defines the order in which signers are called
    -///
    -/// The default value is `100`. Signers with an ordering above that will be called later,
    -/// and they will thus see the partial signatures added to the transaction once they get to sign
    -/// themselves.
    -#[derive(Debug, Clone, PartialOrd, PartialEq, Ord, Eq)]
    -pub struct SignerOrdering(pub usize);
    -
    -impl std::default::Default for SignerOrdering {
    -    fn default() -> Self {
    -        SignerOrdering(100)
    +/// Defines the order in which signers are called
    +///
    +/// The default value is `100`. Signers with an ordering above that will be called later,
    +/// and they will thus see the partial signatures added to the transaction once they get to sign
    +/// themselves.
    +#[derive(Debug, Clone, PartialOrd, PartialEq, Ord, Eq)]
    +pub struct SignerOrdering(pub usize);
    +
    +impl std::default::Default for SignerOrdering {
    +    fn default() -> Self {
    +        SignerOrdering(100)
         }
     }
     
    -#[derive(Debug, Clone)]
    -struct SignersContainerKey {
    -    id: SignerId,
    -    ordering: SignerOrdering,
    +#[derive(Debug, Clone)]
    +struct SignersContainerKey {
    +    id: SignerId,
    +    ordering: SignerOrdering,
     }
     
    -impl From<(SignerId, SignerOrdering)> for SignersContainerKey {
    -    fn from(tuple: (SignerId, SignerOrdering)) -> Self {
    -        SignersContainerKey {
    -            id: tuple.0,
    -            ordering: tuple.1,
    +impl From<(SignerId, SignerOrdering)> for SignersContainerKey {
    +    fn from(tuple: (SignerId, SignerOrdering)) -> Self {
    +        SignersContainerKey {
    +            id: tuple.0,
    +            ordering: tuple.1,
             }
         }
     }
     
    -/// Container for multiple signers
    -#[derive(Debug, Default, Clone)]
    -pub struct SignersContainer(BTreeMap<SignersContainerKey, Arc<dyn TransactionSigner>>);
    -
    -impl SignersContainer {
    -    /// Create a map of public keys to secret keys
    -    pub fn as_key_map(&self, secp: &SecpCtx) -> KeyMap {
    -        self.0
    -            .values()
    -            .filter_map(|signer| signer.descriptor_secret_key())
    -            .filter_map(|secret| secret.to_public(secp).ok().map(|public| (public, secret)))
    -            .collect()
    +/// Container for multiple signers
    +#[derive(Debug, Default, Clone)]
    +pub struct SignersContainer(BTreeMap<SignersContainerKey, Arc<dyn TransactionSigner>>);
    +
    +impl SignersContainer {
    +    /// Create a map of public keys to secret keys
    +    pub fn as_key_map(&self, secp: &SecpCtx) -> KeyMap {
    +        self.0
    +            .values()
    +            .filter_map(|signer| signer.descriptor_secret_key())
    +            .filter_map(|secret| secret.to_public(secp).ok().map(|public| (public, secret)))
    +            .collect()
         }
     
    -    /// Build a new signer container from a [`KeyMap`]
    -    ///
    -    /// Also looks at the corresponding descriptor to determine the [`SignerContext`] to attach to
    -    /// the signers
    -    pub fn build(
    -        keymap: KeyMap,
    -        descriptor: &Descriptor<DescriptorPublicKey>,
    -        secp: &SecpCtx,
    -    ) -> SignersContainer {
    -        let mut container = SignersContainer::new();
    -
    -        for (pubkey, secret) in keymap {
    -            let ctx = match descriptor {
    -                Descriptor::Tr(tr) => SignerContext::Tap {
    -                    is_internal_key: tr.internal_key() == &pubkey,
    +    /// Build a new signer container from a [`KeyMap`]
    +    ///
    +    /// Also looks at the corresponding descriptor to determine the [`SignerContext`] to attach to
    +    /// the signers
    +    pub fn build(
    +        keymap: KeyMap,
    +        descriptor: &Descriptor<DescriptorPublicKey>,
    +        secp: &SecpCtx,
    +    ) -> SignersContainer {
    +        let mut container = SignersContainer::new();
    +
    +        for (pubkey, secret) in keymap {
    +            let ctx = match descriptor {
    +                Descriptor::Tr(tr) => SignerContext::Tap {
    +                    is_internal_key: tr.internal_key() == &pubkey,
                     },
    -                _ if descriptor.is_witness() => SignerContext::Segwitv0,
    -                _ => SignerContext::Legacy,
    +                _ if descriptor.is_witness() => SignerContext::Segwitv0,
    +                _ => SignerContext::Legacy,
                 };
     
    -            match secret {
    -                DescriptorSecretKey::Single(private_key) => container.add_external(
    -                    SignerId::from(
    -                        private_key
    -                            .key
    -                            .public_key(secp)
    -                            .to_pubkeyhash(SigType::Ecdsa),
    +            match secret {
    +                DescriptorSecretKey::Single(private_key) => container.add_external(
    +                    SignerId::from(
    +                        private_key
    +                            .key
    +                            .public_key(secp)
    +                            .to_pubkeyhash(SigType::Ecdsa),
                         ),
    -                    SignerOrdering::default(),
    -                    Arc::new(SignerWrapper::new(private_key.key, ctx)),
    +                    SignerOrdering::default(),
    +                    Arc::new(SignerWrapper::new(private_key.key, ctx)),
                     ),
    -                DescriptorSecretKey::XPrv(xprv) => container.add_external(
    -                    SignerId::from(xprv.root_fingerprint(secp)),
    -                    SignerOrdering::default(),
    -                    Arc::new(SignerWrapper::new(xprv, ctx)),
    +                DescriptorSecretKey::XPrv(xprv) => container.add_external(
    +                    SignerId::from(xprv.root_fingerprint(secp)),
    +                    SignerOrdering::default(),
    +                    Arc::new(SignerWrapper::new(xprv, ctx)),
                     ),
                 };
             }
     
    -        container
    +        container
         }
     }
     
    -impl SignersContainer {
    -    /// Default constructor
    -    pub fn new() -> Self {
    -        SignersContainer(Default::default())
    +impl SignersContainer {
    +    /// Default constructor
    +    pub fn new() -> Self {
    +        SignersContainer(Default::default())
         }
     
    -    /// Adds an external signer to the container for the specified id. Optionally returns the
    -    /// signer that was previously in the container, if any
    -    pub fn add_external(
    -        &mut self,
    -        id: SignerId,
    -        ordering: SignerOrdering,
    -        signer: Arc<dyn TransactionSigner>,
    -    ) -> Option<Arc<dyn TransactionSigner>> {
    -        self.0.insert((id, ordering).into(), signer)
    +    /// Adds an external signer to the container for the specified id. Optionally returns the
    +    /// signer that was previously in the container, if any
    +    pub fn add_external(
    +        &mut self,
    +        id: SignerId,
    +        ordering: SignerOrdering,
    +        signer: Arc<dyn TransactionSigner>,
    +    ) -> Option<Arc<dyn TransactionSigner>> {
    +        self.0.insert((id, ordering).into(), signer)
         }
     
    -    /// Removes a signer from the container and returns it
    -    pub fn remove(
    -        &mut self,
    -        id: SignerId,
    -        ordering: SignerOrdering,
    -    ) -> Option<Arc<dyn TransactionSigner>> {
    -        self.0.remove(&(id, ordering).into())
    +    /// Removes a signer from the container and returns it
    +    pub fn remove(
    +        &mut self,
    +        id: SignerId,
    +        ordering: SignerOrdering,
    +    ) -> Option<Arc<dyn TransactionSigner>> {
    +        self.0.remove(&(id, ordering).into())
         }
     
    -    /// Returns the list of identifiers of all the signers in the container
    -    pub fn ids(&self) -> Vec<&SignerId> {
    -        self.0
    -            .keys()
    -            .map(|SignersContainerKey { id, .. }| id)
    -            .collect()
    +    /// Returns the list of identifiers of all the signers in the container
    +    pub fn ids(&self) -> Vec<&SignerId> {
    +        self.0
    +            .keys()
    +            .map(|SignersContainerKey { id, .. }| id)
    +            .collect()
         }
     
    -    /// Returns the list of signers in the container, sorted by lowest to highest `ordering`
    -    pub fn signers(&self) -> Vec<&Arc<dyn TransactionSigner>> {
    -        self.0.values().collect()
    +    /// Returns the list of signers in the container, sorted by lowest to highest `ordering`
    +    pub fn signers(&self) -> Vec<&Arc<dyn TransactionSigner>> {
    +        self.0.values().collect()
         }
     
    -    /// Finds the signer with lowest ordering for a given id in the container.
    -    pub fn find(&self, id: SignerId) -> Option<&Arc<dyn TransactionSigner>> {
    -        self.0
    -            .range((
    -                Included(&(id.clone(), SignerOrdering(0)).into()),
    -                Included(&(id.clone(), SignerOrdering(usize::MAX)).into()),
    +    /// Finds the signer with lowest ordering for a given id in the container.
    +    pub fn find(&self, id: SignerId) -> Option<&Arc<dyn TransactionSigner>> {
    +        self.0
    +            .range((
    +                Included(&(id.clone(), SignerOrdering(0)).into()),
    +                Included(&(id.clone(), SignerOrdering(usize::MAX)).into()),
                 ))
    -            .filter(|(k, _)| k.id == id)
    -            .map(|(_, v)| v)
    -            .next()
    +            .filter(|(k, _)| k.id == id)
    +            .map(|(_, v)| v)
    +            .next()
         }
     }
     
    -/// Options for a software signer
    -///
    -/// Adjust the behavior of our software signers and the way a transaction is finalized
    -#[derive(Debug, Clone)]
    -pub struct SignOptions {
    -    /// Whether the signer should trust the `witness_utxo`, if the `non_witness_utxo` hasn't been
    -    /// provided
    -    ///
    -    /// Defaults to `false` to mitigate the "SegWit bug" which chould trick the wallet into
    -    /// paying a fee larger than expected.
    -    ///
    -    /// Some wallets, especially if relatively old, might not provide the `non_witness_utxo` for
    -    /// SegWit transactions in the PSBT they generate: in those cases setting this to `true`
    -    /// should correctly produce a signature, at the expense of an increased trust in the creator
    -    /// of the PSBT.
    -    ///
    -    /// For more details see: <https://blog.trezor.io/details-of-firmware-updates-for-trezor-one-version-1-9-1-and-trezor-model-t-version-2-3-1-1eba8f60f2dd>
    -    pub trust_witness_utxo: bool,
    -
    -    /// Whether the wallet should assume a specific height has been reached when trying to finalize
    -    /// a transaction
    -    ///
    -    /// The wallet will only "use" a timelock to satisfy the spending policy of an input if the
    -    /// timelock height has already been reached. This option allows overriding the "current height" to let the
    -    /// wallet use timelocks in the future to spend a coin.
    -    pub assume_height: Option<u32>,
    -
    -    /// Whether the signer should use the `sighash_type` set in the PSBT when signing, no matter
    -    /// what its value is
    -    ///
    -    /// Defaults to `false` which will only allow signing using `SIGHASH_ALL`.
    -    pub allow_all_sighashes: bool,
    -
    -    /// Whether to remove partial signatures from the PSBT inputs while finalizing PSBT.
    -    ///
    -    /// Defaults to `true` which will remove partial signatures during finalization.
    -    pub remove_partial_sigs: bool,
    -
    -    /// Whether to try finalizing the PSBT after the inputs are signed.
    -    ///
    -    /// Defaults to `true` which will try finalizing PSBT after inputs are signed.
    -    pub try_finalize: bool,
    -
    -    /// Specifies which Taproot script-spend leaves we should sign for. This option is
    -    /// ignored if we're signing a non-taproot PSBT.
    -    ///
    -    /// Defaults to All, i.e., the wallet will sign all the leaves it has a key for.
    -    pub tap_leaves_options: TapLeavesOptions,
    -
    -    /// Whether we should try to sign a taproot transaction with the taproot internal key
    -    /// or not. This option is ignored if we're signing a non-taproot PSBT.
    -    ///
    -    /// Defaults to `true`, i.e., we always try to sign with the taproot internal key.
    -    pub sign_with_tap_internal_key: bool,
    -
    -    /// Whether we should grind ECDSA signature to ensure signing with low r
    -    /// or not.
    -    /// Defaults to `true`, i.e., we always grind ECDSA signature to sign with low r.
    -    pub allow_grinding: bool,
    +/// Options for a software signer
    +///
    +/// Adjust the behavior of our software signers and the way a transaction is finalized
    +#[derive(Debug, Clone)]
    +pub struct SignOptions {
    +    /// Whether the signer should trust the `witness_utxo`, if the `non_witness_utxo` hasn't been
    +    /// provided
    +    ///
    +    /// Defaults to `false` to mitigate the "SegWit bug" which chould trick the wallet into
    +    /// paying a fee larger than expected.
    +    ///
    +    /// Some wallets, especially if relatively old, might not provide the `non_witness_utxo` for
    +    /// SegWit transactions in the PSBT they generate: in those cases setting this to `true`
    +    /// should correctly produce a signature, at the expense of an increased trust in the creator
    +    /// of the PSBT.
    +    ///
    +    /// For more details see: <https://blog.trezor.io/details-of-firmware-updates-for-trezor-one-version-1-9-1-and-trezor-model-t-version-2-3-1-1eba8f60f2dd>
    +    pub trust_witness_utxo: bool,
    +
    +    /// Whether the wallet should assume a specific height has been reached when trying to finalize
    +    /// a transaction
    +    ///
    +    /// The wallet will only "use" a timelock to satisfy the spending policy of an input if the
    +    /// timelock height has already been reached. This option allows overriding the "current height" to let the
    +    /// wallet use timelocks in the future to spend a coin.
    +    pub assume_height: Option<u32>,
    +
    +    /// Whether the signer should use the `sighash_type` set in the PSBT when signing, no matter
    +    /// what its value is
    +    ///
    +    /// Defaults to `false` which will only allow signing using `SIGHASH_ALL`.
    +    pub allow_all_sighashes: bool,
    +
    +    /// Whether to remove partial signatures from the PSBT inputs while finalizing PSBT.
    +    ///
    +    /// Defaults to `true` which will remove partial signatures during finalization.
    +    pub remove_partial_sigs: bool,
    +
    +    /// Whether to try finalizing the PSBT after the inputs are signed.
    +    ///
    +    /// Defaults to `true` which will try finalizing PSBT after inputs are signed.
    +    pub try_finalize: bool,
    +
    +    /// Specifies which Taproot script-spend leaves we should sign for. This option is
    +    /// ignored if we're signing a non-taproot PSBT.
    +    ///
    +    /// Defaults to All, i.e., the wallet will sign all the leaves it has a key for.
    +    pub tap_leaves_options: TapLeavesOptions,
    +
    +    /// Whether we should try to sign a taproot transaction with the taproot internal key
    +    /// or not. This option is ignored if we're signing a non-taproot PSBT.
    +    ///
    +    /// Defaults to `true`, i.e., we always try to sign with the taproot internal key.
    +    pub sign_with_tap_internal_key: bool,
    +
    +    /// Whether we should grind ECDSA signature to ensure signing with low r
    +    /// or not.
    +    /// Defaults to `true`, i.e., we always grind ECDSA signature to sign with low r.
    +    pub allow_grinding: bool,
     }
     
    -/// Customize which taproot script-path leaves the signer should sign.
    -#[derive(Debug, Clone, PartialEq, Eq)]
    -pub enum TapLeavesOptions {
    -    /// The signer will sign all the leaves it has a key for.
    -    All,
    -    /// The signer won't sign leaves other than the ones specified. Note that it could still ignore
    -    /// some of the specified leaves, if it doesn't have the right key to sign them.
    -    Include(Vec<taproot::TapLeafHash>),
    -    /// The signer won't sign the specified leaves.
    -    Exclude(Vec<taproot::TapLeafHash>),
    -    /// The signer won't sign any leaf.
    -    None,
    +/// Customize which taproot script-path leaves the signer should sign.
    +#[derive(Debug, Clone, PartialEq, Eq)]
    +pub enum TapLeavesOptions {
    +    /// The signer will sign all the leaves it has a key for.
    +    All,
    +    /// The signer won't sign leaves other than the ones specified. Note that it could still ignore
    +    /// some of the specified leaves, if it doesn't have the right key to sign them.
    +    Include(Vec<taproot::TapLeafHash>),
    +    /// The signer won't sign the specified leaves.
    +    Exclude(Vec<taproot::TapLeafHash>),
    +    /// The signer won't sign any leaf.
    +    None,
     }
     
    -impl Default for TapLeavesOptions {
    -    fn default() -> Self {
    -        TapLeavesOptions::All
    +impl Default for TapLeavesOptions {
    +    fn default() -> Self {
    +        TapLeavesOptions::All
         }
     }
     
    -#[allow(clippy::derivable_impls)]
    -impl Default for SignOptions {
    -    fn default() -> Self {
    -        SignOptions {
    -            trust_witness_utxo: false,
    -            assume_height: None,
    -            allow_all_sighashes: false,
    -            remove_partial_sigs: true,
    -            try_finalize: true,
    -            tap_leaves_options: TapLeavesOptions::default(),
    -            sign_with_tap_internal_key: true,
    -            allow_grinding: true,
    +#[allow(clippy::derivable_impls)]
    +impl Default for SignOptions {
    +    fn default() -> Self {
    +        SignOptions {
    +            trust_witness_utxo: false,
    +            assume_height: None,
    +            allow_all_sighashes: false,
    +            remove_partial_sigs: true,
    +            try_finalize: true,
    +            tap_leaves_options: TapLeavesOptions::default(),
    +            sign_with_tap_internal_key: true,
    +            allow_grinding: true,
             }
         }
     }
     
    -pub(crate) trait ComputeSighash {
    -    type Extra;
    -    type Sighash;
    -    type SighashType;
    +pub(crate) trait ComputeSighash {
    +    type Extra;
    +    type Sighash;
    +    type SighashType;
     
    -    fn sighash(
    -        psbt: &psbt::PartiallySignedTransaction,
    -        input_index: usize,
    -        extra: Self::Extra,
    -    ) -> Result<(Self::Sighash, Self::SighashType), SignerError>;
    +    fn sighash(
    +        psbt: &psbt::PartiallySignedTransaction,
    +        input_index: usize,
    +        extra: Self::Extra,
    +    ) -> Result<(Self::Sighash, Self::SighashType), SignerError>;
     }
     
    -impl ComputeSighash for Legacy {
    -    type Extra = ();
    -    type Sighash = bitcoin::Sighash;
    -    type SighashType = EcdsaSighashType;
    -
    -    fn sighash(
    -        psbt: &psbt::PartiallySignedTransaction,
    -        input_index: usize,
    -        _extra: (),
    -    ) -> Result<(Self::Sighash, Self::SighashType), SignerError> {
    -        if input_index >= psbt.inputs.len() || input_index >= psbt.unsigned_tx.input.len() {
    -            return Err(SignerError::InputIndexOutOfRange);
    +impl ComputeSighash for Legacy {
    +    type Extra = ();
    +    type Sighash = bitcoin::Sighash;
    +    type SighashType = EcdsaSighashType;
    +
    +    fn sighash(
    +        psbt: &psbt::PartiallySignedTransaction,
    +        input_index: usize,
    +        _extra: (),
    +    ) -> Result<(Self::Sighash, Self::SighashType), SignerError> {
    +        if input_index >= psbt.inputs.len() || input_index >= psbt.unsigned_tx.input.len() {
    +            return Err(SignerError::InputIndexOutOfRange);
             }
     
    -        let psbt_input = &psbt.inputs[input_index];
    -        let tx_input = &psbt.unsigned_tx.input[input_index];
    -
    -        let sighash = psbt_input
    -            .sighash_type
    -            .unwrap_or_else(|| EcdsaSighashType::All.into())
    -            .ecdsa_hash_ty()
    -            .map_err(|_| SignerError::InvalidSighash)?;
    -        let script = match psbt_input.redeem_script {
    -            Some(ref redeem_script) => redeem_script.clone(),
    -            None => {
    -                let non_witness_utxo = psbt_input
    -                    .non_witness_utxo
    -                    .as_ref()
    -                    .ok_or(SignerError::MissingNonWitnessUtxo)?;
    -                let prev_out = non_witness_utxo
    -                    .output
    -                    .get(tx_input.previous_output.vout as usize)
    -                    .ok_or(SignerError::InvalidNonWitnessUtxo)?;
    -
    -                prev_out.script_pubkey.clone()
    +        let psbt_input = &psbt.inputs[input_index];
    +        let tx_input = &psbt.unsigned_tx.input[input_index];
    +
    +        let sighash = psbt_input
    +            .sighash_type
    +            .unwrap_or_else(|| EcdsaSighashType::All.into())
    +            .ecdsa_hash_ty()
    +            .map_err(|_| SignerError::InvalidSighash)?;
    +        let script = match psbt_input.redeem_script {
    +            Some(ref redeem_script) => redeem_script.clone(),
    +            None => {
    +                let non_witness_utxo = psbt_input
    +                    .non_witness_utxo
    +                    .as_ref()
    +                    .ok_or(SignerError::MissingNonWitnessUtxo)?;
    +                let prev_out = non_witness_utxo
    +                    .output
    +                    .get(tx_input.previous_output.vout as usize)
    +                    .ok_or(SignerError::InvalidNonWitnessUtxo)?;
    +
    +                prev_out.script_pubkey.clone()
                 }
             };
     
             Ok((
    -            sighash::SighashCache::new(&psbt.unsigned_tx).legacy_signature_hash(
    -                input_index,
    -                &script,
    -                sighash.to_u32(),
    +            sighash::SighashCache::new(&psbt.unsigned_tx).legacy_signature_hash(
    +                input_index,
    +                &script,
    +                sighash.to_u32(),
                 )?,
    -            sighash,
    +            sighash,
             ))
         }
     }
     
    -fn p2wpkh_script_code(script: &Script) -> Script {
    -    ScriptBuilder::new()
    -        .push_opcode(opcodes::all::OP_DUP)
    -        .push_opcode(opcodes::all::OP_HASH160)
    -        .push_slice(&script[2..])
    -        .push_opcode(opcodes::all::OP_EQUALVERIFY)
    -        .push_opcode(opcodes::all::OP_CHECKSIG)
    -        .into_script()
    +fn p2wpkh_script_code(script: &Script) -> Script {
    +    ScriptBuilder::new()
    +        .push_opcode(opcodes::all::OP_DUP)
    +        .push_opcode(opcodes::all::OP_HASH160)
    +        .push_slice(&script[2..])
    +        .push_opcode(opcodes::all::OP_EQUALVERIFY)
    +        .push_opcode(opcodes::all::OP_CHECKSIG)
    +        .into_script()
     }
     
    -impl ComputeSighash for Segwitv0 {
    -    type Extra = ();
    -    type Sighash = bitcoin::Sighash;
    -    type SighashType = EcdsaSighashType;
    -
    -    fn sighash(
    -        psbt: &psbt::PartiallySignedTransaction,
    -        input_index: usize,
    -        _extra: (),
    -    ) -> Result<(Self::Sighash, Self::SighashType), SignerError> {
    -        if input_index >= psbt.inputs.len() || input_index >= psbt.unsigned_tx.input.len() {
    -            return Err(SignerError::InputIndexOutOfRange);
    +impl ComputeSighash for Segwitv0 {
    +    type Extra = ();
    +    type Sighash = bitcoin::Sighash;
    +    type SighashType = EcdsaSighashType;
    +
    +    fn sighash(
    +        psbt: &psbt::PartiallySignedTransaction,
    +        input_index: usize,
    +        _extra: (),
    +    ) -> Result<(Self::Sighash, Self::SighashType), SignerError> {
    +        if input_index >= psbt.inputs.len() || input_index >= psbt.unsigned_tx.input.len() {
    +            return Err(SignerError::InputIndexOutOfRange);
             }
     
    -        let psbt_input = &psbt.inputs[input_index];
    -        let tx_input = &psbt.unsigned_tx.input[input_index];
    +        let psbt_input = &psbt.inputs[input_index];
    +        let tx_input = &psbt.unsigned_tx.input[input_index];
     
    -        let sighash = psbt_input
    -            .sighash_type
    -            .unwrap_or_else(|| EcdsaSighashType::All.into())
    -            .ecdsa_hash_ty()
    -            .map_err(|_| SignerError::InvalidSighash)?;
    +        let sighash = psbt_input
    +            .sighash_type
    +            .unwrap_or_else(|| EcdsaSighashType::All.into())
    +            .ecdsa_hash_ty()
    +            .map_err(|_| SignerError::InvalidSighash)?;
     
    -        // Always try first with the non-witness utxo
    -        let utxo = if let Some(prev_tx) = &psbt_input.non_witness_utxo {
    -            // Check the provided prev-tx
    -            if prev_tx.txid() != tx_input.previous_output.txid {
    -                return Err(SignerError::InvalidNonWitnessUtxo);
    +        // Always try first with the non-witness utxo
    +        let utxo = if let Some(prev_tx) = &psbt_input.non_witness_utxo {
    +            // Check the provided prev-tx
    +            if prev_tx.txid() != tx_input.previous_output.txid {
    +                return Err(SignerError::InvalidNonWitnessUtxo);
                 }
     
    -            // The output should be present, if it's missing the `non_witness_utxo` is invalid
    -            prev_tx
    -                .output
    -                .get(tx_input.previous_output.vout as usize)
    -                .ok_or(SignerError::InvalidNonWitnessUtxo)?
    -        } else if let Some(witness_utxo) = &psbt_input.witness_utxo {
    -            // Fallback to the witness_utxo. If we aren't allowed to use it, signing should fail
    -            // before we get to this point
    -            witness_utxo
    -        } else {
    -            // Nothing has been provided
    -            return Err(SignerError::MissingNonWitnessUtxo);
    +            // The output should be present, if it's missing the `non_witness_utxo` is invalid
    +            prev_tx
    +                .output
    +                .get(tx_input.previous_output.vout as usize)
    +                .ok_or(SignerError::InvalidNonWitnessUtxo)?
    +        } else if let Some(witness_utxo) = &psbt_input.witness_utxo {
    +            // Fallback to the witness_utxo. If we aren't allowed to use it, signing should fail
    +            // before we get to this point
    +            witness_utxo
    +        } else {
    +            // Nothing has been provided
    +            return Err(SignerError::MissingNonWitnessUtxo);
             };
    -        let value = utxo.value;
    -
    -        let script = match psbt_input.witness_script {
    -            Some(ref witness_script) => witness_script.clone(),
    -            None => {
    -                if utxo.script_pubkey.is_v0_p2wpkh() {
    -                    p2wpkh_script_code(&utxo.script_pubkey)
    -                } else if psbt_input
    -                    .redeem_script
    -                    .as_ref()
    -                    .map(Script::is_v0_p2wpkh)
    -                    .unwrap_or(false)
    +        let value = utxo.value;
    +
    +        let script = match psbt_input.witness_script {
    +            Some(ref witness_script) => witness_script.clone(),
    +            None => {
    +                if utxo.script_pubkey.is_v0_p2wpkh() {
    +                    p2wpkh_script_code(&utxo.script_pubkey)
    +                } else if psbt_input
    +                    .redeem_script
    +                    .as_ref()
    +                    .map(Script::is_v0_p2wpkh)
    +                    .unwrap_or(false)
                     {
    -                    p2wpkh_script_code(psbt_input.redeem_script.as_ref().unwrap())
    -                } else {
    -                    return Err(SignerError::MissingWitnessScript);
    +                    p2wpkh_script_code(psbt_input.redeem_script.as_ref().unwrap())
    +                } else {
    +                    return Err(SignerError::MissingWitnessScript);
                     }
                 }
             };
     
             Ok((
    -            sighash::SighashCache::new(&psbt.unsigned_tx).segwit_signature_hash(
    -                input_index,
    -                &script,
    -                value,
    -                sighash,
    +            sighash::SighashCache::new(&psbt.unsigned_tx).segwit_signature_hash(
    +                input_index,
    +                &script,
    +                value,
    +                sighash,
                 )?,
    -            sighash,
    +            sighash,
             ))
         }
     }
     
    -impl ComputeSighash for Tap {
    -    type Extra = Option<taproot::TapLeafHash>;
    -    type Sighash = taproot::TapSighashHash;
    -    type SighashType = SchnorrSighashType;
    -
    -    fn sighash(
    -        psbt: &psbt::PartiallySignedTransaction,
    -        input_index: usize,
    -        extra: Self::Extra,
    -    ) -> Result<(Self::Sighash, SchnorrSighashType), SignerError> {
    -        if input_index >= psbt.inputs.len() || input_index >= psbt.unsigned_tx.input.len() {
    -            return Err(SignerError::InputIndexOutOfRange);
    +impl ComputeSighash for Tap {
    +    type Extra = Option<taproot::TapLeafHash>;
    +    type Sighash = taproot::TapSighashHash;
    +    type SighashType = SchnorrSighashType;
    +
    +    fn sighash(
    +        psbt: &psbt::PartiallySignedTransaction,
    +        input_index: usize,
    +        extra: Self::Extra,
    +    ) -> Result<(Self::Sighash, SchnorrSighashType), SignerError> {
    +        if input_index >= psbt.inputs.len() || input_index >= psbt.unsigned_tx.input.len() {
    +            return Err(SignerError::InputIndexOutOfRange);
             }
     
    -        let psbt_input = &psbt.inputs[input_index];
    -
    -        let sighash_type = psbt_input
    -            .sighash_type
    -            .unwrap_or_else(|| SchnorrSighashType::Default.into())
    -            .schnorr_hash_ty()
    -            .map_err(|_| SignerError::InvalidSighash)?;
    -        let witness_utxos = (0..psbt.inputs.len())
    -            .map(|i| psbt.get_utxo_for(i))
    -            .collect::<Vec<_>>();
    -        let mut all_witness_utxos = vec![];
    -
    -        let mut cache = sighash::SighashCache::new(&psbt.unsigned_tx);
    -        let is_anyone_can_pay = psbt::PsbtSighashType::from(sighash_type).to_u32() & 0x80 != 0;
    -        let prevouts = if is_anyone_can_pay {
    -            sighash::Prevouts::One(
    -                input_index,
    -                witness_utxos[input_index]
    -                    .as_ref()
    -                    .ok_or(SignerError::MissingWitnessUtxo)?,
    +        let psbt_input = &psbt.inputs[input_index];
    +
    +        let sighash_type = psbt_input
    +            .sighash_type
    +            .unwrap_or_else(|| SchnorrSighashType::Default.into())
    +            .schnorr_hash_ty()
    +            .map_err(|_| SignerError::InvalidSighash)?;
    +        let witness_utxos = (0..psbt.inputs.len())
    +            .map(|i| psbt.get_utxo_for(i))
    +            .collect::<Vec<_>>();
    +        let mut all_witness_utxos = vec![];
    +
    +        let mut cache = sighash::SighashCache::new(&psbt.unsigned_tx);
    +        let is_anyone_can_pay = psbt::PsbtSighashType::from(sighash_type).to_u32() & 0x80 != 0;
    +        let prevouts = if is_anyone_can_pay {
    +            sighash::Prevouts::One(
    +                input_index,
    +                witness_utxos[input_index]
    +                    .as_ref()
    +                    .ok_or(SignerError::MissingWitnessUtxo)?,
                 )
    -        } else if witness_utxos.iter().all(Option::is_some) {
    -            all_witness_utxos.extend(witness_utxos.iter().filter_map(|x| x.as_ref()));
    -            sighash::Prevouts::All(&all_witness_utxos)
    -        } else {
    -            return Err(SignerError::MissingWitnessUtxo);
    +        } else if witness_utxos.iter().all(Option::is_some) {
    +            all_witness_utxos.extend(witness_utxos.iter().filter_map(|x| x.as_ref()));
    +            sighash::Prevouts::All(&all_witness_utxos)
    +        } else {
    +            return Err(SignerError::MissingWitnessUtxo);
             };
     
    -        // Assume no OP_CODESEPARATOR
    -        let extra = extra.map(|leaf_hash| (leaf_hash, 0xFFFFFFFF));
    +        // Assume no OP_CODESEPARATOR
    +        let extra = extra.map(|leaf_hash| (leaf_hash, 0xFFFFFFFF));
     
             Ok((
    -            cache.taproot_signature_hash(input_index, &prevouts, None, extra, sighash_type)?,
    -            sighash_type,
    +            cache.taproot_signature_hash(input_index, &prevouts, None, extra, sighash_type)?,
    +            sighash_type,
             ))
         }
     }
     
    -impl PartialOrd for SignersContainerKey {
    -    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
    -        Some(self.cmp(other))
    +impl PartialOrd for SignersContainerKey {
    +    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
    +        Some(self.cmp(other))
         }
     }
     
    -impl Ord for SignersContainerKey {
    -    fn cmp(&self, other: &Self) -> Ordering {
    -        self.ordering
    -            .cmp(&other.ordering)
    -            .then(self.id.cmp(&other.id))
    +impl Ord for SignersContainerKey {
    +    fn cmp(&self, other: &Self) -> Ordering {
    +        self.ordering
    +            .cmp(&other.ordering)
    +            .then(self.id.cmp(&other.id))
         }
     }
     
    -impl PartialEq for SignersContainerKey {
    -    fn eq(&self, other: &Self) -> bool {
    -        self.id == other.id && self.ordering == other.ordering
    +impl PartialEq for SignersContainerKey {
    +    fn eq(&self, other: &Self) -> bool {
    +        self.id == other.id && self.ordering == other.ordering
         }
     }
     
    -impl Eq for SignersContainerKey {}
    -
    -#[cfg(test)]
    -mod signers_container_tests {
    -    use super::*;
    -    use crate::descriptor;
    -    use crate::descriptor::IntoWalletDescriptor;
    -    use crate::keys::{DescriptorKey, IntoDescriptorKey};
    -    use bitcoin::secp256k1::{All, Secp256k1};
    -    use bitcoin::util::bip32;
    -    use bitcoin::Network;
    -    use miniscript::ScriptContext;
    -    use std::str::FromStr;
    -
    -    fn is_equal(this: &Arc<dyn TransactionSigner>, that: &Arc<DummySigner>) -> bool {
    -        let secp = Secp256k1::new();
    -        this.id(&secp) == that.id(&secp)
    +impl Eq for SignersContainerKey {}
    +
    +#[cfg(test)]
    +mod signers_container_tests {
    +    use super::*;
    +    use crate::descriptor;
    +    use crate::descriptor::IntoWalletDescriptor;
    +    use crate::keys::{DescriptorKey, IntoDescriptorKey};
    +    use bitcoin::secp256k1::{All, Secp256k1};
    +    use bitcoin::util::bip32;
    +    use bitcoin::Network;
    +    use miniscript::ScriptContext;
    +    use std::str::FromStr;
    +
    +    fn is_equal(this: &Arc<dyn TransactionSigner>, that: &Arc<DummySigner>) -> bool {
    +        let secp = Secp256k1::new();
    +        this.id(&secp) == that.id(&secp)
         }
     
    -    // Signers added with the same ordering (like `Ordering::default`) created from `KeyMap`
    -    // should be preserved and not overwritten.
    -    // This happens usually when a set of signers is created from a descriptor with private keys.
    -    #[test]
    -    fn signers_with_same_ordering() {
    -        let secp = Secp256k1::new();
    -
    -        let (prvkey1, _, _) = setup_keys(TPRV0_STR);
    -        let (prvkey2, _, _) = setup_keys(TPRV1_STR);
    -        let desc = descriptor!(sh(multi(2, prvkey1, prvkey2))).unwrap();
    -        let (wallet_desc, keymap) = desc
    -            .into_wallet_descriptor(&secp, Network::Testnet)
    -            .unwrap();
    -
    -        let signers = SignersContainer::build(keymap, &wallet_desc, &secp);
    -        assert_eq!(signers.ids().len(), 2);
    -
    -        let signers = signers.signers();
    -        assert_eq!(signers.len(), 2);
    +    // Signers added with the same ordering (like `Ordering::default`) created from `KeyMap`
    +    // should be preserved and not overwritten.
    +    // This happens usually when a set of signers is created from a descriptor with private keys.
    +    #[test]
    +    fn signers_with_same_ordering() {
    +        let secp = Secp256k1::new();
    +
    +        let (prvkey1, _, _) = setup_keys(TPRV0_STR);
    +        let (prvkey2, _, _) = setup_keys(TPRV1_STR);
    +        let desc = descriptor!(sh(multi(2, prvkey1, prvkey2))).unwrap();
    +        let (wallet_desc, keymap) = desc
    +            .into_wallet_descriptor(&secp, Network::Testnet)
    +            .unwrap();
    +
    +        let signers = SignersContainer::build(keymap, &wallet_desc, &secp);
    +        assert_eq!(signers.ids().len(), 2);
    +
    +        let signers = signers.signers();
    +        assert_eq!(signers.len(), 2);
         }
     
    -    #[test]
    -    fn signers_sorted_by_ordering() {
    -        let mut signers = SignersContainer::new();
    -        let signer1 = Arc::new(DummySigner { number: 1 });
    -        let signer2 = Arc::new(DummySigner { number: 2 });
    -        let signer3 = Arc::new(DummySigner { number: 3 });
    +    #[test]
    +    fn signers_sorted_by_ordering() {
    +        let mut signers = SignersContainer::new();
    +        let signer1 = Arc::new(DummySigner { number: 1 });
    +        let signer2 = Arc::new(DummySigner { number: 2 });
    +        let signer3 = Arc::new(DummySigner { number: 3 });
     
    -        // Mixed order insertions verifies we are not inserting at head or tail.
    -        signers.add_external(SignerId::Dummy(2), SignerOrdering(2), signer2.clone());
    -        signers.add_external(SignerId::Dummy(1), SignerOrdering(1), signer1.clone());
    -        signers.add_external(SignerId::Dummy(3), SignerOrdering(3), signer3.clone());
    +        // Mixed order insertions verifies we are not inserting at head or tail.
    +        signers.add_external(SignerId::Dummy(2), SignerOrdering(2), signer2.clone());
    +        signers.add_external(SignerId::Dummy(1), SignerOrdering(1), signer1.clone());
    +        signers.add_external(SignerId::Dummy(3), SignerOrdering(3), signer3.clone());
     
    -        // Check that signers are sorted from lowest to highest ordering
    -        let signers = signers.signers();
    +        // Check that signers are sorted from lowest to highest ordering
    +        let signers = signers.signers();
     
    -        assert!(is_equal(signers[0], &signer1));
    -        assert!(is_equal(signers[1], &signer2));
    -        assert!(is_equal(signers[2], &signer3));
    +        assert!(is_equal(signers[0], &signer1));
    +        assert!(is_equal(signers[1], &signer2));
    +        assert!(is_equal(signers[2], &signer3));
         }
     
    -    #[test]
    -    fn find_signer_by_id() {
    -        let mut signers = SignersContainer::new();
    -        let signer1 = Arc::new(DummySigner { number: 1 });
    -        let signer2 = Arc::new(DummySigner { number: 2 });
    -        let signer3 = Arc::new(DummySigner { number: 3 });
    -        let signer4 = Arc::new(DummySigner { number: 3 }); // Same ID as `signer3` but will use lower ordering.
    -
    -        let id1 = SignerId::Dummy(1);
    -        let id2 = SignerId::Dummy(2);
    -        let id3 = SignerId::Dummy(3);
    -        let id_nonexistent = SignerId::Dummy(999);
    -
    -        signers.add_external(id1.clone(), SignerOrdering(1), signer1.clone());
    -        signers.add_external(id2.clone(), SignerOrdering(2), signer2.clone());
    -        signers.add_external(id3.clone(), SignerOrdering(3), signer3.clone());
    -
    -        assert!(matches!(signers.find(id1), Some(signer) if is_equal(signer, &signer1)));
    -        assert!(matches!(signers.find(id2), Some(signer) if is_equal(signer, &signer2)));
    -        assert!(matches!(signers.find(id3.clone()), Some(signer) if is_equal(signer, &signer3)));
    -
    -        // The `signer4` has the same ID as `signer3` but lower ordering.
    -        // It should be found by `id3` instead of `signer3`.
    -        signers.add_external(id3.clone(), SignerOrdering(2), signer4.clone());
    -        assert!(matches!(signers.find(id3), Some(signer) if is_equal(signer, &signer4)));
    -
    -        // Can't find anything with ID that doesn't exist
    -        assert!(matches!(signers.find(id_nonexistent), None));
    +    #[test]
    +    fn find_signer_by_id() {
    +        let mut signers = SignersContainer::new();
    +        let signer1 = Arc::new(DummySigner { number: 1 });
    +        let signer2 = Arc::new(DummySigner { number: 2 });
    +        let signer3 = Arc::new(DummySigner { number: 3 });
    +        let signer4 = Arc::new(DummySigner { number: 3 }); // Same ID as `signer3` but will use lower ordering.
    +
    +        let id1 = SignerId::Dummy(1);
    +        let id2 = SignerId::Dummy(2);
    +        let id3 = SignerId::Dummy(3);
    +        let id_nonexistent = SignerId::Dummy(999);
    +
    +        signers.add_external(id1.clone(), SignerOrdering(1), signer1.clone());
    +        signers.add_external(id2.clone(), SignerOrdering(2), signer2.clone());
    +        signers.add_external(id3.clone(), SignerOrdering(3), signer3.clone());
    +
    +        assert!(matches!(signers.find(id1), Some(signer) if is_equal(signer, &signer1)));
    +        assert!(matches!(signers.find(id2), Some(signer) if is_equal(signer, &signer2)));
    +        assert!(matches!(signers.find(id3.clone()), Some(signer) if is_equal(signer, &signer3)));
    +
    +        // The `signer4` has the same ID as `signer3` but lower ordering.
    +        // It should be found by `id3` instead of `signer3`.
    +        signers.add_external(id3.clone(), SignerOrdering(2), signer4.clone());
    +        assert!(matches!(signers.find(id3), Some(signer) if is_equal(signer, &signer4)));
    +
    +        // Can't find anything with ID that doesn't exist
    +        assert!(matches!(signers.find(id_nonexistent), None));
         }
     
    -    #[derive(Debug, Clone, Copy)]
    -    struct DummySigner {
    -        number: u64,
    +    #[derive(Debug, Clone, Copy)]
    +    struct DummySigner {
    +        number: u64,
         }
     
    -    impl SignerCommon for DummySigner {
    -        fn id(&self, _secp: &SecpCtx) -> SignerId {
    -            SignerId::Dummy(self.number)
    +    impl SignerCommon for DummySigner {
    +        fn id(&self, _secp: &SecpCtx) -> SignerId {
    +            SignerId::Dummy(self.number)
             }
         }
     
    -    impl TransactionSigner for DummySigner {
    -        fn sign_transaction(
    +    impl TransactionSigner for DummySigner {
    +        fn sign_transaction(
                 &self,
    -            _psbt: &mut psbt::PartiallySignedTransaction,
    -            _sign_options: &SignOptions,
    -            _secp: &SecpCtx,
    -        ) -> Result<(), SignerError> {
    +            _psbt: &mut psbt::PartiallySignedTransaction,
    +            _sign_options: &SignOptions,
    +            _secp: &SecpCtx,
    +        ) -> Result<(), SignerError> {
                 Ok(())
             }
         }
     
    -    const TPRV0_STR:&str = "tprv8ZgxMBicQKsPdZXrcHNLf5JAJWFAoJ2TrstMRdSKtEggz6PddbuSkvHKM9oKJyFgZV1B7rw8oChspxyYbtmEXYyg1AjfWbL3ho3XHDpHRZf";
    -    const TPRV1_STR:&str = "tprv8ZgxMBicQKsPdpkqS7Eair4YxjcuuvDPNYmKX3sCniCf16tHEVrjjiSXEkFRnUH77yXc6ZcwHHcLNfjdi5qUvw3VDfgYiH5mNsj5izuiu2N";
    +    const TPRV0_STR:&str = "tprv8ZgxMBicQKsPdZXrcHNLf5JAJWFAoJ2TrstMRdSKtEggz6PddbuSkvHKM9oKJyFgZV1B7rw8oChspxyYbtmEXYyg1AjfWbL3ho3XHDpHRZf";
    +    const TPRV1_STR:&str = "tprv8ZgxMBicQKsPdpkqS7Eair4YxjcuuvDPNYmKX3sCniCf16tHEVrjjiSXEkFRnUH77yXc6ZcwHHcLNfjdi5qUvw3VDfgYiH5mNsj5izuiu2N";
     
    -    const PATH: &str = "m/44'/1'/0'/0";
    +    const PATH: &str = "m/44'/1'/0'/0";
     
    -    fn setup_keys<Ctx: ScriptContext>(
    -        tprv: &str,
    -    ) -> (DescriptorKey<Ctx>, DescriptorKey<Ctx>, Fingerprint) {
    -        let secp: Secp256k1<All> = Secp256k1::new();
    -        let path = bip32::DerivationPath::from_str(PATH).unwrap();
    -        let tprv = bip32::ExtendedPrivKey::from_str(tprv).unwrap();
    -        let tpub = bip32::ExtendedPubKey::from_priv(&secp, &tprv);
    -        let fingerprint = tprv.fingerprint(&secp);
    -        let prvkey = (tprv, path.clone()).into_descriptor_key().unwrap();
    -        let pubkey = (tpub, path).into_descriptor_key().unwrap();
    +    fn setup_keys<Ctx: ScriptContext>(
    +        tprv: &str,
    +    ) -> (DescriptorKey<Ctx>, DescriptorKey<Ctx>, Fingerprint) {
    +        let secp: Secp256k1<All> = Secp256k1::new();
    +        let path = bip32::DerivationPath::from_str(PATH).unwrap();
    +        let tprv = bip32::ExtendedPrivKey::from_str(tprv).unwrap();
    +        let tpub = bip32::ExtendedPubKey::from_priv(&secp, &tprv);
    +        let fingerprint = tprv.fingerprint(&secp);
    +        let prvkey = (tprv, path.clone()).into_descriptor_key().unwrap();
    +        let pubkey = (tpub, path).into_descriptor_key().unwrap();
     
    -        (prvkey, pubkey, fingerprint)
    +        (prvkey, pubkey, fingerprint)
         }
     }
     
    -
    - \ No newline at end of file +
    \ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/src/bdk/wallet/time.rs.html b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/src/bdk/wallet/time.rs.html index 0434dff210..febcebe3cd 100644 --- a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/src/bdk/wallet/time.rs.html +++ b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/src/bdk/wallet/time.rs.html @@ -1,156 +1,149 @@ -time.rs - source - -
     1
    - 2
    - 3
    - 4
    - 5
    - 6
    - 7
    - 8
    - 9
    -10
    -11
    -12
    -13
    -14
    -15
    -16
    -17
    -18
    -19
    -20
    -21
    -22
    -23
    -24
    -25
    -26
    -27
    -28
    -29
    -30
    -31
    -32
    -33
    -34
    -35
    -36
    -37
    -38
    -39
    -40
    -41
    -42
    -43
    -44
    -45
    -46
    -47
    -48
    -49
    -50
    -51
    -52
    -53
    -54
    -55
    -56
    -57
    -58
    -59
    -60
    -61
    -62
    -63
    -64
    -65
    -66
    -67
    -68
    -69
    -70
    -71
    -72
    -73
    -
    // Bitcoin Dev Kit
    -// Written in 2020 by Alekos Filini <alekos.filini@gmail.com>
    -//
    -// Copyright (c) 2020-2021 Bitcoin Dev Kit Developers
    -//
    -// This file is licensed under the Apache License, Version 2.0 <LICENSE-APACHE
    -// or http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
    -// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your option.
    -// You may not use this file except in accordance with one or both of these
    -// licenses.
    +time.rs - source
    1
    +2
    +3
    +4
    +5
    +6
    +7
    +8
    +9
    +10
    +11
    +12
    +13
    +14
    +15
    +16
    +17
    +18
    +19
    +20
    +21
    +22
    +23
    +24
    +25
    +26
    +27
    +28
    +29
    +30
    +31
    +32
    +33
    +34
    +35
    +36
    +37
    +38
    +39
    +40
    +41
    +42
    +43
    +44
    +45
    +46
    +47
    +48
    +49
    +50
    +51
    +52
    +53
    +54
    +55
    +56
    +57
    +58
    +59
    +60
    +61
    +62
    +63
    +64
    +65
    +66
    +67
    +68
    +69
    +70
    +71
    +72
    +73
    +
    // Bitcoin Dev Kit
    +// Written in 2020 by Alekos Filini <alekos.filini@gmail.com>
    +//
    +// Copyright (c) 2020-2021 Bitcoin Dev Kit Developers
    +//
    +// This file is licensed under the Apache License, Version 2.0 <LICENSE-APACHE
    +// or http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
    +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your option.
    +// You may not use this file except in accordance with one or both of these
    +// licenses.
     
    -//! Cross-platform time
    -//!
    -//! This module provides a function to get the current timestamp that works on all the platforms
    -//! supported by the library.
    -//!
    -//! It can be useful to compare it with the timestamps found in
    -//! [`TransactionDetails`](crate::types::TransactionDetails).
    +//! Cross-platform time
    +//!
    +//! This module provides a function to get the current timestamp that works on all the platforms
    +//! supported by the library.
    +//!
    +//! It can be useful to compare it with the timestamps found in
    +//! [`TransactionDetails`](crate::types::TransactionDetails).
     
    -use std::time::Duration;
    +use std::time::Duration;
     
    -#[cfg(target_arch = "wasm32")]
    -use js_sys::Date;
    -#[cfg(not(target_arch = "wasm32"))]
    -use std::time::{Instant as SystemInstant, SystemTime, UNIX_EPOCH};
    +#[cfg(target_arch = "wasm32")]
    +use js_sys::Date;
    +#[cfg(not(target_arch = "wasm32"))]
    +use std::time::{Instant as SystemInstant, SystemTime, UNIX_EPOCH};
     
    -/// Return the current timestamp in seconds
    -#[cfg(not(target_arch = "wasm32"))]
    -pub fn get_timestamp() -> u64 {
    -    SystemTime::now()
    -        .duration_since(UNIX_EPOCH)
    -        .unwrap()
    -        .as_secs()
    +/// Return the current timestamp in seconds
    +#[cfg(not(target_arch = "wasm32"))]
    +pub fn get_timestamp() -> u64 {
    +    SystemTime::now()
    +        .duration_since(UNIX_EPOCH)
    +        .unwrap()
    +        .as_secs()
     }
    -/// Return the current timestamp in seconds
    -#[cfg(target_arch = "wasm32")]
    -pub fn get_timestamp() -> u64 {
    -    let millis = Date::now();
    +/// Return the current timestamp in seconds
    +#[cfg(target_arch = "wasm32")]
    +pub fn get_timestamp() -> u64 {
    +    let millis = Date::now();
     
    -    (millis / 1000.0) as u64
    +    (millis / 1000.0) as u64
     }
     
    -#[cfg(not(target_arch = "wasm32"))]
    -pub(crate) struct Instant(SystemInstant);
    -#[cfg(target_arch = "wasm32")]
    -pub(crate) struct Instant(Duration);
    +#[cfg(not(target_arch = "wasm32"))]
    +pub(crate) struct Instant(SystemInstant);
    +#[cfg(target_arch = "wasm32")]
    +pub(crate) struct Instant(Duration);
     
    -impl Instant {
    -    #[cfg(not(target_arch = "wasm32"))]
    -    pub fn new() -> Self {
    -        Instant(SystemInstant::now())
    +impl Instant {
    +    #[cfg(not(target_arch = "wasm32"))]
    +    pub fn new() -> Self {
    +        Instant(SystemInstant::now())
         }
    -    #[cfg(target_arch = "wasm32")]
    -    pub fn new() -> Self {
    -        let millis = Date::now();
    +    #[cfg(target_arch = "wasm32")]
    +    pub fn new() -> Self {
    +        let millis = Date::now();
     
    -        let secs = millis / 1000.0;
    -        let nanos = (millis % 1000.0) * 1e6;
    +        let secs = millis / 1000.0;
    +        let nanos = (millis % 1000.0) * 1e6;
     
    -        Instant(Duration::new(secs as u64, nanos as u32))
    +        Instant(Duration::new(secs as u64, nanos as u32))
         }
     
    -    #[cfg(not(target_arch = "wasm32"))]
    -    pub fn elapsed(&self) -> Duration {
    -        self.0.elapsed()
    +    #[cfg(not(target_arch = "wasm32"))]
    +    pub fn elapsed(&self) -> Duration {
    +        self.0.elapsed()
         }
    -    #[cfg(target_arch = "wasm32")]
    -    pub fn elapsed(&self) -> Duration {
    -        let now = Instant::new();
    +    #[cfg(target_arch = "wasm32")]
    +    pub fn elapsed(&self) -> Duration {
    +        let now = Instant::new();
     
    -        now.0.checked_sub(self.0).unwrap_or(Duration::new(0, 0))
    +        now.0.checked_sub(self.0).unwrap_or(Duration::new(0, 0))
         }
     }
     
    -
    - \ No newline at end of file +
    \ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/src/bdk/wallet/tx_builder.rs.html b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/src/bdk/wallet/tx_builder.rs.html index 7c4cd6dfb3..6287c0ea19 100644 --- a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/src/bdk/wallet/tx_builder.rs.html +++ b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/src/bdk/wallet/tx_builder.rs.html @@ -1,1856 +1,1849 @@ -tx_builder.rs - source - -
      1
    -  2
    -  3
    -  4
    -  5
    -  6
    -  7
    -  8
    -  9
    - 10
    - 11
    - 12
    - 13
    - 14
    - 15
    - 16
    - 17
    - 18
    - 19
    - 20
    - 21
    - 22
    - 23
    - 24
    - 25
    - 26
    - 27
    - 28
    - 29
    - 30
    - 31
    - 32
    - 33
    - 34
    - 35
    - 36
    - 37
    - 38
    - 39
    - 40
    - 41
    - 42
    - 43
    - 44
    - 45
    - 46
    - 47
    - 48
    - 49
    - 50
    - 51
    - 52
    - 53
    - 54
    - 55
    - 56
    - 57
    - 58
    - 59
    - 60
    - 61
    - 62
    - 63
    - 64
    - 65
    - 66
    - 67
    - 68
    - 69
    - 70
    - 71
    - 72
    - 73
    - 74
    - 75
    - 76
    - 77
    - 78
    - 79
    - 80
    - 81
    - 82
    - 83
    - 84
    - 85
    - 86
    - 87
    - 88
    - 89
    - 90
    - 91
    - 92
    - 93
    - 94
    - 95
    - 96
    - 97
    - 98
    - 99
    -100
    -101
    -102
    -103
    -104
    -105
    -106
    -107
    -108
    -109
    -110
    -111
    -112
    -113
    -114
    -115
    -116
    -117
    -118
    -119
    -120
    -121
    -122
    -123
    -124
    -125
    -126
    -127
    -128
    -129
    -130
    -131
    -132
    -133
    -134
    -135
    -136
    -137
    -138
    -139
    -140
    -141
    -142
    -143
    -144
    -145
    -146
    -147
    -148
    -149
    -150
    -151
    -152
    -153
    -154
    -155
    -156
    -157
    -158
    -159
    -160
    -161
    -162
    -163
    -164
    -165
    -166
    -167
    -168
    -169
    -170
    -171
    -172
    -173
    -174
    -175
    -176
    -177
    -178
    -179
    -180
    -181
    -182
    -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
    -245
    -246
    -247
    -248
    -249
    -250
    -251
    -252
    -253
    -254
    -255
    -256
    -257
    -258
    -259
    -260
    -261
    -262
    -263
    -264
    -265
    -266
    -267
    -268
    -269
    -270
    -271
    -272
    -273
    -274
    -275
    -276
    -277
    -278
    -279
    -280
    -281
    -282
    -283
    -284
    -285
    -286
    -287
    -288
    -289
    -290
    -291
    -292
    -293
    -294
    -295
    -296
    -297
    -298
    -299
    -300
    -301
    -302
    -303
    -304
    -305
    -306
    -307
    -308
    -309
    -310
    -311
    -312
    -313
    -314
    -315
    -316
    -317
    -318
    -319
    -320
    -321
    -322
    -323
    -324
    -325
    -326
    -327
    -328
    -329
    -330
    -331
    -332
    -333
    -334
    -335
    -336
    -337
    -338
    -339
    -340
    -341
    -342
    -343
    -344
    -345
    -346
    -347
    -348
    -349
    -350
    -351
    -352
    -353
    -354
    -355
    -356
    -357
    -358
    -359
    -360
    -361
    -362
    -363
    -364
    -365
    -366
    -367
    -368
    -369
    -370
    -371
    -372
    -373
    -374
    -375
    -376
    -377
    -378
    -379
    -380
    -381
    -382
    -383
    -384
    -385
    -386
    -387
    -388
    -389
    -390
    -391
    -392
    -393
    -394
    -395
    -396
    -397
    -398
    -399
    -400
    -401
    -402
    -403
    -404
    -405
    -406
    -407
    -408
    -409
    -410
    -411
    -412
    -413
    -414
    -415
    -416
    -417
    -418
    -419
    -420
    -421
    -422
    -423
    -424
    -425
    -426
    -427
    -428
    -429
    -430
    -431
    -432
    -433
    -434
    -435
    -436
    -437
    -438
    -439
    -440
    -441
    -442
    -443
    -444
    -445
    -446
    -447
    -448
    -449
    -450
    -451
    -452
    -453
    -454
    -455
    -456
    -457
    -458
    -459
    -460
    -461
    -462
    -463
    -464
    -465
    -466
    -467
    -468
    -469
    -470
    -471
    -472
    -473
    -474
    -475
    -476
    -477
    -478
    -479
    -480
    -481
    -482
    -483
    -484
    -485
    -486
    -487
    -488
    -489
    -490
    -491
    -492
    -493
    -494
    -495
    -496
    -497
    -498
    -499
    -500
    -501
    -502
    -503
    -504
    -505
    -506
    -507
    -508
    -509
    -510
    -511
    -512
    -513
    -514
    -515
    -516
    -517
    -518
    -519
    -520
    -521
    -522
    -523
    -524
    -525
    -526
    -527
    -528
    -529
    -530
    -531
    -532
    -533
    -534
    -535
    -536
    -537
    -538
    -539
    -540
    -541
    -542
    -543
    -544
    -545
    -546
    -547
    -548
    -549
    -550
    -551
    -552
    -553
    -554
    -555
    -556
    -557
    -558
    -559
    -560
    -561
    -562
    -563
    -564
    -565
    -566
    -567
    -568
    -569
    -570
    -571
    -572
    -573
    -574
    -575
    -576
    -577
    -578
    -579
    -580
    -581
    -582
    -583
    -584
    -585
    -586
    -587
    -588
    -589
    -590
    -591
    -592
    -593
    -594
    -595
    -596
    -597
    -598
    -599
    -600
    -601
    -602
    -603
    -604
    -605
    -606
    -607
    -608
    -609
    -610
    -611
    -612
    -613
    -614
    -615
    -616
    -617
    -618
    -619
    -620
    -621
    -622
    -623
    -624
    -625
    -626
    -627
    -628
    -629
    -630
    -631
    -632
    -633
    -634
    -635
    -636
    -637
    -638
    -639
    -640
    -641
    -642
    -643
    -644
    -645
    -646
    -647
    -648
    -649
    -650
    -651
    -652
    -653
    -654
    -655
    -656
    -657
    -658
    -659
    -660
    -661
    -662
    -663
    -664
    -665
    -666
    -667
    -668
    -669
    -670
    -671
    -672
    -673
    -674
    -675
    -676
    -677
    -678
    -679
    -680
    -681
    -682
    -683
    -684
    -685
    -686
    -687
    -688
    -689
    -690
    -691
    -692
    -693
    -694
    -695
    -696
    -697
    -698
    -699
    -700
    -701
    -702
    -703
    -704
    -705
    -706
    -707
    -708
    -709
    -710
    -711
    -712
    -713
    -714
    -715
    -716
    -717
    -718
    -719
    -720
    -721
    -722
    -723
    -724
    -725
    -726
    -727
    -728
    -729
    -730
    -731
    -732
    -733
    -734
    -735
    -736
    -737
    -738
    -739
    -740
    -741
    -742
    -743
    -744
    -745
    -746
    -747
    -748
    -749
    -750
    -751
    -752
    -753
    -754
    -755
    -756
    -757
    -758
    -759
    -760
    -761
    -762
    -763
    -764
    -765
    -766
    -767
    -768
    -769
    -770
    -771
    -772
    -773
    -774
    -775
    -776
    -777
    -778
    -779
    -780
    -781
    -782
    -783
    -784
    -785
    -786
    -787
    -788
    -789
    -790
    -791
    -792
    -793
    -794
    -795
    -796
    -797
    -798
    -799
    -800
    -801
    -802
    -803
    -804
    -805
    -806
    -807
    -808
    -809
    -810
    -811
    -812
    -813
    -814
    -815
    -816
    -817
    -818
    -819
    -820
    -821
    -822
    -823
    -824
    -825
    -826
    -827
    -828
    -829
    -830
    -831
    -832
    -833
    -834
    -835
    -836
    -837
    -838
    -839
    -840
    -841
    -842
    -843
    -844
    -845
    -846
    -847
    -848
    -849
    -850
    -851
    -852
    -853
    -854
    -855
    -856
    -857
    -858
    -859
    -860
    -861
    -862
    -863
    -864
    -865
    -866
    -867
    -868
    -869
    -870
    -871
    -872
    -873
    -874
    -875
    -876
    -877
    -878
    -879
    -880
    -881
    -882
    -883
    -884
    -885
    -886
    -887
    -888
    -889
    -890
    -891
    -892
    -893
    -894
    -895
    -896
    -897
    -898
    -899
    -900
    -901
    -902
    -903
    -904
    -905
    -906
    -907
    -908
    -909
    -910
    -911
    -912
    -913
    -914
    -915
    -916
    -917
    -918
    -919
    -920
    -921
    -922
    -923
    -
    // Bitcoin Dev Kit
    -// Written in 2020 by Alekos Filini <alekos.filini@gmail.com>
    -//
    -// Copyright (c) 2020-2021 Bitcoin Dev Kit Developers
    -//
    -// This file is licensed under the Apache License, Version 2.0 <LICENSE-APACHE
    -// or http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
    -// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your option.
    -// You may not use this file except in accordance with one or both of these
    -// licenses.
    -
    -//! Transaction builder
    -//!
    -//! ## Example
    -//!
    -//! ```
    -//! # use std::str::FromStr;
    -//! # use bitcoin::*;
    -//! # use bdk::*;
    -//! # use bdk::wallet::tx_builder::CreateTx;
    -//! # let to_address = Address::from_str("2N4eQYCbKUHCCTUjBJeHcJp9ok6J2GZsTDt").unwrap();
    -//! # let wallet = doctest_wallet!();
    -//! // create a TxBuilder from a wallet
    -//! let mut tx_builder = wallet.build_tx();
    -//!
    -//! tx_builder
    -//!     // Create a transaction with one output to `to_address` of 50_000 satoshi
    -//!     .add_recipient(to_address.script_pubkey(), 50_000)
    -//!     // With a custom fee rate of 5.0 satoshi/vbyte
    -//!     .fee_rate(FeeRate::from_sat_per_vb(5.0))
    -//!     // Only spend non-change outputs
    -//!     .do_not_spend_change()
    -//!     // Turn on RBF signaling
    -//!     .enable_rbf();
    -//! let (psbt, tx_details) = tx_builder.finish()?;
    -//! # Ok::<(), bdk::Error>(())
    -//! ```
    -
    -use std::collections::BTreeMap;
    -use std::collections::HashSet;
    -use std::default::Default;
    -use std::marker::PhantomData;
    -
    -use bitcoin::util::psbt::{self, PartiallySignedTransaction as Psbt};
    -use bitcoin::{LockTime, OutPoint, Script, Sequence, Transaction};
    -
    -use super::coin_selection::{CoinSelectionAlgorithm, DefaultCoinSelectionAlgorithm};
    -use crate::{database::BatchDatabase, Error, Utxo, Wallet};
    -use crate::{
    -    types::{FeeRate, KeychainKind, LocalUtxo, WeightedUtxo},
    -    TransactionDetails,
    +tx_builder.rs - source
    1
    +2
    +3
    +4
    +5
    +6
    +7
    +8
    +9
    +10
    +11
    +12
    +13
    +14
    +15
    +16
    +17
    +18
    +19
    +20
    +21
    +22
    +23
    +24
    +25
    +26
    +27
    +28
    +29
    +30
    +31
    +32
    +33
    +34
    +35
    +36
    +37
    +38
    +39
    +40
    +41
    +42
    +43
    +44
    +45
    +46
    +47
    +48
    +49
    +50
    +51
    +52
    +53
    +54
    +55
    +56
    +57
    +58
    +59
    +60
    +61
    +62
    +63
    +64
    +65
    +66
    +67
    +68
    +69
    +70
    +71
    +72
    +73
    +74
    +75
    +76
    +77
    +78
    +79
    +80
    +81
    +82
    +83
    +84
    +85
    +86
    +87
    +88
    +89
    +90
    +91
    +92
    +93
    +94
    +95
    +96
    +97
    +98
    +99
    +100
    +101
    +102
    +103
    +104
    +105
    +106
    +107
    +108
    +109
    +110
    +111
    +112
    +113
    +114
    +115
    +116
    +117
    +118
    +119
    +120
    +121
    +122
    +123
    +124
    +125
    +126
    +127
    +128
    +129
    +130
    +131
    +132
    +133
    +134
    +135
    +136
    +137
    +138
    +139
    +140
    +141
    +142
    +143
    +144
    +145
    +146
    +147
    +148
    +149
    +150
    +151
    +152
    +153
    +154
    +155
    +156
    +157
    +158
    +159
    +160
    +161
    +162
    +163
    +164
    +165
    +166
    +167
    +168
    +169
    +170
    +171
    +172
    +173
    +174
    +175
    +176
    +177
    +178
    +179
    +180
    +181
    +182
    +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
    +245
    +246
    +247
    +248
    +249
    +250
    +251
    +252
    +253
    +254
    +255
    +256
    +257
    +258
    +259
    +260
    +261
    +262
    +263
    +264
    +265
    +266
    +267
    +268
    +269
    +270
    +271
    +272
    +273
    +274
    +275
    +276
    +277
    +278
    +279
    +280
    +281
    +282
    +283
    +284
    +285
    +286
    +287
    +288
    +289
    +290
    +291
    +292
    +293
    +294
    +295
    +296
    +297
    +298
    +299
    +300
    +301
    +302
    +303
    +304
    +305
    +306
    +307
    +308
    +309
    +310
    +311
    +312
    +313
    +314
    +315
    +316
    +317
    +318
    +319
    +320
    +321
    +322
    +323
    +324
    +325
    +326
    +327
    +328
    +329
    +330
    +331
    +332
    +333
    +334
    +335
    +336
    +337
    +338
    +339
    +340
    +341
    +342
    +343
    +344
    +345
    +346
    +347
    +348
    +349
    +350
    +351
    +352
    +353
    +354
    +355
    +356
    +357
    +358
    +359
    +360
    +361
    +362
    +363
    +364
    +365
    +366
    +367
    +368
    +369
    +370
    +371
    +372
    +373
    +374
    +375
    +376
    +377
    +378
    +379
    +380
    +381
    +382
    +383
    +384
    +385
    +386
    +387
    +388
    +389
    +390
    +391
    +392
    +393
    +394
    +395
    +396
    +397
    +398
    +399
    +400
    +401
    +402
    +403
    +404
    +405
    +406
    +407
    +408
    +409
    +410
    +411
    +412
    +413
    +414
    +415
    +416
    +417
    +418
    +419
    +420
    +421
    +422
    +423
    +424
    +425
    +426
    +427
    +428
    +429
    +430
    +431
    +432
    +433
    +434
    +435
    +436
    +437
    +438
    +439
    +440
    +441
    +442
    +443
    +444
    +445
    +446
    +447
    +448
    +449
    +450
    +451
    +452
    +453
    +454
    +455
    +456
    +457
    +458
    +459
    +460
    +461
    +462
    +463
    +464
    +465
    +466
    +467
    +468
    +469
    +470
    +471
    +472
    +473
    +474
    +475
    +476
    +477
    +478
    +479
    +480
    +481
    +482
    +483
    +484
    +485
    +486
    +487
    +488
    +489
    +490
    +491
    +492
    +493
    +494
    +495
    +496
    +497
    +498
    +499
    +500
    +501
    +502
    +503
    +504
    +505
    +506
    +507
    +508
    +509
    +510
    +511
    +512
    +513
    +514
    +515
    +516
    +517
    +518
    +519
    +520
    +521
    +522
    +523
    +524
    +525
    +526
    +527
    +528
    +529
    +530
    +531
    +532
    +533
    +534
    +535
    +536
    +537
    +538
    +539
    +540
    +541
    +542
    +543
    +544
    +545
    +546
    +547
    +548
    +549
    +550
    +551
    +552
    +553
    +554
    +555
    +556
    +557
    +558
    +559
    +560
    +561
    +562
    +563
    +564
    +565
    +566
    +567
    +568
    +569
    +570
    +571
    +572
    +573
    +574
    +575
    +576
    +577
    +578
    +579
    +580
    +581
    +582
    +583
    +584
    +585
    +586
    +587
    +588
    +589
    +590
    +591
    +592
    +593
    +594
    +595
    +596
    +597
    +598
    +599
    +600
    +601
    +602
    +603
    +604
    +605
    +606
    +607
    +608
    +609
    +610
    +611
    +612
    +613
    +614
    +615
    +616
    +617
    +618
    +619
    +620
    +621
    +622
    +623
    +624
    +625
    +626
    +627
    +628
    +629
    +630
    +631
    +632
    +633
    +634
    +635
    +636
    +637
    +638
    +639
    +640
    +641
    +642
    +643
    +644
    +645
    +646
    +647
    +648
    +649
    +650
    +651
    +652
    +653
    +654
    +655
    +656
    +657
    +658
    +659
    +660
    +661
    +662
    +663
    +664
    +665
    +666
    +667
    +668
    +669
    +670
    +671
    +672
    +673
    +674
    +675
    +676
    +677
    +678
    +679
    +680
    +681
    +682
    +683
    +684
    +685
    +686
    +687
    +688
    +689
    +690
    +691
    +692
    +693
    +694
    +695
    +696
    +697
    +698
    +699
    +700
    +701
    +702
    +703
    +704
    +705
    +706
    +707
    +708
    +709
    +710
    +711
    +712
    +713
    +714
    +715
    +716
    +717
    +718
    +719
    +720
    +721
    +722
    +723
    +724
    +725
    +726
    +727
    +728
    +729
    +730
    +731
    +732
    +733
    +734
    +735
    +736
    +737
    +738
    +739
    +740
    +741
    +742
    +743
    +744
    +745
    +746
    +747
    +748
    +749
    +750
    +751
    +752
    +753
    +754
    +755
    +756
    +757
    +758
    +759
    +760
    +761
    +762
    +763
    +764
    +765
    +766
    +767
    +768
    +769
    +770
    +771
    +772
    +773
    +774
    +775
    +776
    +777
    +778
    +779
    +780
    +781
    +782
    +783
    +784
    +785
    +786
    +787
    +788
    +789
    +790
    +791
    +792
    +793
    +794
    +795
    +796
    +797
    +798
    +799
    +800
    +801
    +802
    +803
    +804
    +805
    +806
    +807
    +808
    +809
    +810
    +811
    +812
    +813
    +814
    +815
    +816
    +817
    +818
    +819
    +820
    +821
    +822
    +823
    +824
    +825
    +826
    +827
    +828
    +829
    +830
    +831
    +832
    +833
    +834
    +835
    +836
    +837
    +838
    +839
    +840
    +841
    +842
    +843
    +844
    +845
    +846
    +847
    +848
    +849
    +850
    +851
    +852
    +853
    +854
    +855
    +856
    +857
    +858
    +859
    +860
    +861
    +862
    +863
    +864
    +865
    +866
    +867
    +868
    +869
    +870
    +871
    +872
    +873
    +874
    +875
    +876
    +877
    +878
    +879
    +880
    +881
    +882
    +883
    +884
    +885
    +886
    +887
    +888
    +889
    +890
    +891
    +892
    +893
    +894
    +895
    +896
    +897
    +898
    +899
    +900
    +901
    +902
    +903
    +904
    +905
    +906
    +907
    +908
    +909
    +910
    +911
    +912
    +913
    +914
    +915
    +916
    +917
    +918
    +919
    +920
    +921
    +922
    +923
    +
    // Bitcoin Dev Kit
    +// Written in 2020 by Alekos Filini <alekos.filini@gmail.com>
    +//
    +// Copyright (c) 2020-2021 Bitcoin Dev Kit Developers
    +//
    +// This file is licensed under the Apache License, Version 2.0 <LICENSE-APACHE
    +// or http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
    +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your option.
    +// You may not use this file except in accordance with one or both of these
    +// licenses.
    +
    +//! Transaction builder
    +//!
    +//! ## Example
    +//!
    +//! ```
    +//! # use std::str::FromStr;
    +//! # use bitcoin::*;
    +//! # use bdk::*;
    +//! # use bdk::wallet::tx_builder::CreateTx;
    +//! # let to_address = Address::from_str("2N4eQYCbKUHCCTUjBJeHcJp9ok6J2GZsTDt").unwrap();
    +//! # let wallet = doctest_wallet!();
    +//! // create a TxBuilder from a wallet
    +//! let mut tx_builder = wallet.build_tx();
    +//!
    +//! tx_builder
    +//!     // Create a transaction with one output to `to_address` of 50_000 satoshi
    +//!     .add_recipient(to_address.script_pubkey(), 50_000)
    +//!     // With a custom fee rate of 5.0 satoshi/vbyte
    +//!     .fee_rate(FeeRate::from_sat_per_vb(5.0))
    +//!     // Only spend non-change outputs
    +//!     .do_not_spend_change()
    +//!     // Turn on RBF signaling
    +//!     .enable_rbf();
    +//! let (psbt, tx_details) = tx_builder.finish()?;
    +//! # Ok::<(), bdk::Error>(())
    +//! ```
    +
    +use std::collections::BTreeMap;
    +use std::collections::HashSet;
    +use std::default::Default;
    +use std::marker::PhantomData;
    +
    +use bitcoin::util::psbt::{self, PartiallySignedTransaction as Psbt};
    +use bitcoin::{LockTime, OutPoint, Script, Sequence, Transaction};
    +
    +use super::coin_selection::{CoinSelectionAlgorithm, DefaultCoinSelectionAlgorithm};
    +use crate::{database::BatchDatabase, Error, Utxo, Wallet};
    +use crate::{
    +    types::{FeeRate, KeychainKind, LocalUtxo, WeightedUtxo},
    +    TransactionDetails,
     };
    -/// Context in which the [`TxBuilder`] is valid
    -pub trait TxBuilderContext: std::fmt::Debug + Default + Clone {}
    -
    -/// Marker type to indicate the [`TxBuilder`] is being used to create a new transaction (as opposed
    -/// to bumping the fee of an existing one).
    -#[derive(Debug, Default, Clone)]
    -pub struct CreateTx;
    -impl TxBuilderContext for CreateTx {}
    -
    -/// Marker type to indicate the [`TxBuilder`] is being used to bump the fee of an existing transaction.
    -#[derive(Debug, Default, Clone)]
    -pub struct BumpFee;
    -impl TxBuilderContext for BumpFee {}
    -
    -/// 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.
    -///
    -/// Each option setting method on `TxBuilder` takes and returns `&mut self` so you can chain calls
    -/// as in the following example:
    -///
    -/// ```
    -/// # use bdk::*;
    -/// # use bdk::wallet::tx_builder::*;
    -/// # use bitcoin::*;
    -/// # use core::str::FromStr;
    -/// # let wallet = doctest_wallet!();
    -/// # let addr1 = Address::from_str("2N4eQYCbKUHCCTUjBJeHcJp9ok6J2GZsTDt").unwrap();
    -/// # let addr2 = addr1.clone();
    -/// // chaining
    -/// let (psbt1, details) = {
    -///     let mut builder = wallet.build_tx();
    -///     builder
    -///         .ordering(TxOrdering::Untouched)
    -///         .add_recipient(addr1.script_pubkey(), 50_000)
    -///         .add_recipient(addr2.script_pubkey(), 50_000);
    -///     builder.finish()?
    -/// };
    -///
    -/// // non-chaining
    -/// let (psbt2, details) = {
    -///     let mut builder = wallet.build_tx();
    -///     builder.ordering(TxOrdering::Untouched);
    -///     for addr in &[addr1, addr2] {
    -///         builder.add_recipient(addr.script_pubkey(), 50_000);
    -///     }
    -///     builder.finish()?
    -/// };
    -///
    -/// assert_eq!(psbt1.unsigned_tx.output[..2], psbt2.unsigned_tx.output[..2]);
    -/// # Ok::<(), bdk::Error>(())
    -/// ```
    -///
    -/// 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](super::tx_builder)'s documentation;
    -///
    -/// [`build_tx`]: Wallet::build_tx
    -/// [`build_fee_bump`]: Wallet::build_fee_bump
    -/// [`finish`]: Self::finish
    -/// [`coin_selection`]: Self::coin_selection
    -#[derive(Debug)]
    -pub struct TxBuilder<'a, D, Cs, Ctx> {
    -    pub(crate) wallet: &'a Wallet<D>,
    -    pub(crate) params: TxParams,
    -    pub(crate) coin_selection: Cs,
    -    pub(crate) phantom: PhantomData<Ctx>,
    +/// Context in which the [`TxBuilder`] is valid
    +pub trait TxBuilderContext: std::fmt::Debug + Default + Clone {}
    +
    +/// Marker type to indicate the [`TxBuilder`] is being used to create a new transaction (as opposed
    +/// to bumping the fee of an existing one).
    +#[derive(Debug, Default, Clone)]
    +pub struct CreateTx;
    +impl TxBuilderContext for CreateTx {}
    +
    +/// Marker type to indicate the [`TxBuilder`] is being used to bump the fee of an existing transaction.
    +#[derive(Debug, Default, Clone)]
    +pub struct BumpFee;
    +impl TxBuilderContext for BumpFee {}
    +
    +/// 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.
    +///
    +/// Each option setting method on `TxBuilder` takes and returns `&mut self` so you can chain calls
    +/// as in the following example:
    +///
    +/// ```
    +/// # use bdk::*;
    +/// # use bdk::wallet::tx_builder::*;
    +/// # use bitcoin::*;
    +/// # use core::str::FromStr;
    +/// # let wallet = doctest_wallet!();
    +/// # let addr1 = Address::from_str("2N4eQYCbKUHCCTUjBJeHcJp9ok6J2GZsTDt").unwrap();
    +/// # let addr2 = addr1.clone();
    +/// // chaining
    +/// let (psbt1, details) = {
    +///     let mut builder = wallet.build_tx();
    +///     builder
    +///         .ordering(TxOrdering::Untouched)
    +///         .add_recipient(addr1.script_pubkey(), 50_000)
    +///         .add_recipient(addr2.script_pubkey(), 50_000);
    +///     builder.finish()?
    +/// };
    +///
    +/// // non-chaining
    +/// let (psbt2, details) = {
    +///     let mut builder = wallet.build_tx();
    +///     builder.ordering(TxOrdering::Untouched);
    +///     for addr in &[addr1, addr2] {
    +///         builder.add_recipient(addr.script_pubkey(), 50_000);
    +///     }
    +///     builder.finish()?
    +/// };
    +///
    +/// assert_eq!(psbt1.unsigned_tx.output[..2], psbt2.unsigned_tx.output[..2]);
    +/// # Ok::<(), bdk::Error>(())
    +/// ```
    +///
    +/// 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](super::tx_builder)'s documentation;
    +///
    +/// [`build_tx`]: Wallet::build_tx
    +/// [`build_fee_bump`]: Wallet::build_fee_bump
    +/// [`finish`]: Self::finish
    +/// [`coin_selection`]: Self::coin_selection
    +#[derive(Debug)]
    +pub struct TxBuilder<'a, D, Cs, Ctx> {
    +    pub(crate) wallet: &'a Wallet<D>,
    +    pub(crate) params: TxParams,
    +    pub(crate) coin_selection: Cs,
    +    pub(crate) phantom: PhantomData<Ctx>,
     }
     
    -/// The parameters for transaction creation sans coin selection algorithm.
    -//TODO: TxParams should eventually be exposed publicly.
    -#[derive(Default, Debug, Clone)]
    -pub(crate) struct TxParams {
    -    pub(crate) recipients: Vec<(Script, u64)>,
    -    pub(crate) drain_wallet: bool,
    -    pub(crate) drain_to: Option<Script>,
    -    pub(crate) fee_policy: Option<FeePolicy>,
    -    pub(crate) internal_policy_path: Option<BTreeMap<String, Vec<usize>>>,
    -    pub(crate) external_policy_path: Option<BTreeMap<String, Vec<usize>>>,
    -    pub(crate) utxos: Vec<WeightedUtxo>,
    -    pub(crate) unspendable: HashSet<OutPoint>,
    -    pub(crate) manually_selected_only: bool,
    -    pub(crate) sighash: Option<psbt::PsbtSighashType>,
    -    pub(crate) ordering: TxOrdering,
    -    pub(crate) locktime: Option<LockTime>,
    -    pub(crate) rbf: Option<RbfValue>,
    -    pub(crate) version: Option<Version>,
    -    pub(crate) change_policy: ChangeSpendPolicy,
    -    pub(crate) only_witness_utxo: bool,
    -    pub(crate) add_global_xpubs: bool,
    -    pub(crate) include_output_redeem_witness_script: bool,
    -    pub(crate) bumping_fee: Option<PreviousFee>,
    -    pub(crate) current_height: Option<LockTime>,
    -    pub(crate) allow_dust: bool,
    +/// The parameters for transaction creation sans coin selection algorithm.
    +//TODO: TxParams should eventually be exposed publicly.
    +#[derive(Default, Debug, Clone)]
    +pub(crate) struct TxParams {
    +    pub(crate) recipients: Vec<(Script, u64)>,
    +    pub(crate) drain_wallet: bool,
    +    pub(crate) drain_to: Option<Script>,
    +    pub(crate) fee_policy: Option<FeePolicy>,
    +    pub(crate) internal_policy_path: Option<BTreeMap<String, Vec<usize>>>,
    +    pub(crate) external_policy_path: Option<BTreeMap<String, Vec<usize>>>,
    +    pub(crate) utxos: Vec<WeightedUtxo>,
    +    pub(crate) unspendable: HashSet<OutPoint>,
    +    pub(crate) manually_selected_only: bool,
    +    pub(crate) sighash: Option<psbt::PsbtSighashType>,
    +    pub(crate) ordering: TxOrdering,
    +    pub(crate) locktime: Option<LockTime>,
    +    pub(crate) rbf: Option<RbfValue>,
    +    pub(crate) version: Option<Version>,
    +    pub(crate) change_policy: ChangeSpendPolicy,
    +    pub(crate) only_witness_utxo: bool,
    +    pub(crate) add_global_xpubs: bool,
    +    pub(crate) include_output_redeem_witness_script: bool,
    +    pub(crate) bumping_fee: Option<PreviousFee>,
    +    pub(crate) current_height: Option<LockTime>,
    +    pub(crate) allow_dust: bool,
     }
     
    -#[derive(Clone, Copy, Debug)]
    -pub(crate) struct PreviousFee {
    -    pub absolute: u64,
    -    pub rate: f32,
    +#[derive(Clone, Copy, Debug)]
    +pub(crate) struct PreviousFee {
    +    pub absolute: u64,
    +    pub rate: f32,
     }
     
    -#[derive(Debug, Clone, Copy)]
    -pub(crate) enum FeePolicy {
    -    FeeRate(FeeRate),
    -    FeeAmount(u64),
    +#[derive(Debug, Clone, Copy)]
    +pub(crate) enum FeePolicy {
    +    FeeRate(FeeRate),
    +    FeeAmount(u64),
     }
     
    -impl std::default::Default for FeePolicy {
    -    fn default() -> Self {
    -        FeePolicy::FeeRate(FeeRate::default_min_relay_fee())
    +impl std::default::Default for FeePolicy {
    +    fn default() -> Self {
    +        FeePolicy::FeeRate(FeeRate::default_min_relay_fee())
         }
     }
     
    -impl<'a, Cs: Clone, Ctx, D> Clone for TxBuilder<'a, D, Cs, Ctx> {
    -    fn clone(&self) -> Self {
    -        TxBuilder {
    -            wallet: self.wallet,
    -            params: self.params.clone(),
    -            coin_selection: self.coin_selection.clone(),
    -            phantom: PhantomData,
    +impl<'a, Cs: Clone, Ctx, D> Clone for TxBuilder<'a, D, Cs, Ctx> {
    +    fn clone(&self) -> Self {
    +        TxBuilder {
    +            wallet: self.wallet,
    +            params: self.params.clone(),
    +            coin_selection: self.coin_selection.clone(),
    +            phantom: PhantomData,
             }
         }
     }
     
    -// methods supported by both contexts, for any CoinSelectionAlgorithm
    -impl<'a, D: BatchDatabase, Cs: CoinSelectionAlgorithm<D>, Ctx: TxBuilderContext>
    -    TxBuilder<'a, D, Cs, Ctx>
    +// methods supported by both contexts, for any CoinSelectionAlgorithm
    +impl<'a, D: BatchDatabase, Cs: CoinSelectionAlgorithm<D>, Ctx: TxBuilderContext>
    +    TxBuilder<'a, D, Cs, Ctx>
     {
    -    /// Set a custom fee rate
    -    pub fn fee_rate(&mut self, fee_rate: FeeRate) -> &mut Self {
    -        self.params.fee_policy = Some(FeePolicy::FeeRate(fee_rate));
    -        self
    -    }
    -
    -    /// Set an absolute fee
    -    pub fn fee_absolute(&mut self, fee_amount: u64) -> &mut Self {
    -        self.params.fee_policy = Some(FeePolicy::FeeAmount(fee_amount));
    -        self
    -    }
    -
    -    /// Set the policy path to use while creating the transaction for a given keychain.
    -    ///
    -    /// This method accepts a map where the key is the policy node id (see
    -    /// [`Policy::id`](crate::descriptor::Policy::id)) and the value is the list of the indexes of
    -    /// the items that are intended to be satisfied from the policy node (see
    -    /// [`SatisfiableItem::Thresh::items`](crate::descriptor::policy::SatisfiableItem::Thresh::items)).
    -    ///
    -    /// ## Example
    -    ///
    -    /// An example of when the policy path is needed is the following descriptor:
    -    /// `wsh(thresh(2,pk(A),sj:and_v(v:pk(B),n:older(6)),snj:and_v(v:pk(C),after(630000))))`,
    -    /// derived from the miniscript policy `thresh(2,pk(A),and(pk(B),older(6)),and(pk(C),after(630000)))`.
    -    /// It declares three descriptor fragments, and at the top level it uses `thresh()` to
    -    /// ensure that at least two of them are satisfied. The individual fragments are:
    -    ///
    -    /// 1. `pk(A)`
    -    /// 2. `and(pk(B),older(6))`
    -    /// 3. `and(pk(C),after(630000))`
    -    ///
    -    /// When those conditions are combined in pairs, it's clear that the transaction needs to be created
    -    /// differently depending on how the user intends to satisfy the policy afterwards:
    -    ///
    -    /// * If fragments `1` and `2` are used, the transaction will need to use a specific
    -    ///   `n_sequence` in order to spend an `OP_CSV` branch.
    -    /// * If fragments `1` and `3` are used, the transaction will need to use a specific `locktime`
    -    ///   in order to spend an `OP_CLTV` branch.
    -    /// * If fragments `2` and `3` are used, the transaction will need both.
    -    ///
    -    /// When the spending policy is represented as a tree (see
    -    /// [`Wallet::policies`](super::Wallet::policies)), every node
    -    /// is assigned a unique identifier that can be used in the policy path to specify which of
    -    /// the node's children the user intends to satisfy: for instance, assuming the `thresh()`
    -    /// root node of this example has an id of `aabbccdd`, the policy path map would look like:
    -    ///
    -    /// `{ "aabbccdd" => [0, 1] }`
    -    ///
    -    /// where the key is the node's id, and the value is a list of the children that should be
    -    /// used, in no particular order.
    -    ///
    -    /// If a particularly complex descriptor has multiple ambiguous thresholds in its structure,
    -    /// multiple entries can be added to the map, one for each node that requires an explicit path.
    -    ///
    -    /// ```
    -    /// # use std::str::FromStr;
    -    /// # use std::collections::BTreeMap;
    -    /// # use bitcoin::*;
    -    /// # use bdk::*;
    -    /// # let to_address = Address::from_str("2N4eQYCbKUHCCTUjBJeHcJp9ok6J2GZsTDt").unwrap();
    -    /// # let wallet = doctest_wallet!();
    -    /// let mut path = BTreeMap::new();
    -    /// path.insert("aabbccdd".to_string(), vec![0, 1]);
    -    ///
    -    /// let builder = wallet
    -    ///     .build_tx()
    -    ///     .add_recipient(to_address.script_pubkey(), 50_000)
    -    ///     .policy_path(path, KeychainKind::External);
    -    ///
    -    /// # Ok::<(), bdk::Error>(())
    -    /// ```
    -    pub fn policy_path(
    -        &mut self,
    -        policy_path: BTreeMap<String, Vec<usize>>,
    -        keychain: KeychainKind,
    -    ) -> &mut Self {
    -        let to_update = match keychain {
    -            KeychainKind::Internal => &mut self.params.internal_policy_path,
    -            KeychainKind::External => &mut self.params.external_policy_path,
    +    /// Set a custom fee rate
    +    pub fn fee_rate(&mut self, fee_rate: FeeRate) -> &mut Self {
    +        self.params.fee_policy = Some(FeePolicy::FeeRate(fee_rate));
    +        self
    +    }
    +
    +    /// Set an absolute fee
    +    pub fn fee_absolute(&mut self, fee_amount: u64) -> &mut Self {
    +        self.params.fee_policy = Some(FeePolicy::FeeAmount(fee_amount));
    +        self
    +    }
    +
    +    /// Set the policy path to use while creating the transaction for a given keychain.
    +    ///
    +    /// This method accepts a map where the key is the policy node id (see
    +    /// [`Policy::id`](crate::descriptor::Policy::id)) and the value is the list of the indexes of
    +    /// the items that are intended to be satisfied from the policy node (see
    +    /// [`SatisfiableItem::Thresh::items`](crate::descriptor::policy::SatisfiableItem::Thresh::items)).
    +    ///
    +    /// ## Example
    +    ///
    +    /// An example of when the policy path is needed is the following descriptor:
    +    /// `wsh(thresh(2,pk(A),sj:and_v(v:pk(B),n:older(6)),snj:and_v(v:pk(C),after(630000))))`,
    +    /// derived from the miniscript policy `thresh(2,pk(A),and(pk(B),older(6)),and(pk(C),after(630000)))`.
    +    /// It declares three descriptor fragments, and at the top level it uses `thresh()` to
    +    /// ensure that at least two of them are satisfied. The individual fragments are:
    +    ///
    +    /// 1. `pk(A)`
    +    /// 2. `and(pk(B),older(6))`
    +    /// 3. `and(pk(C),after(630000))`
    +    ///
    +    /// When those conditions are combined in pairs, it's clear that the transaction needs to be created
    +    /// differently depending on how the user intends to satisfy the policy afterwards:
    +    ///
    +    /// * If fragments `1` and `2` are used, the transaction will need to use a specific
    +    ///   `n_sequence` in order to spend an `OP_CSV` branch.
    +    /// * If fragments `1` and `3` are used, the transaction will need to use a specific `locktime`
    +    ///   in order to spend an `OP_CLTV` branch.
    +    /// * If fragments `2` and `3` are used, the transaction will need both.
    +    ///
    +    /// When the spending policy is represented as a tree (see
    +    /// [`Wallet::policies`](super::Wallet::policies)), every node
    +    /// is assigned a unique identifier that can be used in the policy path to specify which of
    +    /// the node's children the user intends to satisfy: for instance, assuming the `thresh()`
    +    /// root node of this example has an id of `aabbccdd`, the policy path map would look like:
    +    ///
    +    /// `{ "aabbccdd" => [0, 1] }`
    +    ///
    +    /// where the key is the node's id, and the value is a list of the children that should be
    +    /// used, in no particular order.
    +    ///
    +    /// If a particularly complex descriptor has multiple ambiguous thresholds in its structure,
    +    /// multiple entries can be added to the map, one for each node that requires an explicit path.
    +    ///
    +    /// ```
    +    /// # use std::str::FromStr;
    +    /// # use std::collections::BTreeMap;
    +    /// # use bitcoin::*;
    +    /// # use bdk::*;
    +    /// # let to_address = Address::from_str("2N4eQYCbKUHCCTUjBJeHcJp9ok6J2GZsTDt").unwrap();
    +    /// # let wallet = doctest_wallet!();
    +    /// let mut path = BTreeMap::new();
    +    /// path.insert("aabbccdd".to_string(), vec![0, 1]);
    +    ///
    +    /// let builder = wallet
    +    ///     .build_tx()
    +    ///     .add_recipient(to_address.script_pubkey(), 50_000)
    +    ///     .policy_path(path, KeychainKind::External);
    +    ///
    +    /// # Ok::<(), bdk::Error>(())
    +    /// ```
    +    pub fn policy_path(
    +        &mut self,
    +        policy_path: BTreeMap<String, Vec<usize>>,
    +        keychain: KeychainKind,
    +    ) -> &mut Self {
    +        let to_update = match keychain {
    +            KeychainKind::Internal => &mut self.params.internal_policy_path,
    +            KeychainKind::External => &mut self.params.external_policy_path,
             };
     
    -        *to_update = Some(policy_path);
    -        self
    -    }
    -
    -    /// 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.
    -    pub fn add_utxos(&mut self, outpoints: &[OutPoint]) -> Result<&mut Self, Error> {
    -        let utxos = outpoints
    -            .iter()
    -            .map(|outpoint| self.wallet.get_utxo(*outpoint)?.ok_or(Error::UnknownUtxo))
    -            .collect::<Result<Vec<_>, _>>()?;
    -
    -        for utxo in utxos {
    -            let descriptor = self.wallet.get_descriptor_for_keychain(utxo.keychain);
    -            let satisfaction_weight = descriptor.max_satisfaction_weight().unwrap();
    -            self.params.utxos.push(WeightedUtxo {
    -                satisfaction_weight,
    -                utxo: Utxo::Local(utxo),
    +        *to_update = Some(policy_path);
    +        self
    +    }
    +
    +    /// 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.
    +    pub fn add_utxos(&mut self, outpoints: &[OutPoint]) -> Result<&mut Self, Error> {
    +        let utxos = outpoints
    +            .iter()
    +            .map(|outpoint| self.wallet.get_utxo(*outpoint)?.ok_or(Error::UnknownUtxo))
    +            .collect::<Result<Vec<_>, _>>()?;
    +
    +        for utxo in utxos {
    +            let descriptor = self.wallet.get_descriptor_for_keychain(utxo.keychain);
    +            let satisfaction_weight = descriptor.max_satisfaction_weight().unwrap();
    +            self.params.utxos.push(WeightedUtxo {
    +                satisfaction_weight,
    +                utxo: Utxo::Local(utxo),
                 });
             }
     
             Ok(self)
         }
     
    -    /// 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.
    -    pub fn add_utxo(&mut self, outpoint: OutPoint) -> Result<&mut Self, Error> {
    -        self.add_utxos(&[outpoint])
    +    /// 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.
    +    pub fn add_utxo(&mut self, outpoint: OutPoint) -> Result<&mut Self, Error> {
    +        self.add_utxos(&[outpoint])
         }
     
    -    /// Add a foreign UTXO i.e. a UTXO not owned by this wallet.
    -    ///
    -    /// At a minimum to add a foreign UTXO we need:
    -    ///
    -    /// 1. `outpoint`: To add it to the raw transaction.
    -    /// 2. `psbt_input`: To know the value.
    -    /// 3. `satisfaction_weight`: To know how much weight/vbytes the input will add to the transaction for fee calculation.
    -    ///
    -    /// There are several security concerns about adding foreign UTXOs that application
    -    /// developers should consider. First, how do you know the value of the input is correct? If a
    -    /// `non_witness_utxo` is provided in the `psbt_input` then this method implicitly verifies the
    -    /// value by checking it against the transaction. If only a `witness_utxo` is provided then this
    -    /// method doesn't verify the value but just takes it as a given -- it is up to you to check
    -    /// that whoever sent you the `input_psbt` was not lying!
    -    ///
    -    /// Secondly, you must somehow provide `satisfaction_weight` of the input. Depending on your
    -    /// application it may be important that this be known precisely. If not, a malicious
    -    /// counterparty may fool you into putting in a value that is too low, giving the transaction a
    -    /// lower than expected feerate. They could also fool you into putting a value that is too high
    -    /// causing you to pay a fee that is too high. The party who is broadcasting the transaction can
    -    /// of course check the real input weight matches the expected weight prior to broadcasting.
    -    ///
    -    /// To guarantee the `satisfaction_weight` is correct, you can require the party providing the
    -    /// `psbt_input` provide a miniscript descriptor for the input so you can check it against the
    -    /// `script_pubkey` and then ask it for the [`max_satisfaction_weight`].
    -    ///
    -    /// This is an **EXPERIMENTAL** feature, API and other major changes are expected.
    -    ///
    -    /// # Errors
    -    ///
    -    /// This method returns errors in the following circumstances:
    -    ///
    -    /// 1. The `psbt_input` does not contain a `witness_utxo` or `non_witness_utxo`.
    -    /// 2. The data in `non_witness_utxo` does not match what is in `outpoint`.
    -    ///
    -    /// 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.
    -    ///
    -    /// [`only_witness_utxo`]: Self::only_witness_utxo
    -    /// [`finish`]: Self::finish
    -    /// [`max_satisfaction_weight`]: miniscript::Descriptor::max_satisfaction_weight
    -    pub fn add_foreign_utxo(
    -        &mut self,
    -        outpoint: OutPoint,
    -        psbt_input: psbt::Input,
    -        satisfaction_weight: usize,
    -    ) -> Result<&mut Self, Error> {
    -        if psbt_input.witness_utxo.is_none() {
    -            match psbt_input.non_witness_utxo.as_ref() {
    -                Some(tx) => {
    -                    if tx.txid() != outpoint.txid {
    -                        return Err(Error::Generic(
    -                            "Foreign utxo outpoint does not match PSBT input".into(),
    +    /// Add a foreign UTXO i.e. a UTXO not owned by this wallet.
    +    ///
    +    /// At a minimum to add a foreign UTXO we need:
    +    ///
    +    /// 1. `outpoint`: To add it to the raw transaction.
    +    /// 2. `psbt_input`: To know the value.
    +    /// 3. `satisfaction_weight`: To know how much weight/vbytes the input will add to the transaction for fee calculation.
    +    ///
    +    /// There are several security concerns about adding foreign UTXOs that application
    +    /// developers should consider. First, how do you know the value of the input is correct? If a
    +    /// `non_witness_utxo` is provided in the `psbt_input` then this method implicitly verifies the
    +    /// value by checking it against the transaction. If only a `witness_utxo` is provided then this
    +    /// method doesn't verify the value but just takes it as a given -- it is up to you to check
    +    /// that whoever sent you the `input_psbt` was not lying!
    +    ///
    +    /// Secondly, you must somehow provide `satisfaction_weight` of the input. Depending on your
    +    /// application it may be important that this be known precisely. If not, a malicious
    +    /// counterparty may fool you into putting in a value that is too low, giving the transaction a
    +    /// lower than expected feerate. They could also fool you into putting a value that is too high
    +    /// causing you to pay a fee that is too high. The party who is broadcasting the transaction can
    +    /// of course check the real input weight matches the expected weight prior to broadcasting.
    +    ///
    +    /// To guarantee the `satisfaction_weight` is correct, you can require the party providing the
    +    /// `psbt_input` provide a miniscript descriptor for the input so you can check it against the
    +    /// `script_pubkey` and then ask it for the [`max_satisfaction_weight`].
    +    ///
    +    /// This is an **EXPERIMENTAL** feature, API and other major changes are expected.
    +    ///
    +    /// # Errors
    +    ///
    +    /// This method returns errors in the following circumstances:
    +    ///
    +    /// 1. The `psbt_input` does not contain a `witness_utxo` or `non_witness_utxo`.
    +    /// 2. The data in `non_witness_utxo` does not match what is in `outpoint`.
    +    ///
    +    /// 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.
    +    ///
    +    /// [`only_witness_utxo`]: Self::only_witness_utxo
    +    /// [`finish`]: Self::finish
    +    /// [`max_satisfaction_weight`]: miniscript::Descriptor::max_satisfaction_weight
    +    pub fn add_foreign_utxo(
    +        &mut self,
    +        outpoint: OutPoint,
    +        psbt_input: psbt::Input,
    +        satisfaction_weight: usize,
    +    ) -> Result<&mut Self, Error> {
    +        if psbt_input.witness_utxo.is_none() {
    +            match psbt_input.non_witness_utxo.as_ref() {
    +                Some(tx) => {
    +                    if tx.txid() != outpoint.txid {
    +                        return Err(Error::Generic(
    +                            "Foreign utxo outpoint does not match PSBT input".into(),
                             ));
                         }
    -                    if tx.output.len() <= outpoint.vout as usize {
    -                        return Err(Error::InvalidOutpoint(outpoint));
    +                    if tx.output.len() <= outpoint.vout as usize {
    +                        return Err(Error::InvalidOutpoint(outpoint));
                         }
                     }
    -                None => {
    -                    return Err(Error::Generic(
    -                        "Foreign utxo missing witness_utxo or non_witness_utxo".into(),
    +                None => {
    +                    return Err(Error::Generic(
    +                        "Foreign utxo missing witness_utxo or non_witness_utxo".into(),
                         ))
                     }
                 }
             }
     
    -        self.params.utxos.push(WeightedUtxo {
    -            satisfaction_weight,
    -            utxo: Utxo::Foreign {
    -                outpoint,
    -                psbt_input: Box::new(psbt_input),
    +        self.params.utxos.push(WeightedUtxo {
    +            satisfaction_weight,
    +            utxo: Utxo::Foreign {
    +                outpoint,
    +                psbt_input: Box::new(psbt_input),
                 },
             });
     
             Ok(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.
    -    ///
    -    /// [`add_utxo`]: Self::add_utxo
    -    pub fn manually_selected_only(&mut self) -> &mut Self {
    -        self.params.manually_selected_only = true;
    -        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.
    -    pub fn unspendable(&mut self, unspendable: Vec<OutPoint>) -> &mut Self {
    -        self.params.unspendable = unspendable.into_iter().collect();
    -        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.
    -    pub fn add_unspendable(&mut self, unspendable: OutPoint) -> &mut Self {
    -        self.params.unspendable.insert(unspendable);
    -        self
    -    }
    -
    -    /// Sign with a specific sig hash
    -    ///
    -    /// **Use this option very carefully**
    -    pub fn sighash(&mut self, sighash: psbt::PsbtSighashType) -> &mut Self {
    -        self.params.sighash = Some(sighash);
    -        self
    -    }
    -
    -    /// Choose the ordering for inputs and outputs of the transaction
    -    pub fn ordering(&mut self, ordering: TxOrdering) -> &mut Self {
    -        self.params.ordering = ordering;
    -        self
    -    }
    -
    -    /// Use a specific nLockTime while creating the transaction
    -    ///
    -    /// This can cause conflicts if the wallet's descriptors contain an "after" (OP_CLTV) operator.
    -    pub fn nlocktime(&mut self, locktime: LockTime) -> &mut Self {
    -        self.params.locktime = Some(locktime);
    -        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.
    -    pub fn version(&mut self, version: i32) -> &mut Self {
    -        self.params.version = Some(Version(version));
    -        self
    -    }
    -
    -    /// Do not spend change outputs
    -    ///
    -    /// This effectively adds all the change outputs to the "unspendable" list. See
    -    /// [`TxBuilder::unspendable`].
    -    pub fn do_not_spend_change(&mut self) -> &mut Self {
    -        self.params.change_policy = ChangeSpendPolicy::ChangeForbidden;
    -        self
    -    }
    -
    -    /// Only spend change outputs
    -    ///
    -    /// This effectively adds all the non-change outputs to the "unspendable" list. See
    -    /// [`TxBuilder::unspendable`].
    -    pub fn only_spend_change(&mut self) -> &mut Self {
    -        self.params.change_policy = ChangeSpendPolicy::OnlyChange;
    -        self
    -    }
    -
    -    /// Set a specific [`ChangeSpendPolicy`]. See [`TxBuilder::do_not_spend_change`] and
    -    /// [`TxBuilder::only_spend_change`] for some shortcuts.
    -    pub fn change_policy(&mut self, change_policy: ChangeSpendPolicy) -> &mut Self {
    -        self.params.change_policy = change_policy;
    -        self
    -    }
    -
    -    /// Only Fill-in the [`psbt::Input::witness_utxo`](bitcoin::util::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`.
    -    pub fn only_witness_utxo(&mut self) -> &mut Self {
    -        self.params.only_witness_utxo = true;
    -        self
    -    }
    -
    -    /// Fill-in the [`psbt::Output::redeem_script`](bitcoin::util::psbt::Output::redeem_script) and
    -    /// [`psbt::Output::witness_script`](bitcoin::util::psbt::Output::witness_script) fields.
    -    ///
    -    /// This is useful for signers which always require it, like ColdCard hardware wallets.
    -    pub fn include_output_redeem_witness_script(&mut self) -> &mut Self {
    -        self.params.include_output_redeem_witness_script = true;
    -        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.
    -    pub fn add_global_xpubs(&mut self) -> &mut Self {
    -        self.params.add_global_xpubs = true;
    -        self
    -    }
    -
    -    /// Spend all the available inputs. This respects filters like [`TxBuilder::unspendable`] and the change policy.
    -    pub fn drain_wallet(&mut self) -> &mut Self {
    -        self.params.drain_wallet = true;
    -        self
    -    }
    -
    -    /// Choose the coin selection algorithm
    -    ///
    -    /// Overrides the [`DefaultCoinSelectionAlgorithm`](super::coin_selection::DefaultCoinSelectionAlgorithm).
    -    ///
    -    /// 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.
    -    pub fn coin_selection<P: CoinSelectionAlgorithm<D>>(
    +    /// 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.
    +    ///
    +    /// [`add_utxo`]: Self::add_utxo
    +    pub fn manually_selected_only(&mut self) -> &mut Self {
    +        self.params.manually_selected_only = true;
    +        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.
    +    pub fn unspendable(&mut self, unspendable: Vec<OutPoint>) -> &mut Self {
    +        self.params.unspendable = unspendable.into_iter().collect();
    +        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.
    +    pub fn add_unspendable(&mut self, unspendable: OutPoint) -> &mut Self {
    +        self.params.unspendable.insert(unspendable);
    +        self
    +    }
    +
    +    /// Sign with a specific sig hash
    +    ///
    +    /// **Use this option very carefully**
    +    pub fn sighash(&mut self, sighash: psbt::PsbtSighashType) -> &mut Self {
    +        self.params.sighash = Some(sighash);
    +        self
    +    }
    +
    +    /// Choose the ordering for inputs and outputs of the transaction
    +    pub fn ordering(&mut self, ordering: TxOrdering) -> &mut Self {
    +        self.params.ordering = ordering;
    +        self
    +    }
    +
    +    /// Use a specific nLockTime while creating the transaction
    +    ///
    +    /// This can cause conflicts if the wallet's descriptors contain an "after" (OP_CLTV) operator.
    +    pub fn nlocktime(&mut self, locktime: LockTime) -> &mut Self {
    +        self.params.locktime = Some(locktime);
    +        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.
    +    pub fn version(&mut self, version: i32) -> &mut Self {
    +        self.params.version = Some(Version(version));
    +        self
    +    }
    +
    +    /// Do not spend change outputs
    +    ///
    +    /// This effectively adds all the change outputs to the "unspendable" list. See
    +    /// [`TxBuilder::unspendable`].
    +    pub fn do_not_spend_change(&mut self) -> &mut Self {
    +        self.params.change_policy = ChangeSpendPolicy::ChangeForbidden;
    +        self
    +    }
    +
    +    /// Only spend change outputs
    +    ///
    +    /// This effectively adds all the non-change outputs to the "unspendable" list. See
    +    /// [`TxBuilder::unspendable`].
    +    pub fn only_spend_change(&mut self) -> &mut Self {
    +        self.params.change_policy = ChangeSpendPolicy::OnlyChange;
    +        self
    +    }
    +
    +    /// Set a specific [`ChangeSpendPolicy`]. See [`TxBuilder::do_not_spend_change`] and
    +    /// [`TxBuilder::only_spend_change`] for some shortcuts.
    +    pub fn change_policy(&mut self, change_policy: ChangeSpendPolicy) -> &mut Self {
    +        self.params.change_policy = change_policy;
    +        self
    +    }
    +
    +    /// Only Fill-in the [`psbt::Input::witness_utxo`](bitcoin::util::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`.
    +    pub fn only_witness_utxo(&mut self) -> &mut Self {
    +        self.params.only_witness_utxo = true;
    +        self
    +    }
    +
    +    /// Fill-in the [`psbt::Output::redeem_script`](bitcoin::util::psbt::Output::redeem_script) and
    +    /// [`psbt::Output::witness_script`](bitcoin::util::psbt::Output::witness_script) fields.
    +    ///
    +    /// This is useful for signers which always require it, like ColdCard hardware wallets.
    +    pub fn include_output_redeem_witness_script(&mut self) -> &mut Self {
    +        self.params.include_output_redeem_witness_script = true;
    +        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.
    +    pub fn add_global_xpubs(&mut self) -> &mut Self {
    +        self.params.add_global_xpubs = true;
    +        self
    +    }
    +
    +    /// Spend all the available inputs. This respects filters like [`TxBuilder::unspendable`] and the change policy.
    +    pub fn drain_wallet(&mut self) -> &mut Self {
    +        self.params.drain_wallet = true;
    +        self
    +    }
    +
    +    /// Choose the coin selection algorithm
    +    ///
    +    /// Overrides the [`DefaultCoinSelectionAlgorithm`](super::coin_selection::DefaultCoinSelectionAlgorithm).
    +    ///
    +    /// 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.
    +    pub fn coin_selection<P: CoinSelectionAlgorithm<D>>(
             self,
    -        coin_selection: P,
    -    ) -> TxBuilder<'a, D, P, Ctx> {
    -        TxBuilder {
    -            wallet: self.wallet,
    -            params: self.params,
    -            coin_selection,
    -            phantom: PhantomData,
    +        coin_selection: P,
    +    ) -> TxBuilder<'a, D, P, Ctx> {
    +        TxBuilder {
    +            wallet: self.wallet,
    +            params: self.params,
    +            coin_selection,
    +            phantom: PhantomData,
             }
         }
     
    -    /// Finish building the transaction.
    -    ///
    -    /// Returns the [`BIP174`] "PSBT" and summary details about the transaction.
    -    ///
    -    /// [`BIP174`]: https://github.com/bitcoin/bips/blob/master/bip-0174.mediawiki
    -    pub fn finish(self) -> Result<(Psbt, TransactionDetails), Error> {
    -        self.wallet.create_tx(self.coin_selection, self.params)
    -    }
    -
    -    /// Enable signaling RBF
    -    ///
    -    /// This will use the default nSequence value of `0xFFFFFFFD`.
    -    pub fn enable_rbf(&mut self) -> &mut Self {
    -        self.params.rbf = Some(RbfValue::Default);
    -        self
    +    /// Finish building the transaction.
    +    ///
    +    /// Returns the [`BIP174`] "PSBT" and summary details about the transaction.
    +    ///
    +    /// [`BIP174`]: https://github.com/bitcoin/bips/blob/master/bip-0174.mediawiki
    +    pub fn finish(self) -> Result<(Psbt, TransactionDetails), Error> {
    +        self.wallet.create_tx(self.coin_selection, self.params)
         }
     
    -    /// 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.
    -    pub fn enable_rbf_with_sequence(&mut self, nsequence: Sequence) -> &mut Self {
    -        self.params.rbf = Some(RbfValue::Value(nsequence));
    -        self
    -    }
    -
    -    /// Set the current blockchain height.
    -    ///
    -    /// This will be used to:
    -    /// 1. Set the nLockTime for preventing fee sniping.
    -    /// **Note**: This will be ignored if you manually specify a nlocktime using [`TxBuilder::nlocktime`].
    -    /// 2. Decide whether coinbase outputs are mature or not. If the coinbase outputs are not
    -    ///    mature at `current_height`, we ignore them in the coin selection.
    -    ///    If you want to create a transaction that spends immature coinbase inputs, manually
    -    ///    add them using [`TxBuilder::add_utxos`].
    -    ///
    -    /// In both cases, if you don't provide a current height, we use the last sync height.
    -    pub fn current_height(&mut self, height: u32) -> &mut Self {
    -        self.params.current_height = Some(LockTime::from_height(height).expect("Invalid height"));
    -        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.
    -    pub fn allow_dust(&mut self, allow_dust: bool) -> &mut Self {
    -        self.params.allow_dust = allow_dust;
    -        self
    -    }
    +    /// Enable signaling RBF
    +    ///
    +    /// This will use the default nSequence value of `0xFFFFFFFD`.
    +    pub fn enable_rbf(&mut self) -> &mut Self {
    +        self.params.rbf = Some(RbfValue::Default);
    +        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.
    +    pub fn enable_rbf_with_sequence(&mut self, nsequence: Sequence) -> &mut Self {
    +        self.params.rbf = Some(RbfValue::Value(nsequence));
    +        self
    +    }
    +
    +    /// Set the current blockchain height.
    +    ///
    +    /// This will be used to:
    +    /// 1. Set the nLockTime for preventing fee sniping.
    +    /// **Note**: This will be ignored if you manually specify a nlocktime using [`TxBuilder::nlocktime`].
    +    /// 2. Decide whether coinbase outputs are mature or not. If the coinbase outputs are not
    +    ///    mature at `current_height`, we ignore them in the coin selection.
    +    ///    If you want to create a transaction that spends immature coinbase inputs, manually
    +    ///    add them using [`TxBuilder::add_utxos`].
    +    ///
    +    /// In both cases, if you don't provide a current height, we use the last sync height.
    +    pub fn current_height(&mut self, height: u32) -> &mut Self {
    +        self.params.current_height = Some(LockTime::from_height(height).expect("Invalid height"));
    +        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.
    +    pub fn allow_dust(&mut self, allow_dust: bool) -> &mut Self {
    +        self.params.allow_dust = allow_dust;
    +        self
    +    }
     }
     
    -impl<'a, D: BatchDatabase, Cs: CoinSelectionAlgorithm<D>> TxBuilder<'a, D, Cs, CreateTx> {
    -    /// Replace the recipients already added with a new list
    -    pub fn set_recipients(&mut self, recipients: Vec<(Script, u64)>) -> &mut Self {
    -        self.params.recipients = recipients;
    -        self
    -    }
    -
    -    /// Add a recipient to the internal list
    -    pub fn add_recipient(&mut self, script_pubkey: Script, amount: u64) -> &mut Self {
    -        self.params.recipients.push((script_pubkey, amount));
    -        self
    -    }
    -
    -    /// Add data as an output, using OP_RETURN
    -    pub fn add_data(&mut self, data: &[u8]) -> &mut Self {
    -        let script = Script::new_op_return(data);
    -        self.add_recipient(script, 0u64);
    -        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
    -    /// coins are too small) it will not be included in the resulting transaction. The only
    -    /// difference is that it is valid to use `drain_to` without setting any ordinary recipients
    -    /// with [`add_recipient`] (but it is perfectly fine to add recipients as well).
    -    ///
    -    /// If you choose not to set any recipients, you should either provide the utxos that the
    -    /// transaction should spend via [`add_utxos`], or set [`drain_wallet`] to spend all of them.
    -    ///
    -    /// When bumping the fees of a transaction made with this option, you probably want to
    -    /// use [`allow_shrinking`] to allow this output to be reduced to pay for the extra fees.
    -    ///
    -    /// # Example
    -    ///
    -    /// `drain_to` is very useful for draining all the coins in a wallet with [`drain_wallet`] to a
    -    /// single address.
    -    ///
    -    /// ```
    -    /// # use std::str::FromStr;
    -    /// # use bitcoin::*;
    -    /// # use bdk::*;
    -    /// # use bdk::wallet::tx_builder::CreateTx;
    -    /// # let to_address = Address::from_str("2N4eQYCbKUHCCTUjBJeHcJp9ok6J2GZsTDt").unwrap();
    -    /// # let wallet = doctest_wallet!();
    -    /// let mut tx_builder = wallet.build_tx();
    -    ///
    -    /// tx_builder
    -    ///     // Spend all outputs in this wallet.
    -    ///     .drain_wallet()
    -    ///     // Send the excess (which is all the coins minus the fee) to this address.
    -    ///     .drain_to(to_address.script_pubkey())
    -    ///     .fee_rate(FeeRate::from_sat_per_vb(5.0))
    -    ///     .enable_rbf();
    -    /// let (psbt, tx_details) = tx_builder.finish()?;
    -    /// # Ok::<(), bdk::Error>(())
    -    /// ```
    -    ///
    -    /// [`allow_shrinking`]: Self::allow_shrinking
    -    /// [`add_recipient`]: Self::add_recipient
    -    /// [`add_utxos`]: Self::add_utxos
    -    /// [`drain_wallet`]: Self::drain_wallet
    -    pub fn drain_to(&mut self, script_pubkey: Script) -> &mut Self {
    -        self.params.drain_to = Some(script_pubkey);
    -        self
    -    }
    +impl<'a, D: BatchDatabase, Cs: CoinSelectionAlgorithm<D>> TxBuilder<'a, D, Cs, CreateTx> {
    +    /// Replace the recipients already added with a new list
    +    pub fn set_recipients(&mut self, recipients: Vec<(Script, u64)>) -> &mut Self {
    +        self.params.recipients = recipients;
    +        self
    +    }
    +
    +    /// Add a recipient to the internal list
    +    pub fn add_recipient(&mut self, script_pubkey: Script, amount: u64) -> &mut Self {
    +        self.params.recipients.push((script_pubkey, amount));
    +        self
    +    }
    +
    +    /// Add data as an output, using OP_RETURN
    +    pub fn add_data(&mut self, data: &[u8]) -> &mut Self {
    +        let script = Script::new_op_return(data);
    +        self.add_recipient(script, 0u64);
    +        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
    +    /// coins are too small) it will not be included in the resulting transaction. The only
    +    /// difference is that it is valid to use `drain_to` without setting any ordinary recipients
    +    /// with [`add_recipient`] (but it is perfectly fine to add recipients as well).
    +    ///
    +    /// If you choose not to set any recipients, you should either provide the utxos that the
    +    /// transaction should spend via [`add_utxos`], or set [`drain_wallet`] to spend all of them.
    +    ///
    +    /// When bumping the fees of a transaction made with this option, you probably want to
    +    /// use [`allow_shrinking`] to allow this output to be reduced to pay for the extra fees.
    +    ///
    +    /// # Example
    +    ///
    +    /// `drain_to` is very useful for draining all the coins in a wallet with [`drain_wallet`] to a
    +    /// single address.
    +    ///
    +    /// ```
    +    /// # use std::str::FromStr;
    +    /// # use bitcoin::*;
    +    /// # use bdk::*;
    +    /// # use bdk::wallet::tx_builder::CreateTx;
    +    /// # let to_address = Address::from_str("2N4eQYCbKUHCCTUjBJeHcJp9ok6J2GZsTDt").unwrap();
    +    /// # let wallet = doctest_wallet!();
    +    /// let mut tx_builder = wallet.build_tx();
    +    ///
    +    /// tx_builder
    +    ///     // Spend all outputs in this wallet.
    +    ///     .drain_wallet()
    +    ///     // Send the excess (which is all the coins minus the fee) to this address.
    +    ///     .drain_to(to_address.script_pubkey())
    +    ///     .fee_rate(FeeRate::from_sat_per_vb(5.0))
    +    ///     .enable_rbf();
    +    /// let (psbt, tx_details) = tx_builder.finish()?;
    +    /// # Ok::<(), bdk::Error>(())
    +    /// ```
    +    ///
    +    /// [`allow_shrinking`]: Self::allow_shrinking
    +    /// [`add_recipient`]: Self::add_recipient
    +    /// [`add_utxos`]: Self::add_utxos
    +    /// [`drain_wallet`]: Self::drain_wallet
    +    pub fn drain_to(&mut self, script_pubkey: Script) -> &mut Self {
    +        self.params.drain_to = Some(script_pubkey);
    +        self
    +    }
     }
     
    -// methods supported only by bump_fee
    -impl<'a, D: BatchDatabase> TxBuilder<'a, D, DefaultCoinSelectionAlgorithm, BumpFee> {
    -    /// Explicitly tells the wallet that it is allowed to reduce the amount of the output matching this
    -    /// `script_pubkey` in order to bump the transaction fee. Without specifying this the wallet
    -    /// will attempt to find a change output to shrink instead.
    -    ///
    -    /// **Note** that the output may shrink to below the dust limit and therefore be removed. If it is
    -    /// preserved then it is currently not guaranteed to be in the same position as it was
    -    /// originally.
    -    ///
    -    /// Returns an `Err` if `script_pubkey` can't be found among the recipients of the
    -    /// transaction we are bumping.
    -    pub fn allow_shrinking(&mut self, script_pubkey: Script) -> Result<&mut Self, Error> {
    -        match self
    -            .params
    -            .recipients
    -            .iter()
    -            .position(|(recipient_script, _)| *recipient_script == script_pubkey)
    +// methods supported only by bump_fee
    +impl<'a, D: BatchDatabase> TxBuilder<'a, D, DefaultCoinSelectionAlgorithm, BumpFee> {
    +    /// Explicitly tells the wallet that it is allowed to reduce the amount of the output matching this
    +    /// `script_pubkey` in order to bump the transaction fee. Without specifying this the wallet
    +    /// will attempt to find a change output to shrink instead.
    +    ///
    +    /// **Note** that the output may shrink to below the dust limit and therefore be removed. If it is
    +    /// preserved then it is currently not guaranteed to be in the same position as it was
    +    /// originally.
    +    ///
    +    /// Returns an `Err` if `script_pubkey` can't be found among the recipients of the
    +    /// transaction we are bumping.
    +    pub fn allow_shrinking(&mut self, script_pubkey: Script) -> Result<&mut Self, Error> {
    +        match self
    +            .params
    +            .recipients
    +            .iter()
    +            .position(|(recipient_script, _)| *recipient_script == script_pubkey)
             {
    -            Some(position) => {
    -                self.params.recipients.remove(position);
    -                self.params.drain_to = Some(script_pubkey);
    +            Some(position) => {
    +                self.params.recipients.remove(position);
    +                self.params.drain_to = Some(script_pubkey);
                     Ok(self)
                 }
    -            None => Err(Error::Generic(format!(
    +            None => Err(Error::Generic(format!(
                     "{} was not in the original transaction",
    -                script_pubkey
    +                script_pubkey
                 ))),
             }
         }
     }
     
    -/// Ordering of the transaction's inputs and outputs
    -#[derive(Debug, Ord, PartialOrd, Eq, PartialEq, Hash, Clone, Copy)]
    -pub enum TxOrdering {
    -    /// Randomized (default)
    -    Shuffle,
    -    /// Unchanged
    -    Untouched,
    -    /// BIP69 / Lexicographic
    -    Bip69Lexicographic,
    +/// Ordering of the transaction's inputs and outputs
    +#[derive(Debug, Ord, PartialOrd, Eq, PartialEq, Hash, Clone, Copy)]
    +pub enum TxOrdering {
    +    /// Randomized (default)
    +    Shuffle,
    +    /// Unchanged
    +    Untouched,
    +    /// BIP69 / Lexicographic
    +    Bip69Lexicographic,
     }
     
    -impl Default for TxOrdering {
    -    fn default() -> Self {
    -        TxOrdering::Shuffle
    +impl Default for TxOrdering {
    +    fn default() -> Self {
    +        TxOrdering::Shuffle
         }
     }
     
    -impl TxOrdering {
    -    /// Sort transaction inputs and outputs by [`TxOrdering`] variant
    -    pub fn sort_tx(&self, tx: &mut Transaction) {
    -        match self {
    -            TxOrdering::Untouched => {}
    -            TxOrdering::Shuffle => {
    -                use rand::seq::SliceRandom;
    -                #[cfg(test)]
    -                use rand::SeedableRng;
    -
    -                #[cfg(not(test))]
    -                let mut rng = rand::thread_rng();
    -                #[cfg(test)]
    -                let mut rng = rand::rngs::StdRng::seed_from_u64(12345);
    -
    -                tx.output.shuffle(&mut rng);
    +impl TxOrdering {
    +    /// Sort transaction inputs and outputs by [`TxOrdering`] variant
    +    pub fn sort_tx(&self, tx: &mut Transaction) {
    +        match self {
    +            TxOrdering::Untouched => {}
    +            TxOrdering::Shuffle => {
    +                use rand::seq::SliceRandom;
    +                #[cfg(test)]
    +                use rand::SeedableRng;
    +
    +                #[cfg(not(test))]
    +                let mut rng = rand::thread_rng();
    +                #[cfg(test)]
    +                let mut rng = rand::rngs::StdRng::seed_from_u64(12345);
    +
    +                tx.output.shuffle(&mut rng);
                 }
    -            TxOrdering::Bip69Lexicographic => {
    -                tx.input.sort_unstable_by_key(|txin| {
    -                    (txin.previous_output.txid, txin.previous_output.vout)
    +            TxOrdering::Bip69Lexicographic => {
    +                tx.input.sort_unstable_by_key(|txin| {
    +                    (txin.previous_output.txid, txin.previous_output.vout)
                     });
    -                tx.output
    -                    .sort_unstable_by_key(|txout| (txout.value, txout.script_pubkey.clone()));
    +                tx.output
    +                    .sort_unstable_by_key(|txout| (txout.value, txout.script_pubkey.clone()));
                 }
             }
         }
     }
     
    -/// Transaction version
    -///
    -/// Has a default value of `1`
    -#[derive(Debug, Ord, PartialOrd, Eq, PartialEq, Hash, Clone, Copy)]
    -pub(crate) struct Version(pub(crate) i32);
    +/// Transaction version
    +///
    +/// Has a default value of `1`
    +#[derive(Debug, Ord, PartialOrd, Eq, PartialEq, Hash, Clone, Copy)]
    +pub(crate) struct Version(pub(crate) i32);
     
    -impl Default for Version {
    -    fn default() -> Self {
    -        Version(1)
    +impl Default for Version {
    +    fn default() -> Self {
    +        Version(1)
         }
     }
     
    -/// RBF nSequence value
    -///
    -/// Has a default value of `0xFFFFFFFD`
    -#[derive(Debug, Ord, PartialOrd, Eq, PartialEq, Hash, Clone, Copy)]
    -pub(crate) enum RbfValue {
    -    Default,
    -    Value(Sequence),
    +/// RBF nSequence value
    +///
    +/// Has a default value of `0xFFFFFFFD`
    +#[derive(Debug, Ord, PartialOrd, Eq, PartialEq, Hash, Clone, Copy)]
    +pub(crate) enum RbfValue {
    +    Default,
    +    Value(Sequence),
     }
     
    -impl RbfValue {
    -    pub(crate) fn get_value(&self) -> Sequence {
    -        match self {
    -            RbfValue::Default => Sequence::ENABLE_RBF_NO_LOCKTIME,
    -            RbfValue::Value(v) => *v,
    +impl RbfValue {
    +    pub(crate) fn get_value(&self) -> Sequence {
    +        match self {
    +            RbfValue::Default => Sequence::ENABLE_RBF_NO_LOCKTIME,
    +            RbfValue::Value(v) => *v,
             }
         }
     }
     
    -/// Policy regarding the use of change outputs when creating a transaction
    -#[derive(Debug, Ord, PartialOrd, Eq, PartialEq, Hash, Clone, Copy)]
    -pub enum ChangeSpendPolicy {
    -    /// Use both change and non-change outputs (default)
    -    ChangeAllowed,
    -    /// Only use change outputs (see [`TxBuilder::only_spend_change`])
    -    OnlyChange,
    -    /// Only use non-change outputs (see [`TxBuilder::do_not_spend_change`])
    -    ChangeForbidden,
    +/// Policy regarding the use of change outputs when creating a transaction
    +#[derive(Debug, Ord, PartialOrd, Eq, PartialEq, Hash, Clone, Copy)]
    +pub enum ChangeSpendPolicy {
    +    /// Use both change and non-change outputs (default)
    +    ChangeAllowed,
    +    /// Only use change outputs (see [`TxBuilder::only_spend_change`])
    +    OnlyChange,
    +    /// Only use non-change outputs (see [`TxBuilder::do_not_spend_change`])
    +    ChangeForbidden,
     }
     
    -impl Default for ChangeSpendPolicy {
    -    fn default() -> Self {
    -        ChangeSpendPolicy::ChangeAllowed
    +impl Default for ChangeSpendPolicy {
    +    fn default() -> Self {
    +        ChangeSpendPolicy::ChangeAllowed
         }
     }
     
    -impl ChangeSpendPolicy {
    -    pub(crate) fn is_satisfied_by(&self, utxo: &LocalUtxo) -> bool {
    -        match self {
    -            ChangeSpendPolicy::ChangeAllowed => true,
    -            ChangeSpendPolicy::OnlyChange => utxo.keychain == KeychainKind::Internal,
    -            ChangeSpendPolicy::ChangeForbidden => utxo.keychain == KeychainKind::External,
    +impl ChangeSpendPolicy {
    +    pub(crate) fn is_satisfied_by(&self, utxo: &LocalUtxo) -> bool {
    +        match self {
    +            ChangeSpendPolicy::ChangeAllowed => true,
    +            ChangeSpendPolicy::OnlyChange => utxo.keychain == KeychainKind::Internal,
    +            ChangeSpendPolicy::ChangeForbidden => utxo.keychain == KeychainKind::External,
             }
         }
     }
     
    -#[cfg(test)]
    -mod test {
    -    const ORDERING_TEST_TX: &str = "0200000003c26f3eb7932f7acddc5ddd26602b77e7516079b03090a16e2c2f54\
    +#[cfg(test)]
    +mod test {
    +    const ORDERING_TEST_TX: &str = "0200000003c26f3eb7932f7acddc5ddd26602b77e7516079b03090a16e2c2f54\
                                         85d1fd600f0100000000ffffffffc26f3eb7932f7acddc5ddd26602b77e75160\
                                         79b03090a16e2c2f5485d1fd600f0000000000ffffffff571fb3e02278217852\
                                         dd5d299947e2b7354a639adc32ec1fa7b82cfb5dec530e0500000000ffffffff\
                                         03e80300000000000002aaeee80300000000000001aa200300000000000001ff\
                                         00000000";
    -    macro_rules! ordering_test_tx {
    +    macro_rules! ordering_test_tx {
             () => {
    -            deserialize::<bitcoin::Transaction>(&Vec::<u8>::from_hex(ORDERING_TEST_TX).unwrap())
    -                .unwrap()
    +            deserialize::<bitcoin::Transaction>(&Vec::<u8>::from_hex(ORDERING_TEST_TX).unwrap())
    +                .unwrap()
             };
         }
     
    -    use bitcoin::consensus::deserialize;
    -    use bitcoin::hashes::hex::FromHex;
    +    use bitcoin::consensus::deserialize;
    +    use bitcoin::hashes::hex::FromHex;
     
    -    use super::*;
    +    use super::*;
     
    -    #[test]
    -    fn test_output_ordering_default_shuffle() {
    -        assert_eq!(TxOrdering::default(), TxOrdering::Shuffle);
    +    #[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!();
    -        let mut tx = original_tx.clone();
    +    #[test]
    +    fn test_output_ordering_untouched() {
    +        let original_tx = ordering_test_tx!();
    +        let mut tx = original_tx.clone();
     
    -        TxOrdering::Untouched.sort_tx(&mut tx);
    +        TxOrdering::Untouched.sort_tx(&mut tx);
     
    -        assert_eq!(original_tx, tx);
    +        assert_eq!(original_tx, tx);
         }
     
    -    #[test]
    -    fn test_output_ordering_shuffle() {
    -        let original_tx = ordering_test_tx!();
    -        let mut tx = original_tx.clone();
    +    #[test]
    +    fn test_output_ordering_shuffle() {
    +        let original_tx = ordering_test_tx!();
    +        let mut tx = original_tx.clone();
     
    -        TxOrdering::Shuffle.sort_tx(&mut tx);
    +        TxOrdering::Shuffle.sort_tx(&mut tx);
     
    -        assert_eq!(original_tx.input, tx.input);
    -        assert_ne!(original_tx.output, tx.output);
    +        assert_eq!(original_tx.input, tx.input);
    +        assert_ne!(original_tx.output, tx.output);
         }
     
    -    #[test]
    -    fn test_output_ordering_bip69() {
    -        use std::str::FromStr;
    +    #[test]
    +    fn test_output_ordering_bip69() {
    +        use std::str::FromStr;
     
    -        let original_tx = ordering_test_tx!();
    -        let mut tx = original_tx;
    +        let original_tx = ordering_test_tx!();
    +        let mut tx = original_tx;
     
    -        TxOrdering::Bip69Lexicographic.sort_tx(&mut tx);
    +        TxOrdering::Bip69Lexicographic.sort_tx(&mut tx);
     
             assert_eq!(
    -            tx.input[0].previous_output,
    -            bitcoin::OutPoint::from_str(
    -                "0e53ec5dfb2cb8a71fec32dc9a634a35b7e24799295ddd5278217822e0b31f57:5"
    -            )
    -            .unwrap()
    +            tx.input[0].previous_output,
    +            bitcoin::OutPoint::from_str(
    +                "0e53ec5dfb2cb8a71fec32dc9a634a35b7e24799295ddd5278217822e0b31f57:5"
    +            )
    +            .unwrap()
             );
             assert_eq!(
    -            tx.input[1].previous_output,
    -            bitcoin::OutPoint::from_str(
    -                "0f60fdd185542f2c6ea19030b0796051e7772b6026dd5ddccd7a2f93b73e6fc2:0"
    -            )
    -            .unwrap()
    +            tx.input[1].previous_output,
    +            bitcoin::OutPoint::from_str(
    +                "0f60fdd185542f2c6ea19030b0796051e7772b6026dd5ddccd7a2f93b73e6fc2:0"
    +            )
    +            .unwrap()
             );
             assert_eq!(
    -            tx.input[2].previous_output,
    -            bitcoin::OutPoint::from_str(
    -                "0f60fdd185542f2c6ea19030b0796051e7772b6026dd5ddccd7a2f93b73e6fc2:1"
    -            )
    -            .unwrap()
    +            tx.input[2].previous_output,
    +            bitcoin::OutPoint::from_str(
    +                "0f60fdd185542f2c6ea19030b0796051e7772b6026dd5ddccd7a2f93b73e6fc2:1"
    +            )
    +            .unwrap()
             );
     
    -        assert_eq!(tx.output[0].value, 800);
    -        assert_eq!(tx.output[1].script_pubkey, From::from(vec![0xAA]));
    -        assert_eq!(tx.output[2].script_pubkey, From::from(vec![0xAA, 0xEE]));
    +        assert_eq!(tx.output[0].value, 800);
    +        assert_eq!(tx.output[1].script_pubkey, From::from(vec![0xAA]));
    +        assert_eq!(tx.output[2].script_pubkey, From::from(vec![0xAA, 0xEE]));
         }
     
    -    fn get_test_utxos() -> Vec<LocalUtxo> {
    -        use bitcoin::hashes::Hash;
    +    fn get_test_utxos() -> Vec<LocalUtxo> {
    +        use bitcoin::hashes::Hash;
     
             vec![
    -            LocalUtxo {
    -                outpoint: OutPoint {
    -                    txid: bitcoin::Txid::from_inner([0; 32]),
    -                    vout: 0,
    +            LocalUtxo {
    +                outpoint: OutPoint {
    +                    txid: bitcoin::Txid::from_inner([0; 32]),
    +                    vout: 0,
                     },
    -                txout: Default::default(),
    -                keychain: KeychainKind::External,
    -                is_spent: false,
    +                txout: Default::default(),
    +                keychain: KeychainKind::External,
    +                is_spent: false,
                 },
    -            LocalUtxo {
    -                outpoint: OutPoint {
    -                    txid: bitcoin::Txid::from_inner([0; 32]),
    -                    vout: 1,
    +            LocalUtxo {
    +                outpoint: OutPoint {
    +                    txid: bitcoin::Txid::from_inner([0; 32]),
    +                    vout: 1,
                     },
    -                txout: Default::default(),
    -                keychain: KeychainKind::Internal,
    -                is_spent: false,
    +                txout: Default::default(),
    +                keychain: KeychainKind::Internal,
    +                is_spent: false,
                 },
             ]
         }
     
    -    #[test]
    -    fn test_change_spend_policy_default() {
    -        let change_spend_policy = ChangeSpendPolicy::default();
    -        let filtered = get_test_utxos()
    -            .into_iter()
    -            .filter(|u| change_spend_policy.is_satisfied_by(u))
    -            .count();
    +    #[test]
    +    fn test_change_spend_policy_default() {
    +        let change_spend_policy = ChangeSpendPolicy::default();
    +        let filtered = get_test_utxos()
    +            .into_iter()
    +            .filter(|u| change_spend_policy.is_satisfied_by(u))
    +            .count();
     
    -        assert_eq!(filtered, 2);
    +        assert_eq!(filtered, 2);
         }
     
    -    #[test]
    -    fn test_change_spend_policy_no_internal() {
    -        let change_spend_policy = ChangeSpendPolicy::ChangeForbidden;
    -        let filtered = get_test_utxos()
    -            .into_iter()
    -            .filter(|u| change_spend_policy.is_satisfied_by(u))
    -            .collect::<Vec<_>>();
    +    #[test]
    +    fn test_change_spend_policy_no_internal() {
    +        let change_spend_policy = ChangeSpendPolicy::ChangeForbidden;
    +        let filtered = get_test_utxos()
    +            .into_iter()
    +            .filter(|u| change_spend_policy.is_satisfied_by(u))
    +            .collect::<Vec<_>>();
     
    -        assert_eq!(filtered.len(), 1);
    -        assert_eq!(filtered[0].keychain, KeychainKind::External);
    +        assert_eq!(filtered.len(), 1);
    +        assert_eq!(filtered[0].keychain, KeychainKind::External);
         }
     
    -    #[test]
    -    fn test_change_spend_policy_only_internal() {
    -        let change_spend_policy = ChangeSpendPolicy::OnlyChange;
    -        let filtered = get_test_utxos()
    -            .into_iter()
    -            .filter(|u| change_spend_policy.is_satisfied_by(u))
    -            .collect::<Vec<_>>();
    +    #[test]
    +    fn test_change_spend_policy_only_internal() {
    +        let change_spend_policy = ChangeSpendPolicy::OnlyChange;
    +        let filtered = get_test_utxos()
    +            .into_iter()
    +            .filter(|u| change_spend_policy.is_satisfied_by(u))
    +            .collect::<Vec<_>>();
     
    -        assert_eq!(filtered.len(), 1);
    -        assert_eq!(filtered[0].keychain, KeychainKind::Internal);
    +        assert_eq!(filtered.len(), 1);
    +        assert_eq!(filtered[0].keychain, KeychainKind::Internal);
         }
     
    -    #[test]
    -    fn test_default_tx_version_1() {
    -        let version = Version::default();
    -        assert_eq!(version.0, 1);
    +    #[test]
    +    fn test_default_tx_version_1() {
    +        let version = Version::default();
    +        assert_eq!(version.0, 1);
         }
     }
     
    -
    - \ No newline at end of file +
    \ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/src/bdk/wallet/utils.rs.html b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/src/bdk/wallet/utils.rs.html index 830d2c4276..c4d635112c 100644 --- a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/src/bdk/wallet/utils.rs.html +++ b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/src/bdk/wallet/utils.rs.html @@ -1,372 +1,365 @@ -utils.rs - source - -
      1
    -  2
    -  3
    -  4
    -  5
    -  6
    -  7
    -  8
    -  9
    - 10
    - 11
    - 12
    - 13
    - 14
    - 15
    - 16
    - 17
    - 18
    - 19
    - 20
    - 21
    - 22
    - 23
    - 24
    - 25
    - 26
    - 27
    - 28
    - 29
    - 30
    - 31
    - 32
    - 33
    - 34
    - 35
    - 36
    - 37
    - 38
    - 39
    - 40
    - 41
    - 42
    - 43
    - 44
    - 45
    - 46
    - 47
    - 48
    - 49
    - 50
    - 51
    - 52
    - 53
    - 54
    - 55
    - 56
    - 57
    - 58
    - 59
    - 60
    - 61
    - 62
    - 63
    - 64
    - 65
    - 66
    - 67
    - 68
    - 69
    - 70
    - 71
    - 72
    - 73
    - 74
    - 75
    - 76
    - 77
    - 78
    - 79
    - 80
    - 81
    - 82
    - 83
    - 84
    - 85
    - 86
    - 87
    - 88
    - 89
    - 90
    - 91
    - 92
    - 93
    - 94
    - 95
    - 96
    - 97
    - 98
    - 99
    -100
    -101
    -102
    -103
    -104
    -105
    -106
    -107
    -108
    -109
    -110
    -111
    -112
    -113
    -114
    -115
    -116
    -117
    -118
    -119
    -120
    -121
    -122
    -123
    -124
    -125
    -126
    -127
    -128
    -129
    -130
    -131
    -132
    -133
    -134
    -135
    -136
    -137
    -138
    -139
    -140
    -141
    -142
    -143
    -144
    -145
    -146
    -147
    -148
    -149
    -150
    -151
    -152
    -153
    -154
    -155
    -156
    -157
    -158
    -159
    -160
    -161
    -162
    -163
    -164
    -165
    -166
    -167
    -168
    -169
    -170
    -171
    -172
    -173
    -174
    -175
    -176
    -177
    -178
    -179
    -180
    -181
    -
    // Bitcoin Dev Kit
    -// Written in 2020 by Alekos Filini <alekos.filini@gmail.com>
    -//
    -// Copyright (c) 2020-2021 Bitcoin Dev Kit Developers
    -//
    -// This file is licensed under the Apache License, Version 2.0 <LICENSE-APACHE
    -// or http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
    -// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your option.
    -// You may not use this file except in accordance with one or both of these
    -// licenses.
    +utils.rs - source
    1
    +2
    +3
    +4
    +5
    +6
    +7
    +8
    +9
    +10
    +11
    +12
    +13
    +14
    +15
    +16
    +17
    +18
    +19
    +20
    +21
    +22
    +23
    +24
    +25
    +26
    +27
    +28
    +29
    +30
    +31
    +32
    +33
    +34
    +35
    +36
    +37
    +38
    +39
    +40
    +41
    +42
    +43
    +44
    +45
    +46
    +47
    +48
    +49
    +50
    +51
    +52
    +53
    +54
    +55
    +56
    +57
    +58
    +59
    +60
    +61
    +62
    +63
    +64
    +65
    +66
    +67
    +68
    +69
    +70
    +71
    +72
    +73
    +74
    +75
    +76
    +77
    +78
    +79
    +80
    +81
    +82
    +83
    +84
    +85
    +86
    +87
    +88
    +89
    +90
    +91
    +92
    +93
    +94
    +95
    +96
    +97
    +98
    +99
    +100
    +101
    +102
    +103
    +104
    +105
    +106
    +107
    +108
    +109
    +110
    +111
    +112
    +113
    +114
    +115
    +116
    +117
    +118
    +119
    +120
    +121
    +122
    +123
    +124
    +125
    +126
    +127
    +128
    +129
    +130
    +131
    +132
    +133
    +134
    +135
    +136
    +137
    +138
    +139
    +140
    +141
    +142
    +143
    +144
    +145
    +146
    +147
    +148
    +149
    +150
    +151
    +152
    +153
    +154
    +155
    +156
    +157
    +158
    +159
    +160
    +161
    +162
    +163
    +164
    +165
    +166
    +167
    +168
    +169
    +170
    +171
    +172
    +173
    +174
    +175
    +176
    +177
    +178
    +179
    +180
    +181
    +
    // Bitcoin Dev Kit
    +// Written in 2020 by Alekos Filini <alekos.filini@gmail.com>
    +//
    +// Copyright (c) 2020-2021 Bitcoin Dev Kit Developers
    +//
    +// This file is licensed under the Apache License, Version 2.0 <LICENSE-APACHE
    +// or http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
    +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your option.
    +// You may not use this file except in accordance with one or both of these
    +// licenses.
     
    -use bitcoin::secp256k1::{All, Secp256k1};
    -use bitcoin::{LockTime, Script, Sequence};
    +use bitcoin::secp256k1::{All, Secp256k1};
    +use bitcoin::{LockTime, Script, Sequence};
     
    -use miniscript::{MiniscriptKey, Satisfier, ToPublicKey};
    +use miniscript::{MiniscriptKey, Satisfier, ToPublicKey};
     
    -/// 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
    -// we implement this trait to make sure we don't mess up the comparison with off-by-one like a <
    -// instead of a <= etc.
    -pub trait IsDust {
    -    /// Check whether or not a value is below dust limit
    -    fn is_dust(&self, script: &Script) -> bool;
    +/// 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
    +// we implement this trait to make sure we don't mess up the comparison with off-by-one like a <
    +// instead of a <= etc.
    +pub trait IsDust {
    +    /// Check whether or not a value is below dust limit
    +    fn is_dust(&self, script: &Script) -> bool;
     }
     
    -impl IsDust for u64 {
    -    fn is_dust(&self, script: &Script) -> bool {
    -        *self < script.dust_value().to_sat()
    +impl IsDust for u64 {
    +    fn is_dust(&self, script: &Script) -> bool {
    +        *self < script.dust_value().to_sat()
         }
     }
     
    -pub struct After {
    -    pub current_height: Option<u32>,
    -    pub assume_height_reached: bool,
    +pub struct After {
    +    pub current_height: Option<u32>,
    +    pub assume_height_reached: bool,
     }
     
    -impl After {
    -    pub(crate) fn new(current_height: Option<u32>, assume_height_reached: bool) -> After {
    -        After {
    -            current_height,
    -            assume_height_reached,
    +impl After {
    +    pub(crate) fn new(current_height: Option<u32>, assume_height_reached: bool) -> After {
    +        After {
    +            current_height,
    +            assume_height_reached,
             }
         }
     }
     
    -pub(crate) fn check_nsequence_rbf(rbf: Sequence, csv: Sequence) -> bool {
    -    // The RBF value must enable relative timelocks
    -    if !rbf.is_relative_lock_time() {
    -        return false;
    +pub(crate) fn check_nsequence_rbf(rbf: Sequence, csv: Sequence) -> bool {
    +    // The RBF value must enable relative timelocks
    +    if !rbf.is_relative_lock_time() {
    +        return false;
         }
     
    -    // Both values should be represented in the same unit (either time-based or
    -    // block-height based)
    -    if rbf.is_time_locked() != csv.is_time_locked() {
    -        return false;
    +    // Both values should be represented in the same unit (either time-based or
    +    // block-height based)
    +    if rbf.is_time_locked() != csv.is_time_locked() {
    +        return false;
         }
     
    -    // The value should be at least `csv`
    -    if rbf < csv {
    -        return false;
    +    // The value should be at least `csv`
    +    if rbf < csv {
    +        return false;
         }
     
    -    true
    -}
    +    true
    +}
     
    -impl<Pk: MiniscriptKey + ToPublicKey> Satisfier<Pk> for After {
    -    fn check_after(&self, n: LockTime) -> bool {
    -        if let Some(current_height) = self.current_height {
    -            current_height >= n.to_consensus_u32()
    -        } else {
    -            self.assume_height_reached
    +impl<Pk: MiniscriptKey + ToPublicKey> Satisfier<Pk> for After {
    +    fn check_after(&self, n: LockTime) -> bool {
    +        if let Some(current_height) = self.current_height {
    +            current_height >= n.to_consensus_u32()
    +        } else {
    +            self.assume_height_reached
             }
         }
     }
     
    -pub struct Older {
    -    pub current_height: Option<u32>,
    -    pub create_height: Option<u32>,
    -    pub assume_height_reached: bool,
    +pub struct Older {
    +    pub current_height: Option<u32>,
    +    pub create_height: Option<u32>,
    +    pub assume_height_reached: bool,
     }
     
    -impl Older {
    -    pub(crate) fn new(
    -        current_height: Option<u32>,
    -        create_height: Option<u32>,
    -        assume_height_reached: bool,
    -    ) -> Older {
    -        Older {
    -            current_height,
    -            create_height,
    -            assume_height_reached,
    +impl Older {
    +    pub(crate) fn new(
    +        current_height: Option<u32>,
    +        create_height: Option<u32>,
    +        assume_height_reached: bool,
    +    ) -> Older {
    +        Older {
    +            current_height,
    +            create_height,
    +            assume_height_reached,
             }
         }
     }
     
    -impl<Pk: MiniscriptKey + ToPublicKey> Satisfier<Pk> for Older {
    -    fn check_older(&self, n: Sequence) -> bool {
    -        if let Some(current_height) = self.current_height {
    -            // TODO: test >= / >
    -            current_height
    -                >= self
    -                    .create_height
    -                    .unwrap_or(0)
    -                    .checked_add(n.to_consensus_u32())
    -                    .expect("Overflowing addition")
    -        } else {
    -            self.assume_height_reached
    +impl<Pk: MiniscriptKey + ToPublicKey> Satisfier<Pk> for Older {
    +    fn check_older(&self, n: Sequence) -> bool {
    +        if let Some(current_height) = self.current_height {
    +            // TODO: test >= / >
    +            current_height
    +                >= self
    +                    .create_height
    +                    .unwrap_or(0)
    +                    .checked_add(n.to_consensus_u32())
    +                    .expect("Overflowing addition")
    +        } else {
    +            self.assume_height_reached
             }
         }
     }
     
    -pub(crate) type SecpCtx = Secp256k1<All>;
    +pub(crate) type SecpCtx = Secp256k1<All>;
     
    -#[cfg(test)]
    -mod test {
    -    // When nSequence is lower than this flag the timelock is interpreted as block-height-based,
    -    // otherwise it's time-based
    -    pub(crate) const SEQUENCE_LOCKTIME_TYPE_FLAG: u32 = 1 << 22;
    +#[cfg(test)]
    +mod test {
    +    // When nSequence is lower than this flag the timelock is interpreted as block-height-based,
    +    // otherwise it's time-based
    +    pub(crate) const SEQUENCE_LOCKTIME_TYPE_FLAG: u32 = 1 << 22;
     
    -    use super::{check_nsequence_rbf, IsDust};
    -    use crate::bitcoin::{Address, Sequence};
    -    use std::str::FromStr;
    +    use super::{check_nsequence_rbf, IsDust};
    +    use crate::bitcoin::{Address, Sequence};
    +    use std::str::FromStr;
     
    -    #[test]
    -    fn test_is_dust() {
    -        let script_p2pkh = Address::from_str("1GNgwA8JfG7Kc8akJ8opdNWJUihqUztfPe")
    -            .unwrap()
    -            .script_pubkey();
    -        assert!(script_p2pkh.is_p2pkh());
    -        assert!(545.is_dust(&script_p2pkh));
    -        assert!(!546.is_dust(&script_p2pkh));
    +    #[test]
    +    fn test_is_dust() {
    +        let script_p2pkh = Address::from_str("1GNgwA8JfG7Kc8akJ8opdNWJUihqUztfPe")
    +            .unwrap()
    +            .script_pubkey();
    +        assert!(script_p2pkh.is_p2pkh());
    +        assert!(545.is_dust(&script_p2pkh));
    +        assert!(!546.is_dust(&script_p2pkh));
     
    -        let script_p2wpkh = Address::from_str("bc1qxlh2mnc0yqwas76gqq665qkggee5m98t8yskd8")
    -            .unwrap()
    -            .script_pubkey();
    -        assert!(script_p2wpkh.is_v0_p2wpkh());
    -        assert!(293.is_dust(&script_p2wpkh));
    -        assert!(!294.is_dust(&script_p2wpkh));
    +        let script_p2wpkh = Address::from_str("bc1qxlh2mnc0yqwas76gqq665qkggee5m98t8yskd8")
    +            .unwrap()
    +            .script_pubkey();
    +        assert!(script_p2wpkh.is_v0_p2wpkh());
    +        assert!(293.is_dust(&script_p2wpkh));
    +        assert!(!294.is_dust(&script_p2wpkh));
         }
     
    -    #[test]
    -    fn test_check_nsequence_rbf_msb_set() {
    -        let result = check_nsequence_rbf(Sequence(0x80000000), Sequence(5000));
    -        assert!(!result);
    +    #[test]
    +    fn test_check_nsequence_rbf_msb_set() {
    +        let result = check_nsequence_rbf(Sequence(0x80000000), Sequence(5000));
    +        assert!(!result);
         }
     
    -    #[test]
    -    fn test_check_nsequence_rbf_lt_csv() {
    -        let result = check_nsequence_rbf(Sequence(4000), Sequence(5000));
    -        assert!(!result);
    +    #[test]
    +    fn test_check_nsequence_rbf_lt_csv() {
    +        let result = check_nsequence_rbf(Sequence(4000), Sequence(5000));
    +        assert!(!result);
         }
     
    -    #[test]
    -    fn test_check_nsequence_rbf_different_unit() {
    -        let result =
    -            check_nsequence_rbf(Sequence(SEQUENCE_LOCKTIME_TYPE_FLAG + 5000), Sequence(5000));
    -        assert!(!result);
    +    #[test]
    +    fn test_check_nsequence_rbf_different_unit() {
    +        let result =
    +            check_nsequence_rbf(Sequence(SEQUENCE_LOCKTIME_TYPE_FLAG + 5000), Sequence(5000));
    +        assert!(!result);
         }
     
    -    #[test]
    -    fn test_check_nsequence_rbf_mask() {
    -        let result = check_nsequence_rbf(Sequence(0x3f + 10_000), Sequence(5000));
    -        assert!(result);
    +    #[test]
    +    fn test_check_nsequence_rbf_mask() {
    +        let result = check_nsequence_rbf(Sequence(0x3f + 10_000), Sequence(5000));
    +        assert!(result);
         }
     
    -    #[test]
    -    fn test_check_nsequence_rbf_same_unit_blocks() {
    -        let result = check_nsequence_rbf(Sequence(10_000), Sequence(5000));
    -        assert!(result);
    +    #[test]
    +    fn test_check_nsequence_rbf_same_unit_blocks() {
    +        let result = check_nsequence_rbf(Sequence(10_000), Sequence(5000));
    +        assert!(result);
         }
     
    -    #[test]
    -    fn test_check_nsequence_rbf_same_unit_time() {
    -        let result = check_nsequence_rbf(
    -            Sequence(SEQUENCE_LOCKTIME_TYPE_FLAG + 10_000),
    -            Sequence(SEQUENCE_LOCKTIME_TYPE_FLAG + 5000),
    +    #[test]
    +    fn test_check_nsequence_rbf_same_unit_time() {
    +        let result = check_nsequence_rbf(
    +            Sequence(SEQUENCE_LOCKTIME_TYPE_FLAG + 10_000),
    +            Sequence(SEQUENCE_LOCKTIME_TYPE_FLAG + 5000),
             );
    -        assert!(result);
    +        assert!(result);
         }
     }
     
    -
    - \ No newline at end of file +
    \ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/src/bdk/wallet/verify.rs.html b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/src/bdk/wallet/verify.rs.html index 1c8bc735b0..95731792b9 100644 --- a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/src/bdk/wallet/verify.rs.html +++ b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/src/bdk/wallet/verify.rs.html @@ -1,334 +1,327 @@ -verify.rs - source - -
      1
    -  2
    -  3
    -  4
    -  5
    -  6
    -  7
    -  8
    -  9
    - 10
    - 11
    - 12
    - 13
    - 14
    - 15
    - 16
    - 17
    - 18
    - 19
    - 20
    - 21
    - 22
    - 23
    - 24
    - 25
    - 26
    - 27
    - 28
    - 29
    - 30
    - 31
    - 32
    - 33
    - 34
    - 35
    - 36
    - 37
    - 38
    - 39
    - 40
    - 41
    - 42
    - 43
    - 44
    - 45
    - 46
    - 47
    - 48
    - 49
    - 50
    - 51
    - 52
    - 53
    - 54
    - 55
    - 56
    - 57
    - 58
    - 59
    - 60
    - 61
    - 62
    - 63
    - 64
    - 65
    - 66
    - 67
    - 68
    - 69
    - 70
    - 71
    - 72
    - 73
    - 74
    - 75
    - 76
    - 77
    - 78
    - 79
    - 80
    - 81
    - 82
    - 83
    - 84
    - 85
    - 86
    - 87
    - 88
    - 89
    - 90
    - 91
    - 92
    - 93
    - 94
    - 95
    - 96
    - 97
    - 98
    - 99
    -100
    -101
    -102
    -103
    -104
    -105
    -106
    -107
    -108
    -109
    -110
    -111
    -112
    -113
    -114
    -115
    -116
    -117
    -118
    -119
    -120
    -121
    -122
    -123
    -124
    -125
    -126
    -127
    -128
    -129
    -130
    -131
    -132
    -133
    -134
    -135
    -136
    -137
    -138
    -139
    -140
    -141
    -142
    -143
    -144
    -145
    -146
    -147
    -148
    -149
    -150
    -151
    -152
    -153
    -154
    -155
    -156
    -157
    -158
    -159
    -160
    -161
    -162
    -
    // Bitcoin Dev Kit
    -// Written in 2021 by Alekos Filini <alekos.filini@gmail.com>
    -//
    -// Copyright (c) 2020-2021 Bitcoin Dev Kit Developers
    -//
    -// This file is licensed under the Apache License, Version 2.0 <LICENSE-APACHE
    -// or http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
    -// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your option.
    -// You may not use this file except in accordance with one or both of these
    -// licenses.
    +verify.rs - source
    1
    +2
    +3
    +4
    +5
    +6
    +7
    +8
    +9
    +10
    +11
    +12
    +13
    +14
    +15
    +16
    +17
    +18
    +19
    +20
    +21
    +22
    +23
    +24
    +25
    +26
    +27
    +28
    +29
    +30
    +31
    +32
    +33
    +34
    +35
    +36
    +37
    +38
    +39
    +40
    +41
    +42
    +43
    +44
    +45
    +46
    +47
    +48
    +49
    +50
    +51
    +52
    +53
    +54
    +55
    +56
    +57
    +58
    +59
    +60
    +61
    +62
    +63
    +64
    +65
    +66
    +67
    +68
    +69
    +70
    +71
    +72
    +73
    +74
    +75
    +76
    +77
    +78
    +79
    +80
    +81
    +82
    +83
    +84
    +85
    +86
    +87
    +88
    +89
    +90
    +91
    +92
    +93
    +94
    +95
    +96
    +97
    +98
    +99
    +100
    +101
    +102
    +103
    +104
    +105
    +106
    +107
    +108
    +109
    +110
    +111
    +112
    +113
    +114
    +115
    +116
    +117
    +118
    +119
    +120
    +121
    +122
    +123
    +124
    +125
    +126
    +127
    +128
    +129
    +130
    +131
    +132
    +133
    +134
    +135
    +136
    +137
    +138
    +139
    +140
    +141
    +142
    +143
    +144
    +145
    +146
    +147
    +148
    +149
    +150
    +151
    +152
    +153
    +154
    +155
    +156
    +157
    +158
    +159
    +160
    +161
    +162
    +
    // Bitcoin Dev Kit
    +// Written in 2021 by Alekos Filini <alekos.filini@gmail.com>
    +//
    +// Copyright (c) 2020-2021 Bitcoin Dev Kit Developers
    +//
    +// This file is licensed under the Apache License, Version 2.0 <LICENSE-APACHE
    +// or http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
    +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your option.
    +// You may not use this file except in accordance with one or both of these
    +// licenses.
     
    -//! Verify transactions against the consensus rules
    +//! Verify transactions against the consensus rules
     
    -use std::collections::HashMap;
    -use std::fmt;
    +use std::collections::HashMap;
    +use std::fmt;
     
    -use bitcoin::consensus::serialize;
    -use bitcoin::{OutPoint, Transaction, Txid};
    +use bitcoin::consensus::serialize;
    +use bitcoin::{OutPoint, Transaction, Txid};
     
    -use crate::blockchain::GetTx;
    -use crate::database::Database;
    -use crate::error::Error;
    +use crate::blockchain::GetTx;
    +use crate::database::Database;
    +use crate::error::Error;
     
    -/// Verify a transaction against the consensus rules
    -///
    -/// This function uses [`bitcoinconsensus`] to verify transactions by fetching the required data
    -/// either from the [`Database`] or using the [`Blockchain`].
    -///
    -/// Depending on the [capabilities](crate::blockchain::Blockchain::get_capabilities) of the
    -/// [`Blockchain`] backend, the method could fail when called with old "historical" transactions or
    -/// with unconfirmed transactions that have been evicted from the backend's memory.
    -///
    -/// [`Blockchain`]: crate::blockchain::Blockchain
    -pub fn verify_tx<D: Database, B: GetTx>(
    -    tx: &Transaction,
    -    database: &D,
    -    blockchain: &B,
    -) -> Result<(), VerifyError> {
    -    log::debug!("Verifying {}", tx.txid());
    +/// Verify a transaction against the consensus rules
    +///
    +/// This function uses [`bitcoinconsensus`] to verify transactions by fetching the required data
    +/// either from the [`Database`] or using the [`Blockchain`].
    +///
    +/// Depending on the [capabilities](crate::blockchain::Blockchain::get_capabilities) of the
    +/// [`Blockchain`] backend, the method could fail when called with old "historical" transactions or
    +/// with unconfirmed transactions that have been evicted from the backend's memory.
    +///
    +/// [`Blockchain`]: crate::blockchain::Blockchain
    +pub fn verify_tx<D: Database, B: GetTx>(
    +    tx: &Transaction,
    +    database: &D,
    +    blockchain: &B,
    +) -> Result<(), VerifyError> {
    +    log::debug!("Verifying {}", tx.txid());
     
    -    let serialized_tx = serialize(tx);
    -    let mut tx_cache = HashMap::<_, Transaction>::new();
    +    let serialized_tx = serialize(tx);
    +    let mut tx_cache = HashMap::<_, Transaction>::new();
     
    -    for (index, input) in tx.input.iter().enumerate() {
    -        let prev_tx = if let Some(prev_tx) = tx_cache.get(&input.previous_output.txid) {
    -            prev_tx.clone()
    -        } else if let Some(prev_tx) = database.get_raw_tx(&input.previous_output.txid)? {
    -            prev_tx
    -        } else if let Some(prev_tx) = blockchain.get_tx(&input.previous_output.txid)? {
    -            prev_tx
    -        } else {
    -            return Err(VerifyError::MissingInputTx(input.previous_output.txid));
    +    for (index, input) in tx.input.iter().enumerate() {
    +        let prev_tx = if let Some(prev_tx) = tx_cache.get(&input.previous_output.txid) {
    +            prev_tx.clone()
    +        } else if let Some(prev_tx) = database.get_raw_tx(&input.previous_output.txid)? {
    +            prev_tx
    +        } else if let Some(prev_tx) = blockchain.get_tx(&input.previous_output.txid)? {
    +            prev_tx
    +        } else {
    +            return Err(VerifyError::MissingInputTx(input.previous_output.txid));
             };
     
    -        let spent_output = prev_tx
    -            .output
    -            .get(input.previous_output.vout as usize)
    -            .ok_or(VerifyError::InvalidInput(input.previous_output))?;
    +        let spent_output = prev_tx
    +            .output
    +            .get(input.previous_output.vout as usize)
    +            .ok_or(VerifyError::InvalidInput(input.previous_output))?;
     
    -        bitcoinconsensus::verify(
    -            &spent_output.script_pubkey.to_bytes(),
    -            spent_output.value,
    -            &serialized_tx,
    -            index,
    +        bitcoinconsensus::verify(
    +            &spent_output.script_pubkey.to_bytes(),
    +            spent_output.value,
    +            &serialized_tx,
    +            index,
             )?;
     
    -        // Since we have a local cache we might as well cache stuff from the db, as it will very
    -        // likely decrease latency compared to reading from disk or performing an SQL query.
    -        tx_cache.insert(prev_tx.txid(), prev_tx);
    +        // Since we have a local cache we might as well cache stuff from the db, as it will very
    +        // likely decrease latency compared to reading from disk or performing an SQL query.
    +        tx_cache.insert(prev_tx.txid(), prev_tx);
         }
     
         Ok(())
     }
     
    -/// Error during validation of a tx agains the consensus rules
    -#[derive(Debug)]
    -pub enum VerifyError {
    -    /// The transaction being spent is not available in the database or the blockchain client
    -    MissingInputTx(Txid),
    -    /// The transaction being spent doesn't have the requested output
    -    InvalidInput(OutPoint),
    +/// Error during validation of a tx agains the consensus rules
    +#[derive(Debug)]
    +pub enum VerifyError {
    +    /// The transaction being spent is not available in the database or the blockchain client
    +    MissingInputTx(Txid),
    +    /// The transaction being spent doesn't have the requested output
    +    InvalidInput(OutPoint),
     
    -    /// Consensus error
    -    Consensus(bitcoinconsensus::Error),
    +    /// Consensus error
    +    Consensus(bitcoinconsensus::Error),
     
    -    /// Generic error
    -    ///
    -    /// It has to be wrapped in a `Box` since `Error` has a variant that contains this enum
    -    Global(Box<Error>),
    +    /// Generic error
    +    ///
    +    /// It has to be wrapped in a `Box` since `Error` has a variant that contains this enum
    +    Global(Box<Error>),
     }
     
    -impl fmt::Display for VerifyError {
    -    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
    -        write!(f, "{:?}", self)
    +impl fmt::Display for VerifyError {
    +    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
    +        write!(f, "{:?}", self)
         }
     }
     
    -impl std::error::Error for VerifyError {}
    +impl std::error::Error for VerifyError {}
     
    -impl From<Error> for VerifyError {
    -    fn from(other: Error) -> Self {
    -        VerifyError::Global(Box::new(other))
    +impl From<Error> for VerifyError {
    +    fn from(other: Error) -> Self {
    +        VerifyError::Global(Box::new(other))
         }
     }
    -impl_error!(bitcoinconsensus::Error, Consensus, VerifyError);
    +impl_error!(bitcoinconsensus::Error, Consensus, VerifyError);
     
    -#[cfg(test)]
    -mod test {
    -    use super::*;
    -    use crate::database::{BatchOperations, MemoryDatabase};
    -    use bitcoin::consensus::encode::deserialize;
    -    use bitcoin::hashes::hex::FromHex;
    -    use bitcoin::{Transaction, Txid};
    +#[cfg(test)]
    +mod test {
    +    use super::*;
    +    use crate::database::{BatchOperations, MemoryDatabase};
    +    use bitcoin::consensus::encode::deserialize;
    +    use bitcoin::hashes::hex::FromHex;
    +    use bitcoin::{Transaction, Txid};
     
    -    struct DummyBlockchain;
    +    struct DummyBlockchain;
     
    -    impl GetTx for DummyBlockchain {
    -        fn get_tx(&self, _txid: &Txid) -> Result<Option<Transaction>, Error> {
    +    impl GetTx for DummyBlockchain {
    +        fn get_tx(&self, _txid: &Txid) -> Result<Option<Transaction>, Error> {
                 Ok(None)
             }
         }
     
    -    #[test]
    -    fn test_verify_fail_unsigned_tx() {
    -        // https://blockstream.info/tx/95da344585fcf2e5f7d6cbf2c3df2dcce84f9196f7a7bb901a43275cd6eb7c3f
    -        let prev_tx: Transaction = deserialize(&Vec::<u8>::from_hex("020000000101192dea5e66d444380e106f8e53acb171703f00d43fb6b3ae88ca5644bdb7e1000000006b48304502210098328d026ce138411f957966c1cf7f7597ccbb170f5d5655ee3e9f47b18f6999022017c3526fc9147830e1340e04934476a3d1521af5b4de4e98baf49ec4c072079e01210276f847f77ec8dd66d78affd3c318a0ed26d89dab33fa143333c207402fcec352feffffff023d0ac203000000001976a9144bfbaf6afb76cc5771bc6404810d1cc041a6933988aca4b956050000000017a91494d5543c74a3ee98e0cf8e8caef5dc813a0f34b48768cb0700").unwrap()).unwrap();
    -        // https://blockstream.info/tx/aca326a724eda9a461c10a876534ecd5ae7b27f10f26c3862fb996f80ea2d45d
    -        let signed_tx: Transaction = deserialize(&Vec::<u8>::from_hex("02000000013f7cebd65c27431a90bba7f796914fe8cc2ddfc3f2cbd6f7e5f2fc854534da95000000006b483045022100de1ac3bcdfb0332207c4a91f3832bd2c2915840165f876ab47c5f8996b971c3602201c6c053d750fadde599e6f5c4e1963df0f01fc0d97815e8157e3d59fe09ca30d012103699b464d1d8bc9e47d4fb1cdaa89a1c5783d68363c4dbc4b524ed3d857148617feffffff02836d3c01000000001976a914fc25d6d5c94003bf5b0c7b640a248e2c637fcfb088ac7ada8202000000001976a914fbed3d9b11183209a57999d54d59f67c019e756c88ac6acb0700").unwrap()).unwrap();
    +    #[test]
    +    fn test_verify_fail_unsigned_tx() {
    +        // https://blockstream.info/tx/95da344585fcf2e5f7d6cbf2c3df2dcce84f9196f7a7bb901a43275cd6eb7c3f
    +        let prev_tx: Transaction = deserialize(&Vec::<u8>::from_hex("020000000101192dea5e66d444380e106f8e53acb171703f00d43fb6b3ae88ca5644bdb7e1000000006b48304502210098328d026ce138411f957966c1cf7f7597ccbb170f5d5655ee3e9f47b18f6999022017c3526fc9147830e1340e04934476a3d1521af5b4de4e98baf49ec4c072079e01210276f847f77ec8dd66d78affd3c318a0ed26d89dab33fa143333c207402fcec352feffffff023d0ac203000000001976a9144bfbaf6afb76cc5771bc6404810d1cc041a6933988aca4b956050000000017a91494d5543c74a3ee98e0cf8e8caef5dc813a0f34b48768cb0700").unwrap()).unwrap();
    +        // https://blockstream.info/tx/aca326a724eda9a461c10a876534ecd5ae7b27f10f26c3862fb996f80ea2d45d
    +        let signed_tx: Transaction = deserialize(&Vec::<u8>::from_hex("02000000013f7cebd65c27431a90bba7f796914fe8cc2ddfc3f2cbd6f7e5f2fc854534da95000000006b483045022100de1ac3bcdfb0332207c4a91f3832bd2c2915840165f876ab47c5f8996b971c3602201c6c053d750fadde599e6f5c4e1963df0f01fc0d97815e8157e3d59fe09ca30d012103699b464d1d8bc9e47d4fb1cdaa89a1c5783d68363c4dbc4b524ed3d857148617feffffff02836d3c01000000001976a914fc25d6d5c94003bf5b0c7b640a248e2c637fcfb088ac7ada8202000000001976a914fbed3d9b11183209a57999d54d59f67c019e756c88ac6acb0700").unwrap()).unwrap();
     
    -        let mut database = MemoryDatabase::new();
    -        let blockchain = DummyBlockchain;
    +        let mut database = MemoryDatabase::new();
    +        let blockchain = DummyBlockchain;
     
    -        let mut unsigned_tx = signed_tx.clone();
    -        for input in &mut unsigned_tx.input {
    -            input.script_sig = Default::default();
    -            input.witness = Default::default();
    +        let mut unsigned_tx = signed_tx.clone();
    +        for input in &mut unsigned_tx.input {
    +            input.script_sig = Default::default();
    +            input.witness = Default::default();
             }
     
    -        let result = verify_tx(&signed_tx, &database, &blockchain);
    -        assert!(result.is_err(), "Should fail with missing input tx");
    +        let result = verify_tx(&signed_tx, &database, &blockchain);
    +        assert!(result.is_err(), "Should fail with missing input tx");
             assert!(
    -            matches!(result, Err(VerifyError::MissingInputTx(txid)) if txid == prev_tx.txid()),
    -            "Error should be a `MissingInputTx` error"
    -        );
    +            matches!(result, Err(VerifyError::MissingInputTx(txid)) if txid == prev_tx.txid()),
    +            "Error should be a `MissingInputTx` error"
    +        );
     
    -        // insert the prev_tx
    -        database.set_raw_tx(&prev_tx).unwrap();
    +        // insert the prev_tx
    +        database.set_raw_tx(&prev_tx).unwrap();
     
    -        let result = verify_tx(&unsigned_tx, &database, &blockchain);
    -        assert!(result.is_err(), "Should fail since the TX is unsigned");
    +        let result = verify_tx(&unsigned_tx, &database, &blockchain);
    +        assert!(result.is_err(), "Should fail since the TX is unsigned");
             assert!(
    -            matches!(result, Err(VerifyError::Consensus(_))),
    -            "Error should be a `Consensus` error"
    -        );
    +            matches!(result, Err(VerifyError::Consensus(_))),
    +            "Error should be a `Consensus` error"
    +        );
     
    -        let result = verify_tx(&signed_tx, &database, &blockchain);
    +        let result = verify_tx(&signed_tx, &database, &blockchain);
             assert!(
    -            result.is_ok(),
    -            "Should work since the TX is correctly signed"
    -        );
    +            result.is_ok(),
    +            "Should work since the TX is correctly signed"
    +        );
         }
     }
     
    -
    - \ No newline at end of file +
    \ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/static.files/COPYRIGHT-002d5dd09d9a4f50.txt b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/static.files/COPYRIGHT-002d5dd09d9a4f50.txt new file mode 100644 index 0000000000..34e48134cc --- /dev/null +++ b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/static.files/COPYRIGHT-002d5dd09d9a4f50.txt @@ -0,0 +1,46 @@ +These documentation pages include resources by third parties. This copyright +file applies only to those resources. The following third party resources are +included, and carry their own copyright notices and license terms: + +* Fira Sans (FiraSans-Regular.woff2, FiraSans-Medium.woff2): + + Copyright (c) 2014, Mozilla Foundation https://mozilla.org/ + with Reserved Font Name Fira Sans. + + Copyright (c) 2014, Telefonica S.A. + + Licensed under the SIL Open Font License, Version 1.1. + See FiraSans-LICENSE.txt. + +* rustdoc.css, main.js, and playpen.js: + + Copyright 2015 The Rust Developers. + Licensed under the Apache License, Version 2.0 (see LICENSE-APACHE.txt) or + the MIT license (LICENSE-MIT.txt) at your option. + +* normalize.css: + + Copyright (c) Nicolas Gallagher and Jonathan Neal. + Licensed under the MIT license (see LICENSE-MIT.txt). + +* Source Code Pro (SourceCodePro-Regular.ttf.woff2, + SourceCodePro-Semibold.ttf.woff2, SourceCodePro-It.ttf.woff2): + + Copyright 2010, 2012 Adobe Systems Incorporated (http://www.adobe.com/), + with Reserved Font Name 'Source'. All Rights Reserved. Source is a trademark + of Adobe Systems Incorporated in the United States and/or other countries. + + Licensed under the SIL Open Font License, Version 1.1. + See SourceCodePro-LICENSE.txt. + +* Source Serif 4 (SourceSerif4-Regular.ttf.woff2, SourceSerif4-Bold.ttf.woff2, + SourceSerif4-It.ttf.woff2): + + Copyright 2014-2021 Adobe (http://www.adobe.com/), with Reserved Font Name + 'Source'. All Rights Reserved. Source is a trademark of Adobe in the United + States and/or other countries. + + Licensed under the SIL Open Font License, Version 1.1. + See SourceSerif4-LICENSE.md. + +This copyright file is intended to be distributed with rustdoc output. diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/static.files/FiraSans-LICENSE-1761dca11ffc8f19.txt b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/static.files/FiraSans-LICENSE-1761dca11ffc8f19.txt new file mode 100644 index 0000000000..ff9afab064 --- /dev/null +++ b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/static.files/FiraSans-LICENSE-1761dca11ffc8f19.txt @@ -0,0 +1,94 @@ +Digitized data copyright (c) 2012-2015, The Mozilla Foundation and Telefonica S.A. +with Reserved Font Name < Fira >, + +This Font Software is licensed under the SIL Open Font License, Version 1.1. +This license is copied below, and is also available with a FAQ at: +http://scripts.sil.org/OFL + + +----------------------------------------------------------- +SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007 +----------------------------------------------------------- + +PREAMBLE +The goals of the Open Font License (OFL) are to stimulate worldwide +development of collaborative font projects, to support the font creation +efforts of academic and linguistic communities, and to provide a free and +open framework in which fonts may be shared and improved in partnership +with others. + +The OFL allows the licensed fonts to be used, studied, modified and +redistributed freely as long as they are not sold by themselves. The +fonts, including any derivative works, can be bundled, embedded, +redistributed and/or sold with any software provided that any reserved +names are not used by derivative works. The fonts and derivatives, +however, cannot be released under any other type of license. The +requirement for fonts to remain under this license does not apply +to any document created using the fonts or their derivatives. + +DEFINITIONS +"Font Software" refers to the set of files released by the Copyright +Holder(s) under this license and clearly marked as such. This may +include source files, build scripts and documentation. + +"Reserved Font Name" refers to any names specified as such after the +copyright statement(s). + +"Original Version" refers to the collection of Font Software components as +distributed by the Copyright Holder(s). + +"Modified Version" refers to any derivative made by adding to, deleting, +or substituting -- in part or in whole -- any of the components of the +Original Version, by changing formats or by porting the Font Software to a +new environment. + +"Author" refers to any designer, engineer, programmer, technical +writer or other person who contributed to the Font Software. + +PERMISSION & CONDITIONS +Permission is hereby granted, free of charge, to any person obtaining +a copy of the Font Software, to use, study, copy, merge, embed, modify, +redistribute, and sell modified and unmodified copies of the Font +Software, subject to the following conditions: + +1) Neither the Font Software nor any of its individual components, +in Original or Modified Versions, may be sold by itself. + +2) Original or Modified Versions of the Font Software may be bundled, +redistributed and/or sold with any software, provided that each copy +contains the above copyright notice and this license. These can be +included either as stand-alone text files, human-readable headers or +in the appropriate machine-readable metadata fields within text or +binary files as long as those fields can be easily viewed by the user. + +3) No Modified Version of the Font Software may use the Reserved Font +Name(s) unless explicit written permission is granted by the corresponding +Copyright Holder. This restriction only applies to the primary font name as +presented to the users. + +4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font +Software shall not be used to promote, endorse or advertise any +Modified Version, except to acknowledge the contribution(s) of the +Copyright Holder(s) and the Author(s) or with their explicit written +permission. + +5) The Font Software, modified or unmodified, in part or in whole, +must be distributed entirely under this license, and must not be +distributed under any other license. The requirement for fonts to +remain under this license does not apply to any document created +using the Font Software. + +TERMINATION +This license becomes null and void if any of the above conditions are +not met. + +DISCLAIMER +THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT +OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE +COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM +OTHER DEALINGS IN THE FONT SOFTWARE. diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/static.files/FiraSans-Medium-8f9a781e4970d388.woff2 b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/static.files/FiraSans-Medium-8f9a781e4970d388.woff2 new file mode 100644 index 0000000000..7a1e5fc548 Binary files /dev/null and b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/static.files/FiraSans-Medium-8f9a781e4970d388.woff2 differ diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/static.files/FiraSans-Regular-018c141bf0843ffd.woff2 b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/static.files/FiraSans-Regular-018c141bf0843ffd.woff2 new file mode 100644 index 0000000000..e766e06ccb Binary files /dev/null and b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/static.files/FiraSans-Regular-018c141bf0843ffd.woff2 differ diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/static.files/LICENSE-APACHE-b91fa81cba47b86a.txt b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/static.files/LICENSE-APACHE-b91fa81cba47b86a.txt new file mode 100644 index 0000000000..16fe87b06e --- /dev/null +++ b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/static.files/LICENSE-APACHE-b91fa81cba47b86a.txt @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + +TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + +1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + +2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + +3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + +4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + +5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + +6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + +7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + +8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + +9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + +END OF TERMS AND CONDITIONS + +APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + +Copyright [yyyy] [name of copyright owner] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/static.files/LICENSE-MIT-65090b722b3f6c56.txt b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/static.files/LICENSE-MIT-65090b722b3f6c56.txt new file mode 100644 index 0000000000..31aa79387f --- /dev/null +++ b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/static.files/LICENSE-MIT-65090b722b3f6c56.txt @@ -0,0 +1,23 @@ +Permission is hereby granted, free of charge, to any +person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the +Software without restriction, including without +limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software +is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice +shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT +SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR +IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/static.files/NanumBarunGothic-0f09457c7a19b7c6.ttf.woff2 b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/static.files/NanumBarunGothic-0f09457c7a19b7c6.ttf.woff2 new file mode 100644 index 0000000000..1866ad4bce Binary files /dev/null and b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/static.files/NanumBarunGothic-0f09457c7a19b7c6.ttf.woff2 differ diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/static.files/NanumBarunGothic-LICENSE-2fe9ce67ec95245d.txt b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/static.files/NanumBarunGothic-LICENSE-2fe9ce67ec95245d.txt new file mode 100644 index 0000000000..0bf46682b5 --- /dev/null +++ b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/static.files/NanumBarunGothic-LICENSE-2fe9ce67ec95245d.txt @@ -0,0 +1,99 @@ +Copyright (c) 2010, NAVER Corporation (https://www.navercorp.com/), + +with Reserved Font Name Nanum, Naver Nanum, NanumGothic, Naver NanumGothic, +NanumMyeongjo, Naver NanumMyeongjo, NanumBrush, Naver NanumBrush, NanumPen, +Naver NanumPen, Naver NanumGothicEco, NanumGothicEco, Naver NanumMyeongjoEco, +NanumMyeongjoEco, Naver NanumGothicLight, NanumGothicLight, NanumBarunGothic, +Naver NanumBarunGothic, NanumSquareRound, NanumBarunPen, MaruBuri + +This Font Software is licensed under the SIL Open Font License, Version 1.1. +This license is copied below, and is also available with a FAQ at: +http://scripts.sil.org/OFL + + +----------------------------------------------------------- +SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007 +----------------------------------------------------------- + +PREAMBLE +The goals of the Open Font License (OFL) are to stimulate worldwide +development of collaborative font projects, to support the font creation +efforts of academic and linguistic communities, and to provide a free and +open framework in which fonts may be shared and improved in partnership +with others. + +The OFL allows the licensed fonts to be used, studied, modified and +redistributed freely as long as they are not sold by themselves. The +fonts, including any derivative works, can be bundled, embedded, +redistributed and/or sold with any software provided that any reserved +names are not used by derivative works. The fonts and derivatives, +however, cannot be released under any other type of license. The +requirement for fonts to remain under this license does not apply +to any document created using the fonts or their derivatives. + +DEFINITIONS +"Font Software" refers to the set of files released by the Copyright +Holder(s) under this license and clearly marked as such. This may +include source files, build scripts and documentation. + +"Reserved Font Name" refers to any names specified as such after the +copyright statement(s). + +"Original Version" refers to the collection of Font Software components as +distributed by the Copyright Holder(s). + +"Modified Version" refers to any derivative made by adding to, deleting, +or substituting -- in part or in whole -- any of the components of the +Original Version, by changing formats or by porting the Font Software to a +new environment. + +"Author" refers to any designer, engineer, programmer, technical +writer or other person who contributed to the Font Software. + +PERMISSION & CONDITIONS +Permission is hereby granted, free of charge, to any person obtaining +a copy of the Font Software, to use, study, copy, merge, embed, modify, +redistribute, and sell modified and unmodified copies of the Font +Software, subject to the following conditions: + +1) Neither the Font Software nor any of its individual components, +in Original or Modified Versions, may be sold by itself. + +2) Original or Modified Versions of the Font Software may be bundled, +redistributed and/or sold with any software, provided that each copy +contains the above copyright notice and this license. These can be +included either as stand-alone text files, human-readable headers or +in the appropriate machine-readable metadata fields within text or +binary files as long as those fields can be easily viewed by the user. + +3) No Modified Version of the Font Software may use the Reserved Font +Name(s) unless explicit written permission is granted by the corresponding +Copyright Holder. This restriction only applies to the primary font name as +presented to the users. + +4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font +Software shall not be used to promote, endorse or advertise any +Modified Version, except to acknowledge the contribution(s) of the +Copyright Holder(s) and the Author(s) or with their explicit written +permission. + +5) The Font Software, modified or unmodified, in part or in whole, +must be distributed entirely under this license, and must not be +distributed under any other license. The requirement for fonts to +remain under this license does not apply to any document created +using the Font Software. + +TERMINATION +This license becomes null and void if any of the above conditions are +not met. + +DISCLAIMER +THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT +OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE +COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM +OTHER DEALINGS IN THE FONT SOFTWARE. diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/static.files/SourceCodePro-It-1cc31594bf4f1f79.ttf.woff2 b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/static.files/SourceCodePro-It-1cc31594bf4f1f79.ttf.woff2 new file mode 100644 index 0000000000..462c34efcd Binary files /dev/null and b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/static.files/SourceCodePro-It-1cc31594bf4f1f79.ttf.woff2 differ diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/static.files/SourceCodePro-LICENSE-f554967dca0cf1dd.txt b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/static.files/SourceCodePro-LICENSE-f554967dca0cf1dd.txt new file mode 100644 index 0000000000..07542572e3 --- /dev/null +++ b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/static.files/SourceCodePro-LICENSE-f554967dca0cf1dd.txt @@ -0,0 +1,93 @@ +Copyright 2010, 2012 Adobe Systems Incorporated (http://www.adobe.com/), with Reserved Font Name 'Source'. All Rights Reserved. Source is a trademark of Adobe Systems Incorporated in the United States and/or other countries. + +This Font Software is licensed under the SIL Open Font License, Version 1.1. + +This license is copied below, and is also available with a FAQ at: http://scripts.sil.org/OFL + + +----------------------------------------------------------- +SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007 +----------------------------------------------------------- + +PREAMBLE +The goals of the Open Font License (OFL) are to stimulate worldwide +development of collaborative font projects, to support the font creation +efforts of academic and linguistic communities, and to provide a free and +open framework in which fonts may be shared and improved in partnership +with others. + +The OFL allows the licensed fonts to be used, studied, modified and +redistributed freely as long as they are not sold by themselves. The +fonts, including any derivative works, can be bundled, embedded, +redistributed and/or sold with any software provided that any reserved +names are not used by derivative works. The fonts and derivatives, +however, cannot be released under any other type of license. The +requirement for fonts to remain under this license does not apply +to any document created using the fonts or their derivatives. + +DEFINITIONS +"Font Software" refers to the set of files released by the Copyright +Holder(s) under this license and clearly marked as such. This may +include source files, build scripts and documentation. + +"Reserved Font Name" refers to any names specified as such after the +copyright statement(s). + +"Original Version" refers to the collection of Font Software components as +distributed by the Copyright Holder(s). + +"Modified Version" refers to any derivative made by adding to, deleting, +or substituting -- in part or in whole -- any of the components of the +Original Version, by changing formats or by porting the Font Software to a +new environment. + +"Author" refers to any designer, engineer, programmer, technical +writer or other person who contributed to the Font Software. + +PERMISSION & CONDITIONS +Permission is hereby granted, free of charge, to any person obtaining +a copy of the Font Software, to use, study, copy, merge, embed, modify, +redistribute, and sell modified and unmodified copies of the Font +Software, subject to the following conditions: + +1) Neither the Font Software nor any of its individual components, +in Original or Modified Versions, may be sold by itself. + +2) Original or Modified Versions of the Font Software may be bundled, +redistributed and/or sold with any software, provided that each copy +contains the above copyright notice and this license. These can be +included either as stand-alone text files, human-readable headers or +in the appropriate machine-readable metadata fields within text or +binary files as long as those fields can be easily viewed by the user. + +3) No Modified Version of the Font Software may use the Reserved Font +Name(s) unless explicit written permission is granted by the corresponding +Copyright Holder. This restriction only applies to the primary font name as +presented to the users. + +4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font +Software shall not be used to promote, endorse or advertise any +Modified Version, except to acknowledge the contribution(s) of the +Copyright Holder(s) and the Author(s) or with their explicit written +permission. + +5) The Font Software, modified or unmodified, in part or in whole, +must be distributed entirely under this license, and must not be +distributed under any other license. The requirement for fonts to +remain under this license does not apply to any document created +using the Font Software. + +TERMINATION +This license becomes null and void if any of the above conditions are +not met. + +DISCLAIMER +THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT +OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE +COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM +OTHER DEALINGS IN THE FONT SOFTWARE. diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/static.files/SourceCodePro-Regular-562dcc5011b6de7d.ttf.woff2 b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/static.files/SourceCodePro-Regular-562dcc5011b6de7d.ttf.woff2 new file mode 100644 index 0000000000..10b558e0b6 Binary files /dev/null and b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/static.files/SourceCodePro-Regular-562dcc5011b6de7d.ttf.woff2 differ diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/static.files/SourceCodePro-Semibold-d899c5a5c4aeb14a.ttf.woff2 b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/static.files/SourceCodePro-Semibold-d899c5a5c4aeb14a.ttf.woff2 new file mode 100644 index 0000000000..5ec64eef0e Binary files /dev/null and b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/static.files/SourceCodePro-Semibold-d899c5a5c4aeb14a.ttf.woff2 differ diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/static.files/SourceSerif4-Bold-124a1ca42af929b6.ttf.woff2 b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/static.files/SourceSerif4-Bold-124a1ca42af929b6.ttf.woff2 new file mode 100644 index 0000000000..db57d21455 Binary files /dev/null and b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/static.files/SourceSerif4-Bold-124a1ca42af929b6.ttf.woff2 differ diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/static.files/SourceSerif4-It-d034fe4ef9d0fa00.ttf.woff2 b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/static.files/SourceSerif4-It-d034fe4ef9d0fa00.ttf.woff2 new file mode 100644 index 0000000000..1cbc021a3a Binary files /dev/null and b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/static.files/SourceSerif4-It-d034fe4ef9d0fa00.ttf.woff2 differ diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/static.files/SourceSerif4-LICENSE-964d32dc04f20ca3.md b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/static.files/SourceSerif4-LICENSE-964d32dc04f20ca3.md new file mode 100644 index 0000000000..68ea189240 --- /dev/null +++ b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/static.files/SourceSerif4-LICENSE-964d32dc04f20ca3.md @@ -0,0 +1,93 @@ +Copyright 2014-2021 Adobe (http://www.adobe.com/), with Reserved Font Name 'Source'. All Rights Reserved. Source is a trademark of Adobe in the United States and/or other countries. + +This Font Software is licensed under the SIL Open Font License, Version 1.1. + +This license is copied below, and is also available with a FAQ at: http://scripts.sil.org/OFL + + +----------------------------------------------------------- +SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007 +----------------------------------------------------------- + +PREAMBLE +The goals of the Open Font License (OFL) are to stimulate worldwide +development of collaborative font projects, to support the font creation +efforts of academic and linguistic communities, and to provide a free and +open framework in which fonts may be shared and improved in partnership +with others. + +The OFL allows the licensed fonts to be used, studied, modified and +redistributed freely as long as they are not sold by themselves. The +fonts, including any derivative works, can be bundled, embedded, +redistributed and/or sold with any software provided that any reserved +names are not used by derivative works. The fonts and derivatives, +however, cannot be released under any other type of license. The +requirement for fonts to remain under this license does not apply +to any document created using the fonts or their derivatives. + +DEFINITIONS +"Font Software" refers to the set of files released by the Copyright +Holder(s) under this license and clearly marked as such. This may +include source files, build scripts and documentation. + +"Reserved Font Name" refers to any names specified as such after the +copyright statement(s). + +"Original Version" refers to the collection of Font Software components as +distributed by the Copyright Holder(s). + +"Modified Version" refers to any derivative made by adding to, deleting, +or substituting -- in part or in whole -- any of the components of the +Original Version, by changing formats or by porting the Font Software to a +new environment. + +"Author" refers to any designer, engineer, programmer, technical +writer or other person who contributed to the Font Software. + +PERMISSION & CONDITIONS +Permission is hereby granted, free of charge, to any person obtaining +a copy of the Font Software, to use, study, copy, merge, embed, modify, +redistribute, and sell modified and unmodified copies of the Font +Software, subject to the following conditions: + +1) Neither the Font Software nor any of its individual components, +in Original or Modified Versions, may be sold by itself. + +2) Original or Modified Versions of the Font Software may be bundled, +redistributed and/or sold with any software, provided that each copy +contains the above copyright notice and this license. These can be +included either as stand-alone text files, human-readable headers or +in the appropriate machine-readable metadata fields within text or +binary files as long as those fields can be easily viewed by the user. + +3) No Modified Version of the Font Software may use the Reserved Font +Name(s) unless explicit written permission is granted by the corresponding +Copyright Holder. This restriction only applies to the primary font name as +presented to the users. + +4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font +Software shall not be used to promote, endorse or advertise any +Modified Version, except to acknowledge the contribution(s) of the +Copyright Holder(s) and the Author(s) or with their explicit written +permission. + +5) The Font Software, modified or unmodified, in part or in whole, +must be distributed entirely under this license, and must not be +distributed under any other license. The requirement for fonts to +remain under this license does not apply to any document created +using the Font Software. + +TERMINATION +This license becomes null and void if any of the above conditions are +not met. + +DISCLAIMER +THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT +OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE +COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM +OTHER DEALINGS IN THE FONT SOFTWARE. diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/static.files/SourceSerif4-Regular-1f7d512b176f0f72.ttf.woff2 b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/static.files/SourceSerif4-Regular-1f7d512b176f0f72.ttf.woff2 new file mode 100644 index 0000000000..2db73fe2b4 Binary files /dev/null and b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/static.files/SourceSerif4-Regular-1f7d512b176f0f72.ttf.woff2 differ diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/static.files/ayu-94f39d4346842c1e.css b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/static.files/ayu-94f39d4346842c1e.css new file mode 100644 index 0000000000..4674f8370a --- /dev/null +++ b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/static.files/ayu-94f39d4346842c1e.css @@ -0,0 +1 @@ + :root{--main-background-color:#0f1419;--main-color:#c5c5c5;--settings-input-color:#ffb454;--settings-button-color:#fff;--settings-button-border-focus:#e0e0e0;--sidebar-background-color:#14191f;--sidebar-background-color-hover:rgba(70,70,70,0.33);--code-block-background-color:#191f26;--scrollbar-track-background-color:transparent;--scrollbar-thumb-background-color:#5c6773;--scrollbar-color:#5c6773 #24292f;--headings-border-bottom-color:#5c6773;--border-color:#5c6773;--button-background-color:#141920;--right-side-color:grey;--code-attribute-color:#999;--toggles-color:#999;--toggle-filter:invert(100%);--search-input-focused-border-color:#5c6773;--copy-path-button-color:#fff;--copy-path-img-filter:invert(70%);--copy-path-img-hover-filter:invert(100%);--codeblock-error-hover-color:rgb(255,0,0);--codeblock-error-color:rgba(255,0,0,.5);--codeblock-ignore-hover-color:rgb(255,142,0);--codeblock-ignore-color:rgba(255,142,0,.6);--type-link-color:#ffa0a5;--trait-link-color:#39afd7;--assoc-item-link-color:#39afd7;--function-link-color:#fdd687;--macro-link-color:#a37acc;--keyword-link-color:#39afd7;--mod-link-color:#39afd7;--link-color:#39afd7;--sidebar-link-color:#53b1db;--sidebar-current-link-background-color:transparent;--search-result-link-focus-background-color:#3c3c3c;--search-result-border-color:#aaa3;--search-color:#fff;--search-results-alias-color:#c5c5c5;--search-results-grey-color:#999;--stab-background-color:#314559;--stab-code-color:#e6e1cf;--code-highlight-kw-color:#ff7733;--code-highlight-kw-2-color:#ff7733;--code-highlight-lifetime-color:#ff7733;--code-highlight-prelude-color:#69f2df;--code-highlight-prelude-val-color:#ff7733;--code-highlight-number-color:#b8cc52;--code-highlight-string-color:#b8cc52;--code-highlight-literal-color:#ff7733;--code-highlight-attribute-color:#e6e1cf;--code-highlight-self-color:#36a3d9;--code-highlight-macro-color:#a37acc;--code-highlight-question-mark-color:#ff9011;--code-highlight-comment-color:#788797;--code-highlight-doc-comment-color:#a1ac88;--example-line-numbers-border-color:none;--src-line-numbers-span-color:#5c6773;--src-line-number-highlighted-background-color:rgba(255,236,164,0.06);--test-arrow-color:#788797;--test-arrow-background-color:rgba(57,175,215,0.09);--test-arrow-hover-color:#c5c5c5;--test-arrow-hover-background-color:rgba(57,175,215,0.368);--target-background-color:rgba(255,236,164,0.06);--target-border-color:rgba(255,180,76,0.85);--tooltip-background-color:#314559;--tooltip-color:#c5c5c5;--kbd-color:#c5c5c5;--kbd-background:#314559;--kbd-box-shadow-color:#5c6773;--rust-logo-filter:drop-shadow(1px 0 0px #fff) drop-shadow(0 1px 0 #fff) drop-shadow(-1px 0 0 #fff) drop-shadow(0 -1px 0 #fff);--crate-search-div-filter:invert(41%) sepia(12%) saturate(487%) hue-rotate(171deg) brightness(94%) contrast(94%);--crate-search-div-hover-filter:invert(98%) sepia(12%) saturate(81%) hue-rotate(343deg) brightness(113%) contrast(76%);--crate-search-hover-border:#e0e0e0;--source-sidebar-background-selected:#14191f;--source-sidebar-background-hover:#14191f;--table-alt-row-background-color:#191f26;}h1,h2,h3,h4{color:white;}h1 a{color:#fff;}h4{border:none;}.docblock code{color:#ffb454;}.code-header{color:#e6e1cf;}.docblock pre>code,pre>code{color:#e6e1cf;}.item-info code{color:#e6e1cf;}.docblock a>code{color:#39AFD7 !important;}pre,.rustdoc.source .example-wrap{color:#e6e1cf;}.sidebar .current,.sidebar a:hover{color:#ffb44c;}.sidebar-elems .location{color:#ff7733;}.src-line-numbers .line-highlighted{color:#708090;padding-right:4px;border-right:1px solid #ffb44c;}.search-results a:hover{color:#fff !important;background-color:#3c3c3c;}.search-results a:focus{color:#fff !important;background-color:#3c3c3c;}.search-results a{color:#0096cf;}.search-results a div.desc{color:#c5c5c5;}.content .item-info::before{color:#ccc;}.sidebar h2 a,.sidebar h3 a{color:white;}body.source .example-wrap pre.rust a{background:#333;}.result-name .primitive>i,.result-name .keyword>i{color:#788797;}#titles>button.selected{background-color:#141920 !important;border-bottom:1px solid #ffb44c !important;border-top:none;}#titles>button:not(.selected){background-color:transparent !important;border:none;}#titles>button:hover{border-bottom:1px solid rgba(242,151,24,0.3);}#titles>button>div.count{color:#888;}pre.rust .lifetime{}pre.rust .kw{}#titles>button:hover,#titles>button.selected{}pre.rust .self,pre.rust .bool-val,pre.rust .prelude-val,pre.rust .attribute{}pre.rust .kw-2,pre.rust .prelude-ty{}#settings-menu>a img{filter:invert(100);}#source-sidebar>.title{color:#fff;}#source-sidebar div.files>a:hover,details.dir-entry summary:hover,#source-sidebar div.files>a:focus,details.dir-entry summary:focus,#source-sidebar div.files>a.selected{color:#ffb44c;}.scraped-example-list .scrape-help{border-color:#aaa;color:#eee;}.scraped-example-list .scrape-help:hover{border-color:white;color:white;}.scraped-example .example-wrap .rust span.highlight{background:rgb(91,59,1);}.scraped-example .example-wrap .rust span.highlight.focus{background:rgb(124,75,15);}.scraped-example:not(.expanded) .code-wrapper:before{background:linear-gradient(to bottom,rgba(15,20,25,1),rgba(15,20,25,0));}.scraped-example:not(.expanded) .code-wrapper:after{background:linear-gradient(to top,rgba(15,20,25,1),rgba(15,20,25,0));}.toggle-line-inner{background:#999;}.toggle-line:hover .toggle-line-inner{background:#c5c5c5;} \ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/static.files/clipboard-7571035ce49a181d.svg b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/static.files/clipboard-7571035ce49a181d.svg new file mode 100644 index 0000000000..8adbd99630 --- /dev/null +++ b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/static.files/clipboard-7571035ce49a181d.svg @@ -0,0 +1 @@ + diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/static.files/dark-f23faae4a2daf9a6.css b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/static.files/dark-f23faae4a2daf9a6.css new file mode 100644 index 0000000000..64d4dec2ba --- /dev/null +++ b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/static.files/dark-f23faae4a2daf9a6.css @@ -0,0 +1 @@ +:root{--main-background-color:#353535;--main-color:#ddd;--settings-input-color:#2196f3;--settings-button-color:#000;--settings-button-border-focus:#ffb900;--sidebar-background-color:#505050;--sidebar-background-color-hover:#676767;--code-block-background-color:#2A2A2A;--scrollbar-track-background-color:#717171;--scrollbar-thumb-background-color:rgba(32,34,37,.6);--scrollbar-color:rgba(32,34,37,.6) #5a5a5a;--headings-border-bottom-color:#d2d2d2;--border-color:#e0e0e0;--button-background-color:#f0f0f0;--right-side-color:grey;--code-attribute-color:#999;--toggles-color:#999;--toggle-filter:invert(100%);--search-input-focused-border-color:#008dfd;--copy-path-button-color:#999;--copy-path-img-filter:invert(50%);--copy-path-img-hover-filter:invert(65%);--codeblock-error-hover-color:rgb(255,0,0);--codeblock-error-color:rgba(255,0,0,.5);--codeblock-ignore-hover-color:rgb(255,142,0);--codeblock-ignore-color:rgba(255,142,0,.6);--type-link-color:#2dbfb8;--trait-link-color:#b78cf2;--assoc-item-link-color:#d2991d;--function-link-color:#2bab63;--macro-link-color:#09bd00;--keyword-link-color:#d2991d;--mod-link-color:#d2991d;--link-color:#d2991d;--sidebar-link-color:#fdbf35;--sidebar-current-link-background-color:#444;--search-result-link-focus-background-color:#616161;--search-result-border-color:#aaa3;--search-color:#111;--search-results-alias-color:#fff;--search-results-grey-color:#ccc;--stab-background-color:#314559;--stab-code-color:#e6e1cf;--code-highlight-kw-color:#ab8ac1;--code-highlight-kw-2-color:#769acb;--code-highlight-lifetime-color:#d97f26;--code-highlight-prelude-color:#769acb;--code-highlight-prelude-val-color:#ee6868;--code-highlight-number-color:#83a300;--code-highlight-string-color:#83a300;--code-highlight-literal-color:#ee6868;--code-highlight-attribute-color:#ee6868;--code-highlight-self-color:#ee6868;--code-highlight-macro-color:#3e999f;--code-highlight-question-mark-color:#ff9011;--code-highlight-comment-color:#8d8d8b;--code-highlight-doc-comment-color:#8ca375;--example-line-numbers-border-color:#4a4949;--src-line-numbers-span-color:#3b91e2;--src-line-number-highlighted-background-color:#0a042f;--test-arrow-color:#dedede;--test-arrow-background-color:rgba(78,139,202,0.2);--test-arrow-hover-color:#dedede;--test-arrow-hover-background-color:#4e8bca;--target-background-color:#494a3d;--target-border-color:#bb7410;--tooltip-background-color:#000;--tooltip-color:#fff;--kbd-color:#000;--kbd-background:#fafbfc;--kbd-box-shadow-color:#c6cbd1;--rust-logo-filter:drop-shadow(1px 0 0px #fff) drop-shadow(0 1px 0 #fff) drop-shadow(-1px 0 0 #fff) drop-shadow(0 -1px 0 #fff);--crate-search-div-filter:invert(94%) sepia(0%) saturate(721%) hue-rotate(255deg) brightness(90%) contrast(90%);--crate-search-div-hover-filter:invert(69%) sepia(60%) saturate(6613%) hue-rotate(184deg) brightness(100%) contrast(91%);--crate-search-hover-border:#2196f3;--source-sidebar-background-selected:#333;--source-sidebar-background-hover:#444;--table-alt-row-background-color:#2A2A2A;}.content .item-info::before{color:#ccc;}body.source .example-wrap pre.rust a{background:#333;}#titles>button:not(.selected){background-color:#252525;border-top-color:#252525;}#titles>button:hover,#titles>button.selected{border-top-color:#0089ff;background-color:#353535;}#titles>button>div.count{color:#888;}.scraped-example-list .scrape-help{border-color:#aaa;color:#eee;}.scraped-example-list .scrape-help:hover{border-color:white;color:white;}.scraped-example .example-wrap .rust span.highlight{background:rgb(91,59,1);}.scraped-example .example-wrap .rust span.highlight.focus{background:rgb(124,75,15);}.scraped-example:not(.expanded) .code-wrapper:before{background:linear-gradient(to bottom,rgba(53,53,53,1),rgba(53,53,53,0));}.scraped-example:not(.expanded) .code-wrapper:after{background:linear-gradient(to top,rgba(53,53,53,1),rgba(53,53,53,0));}.toggle-line-inner{background:#999;}.toggle-line:hover .toggle-line-inner{background:#c5c5c5;} \ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/static.files/down-arrow-927217e04c7463ac.svg b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/static.files/down-arrow-927217e04c7463ac.svg new file mode 100644 index 0000000000..5d76a64e92 --- /dev/null +++ b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/static.files/down-arrow-927217e04c7463ac.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/static.files/favicon-16x16-8b506e7a72182f1c.png b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/static.files/favicon-16x16-8b506e7a72182f1c.png new file mode 100644 index 0000000000..ea4b45cae1 Binary files /dev/null and b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/static.files/favicon-16x16-8b506e7a72182f1c.png differ diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/static.files/favicon-2c020d218678b618.svg b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/static.files/favicon-2c020d218678b618.svg new file mode 100644 index 0000000000..8b34b51198 --- /dev/null +++ b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/static.files/favicon-2c020d218678b618.svg @@ -0,0 +1,24 @@ + + + + + diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/static.files/favicon-32x32-422f7d1d52889060.png b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/static.files/favicon-32x32-422f7d1d52889060.png new file mode 100644 index 0000000000..69b8613ce1 Binary files /dev/null and b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/static.files/favicon-32x32-422f7d1d52889060.png differ diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/static.files/light-ebce58d0a40c3431.css b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/static.files/light-ebce58d0a40c3431.css new file mode 100644 index 0000000000..ec0cb610e7 --- /dev/null +++ b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/static.files/light-ebce58d0a40c3431.css @@ -0,0 +1 @@ +:root{--main-background-color:white;--main-color:black;--settings-input-color:#2196f3;--settings-button-color:#000;--settings-button-border-focus:#717171;--sidebar-background-color:#F5F5F5;--sidebar-background-color-hover:#E0E0E0;--code-block-background-color:#F5F5F5;--scrollbar-track-background-color:#dcdcdc;--scrollbar-thumb-background-color:rgba(36,37,39,0.6);--scrollbar-color:rgba(36,37,39,0.6) #d9d9d9;--headings-border-bottom-color:#ddd;--border-color:#e0e0e0;--button-background-color:#fff;--right-side-color:grey;--code-attribute-color:#999;--toggles-color:#999;--toggle-filter:none;--search-input-focused-border-color:#66afe9;--copy-path-button-color:#999;--copy-path-img-filter:invert(50%);--copy-path-img-hover-filter:invert(35%);--codeblock-error-hover-color:rgb(255,0,0);--codeblock-error-color:rgba(255,0,0,.5);--codeblock-ignore-hover-color:rgb(255,142,0);--codeblock-ignore-color:rgba(255,142,0,.6);--type-link-color:#ad378a;--trait-link-color:#6e4fc9;--assoc-item-link-color:#3873ad;--function-link-color:#ad7c37;--macro-link-color:#068000;--keyword-link-color:#3873ad;--mod-link-color:#3873ad;--link-color:#3873ad;--sidebar-link-color:#356da4;--sidebar-current-link-background-color:#fff;--search-result-link-focus-background-color:#ccc;--search-result-border-color:#aaa3;--search-color:#000;--search-results-alias-color:#000;--search-results-grey-color:#999;--stab-background-color:#fff5d6;--stab-code-color:#000;--code-highlight-kw-color:#8959a8;--code-highlight-kw-2-color:#4271ae;--code-highlight-lifetime-color:#b76514;--code-highlight-prelude-color:#4271ae;--code-highlight-prelude-val-color:#c82829;--code-highlight-number-color:#718c00;--code-highlight-string-color:#718c00;--code-highlight-literal-color:#c82829;--code-highlight-attribute-color:#c82829;--code-highlight-self-color:#c82829;--code-highlight-macro-color:#3e999f;--code-highlight-question-mark-color:#ff9011;--code-highlight-comment-color:#8e908c;--code-highlight-doc-comment-color:#4d4d4c;--example-line-numbers-border-color:#c7c7c7;--src-line-numbers-span-color:#c67e2d;--src-line-number-highlighted-background-color:#fdffd3;--test-arrow-color:#f5f5f5;--test-arrow-background-color:rgba(78,139,202,0.2);--test-arrow-hover-color:#f5f5f5;--test-arrow-hover-background-color:#4e8bca;--target-background-color:#fdffd3;--target-border-color:#ad7c37;--tooltip-background-color:#000;--tooltip-color:#fff;--kbd-color:#000;--kbd-background:#fafbfc;--kbd-box-shadow-color:#c6cbd1;--rust-logo-filter:initial;--crate-search-div-filter:invert(100%) sepia(0%) saturate(4223%) hue-rotate(289deg) brightness(114%) contrast(76%);--crate-search-div-hover-filter:invert(44%) sepia(18%) saturate(23%) hue-rotate(317deg) brightness(96%) contrast(93%);--crate-search-hover-border:#717171;--source-sidebar-background-selected:#fff;--source-sidebar-background-hover:#e0e0e0;--table-alt-row-background-color:#F5F5F5;}.content .item-info::before{color:#ccc;}body.source .example-wrap pre.rust a{background:#eee;}#titles>button:not(.selected){background-color:#e6e6e6;border-top-color:#e6e6e6;}#titles>button:hover,#titles>button.selected{background-color:#ffffff;border-top-color:#0089ff;}#titles>button>div.count{color:#888;}.scraped-example-list .scrape-help{border-color:#555;color:#333;}.scraped-example-list .scrape-help:hover{border-color:black;color:black;}.scraped-example .example-wrap .rust span.highlight{background:#fcffd6;}.scraped-example .example-wrap .rust span.highlight.focus{background:#f6fdb0;}.scraped-example:not(.expanded) .code-wrapper:before{background:linear-gradient(to bottom,rgba(255,255,255,1),rgba(255,255,255,0));}.scraped-example:not(.expanded) .code-wrapper:after{background:linear-gradient(to top,rgba(255,255,255,1),rgba(255,255,255,0));}.toggle-line-inner{background:#ccc;}.toggle-line:hover .toggle-line-inner{background:#999;} \ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/static.files/main-a211dbb005fb8161.js b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/static.files/main-a211dbb005fb8161.js new file mode 100644 index 0000000000..9cbd183d0b --- /dev/null +++ b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/static.files/main-a211dbb005fb8161.js @@ -0,0 +1,8 @@ +"use strict";function getVar(name){const el=document.getElementById("rustdoc-vars");if(el){return el.attributes["data-"+name].value}else{return null}}function resourcePath(basename,extension){return getVar("root-path")+basename+getVar("resource-suffix")+extension}function hideMain(){addClass(document.getElementById(MAIN_ID),"hidden")}function showMain(){removeClass(document.getElementById(MAIN_ID),"hidden")}function elemIsInParent(elem,parent){while(elem&&elem!==document.body){if(elem===parent){return true}elem=elem.parentElement}return false}function blurHandler(event,parentElem,hideCallback){if(!elemIsInParent(document.activeElement,parentElem)&&!elemIsInParent(event.relatedTarget,parentElem)){hideCallback()}}window.rootPath=getVar("root-path");window.currentCrate=getVar("current-crate");function setMobileTopbar(){const mobileLocationTitle=document.querySelector(".mobile-topbar h2");const locationTitle=document.querySelector(".sidebar h2.location");if(mobileLocationTitle&&locationTitle){mobileLocationTitle.innerHTML=locationTitle.innerHTML}}function getVirtualKey(ev){if("key"in ev&&typeof ev.key!=="undefined"){return ev.key}const c=ev.charCode||ev.keyCode;if(c===27){return"Escape"}return String.fromCharCode(c)}const MAIN_ID="main-content";const SETTINGS_BUTTON_ID="settings-menu";const ALTERNATIVE_DISPLAY_ID="alternative-display";const NOT_DISPLAYED_ID="not-displayed";const HELP_BUTTON_ID="help-button";function getSettingsButton(){return document.getElementById(SETTINGS_BUTTON_ID)}function getHelpButton(){return document.getElementById(HELP_BUTTON_ID)}function getNakedUrl(){return window.location.href.split("?")[0].split("#")[0]}function insertAfter(newNode,referenceNode){referenceNode.parentNode.insertBefore(newNode,referenceNode.nextSibling)}function getOrCreateSection(id,classes){let el=document.getElementById(id);if(!el){el=document.createElement("section");el.id=id;el.className=classes;insertAfter(el,document.getElementById(MAIN_ID))}return el}function getAlternativeDisplayElem(){return getOrCreateSection(ALTERNATIVE_DISPLAY_ID,"content hidden")}function getNotDisplayedElem(){return getOrCreateSection(NOT_DISPLAYED_ID,"hidden")}function switchDisplayedElement(elemToDisplay){const el=getAlternativeDisplayElem();if(el.children.length>0){getNotDisplayedElem().appendChild(el.firstElementChild)}if(elemToDisplay===null){addClass(el,"hidden");showMain();return}el.appendChild(elemToDisplay);hideMain();removeClass(el,"hidden")}function browserSupportsHistoryApi(){return window.history&&typeof window.history.pushState==="function"}function loadCss(cssUrl){const link=document.createElement("link");link.href=cssUrl;link.rel="stylesheet";document.getElementsByTagName("head")[0].appendChild(link)}(function(){const isHelpPage=window.location.pathname.endsWith("/help.html");function loadScript(url){const script=document.createElement("script");script.src=url;document.head.append(script)}getSettingsButton().onclick=event=>{if(event.ctrlKey||event.altKey||event.metaKey){return}window.hideAllModals(false);addClass(getSettingsButton(),"rotate");event.preventDefault();loadCss(getVar("static-root-path")+getVar("settings-css"));loadScript(getVar("static-root-path")+getVar("settings-js"))};window.searchState={loadingText:"Loading search results...",input:document.getElementsByClassName("search-input")[0],outputElement:()=>{let el=document.getElementById("search");if(!el){el=document.createElement("section");el.id="search";getNotDisplayedElem().appendChild(el)}return el},title:document.title,titleBeforeSearch:document.title,timeout:null,currentTab:0,focusedByTab:[null,null,null],clearInputTimeout:()=>{if(searchState.timeout!==null){clearTimeout(searchState.timeout);searchState.timeout=null}},isDisplayed:()=>searchState.outputElement().parentElement.id===ALTERNATIVE_DISPLAY_ID,focus:()=>{searchState.input.focus()},defocus:()=>{searchState.input.blur()},showResults:search=>{if(search===null||typeof search==="undefined"){search=searchState.outputElement()}switchDisplayedElement(search);searchState.mouseMovedAfterSearch=false;document.title=searchState.title},hideResults:()=>{switchDisplayedElement(null);document.title=searchState.titleBeforeSearch;if(browserSupportsHistoryApi()){history.replaceState(null,window.currentCrate+" - Rust",getNakedUrl()+window.location.hash)}},getQueryStringParams:()=>{const params={};window.location.search.substring(1).split("&").map(s=>{const pair=s.split("=");params[decodeURIComponent(pair[0])]=typeof pair[1]==="undefined"?null:decodeURIComponent(pair[1])});return params},setup:()=>{const search_input=searchState.input;if(!searchState.input){return}let searchLoaded=false;function loadSearch(){if(!searchLoaded){searchLoaded=true;loadScript(getVar("static-root-path")+getVar("search-js"));loadScript(resourcePath("search-index",".js"))}}search_input.addEventListener("focus",()=>{search_input.origPlaceholder=search_input.placeholder;search_input.placeholder="Type your search here.";loadSearch()});if(search_input.value!==""){loadSearch()}const params=searchState.getQueryStringParams();if(params.search!==undefined){searchState.setLoadingSearch();loadSearch()}},setLoadingSearch:()=>{const search=searchState.outputElement();search.innerHTML="

    "+searchState.loadingText+"

    ";searchState.showResults(search)},};function getPageId(){if(window.location.hash){const tmp=window.location.hash.replace(/^#/,"");if(tmp.length>0){return tmp}}return null}const toggleAllDocsId="toggle-all-docs";let savedHash="";function handleHashes(ev){if(ev!==null&&searchState.isDisplayed()&&ev.newURL){switchDisplayedElement(null);const hash=ev.newURL.slice(ev.newURL.indexOf("#")+1);if(browserSupportsHistoryApi()){history.replaceState(null,"",getNakedUrl()+window.location.search+"#"+hash)}const elem=document.getElementById(hash);if(elem){elem.scrollIntoView()}}if(savedHash!==window.location.hash){savedHash=window.location.hash;if(savedHash.length===0){return}expandSection(savedHash.slice(1))}}function onHashChange(ev){hideSidebar();handleHashes(ev)}function openParentDetails(elem){while(elem){if(elem.tagName==="DETAILS"){elem.open=true}elem=elem.parentNode}}function expandSection(id){openParentDetails(document.getElementById(id))}function handleEscape(ev){searchState.clearInputTimeout();switchDisplayedElement(null);if(browserSupportsHistoryApi()){history.replaceState(null,window.currentCrate+" - Rust",getNakedUrl()+window.location.hash)}ev.preventDefault();searchState.defocus();window.hideAllModals(true)}function handleShortcut(ev){const disableShortcuts=getSettingValue("disable-shortcuts")==="true";if(ev.ctrlKey||ev.altKey||ev.metaKey||disableShortcuts){return}if(document.activeElement.tagName==="INPUT"&&document.activeElement.type!=="checkbox"){switch(getVirtualKey(ev)){case"Escape":handleEscape(ev);break}}else{switch(getVirtualKey(ev)){case"Escape":handleEscape(ev);break;case"s":case"S":ev.preventDefault();searchState.focus();break;case"+":ev.preventDefault();expandAllDocs();break;case"-":ev.preventDefault();collapseAllDocs();break;case"?":showHelp();break;default:break}}}document.addEventListener("keypress",handleShortcut);document.addEventListener("keydown",handleShortcut);function addSidebarItems(){if(!window.SIDEBAR_ITEMS){return}const sidebar=document.getElementsByClassName("sidebar-elems")[0];function block(shortty,id,longty){const filtered=window.SIDEBAR_ITEMS[shortty];if(!filtered){return}const h3=document.createElement("h3");h3.innerHTML=`${longty}`;const ul=document.createElement("ul");ul.className="block "+shortty;for(const item of filtered){const name=item[0];const desc=item[1];let path;if(shortty==="mod"){path=name+"/index.html"}else{path=shortty+"."+name+".html"}const current_page=document.location.href.split("/").pop();const link=document.createElement("a");link.href=path;link.title=desc;if(path===current_page){link.className="current"}link.textContent=name;const li=document.createElement("li");li.appendChild(link);ul.appendChild(li)}sidebar.appendChild(h3);sidebar.appendChild(ul)}if(sidebar){block("primitive","primitives","Primitive Types");block("mod","modules","Modules");block("macro","macros","Macros");block("struct","structs","Structs");block("enum","enums","Enums");block("union","unions","Unions");block("constant","constants","Constants");block("static","static","Statics");block("trait","traits","Traits");block("fn","functions","Functions");block("type","types","Type Definitions");block("foreigntype","foreign-types","Foreign Types");block("keyword","keywords","Keywords");block("traitalias","trait-aliases","Trait Aliases")}}window.register_implementors=imp=>{const implementors=document.getElementById("implementors-list");const synthetic_implementors=document.getElementById("synthetic-implementors-list");const inlined_types=new Set();const TEXT_IDX=0;const SYNTHETIC_IDX=1;const TYPES_IDX=2;if(synthetic_implementors){onEachLazy(synthetic_implementors.getElementsByClassName("impl"),el=>{const aliases=el.getAttribute("data-aliases");if(!aliases){return}aliases.split(",").forEach(alias=>{inlined_types.add(alias)})})}let currentNbImpls=implementors.getElementsByClassName("impl").length;const traitName=document.querySelector("h1.fqn > .trait").textContent;const baseIdName="impl-"+traitName+"-";const libs=Object.getOwnPropertyNames(imp);const script=document.querySelector("script[data-ignore-extern-crates]");const ignoreExternCrates=script?script.getAttribute("data-ignore-extern-crates"):"";for(const lib of libs){if(lib===window.currentCrate||ignoreExternCrates.indexOf(lib)!==-1){continue}const structs=imp[lib];struct_loop:for(const struct of structs){const list=struct[SYNTHETIC_IDX]?synthetic_implementors:implementors;if(struct[SYNTHETIC_IDX]){for(const struct_type of struct[TYPES_IDX]){if(inlined_types.has(struct_type)){continue struct_loop}inlined_types.add(struct_type)}}const code=document.createElement("h3");code.innerHTML=struct[TEXT_IDX];addClass(code,"code-header");onEachLazy(code.getElementsByTagName("a"),elem=>{const href=elem.getAttribute("href");if(href&&href.indexOf("http")!==0){elem.setAttribute("href",window.rootPath+href)}});const currentId=baseIdName+currentNbImpls;const anchor=document.createElement("a");anchor.href="#"+currentId;addClass(anchor,"anchor");const display=document.createElement("div");display.id=currentId;addClass(display,"impl");display.appendChild(anchor);display.appendChild(code);list.appendChild(display);currentNbImpls+=1}}};if(window.pending_implementors){window.register_implementors(window.pending_implementors)}function addSidebarCrates(){if(!window.ALL_CRATES){return}const sidebarElems=document.getElementsByClassName("sidebar-elems")[0];if(!sidebarElems){return}const h3=document.createElement("h3");h3.innerHTML="Crates";const ul=document.createElement("ul");ul.className="block crate";for(const crate of window.ALL_CRATES){const link=document.createElement("a");link.href=window.rootPath+crate+"/index.html";if(window.rootPath!=="./"&&crate===window.currentCrate){link.className="current"}link.textContent=crate;const li=document.createElement("li");li.appendChild(link);ul.appendChild(li)}sidebarElems.appendChild(h3);sidebarElems.appendChild(ul)}function expandAllDocs(){const innerToggle=document.getElementById(toggleAllDocsId);removeClass(innerToggle,"will-expand");onEachLazy(document.getElementsByClassName("rustdoc-toggle"),e=>{if(!hasClass(e,"type-contents-toggle")&&!hasClass(e,"more-examples-toggle")){e.open=true}});innerToggle.title="collapse all docs";innerToggle.children[0].innerText="\u2212"}function collapseAllDocs(){const innerToggle=document.getElementById(toggleAllDocsId);addClass(innerToggle,"will-expand");onEachLazy(document.getElementsByClassName("rustdoc-toggle"),e=>{if(e.parentNode.id!=="implementations-list"||(!hasClass(e,"implementors-toggle")&&!hasClass(e,"type-contents-toggle"))){e.open=false}});innerToggle.title="expand all docs";innerToggle.children[0].innerText="+"}function toggleAllDocs(){const innerToggle=document.getElementById(toggleAllDocsId);if(!innerToggle){return}if(hasClass(innerToggle,"will-expand")){expandAllDocs()}else{collapseAllDocs()}}(function(){const toggles=document.getElementById(toggleAllDocsId);if(toggles){toggles.onclick=toggleAllDocs}const hideMethodDocs=getSettingValue("auto-hide-method-docs")==="true";const hideImplementations=getSettingValue("auto-hide-trait-implementations")==="true";const hideLargeItemContents=getSettingValue("auto-hide-large-items")!=="false";function setImplementorsTogglesOpen(id,open){const list=document.getElementById(id);if(list!==null){onEachLazy(list.getElementsByClassName("implementors-toggle"),e=>{e.open=open})}}if(hideImplementations){setImplementorsTogglesOpen("trait-implementations-list",false);setImplementorsTogglesOpen("blanket-implementations-list",false)}onEachLazy(document.getElementsByClassName("rustdoc-toggle"),e=>{if(!hideLargeItemContents&&hasClass(e,"type-contents-toggle")){e.open=true}if(hideMethodDocs&&hasClass(e,"method-toggle")){e.open=false}});const pageId=getPageId();if(pageId!==null){expandSection(pageId)}}());window.rustdoc_add_line_numbers_to_examples=()=>{onEachLazy(document.getElementsByClassName("rust-example-rendered"),x=>{const parent=x.parentNode;const line_numbers=parent.querySelectorAll(".example-line-numbers");if(line_numbers.length>0){return}const count=x.textContent.split("\n").length;const elems=[];for(let i=0;i{onEachLazy(document.getElementsByClassName("rust-example-rendered"),x=>{const parent=x.parentNode;const line_numbers=parent.querySelectorAll(".example-line-numbers");for(const node of line_numbers){parent.removeChild(node)}})};if(getSettingValue("line-numbers")==="true"){window.rustdoc_add_line_numbers_to_examples()}let oldSidebarScrollPosition=null;window.rustdocMobileScrollLock=function(){const mobile_topbar=document.querySelector(".mobile-topbar");if(window.innerWidth<=window.RUSTDOC_MOBILE_BREAKPOINT){oldSidebarScrollPosition=window.scrollY;document.body.style.width=`${document.body.offsetWidth}px`;document.body.style.position="fixed";document.body.style.top=`-${oldSidebarScrollPosition}px`;if(mobile_topbar){mobile_topbar.style.top=`${oldSidebarScrollPosition}px`;mobile_topbar.style.position="relative"}}else{oldSidebarScrollPosition=null}};window.rustdocMobileScrollUnlock=function(){const mobile_topbar=document.querySelector(".mobile-topbar");if(oldSidebarScrollPosition!==null){document.body.style.width="";document.body.style.position="";document.body.style.top="";if(mobile_topbar){mobile_topbar.style.top="";mobile_topbar.style.position=""}window.scrollTo(0,oldSidebarScrollPosition);oldSidebarScrollPosition=null}};function showSidebar(){window.hideAllModals(false);window.rustdocMobileScrollLock();const sidebar=document.getElementsByClassName("sidebar")[0];addClass(sidebar,"shown")}function hideSidebar(){window.rustdocMobileScrollUnlock();const sidebar=document.getElementsByClassName("sidebar")[0];removeClass(sidebar,"shown")}window.addEventListener("resize",()=>{if(window.innerWidth>window.RUSTDOC_MOBILE_BREAKPOINT&&oldSidebarScrollPosition!==null){hideSidebar()}if(window.CURRENT_NOTABLE_ELEMENT){const base=window.CURRENT_NOTABLE_ELEMENT.NOTABLE_BASE;const force_visible=base.NOTABLE_FORCE_VISIBLE;hideNotable(false);if(force_visible){showNotable(base);base.NOTABLE_FORCE_VISIBLE=true}}});function handleClick(id,f){const elem=document.getElementById(id);if(elem){elem.addEventListener("click",f)}}handleClick(MAIN_ID,()=>{hideSidebar()});onEachLazy(document.getElementsByTagName("a"),el=>{if(el.hash){el.addEventListener("click",()=>{expandSection(el.hash.slice(1));hideSidebar()})}});onEachLazy(document.querySelectorAll(".rustdoc-toggle > summary:not(.hideme)"),el=>{el.addEventListener("click",e=>{if(e.target.tagName!=="SUMMARY"&&e.target.tagName!=="A"){e.preventDefault()}})});function showNotable(e){if(!window.NOTABLE_TRAITS){const data=document.getElementById("notable-traits-data");if(data){window.NOTABLE_TRAITS=JSON.parse(data.innerText)}else{throw new Error("showNotable() called on page without any notable traits!")}}if(window.CURRENT_NOTABLE_ELEMENT&&window.CURRENT_NOTABLE_ELEMENT.NOTABLE_BASE===e){return}window.hideAllModals(false);const ty=e.getAttribute("data-ty");const wrapper=document.createElement("div");wrapper.innerHTML="
    "+window.NOTABLE_TRAITS[ty]+"
    ";wrapper.className="notable popover";const focusCatcher=document.createElement("div");focusCatcher.setAttribute("tabindex","0");focusCatcher.onfocus=hideNotable;wrapper.appendChild(focusCatcher);const pos=e.getBoundingClientRect();wrapper.style.top=(pos.top+window.scrollY+pos.height)+"px";wrapper.style.left=0;wrapper.style.right="auto";wrapper.style.visibility="hidden";const body=document.getElementsByTagName("body")[0];body.appendChild(wrapper);const wrapperPos=wrapper.getBoundingClientRect();const finalPos=pos.left+window.scrollX-wrapperPos.width+24;if(finalPos>0){wrapper.style.left=finalPos+"px"}else{wrapper.style.setProperty("--popover-arrow-offset",(wrapperPos.right-pos.right+4)+"px")}wrapper.style.visibility="";window.CURRENT_NOTABLE_ELEMENT=wrapper;window.CURRENT_NOTABLE_ELEMENT.NOTABLE_BASE=e;wrapper.onpointerleave=function(ev){if(ev.pointerType!=="mouse"){return}if(!e.NOTABLE_FORCE_VISIBLE&&!elemIsInParent(event.relatedTarget,e)){hideNotable(true)}}}function notableBlurHandler(event){if(window.CURRENT_NOTABLE_ELEMENT&&!elemIsInParent(document.activeElement,window.CURRENT_NOTABLE_ELEMENT)&&!elemIsInParent(event.relatedTarget,window.CURRENT_NOTABLE_ELEMENT)&&!elemIsInParent(document.activeElement,window.CURRENT_NOTABLE_ELEMENT.NOTABLE_BASE)&&!elemIsInParent(event.relatedTarget,window.CURRENT_NOTABLE_ELEMENT.NOTABLE_BASE)){setTimeout(()=>hideNotable(false),0)}}function hideNotable(focus){if(window.CURRENT_NOTABLE_ELEMENT){if(window.CURRENT_NOTABLE_ELEMENT.NOTABLE_BASE.NOTABLE_FORCE_VISIBLE){if(focus){window.CURRENT_NOTABLE_ELEMENT.NOTABLE_BASE.focus()}window.CURRENT_NOTABLE_ELEMENT.NOTABLE_BASE.NOTABLE_FORCE_VISIBLE=false}const body=document.getElementsByTagName("body")[0];body.removeChild(window.CURRENT_NOTABLE_ELEMENT);window.CURRENT_NOTABLE_ELEMENT=null}}onEachLazy(document.getElementsByClassName("notable-traits"),e=>{e.onclick=function(){this.NOTABLE_FORCE_VISIBLE=this.NOTABLE_FORCE_VISIBLE?false:true;if(window.CURRENT_NOTABLE_ELEMENT&&!this.NOTABLE_FORCE_VISIBLE){hideNotable(true)}else{showNotable(this);window.CURRENT_NOTABLE_ELEMENT.setAttribute("tabindex","0");window.CURRENT_NOTABLE_ELEMENT.focus();window.CURRENT_NOTABLE_ELEMENT.onblur=notableBlurHandler}return false};e.onpointerenter=function(ev){if(ev.pointerType!=="mouse"){return}showNotable(this)};e.onpointerleave=function(ev){if(ev.pointerType!=="mouse"){return}if(!this.NOTABLE_FORCE_VISIBLE&&!elemIsInParent(event.relatedTarget,window.CURRENT_NOTABLE_ELEMENT)){hideNotable(true)}}});const sidebar_menu_toggle=document.getElementsByClassName("sidebar-menu-toggle")[0];if(sidebar_menu_toggle){sidebar_menu_toggle.addEventListener("click",()=>{const sidebar=document.getElementsByClassName("sidebar")[0];if(!hasClass(sidebar,"shown")){showSidebar()}else{hideSidebar()}})}function helpBlurHandler(event){blurHandler(event,getHelpButton(),window.hidePopoverMenus)}function buildHelpMenu(){const book_info=document.createElement("span");book_info.className="top";book_info.innerHTML="You can find more information in \ + the rustdoc book.";const shortcuts=[["?","Show this help dialog"],["S","Focus the search field"],["↑","Move up in search results"],["↓","Move down in search results"],["← / →","Switch result tab (when results focused)"],["⏎","Go to active search result"],["+","Expand all sections"],["-","Collapse all sections"],].map(x=>"
    "+x[0].split(" ").map((y,index)=>((index&1)===0?""+y+"":" "+y+" ")).join("")+"
    "+x[1]+"
    ").join("");const div_shortcuts=document.createElement("div");addClass(div_shortcuts,"shortcuts");div_shortcuts.innerHTML="

    Keyboard Shortcuts

    "+shortcuts+"
    ";const infos=["Prefix searches with a type followed by a colon (e.g., fn:) to \ + restrict the search to a given item kind.","Accepted kinds are: fn, mod, struct, \ + enum, trait, type, macro, \ + and const.","Search functions by type signature (e.g., vec -> usize or \ + -> vec)","Search multiple things at once by splitting your query with comma (e.g., \ + str,u8 or String,struct:Vec,test)","You can look for items with an exact name by putting double quotes around \ + your request: \"string\"","Look for items inside another one by searching for a path: vec::Vec",].map(x=>"

    "+x+"

    ").join("");const div_infos=document.createElement("div");addClass(div_infos,"infos");div_infos.innerHTML="

    Search Tricks

    "+infos;const rustdoc_version=document.createElement("span");rustdoc_version.className="bottom";const rustdoc_version_code=document.createElement("code");rustdoc_version_code.innerText="rustdoc "+getVar("rustdoc-version");rustdoc_version.appendChild(rustdoc_version_code);const container=document.createElement("div");if(!isHelpPage){container.className="popover"}container.id="help";container.style.display="none";const side_by_side=document.createElement("div");side_by_side.className="side-by-side";side_by_side.appendChild(div_shortcuts);side_by_side.appendChild(div_infos);container.appendChild(book_info);container.appendChild(side_by_side);container.appendChild(rustdoc_version);if(isHelpPage){const help_section=document.createElement("section");help_section.appendChild(container);document.getElementById("main-content").appendChild(help_section);container.style.display="block"}else{const help_button=getHelpButton();help_button.appendChild(container);container.onblur=helpBlurHandler;container.onclick=event=>{event.preventDefault()};help_button.onblur=helpBlurHandler;help_button.children[0].onblur=helpBlurHandler}return container}window.hideAllModals=function(switchFocus){hideSidebar();window.hidePopoverMenus();hideNotable(switchFocus)};window.hidePopoverMenus=function(){onEachLazy(document.querySelectorAll(".search-form .popover"),elem=>{elem.style.display="none"})};function getHelpMenu(buildNeeded){let menu=getHelpButton().querySelector(".popover");if(!menu&&buildNeeded){menu=buildHelpMenu()}return menu}function showHelp(){const menu=getHelpMenu(true);if(menu.style.display==="none"){window.hideAllModals();menu.style.display=""}}if(isHelpPage){showHelp();document.querySelector(`#${HELP_BUTTON_ID} > a`).addEventListener("click",event=>{const target=event.target;if(target.tagName!=="A"||target.parentElement.id!==HELP_BUTTON_ID||event.ctrlKey||event.altKey||event.metaKey){return}event.preventDefault()})}else{document.querySelector(`#${HELP_BUTTON_ID} > a`).addEventListener("click",event=>{const target=event.target;if(target.tagName!=="A"||target.parentElement.id!==HELP_BUTTON_ID||event.ctrlKey||event.altKey||event.metaKey){return}event.preventDefault();const menu=getHelpMenu(true);const shouldShowHelp=menu.style.display==="none";if(shouldShowHelp){showHelp()}else{window.hidePopoverMenus()}})}setMobileTopbar();addSidebarItems();addSidebarCrates();onHashChange(null);window.addEventListener("hashchange",onHashChange);searchState.setup()}());(function(){let reset_button_timeout=null;window.copy_path=but=>{const parent=but.parentElement;const path=[];onEach(parent.childNodes,child=>{if(child.tagName==="A"){path.push(child.textContent)}});const el=document.createElement("textarea");el.value=path.join("::");el.setAttribute("readonly","");el.style.position="absolute";el.style.left="-9999px";document.body.appendChild(el);el.select();document.execCommand("copy");document.body.removeChild(el);but.children[0].style.display="none";let tmp;if(but.childNodes.length<2){tmp=document.createTextNode("✓");but.appendChild(tmp)}else{onEachLazy(but.childNodes,e=>{if(e.nodeType===Node.TEXT_NODE){tmp=e;return true}});tmp.textContent="✓"}if(reset_button_timeout!==null){window.clearTimeout(reset_button_timeout)}function reset_button(){tmp.textContent="";reset_button_timeout=null;but.children[0].style.display=""}reset_button_timeout=window.setTimeout(reset_button,1000)}}()) \ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/static.files/normalize-76eba96aa4d2e634.css b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/static.files/normalize-76eba96aa4d2e634.css new file mode 100644 index 0000000000..469959f137 --- /dev/null +++ b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/static.files/normalize-76eba96aa4d2e634.css @@ -0,0 +1,2 @@ + /*! normalize.css v8.0.1 | MIT License | github.com/necolas/normalize.css */ +html{line-height:1.15;-webkit-text-size-adjust:100%}body{margin:0}main{display:block}h1{font-size:2em;margin:0.67em 0}hr{box-sizing:content-box;height:0;overflow:visible}pre{font-family:monospace,monospace;font-size:1em}a{background-color:transparent}abbr[title]{border-bottom:none;text-decoration:underline;text-decoration:underline dotted}b,strong{font-weight:bolder}code,kbd,samp{font-family:monospace,monospace;font-size:1em}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sub{bottom:-0.25em}sup{top:-0.5em}img{border-style:none}button,input,optgroup,select,textarea{font-family:inherit;font-size:100%;line-height:1.15;margin:0}button,input{overflow:visible}button,select{text-transform:none}[type="button"],[type="reset"],[type="submit"],button{-webkit-appearance:button}[type="button"]::-moz-focus-inner,[type="reset"]::-moz-focus-inner,[type="submit"]::-moz-focus-inner,button::-moz-focus-inner{border-style:none;padding:0}[type="button"]:-moz-focusring,[type="reset"]:-moz-focusring,[type="submit"]:-moz-focusring,button:-moz-focusring{outline:1px dotted ButtonText}fieldset{padding:0.35em 0.75em 0.625em}legend{box-sizing:border-box;color:inherit;display:table;max-width:100%;padding:0;white-space:normal}progress{vertical-align:baseline}textarea{overflow:auto}[type="checkbox"],[type="radio"]{box-sizing:border-box;padding:0}[type="number"]::-webkit-inner-spin-button,[type="number"]::-webkit-outer-spin-button{height:auto}[type="search"]{-webkit-appearance:textfield;outline-offset:-2px}[type="search"]::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}details{display:block}summary{display:list-item}template{display:none}[hidden]{display:none} \ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/static.files/noscript-13285aec31fa243e.css b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/static.files/noscript-13285aec31fa243e.css new file mode 100644 index 0000000000..c32e0cb135 --- /dev/null +++ b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/static.files/noscript-13285aec31fa243e.css @@ -0,0 +1 @@ + #main-content .attributes{margin-left:0 !important;}#copy-path{display:none;}nav.sub{display:none;}.source .sidebar{display:none;}.notable-traits{display:none;} \ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/static.files/rust-logo-151179464ae7ed46.svg b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/static.files/rust-logo-151179464ae7ed46.svg new file mode 100644 index 0000000000..62424d8ffd --- /dev/null +++ b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/static.files/rust-logo-151179464ae7ed46.svg @@ -0,0 +1,61 @@ + + + diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/static.files/rustdoc-64f7dca12162a801.css b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/static.files/rustdoc-64f7dca12162a801.css new file mode 100644 index 0000000000..e35436b639 --- /dev/null +++ b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/static.files/rustdoc-64f7dca12162a801.css @@ -0,0 +1 @@ + @font-face {font-family:'Fira Sans';font-style:normal;font-weight:400;src:local('Fira Sans'),url("FiraSans-Regular-018c141bf0843ffd.woff2") format("woff2");font-display:swap;}@font-face {font-family:'Fira Sans';font-style:normal;font-weight:500;src:local('Fira Sans Medium'),url("FiraSans-Medium-8f9a781e4970d388.woff2") format("woff2");font-display:swap;}@font-face {font-family:'Source Serif 4';font-style:normal;font-weight:400;src:local('Source Serif 4'),url("SourceSerif4-Regular-1f7d512b176f0f72.ttf.woff2") format("woff2");font-display:swap;}@font-face {font-family:'Source Serif 4';font-style:italic;font-weight:400;src:local('Source Serif 4 Italic'),url("SourceSerif4-It-d034fe4ef9d0fa00.ttf.woff2") format("woff2");font-display:swap;}@font-face {font-family:'Source Serif 4';font-style:normal;font-weight:700;src:local('Source Serif 4 Bold'),url("SourceSerif4-Bold-124a1ca42af929b6.ttf.woff2") format("woff2");font-display:swap;}@font-face {font-family:'Source Code Pro';font-style:normal;font-weight:400;src:url("SourceCodePro-Regular-562dcc5011b6de7d.ttf.woff2") format("woff2");font-display:swap;}@font-face {font-family:'Source Code Pro';font-style:italic;font-weight:400;src:url("SourceCodePro-It-1cc31594bf4f1f79.ttf.woff2") format("woff2");font-display:swap;}@font-face {font-family:'Source Code Pro';font-style:normal;font-weight:600;src:url("SourceCodePro-Semibold-d899c5a5c4aeb14a.ttf.woff2") format("woff2");font-display:swap;}@font-face {font-family:'NanumBarunGothic';src:url("NanumBarunGothic-0f09457c7a19b7c6.ttf.woff2") format("woff2");font-display:swap;unicode-range:U+AC00-D7AF,U+1100-11FF,U+3130-318F,U+A960-A97F,U+D7B0-D7FF;}*{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;}html{content:"";}@media (prefers-color-scheme:light){html{content:"light";}}@media (prefers-color-scheme:dark){html{content:"dark";}}body{font:1rem/1.5 "Source Serif 4",NanumBarunGothic,serif;margin:0;position:relative;overflow-wrap:break-word;overflow-wrap:anywhere;-webkit-font-feature-settings:"kern","liga";-moz-font-feature-settings:"kern","liga";font-feature-settings:"kern","liga";background-color:var(--main-background-color);color:var(--main-color);}h1{font-size:1.5rem;}h2{font-size:1.375rem;}h3{font-size:1.25rem;}h1,h2,h3,h4,h5,h6{font-weight:500;}h1,h2,h3,h4{margin:25px 0 15px 0;padding-bottom:6px;}.docblock h3,.docblock h4,h5,h6{margin:15px 0 5px 0;}.docblock>h2:first-child,.docblock>h3:first-child,.docblock>h4:first-child,.docblock>h5:first-child,.docblock>h6:first-child{margin-top:0;}h1.fqn{margin:0;padding:0;flex-grow:1;overflow-wrap:break-word;overflow-wrap:anywhere;}.main-heading{display:flex;flex-wrap:wrap;padding-bottom:6px;margin-bottom:15px;}.content h2,.top-doc .docblock>h3,.top-doc .docblock>h4{border-bottom:1px solid var(--headings-border-bottom-color);}h3.code-header{font-size:1.125rem;}h4.code-header{font-size:1rem;}.code-header{font-weight:600;margin:0;padding:0;}#crate-search,h1,h2,h3,h4,h5,h6,.sidebar,.mobile-topbar,.search-input,.search-results .result-name,.item-left>a,.out-of-band,span.since,a.srclink,#help-button>a,summary.hideme,.scraped-example-list,ul.all-items{font-family:"Fira Sans",Arial,NanumBarunGothic,sans-serif;}#toggle-all-docs,a.anchor,.small-section-header a,#source-sidebar a,pre.rust a,.sidebar h2 a,.sidebar h3 a,.mobile-topbar h2 a,h1 a,.search-results a,.stab,.result-name .primitive>i,.result-name .keyword>i{color:var(--main-color);}.content span.enum,.content a.enum,.content span.struct,.content a.struct,.content span.union,.content a.union,.content span.primitive,.content a.primitive,.content span.type,.content a.type,.content span.foreigntype,.content a.foreigntype{color:var(--type-link-color);}.content span.trait,.content a.trait,.content span.traitalias,.content a.traitalias{color:var(--trait-link-color);}.content span.associatedtype,.content a.associatedtype,.content span.constant,.content a.constant,.content span.static,.content a.static{color:var(--assoc-item-link-color);}.content span.fn,.content a.fn,.content span.method,.content a.method,.content span.tymethod,.content a.tymethod{color:var(--function-link-color);}.content span.attr,.content a.attr,.content span.derive,.content a.derive,.content span.macro,.content a.macro{color:var(--macro-link-color);}.content span.mod,.content a.mod{color:var(--mod-link-color);}.content span.keyword,.content a.keyword{color:var(--keyword-link-color);}a{color:var(--link-color);}ol,ul{padding-left:24px;}ul ul,ol ul,ul ol,ol ol{margin-bottom:.625em;}p{margin:0 0 .75em 0;}p:last-child{margin:0;}button{padding:1px 6px;cursor:pointer;}button#toggle-all-docs{padding:0;background:none;border:none;-webkit-appearance:none;opacity:1;}.rustdoc{display:flex;flex-direction:row;flex-wrap:nowrap;}main{position:relative;flex-grow:1;padding:10px 15px 40px 45px;min-width:0;}.source main{padding:15px;}.width-limiter{max-width:960px;margin-right:auto;}.source .width-limiter{max-width:unset;}details:not(.rustdoc-toggle) summary{margin-bottom:.6em;}code,pre,a.test-arrow,.code-header{font-family:"Source Code Pro",monospace;}.docblock code,.docblock-short code{border-radius:3px;padding:0 0.125em;}.docblock pre code,.docblock-short pre code{padding:0;}pre{padding:14px;}.item-decl pre{overflow-x:auto;}.source .content pre{padding:20px;}img{max-width:100%;}.source .content{overflow:visible;}.sub-logo-container,.logo-container{line-height:0;}.sub-logo-container>img{height:60px;width:60px;object-fit:contain;}.rust-logo{filter:var(--rust-logo-filter);}.sidebar,.mobile-topbar,.sidebar-menu-toggle{background-color:var(--sidebar-background-color);}.sidebar{font-size:0.875rem;flex:0 0 200px;overflow-y:scroll;position:sticky;height:100vh;top:0;left:0;}.rustdoc.source .sidebar{flex-basis:50px;border-right:1px solid;overflow-x:hidden;overflow-y:hidden;}.source .sidebar,#sidebar-toggle,#source-sidebar{background-color:var(--sidebar-background-color);}#sidebar-toggle>button:hover,#sidebar-toggle>button:focus{background-color:var(--sidebar-background-color-hover);}.source .sidebar>*:not(#sidebar-toggle){visibility:hidden;}.source-sidebar-expanded .source .sidebar{overflow-y:auto;flex-basis:300px;}.source-sidebar-expanded .source .sidebar>*:not(#sidebar-toggle){visibility:visible;}#all-types{margin-top:1em;}*{scrollbar-width:initial;scrollbar-color:var(--scrollbar-color);}.sidebar{scrollbar-width:thin;scrollbar-color:var(--scrollbar-color);}::-webkit-scrollbar{width:12px;}.sidebar::-webkit-scrollbar{width:8px;}::-webkit-scrollbar-track{-webkit-box-shadow:inset 0;background-color:var(--scrollbar-track-background-color);}.sidebar::-webkit-scrollbar-track{background-color:var(--scrollbar-track-background-color);}::-webkit-scrollbar-thumb,.sidebar::-webkit-scrollbar-thumb{background-color:var(--scrollbar-thumb-background-color);}.hidden{display:none !important;}.sidebar .logo-container{margin-top:10px;margin-bottom:10px;text-align:center;}.version{overflow-wrap:break-word;}.logo-container>img{height:100px;width:100px;}ul.block,.block li{padding:0;margin:0;list-style:none;}.sidebar-elems a,.sidebar>h2 a{display:block;padding:0.25rem;margin-left:-0.25rem;}.sidebar h2{overflow-wrap:anywhere;padding:0;margin:0.7rem 0;}.sidebar h3{font-size:1.125rem;padding:0;margin:0;}.sidebar-elems,.sidebar>h2{padding-left:24px;}.sidebar a,.sidebar .current{color:var(--sidebar-link-color);}.sidebar .current,.sidebar a:hover{background-color:var(--sidebar-current-link-background-color);}.sidebar-elems .block{margin-bottom:2em;}.sidebar-elems .block li a{white-space:nowrap;text-overflow:ellipsis;overflow:hidden;}.mobile-topbar{display:none;}.source .content pre.rust{padding-left:0;}.rustdoc .example-wrap{display:flex;position:relative;margin-bottom:10px;}.rustdoc .example-wrap:last-child{margin-bottom:0px;}.rustdoc .example-wrap>pre{margin:0;flex-grow:1;overflow-x:auto;}.rustdoc .example-wrap>pre.example-line-numbers,.rustdoc .example-wrap>pre.src-line-numbers{flex-grow:0;overflow:initial;text-align:right;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;}.example-line-numbers{border:1px solid;padding:13px 8px;border-top-left-radius:5px;border-bottom-left-radius:5px;border-color:var(--example-line-numbers-border-color);}.src-line-numbers a,.src-line-numbers span{color:var(--src-line-numbers-span-color);}.src-line-numbers :target{background-color:transparent;border-right:none;padding-right:0;}.src-line-numbers .line-highlighted{background-color:var(--src-line-number-highlighted-background-color);}.search-loading{text-align:center;}.docblock-short{overflow-wrap:break-word;overflow-wrap:anywhere;overflow:hidden;text-overflow:ellipsis;}.docblock>:not(pre)>code,.docblock-short>code{white-space:pre-wrap;}.top-doc .docblock h2{font-size:1.375rem;}.top-doc .docblock h3{font-size:1.25rem;}.top-doc .docblock h4,.top-doc .docblock h5{font-size:1.125rem;}.top-doc .docblock h6{font-size:1rem;}.docblock h5{font-size:1rem;}.docblock h6{font-size:0.875rem;}.docblock{margin-left:24px;position:relative;}.docblock>:not(.more-examples-toggle):not(.example-wrap){max-width:100%;overflow-x:auto;}.out-of-band{flex-grow:0;font-size:1.125rem;}.docblock code,.docblock-short code,pre,.rustdoc.source .example-wrap{background-color:var(--code-block-background-color);}#main-content{position:relative;}.docblock table{margin:.5em 0;border-collapse:collapse;}.docblock table td,.docblock table th{padding:.5em;border:1px solid var(--border-color);}.docblock table tbody tr:nth-child(2n){background:var(--table-alt-row-background-color);}.method .where,.fn .where,.where.fmt-newline{display:block;font-size:0.875rem;}.item-info{display:block;margin-left:24px;}.item-info code{font-size:0.875rem;}#main-content>.item-info{margin-left:0;}nav.sub{flex-grow:1;flex-flow:row nowrap;margin:4px 0 25px 0;display:flex;align-items:center;}.search-form{position:relative;display:flex;height:34px;flex-grow:1;}.source nav.sub{margin:0 0 15px 0;}.source .search-form{margin-left:32px;}a{text-decoration:none;}.small-section-header{display:block;position:relative;}.small-section-header:hover>.anchor{display:initial;}.impl:hover>.anchor,.trait-impl:hover>.anchor,.variant:hover>.anchor{display:inline-block;position:absolute;}.anchor{display:none;position:absolute;left:-0.5em;background:none !important;}.anchor.field{left:-5px;}.small-section-header>.anchor{left:-15px;padding-right:8px;}h2.small-section-header>.anchor{padding-right:6px;}.main-heading a:hover,.example-wrap>pre.rust a:hover,.all-items a:hover,.docblock a:not(.test-arrow):not(.scrape-help):hover,.docblock-short a:not(.test-arrow):not(.scrape-help):hover,.item-info a{text-decoration:underline;}.crate.block a.current{font-weight:500;}table,.item-table{overflow-wrap:break-word;}.item-table{display:table;}.item-row{display:table-row;}.item-left,.item-right{display:table-cell;}.item-left{padding-right:1.25rem;}.search-results-title{margin-top:0;white-space:nowrap;display:flex;align-items:baseline;}#crate-search-div{position:relative;min-width:5em;}#crate-search{min-width:115px;padding:0 23px 0 4px;max-width:100%;text-overflow:ellipsis;border:1px solid var(--border-color);border-radius:4px;outline:none;cursor:pointer;-moz-appearance:none;-webkit-appearance:none;text-indent:0.01px;background-color:var(--main-background-color);color:inherit;line-height:1.5;font-weight:500;}#crate-search:hover,#crate-search:focus{border-color:var(--crate-search-hover-border);}@-moz-document url-prefix(){#crate-search{padding-left:0px;padding-right:19px;}}#crate-search-div::after{pointer-events:none;width:100%;height:100%;position:absolute;top:0;left:0;content:"";background-repeat:no-repeat;background-size:20px;background-position:calc(100% - 2px) 56%;background-image:url("down-arrow-927217e04c7463ac.svg");filter:var(--crate-search-div-filter);}#crate-search-div:hover::after,#crate-search-div:focus-within::after{filter:var(--crate-search-div-hover-filter);}#crate-search>option{font-size:1rem;}.search-input{-webkit-appearance:none;outline:none;border:1px solid var(--border-color);border-radius:2px;padding:8px;font-size:1rem;flex-grow:1;background-color:var(--button-background-color);color:var(--search-color);}.search-input:focus{border-color:var(--search-input-focused-border-color);}.search-results{display:none;}.search-results.active{display:block;}.search-results>a{display:flex;margin-left:2px;margin-right:2px;border-bottom:1px solid var(--search-result-border-color);gap:1em;}.search-results>a>div{flex:1;}.search-results>a>div.desc{white-space:nowrap;text-overflow:ellipsis;overflow:hidden;}.search-results a:hover,.search-results a:focus{background-color:var(--search-result-link-focus-background-color);}.search-results .result-name span.alias{color:var(--search-results-alias-color);}.search-results .result-name span.grey{color:var(--search-results-grey-color);}.popover{position:absolute;top:100%;right:0;z-index:2;display:block;margin-top:7px;border-radius:3px;border:1px solid var(--border-color);--popover-arrow-offset:11px;}.popover::before{content:'';position:absolute;right:var(--popover-arrow-offset);border:solid var(--border-color);border-width:1px 1px 0 0;padding:4px;transform:rotate(-45deg);top:-5px;}.popover,.popover::before{background-color:var(--main-background-color);color:var(--main-color);}#help.popover{max-width:600px;--popover-arrow-offset:48px;}#help dt{float:left;clear:left;margin-right:0.5rem;}#help span.top,#help span.bottom{text-align:center;display:block;font-size:1.125rem;}#help span.top{margin:10px 0;border-bottom:1px solid var(--border-color);padding-bottom:4px;margin-bottom:6px;}#help span.bottom{clear:both;border-top:1px solid var(--border-color);}.side-by-side>div{width:50%;float:left;padding:0 20px 20px 17px;}.item-info .stab{min-height:36px;display:flex;padding:3px;margin-bottom:5px;}.item-left .stab{margin-left:0.3125em;}.stab{padding:0 2px;font-size:0.875rem;font-weight:normal;color:var(--main-color);background-color:var(--stab-background-color);width:fit-content;align-items:center;white-space:pre-wrap;border-radius:3px;display:inline-flex;vertical-align:text-bottom;}.stab.portability>code{background:none;color:var(--stab-code-color);}.stab .emoji{font-size:1.25rem;margin-right:0.3rem;}.emoji{text-shadow:1px 0 0 black,-1px 0 0 black,0 1px 0 black,0 -1px 0 black;}.module-item.unstable,.import-item.unstable{opacity:0.65;}.since{font-weight:normal;font-size:initial;}.rightside{padding-left:12px;float:right;}.rightside:not(a),.out-of-band{color:var(--right-side-color);}pre.rust{tab-size:4;-moz-tab-size:4;}pre.rust .kw{color:var(--code-highlight-kw-color);}pre.rust .kw-2{color:var(--code-highlight-kw-2-color);}pre.rust .lifetime{color:var(--code-highlight-lifetime-color);}pre.rust .prelude-ty{color:var(--code-highlight-prelude-color);}pre.rust .prelude-val{color:var(--code-highlight-prelude-val-color);}pre.rust .string{color:var(--code-highlight-string-color);}pre.rust .number{color:var(--code-highlight-number-color);}pre.rust .bool-val{color:var(--code-highlight-literal-color);}pre.rust .self{color:var(--code-highlight-self-color);}pre.rust .attr{color:var(--code-highlight-attribute-color);}pre.rust .macro,pre.rust .macro-nonterminal{color:var(--code-highlight-macro-color);}pre.rust .question-mark{font-weight:bold;color:var(--code-highlight-question-mark-color);}pre.rust .comment{color:var(--code-highlight-comment-color);}pre.rust .doccomment{color:var(--code-highlight-doc-comment-color);}.example-wrap.compile_fail,.example-wrap.should_panic{border-left:2px solid var(--codeblock-error-color);}.ignore.example-wrap{border-left:2px solid var(--codeblock-ignore-color);}.example-wrap.compile_fail:hover,.example-wrap.should_panic:hover{border-left:2px solid var(--codeblock-error-hover-color);}.example-wrap.ignore:hover{border-left:2px solid var(--codeblock-ignore-hover-color);}.example-wrap.compile_fail .tooltip,.example-wrap.should_panic .tooltip{color:var(--codeblock-error-color);}.example-wrap.ignore .tooltip{color:var(--codeblock-ignore-color);}.example-wrap.compile_fail:hover .tooltip,.example-wrap.should_panic:hover .tooltip{color:var(--codeblock-error-hover-color);}.example-wrap.ignore:hover .tooltip{color:var(--codeblock-ignore-hover-color);}.example-wrap .tooltip{position:absolute;display:block;left:-25px;top:5px;}.example-wrap .tooltip::after{display:none;text-align:center;padding:5px 3px 3px 3px;border-radius:6px;margin-left:5px;font-size:1rem;border:1px solid var(--border-color);position:absolute;width:max-content;top:-2px;z-index:1;background-color:var(--tooltip-background-color);color:var(--tooltip-color);}.example-wrap .tooltip::before{content:" ";position:absolute;top:50%;left:16px;margin-top:-5px;display:none;z-index:1;border:5px solid transparent;border-right-color:var(--tooltip-background-color);}.example-wrap.ignore .tooltip::after{content:"This example is not tested";}.example-wrap.compile_fail .tooltip::after{content:"This example deliberately fails to compile";}.example-wrap.should_panic .tooltip::after{content:"This example panics";}.example-wrap.edition .tooltip::after{content:"This code runs with edition " attr(data-edition);}.example-wrap .tooltip:hover::before,.example-wrap .tooltip:hover::after{display:inline;}.example-wrap.compile_fail .tooltip,.example-wrap.should_panic .tooltip,.example-wrap.ignore .tooltip{font-weight:bold;font-size:1.25rem;}a.test-arrow{visibility:hidden;position:absolute;padding:5px 10px 5px 10px;border-radius:5px;font-size:1.375rem;top:5px;right:5px;z-index:1;color:var(--test-arrow-color);background-color:var(--test-arrow-background-color);}a.test-arrow:hover{color:var(--test-arrow-hover-color);background-color:var(--test-arrow-hover-background-color);}.example-wrap:hover .test-arrow{visibility:visible;}.code-attribute{font-weight:300;color:var(--code-attribute-color);}.item-spacer{width:100%;height:12px;}.out-of-band>span.since{font-size:1.25rem;}.sub-variant h4{font-size:1rem;font-weight:400;margin-top:0;margin-bottom:0;}.sub-variant{margin-left:24px;margin-bottom:40px;}.sub-variant>.sub-variant-field{margin-left:24px;}:target{padding-right:3px;background-color:var(--target-background-color);border-right:3px solid var(--target-border-color);}.notable-traits{color:inherit;margin-right:15px;position:relative;}.notable-traits:hover::after{position:absolute;top:calc(100% - 10px);left:-15px;right:-15px;height:20px;content:"\00a0";}.notable .docblock{margin:0.25em 0.5em;}.notable .docblock pre,.notable .docblock code{background:transparent;margin:0;padding:0;font-size:1.25rem;white-space:pre-wrap;}.search-failed{text-align:center;margin-top:20px;display:none;}.search-failed.active{display:block;}.search-failed>ul{text-align:left;max-width:570px;margin-left:auto;margin-right:auto;}#titles{display:flex;flex-direction:row;gap:1px;margin-bottom:4px;}#titles>button{text-align:center;font-size:1.125rem;border:0;border-top:2px solid;flex:1;line-height:1.5;color:inherit;}#titles>button>div.count{display:inline-block;font-size:1rem;}#sidebar-toggle{position:sticky;top:0;left:0;font-size:1.25rem;border-bottom:1px solid;display:flex;height:40px;justify-content:stretch;align-items:stretch;z-index:10;}#source-sidebar{width:100%;overflow:auto;}#source-sidebar>.title{font-size:1.5rem;text-align:center;border-bottom:1px solid var(--border-color);margin-bottom:6px;}#source-sidebar div.files>a:hover,details.dir-entry summary:hover,#source-sidebar div.files>a:focus,details.dir-entry summary:focus{background-color:var(--source-sidebar-background-hover);}#source-sidebar div.files>a.selected{background-color:var(--source-sidebar-background-selected);}#sidebar-toggle>button{font-size:inherit;font-weight:bold;background:none;color:inherit;text-align:center;border:none;outline:none;flex:1 1;-webkit-appearance:none;opacity:1;}#settings-menu,#help-button{margin-left:4px;display:flex;}#settings-menu>a,#help-button>a,#copy-path{width:33px;}#settings-menu>a,#help-button>a{display:flex;align-items:center;justify-content:center;background-color:var(--button-background-color);border:1px solid var(--border-color);border-radius:2px;color:var(--settings-button-color);font-size:20px;}#settings-menu>a:hover,#settings-menu>a:focus,#help-button>a:hover,#help-button>a:focus{border-color:var(--settings-button-border-focus);}#copy-path{color:var(--copy-path-button-color);background:var(--main-background-color);height:34px;margin-left:10px;padding:0;padding-left:2px;border:0;}#copy-path>img{filter:var(--copy-path-img-filter);}#copy-path:hover>img{filter:var(--copy-path-img-hover-filter);}@keyframes rotating{from{transform:rotate(0deg);}to{transform:rotate(360deg);}}#settings-menu.rotate>a img{animation:rotating 2s linear infinite;}kbd{display:inline-block;padding:3px 5px;font:15px monospace;line-height:10px;vertical-align:middle;border:solid 1px var(--border-color);border-radius:3px;cursor:default;color:var(--kbd--color);background-color:var(--kbd-background);box-shadow:inset 0 -1px 0 var(--kbd-box-shadow-color);}ul.all-items>li{list-style:none;}details.dir-entry{padding-left:4px;}details.dir-entry>summary::after{content:" ►";position:absolute;left:-15px;top:0px;font-size:80%;padding:2px 0px;width:25px;}details[open].dir-entry>summary::after{content:" ▼";}details.dir-entry>summary::-webkit-details-marker,details.dir-entry>summary::marker{display:none;}details.dir-entry>summary{margin:0 0 0 13px;list-style:none;cursor:pointer;position:relative;}details.dir-entry div.folders,details.dir-entry div.files{padding-left:23px;}details.dir-entry a{display:block;}details.rustdoc-toggle{contain:layout;position:relative;}details.rustdoc-toggle>summary.hideme{cursor:pointer;font-size:1rem;}details.rustdoc-toggle>summary{list-style:none;outline:none;}details.rustdoc-toggle>summary::-webkit-details-marker,details.rustdoc-toggle>summary::marker{display:none;}details.rustdoc-toggle>summary.hideme>span{margin-left:9px;}details.rustdoc-toggle>summary::before{background:url("toggle-plus-1092eb4930d581b0.svg") no-repeat top left;content:"";cursor:pointer;width:16px;height:16px;display:inline-block;vertical-align:middle;opacity:.5;filter:var(--toggle-filter);}details.rustdoc-toggle>summary.hideme>span,.more-examples-toggle summary,.more-examples-toggle .hide-more{color:var(--toggles-color);}details.rustdoc-toggle>summary::after{content:"Expand";overflow:hidden;width:0;height:0;position:absolute;}details.rustdoc-toggle>summary.hideme::after{content:"";}details.rustdoc-toggle>summary:focus::before,details.rustdoc-toggle>summary:hover::before{opacity:1;}details.rustdoc-toggle>summary:focus-visible::before{outline:1px dotted #000;outline-offset:1px;}details.non-exhaustive{margin-bottom:8px;}details.rustdoc-toggle>summary.hideme::before{position:relative;}details.rustdoc-toggle>summary:not(.hideme)::before{position:absolute;left:-24px;top:4px;}.impl-items>details.rustdoc-toggle>summary:not(.hideme)::before{position:absolute;left:-24px;}details.rustdoc-toggle[open] >summary.hideme{position:absolute;}details.rustdoc-toggle[open] >summary.hideme>span{display:none;}details.rustdoc-toggle[open] >summary::before{background:url("toggle-minus-31bbd6e4c77f5c96.svg") no-repeat top left;}details.rustdoc-toggle[open] >summary::after{content:"Collapse";}.docblock summary>*{display:inline-block;}.docblock>.example-wrap:first-child .tooltip{margin-top:16px;}@media (max-width:700px){*[id]{scroll-margin-top:45px;}.rustdoc{display:block;}main{padding-left:15px;padding-top:0px;}.main-heading{flex-direction:column;}.out-of-band{text-align:left;margin-left:initial;padding:initial;}.out-of-band .since::before{content:"Since ";}.sidebar .sidebar-logo,.sidebar .location{display:none;}.sidebar{position:fixed;top:45px;left:-1000px;z-index:11;height:calc(100vh - 45px);width:200px;}.source main,.rustdoc.source .sidebar{top:0;padding:0;height:100vh;border:0;}.sidebar.shown,.source-sidebar-expanded .source .sidebar,.sidebar:focus-within{left:0;}.rustdoc.source>.sidebar{width:0;}.mobile-topbar h2{padding-bottom:0;margin:auto 0.5em auto auto;overflow:hidden;font-size:24px;}.mobile-topbar h2 a{display:block;text-overflow:ellipsis;overflow:hidden;white-space:nowrap;}.mobile-topbar .logo-container>img{max-width:35px;max-height:35px;margin:5px 0 5px 20px;}.mobile-topbar{display:flex;flex-direction:row;position:sticky;z-index:10;font-size:2rem;height:45px;width:100%;left:0;top:0;}.sidebar-menu-toggle{width:45px;font-size:32px;border:none;color:var(--main-color);}.sidebar-elems{margin-top:1em;}.content{margin-left:0px;}.anchor{display:none !important;}#titles>button>div.count{display:block;}#main-content>details.rustdoc-toggle>summary::before,#main-content>div>details.rustdoc-toggle>summary::before{left:-11px;}#sidebar-toggle{position:fixed;left:1px;top:100px;width:30px;font-size:1.5rem;padding:0;z-index:10;border-top-right-radius:3px;border-bottom-right-radius:3px;border:1px solid;border-left:0;}.source-sidebar-expanded #sidebar-toggle{left:unset;top:unset;width:unset;border-top-right-radius:unset;border-bottom-right-radius:unset;position:sticky;border:0;border-bottom:1px solid;}#copy-path,#help-button{display:none;}.item-table,.item-row,.item-left,.item-right,.search-results>a,.search-results>a>div{display:block;}.search-results>a{padding:5px 0px;}.search-results>a>div.desc,.item-right{padding-left:2em;}.source-sidebar-expanded .source .sidebar{max-width:100vw;width:100vw;}details.rustdoc-toggle:not(.top-doc)>summary{margin-left:10px;}.impl-items>details.rustdoc-toggle>summary:not(.hideme)::before,#main-content>details.rustdoc-toggle:not(.top-doc)>summary::before,#main-content>div>details.rustdoc-toggle>summary::before{left:-11px;}.impl-items>.item-info{margin-left:34px;}.source nav.sub{margin:0;padding:8px;}}@media (min-width:701px){.scraped-example-title{position:absolute;z-index:10;background:var(--main-background-color);bottom:8px;right:5px;padding:2px 4px;box-shadow:0 0 4px var(--main-background-color);}}@media print{nav.sidebar,nav.sub,.out-of-band,a.srclink,#copy-path,details.rustdoc-toggle[open] >summary::before,details.rustdoc-toggle>summary::before,details.rustdoc-toggle.top-doc>summary{display:none;}.docblock{margin-left:0;}main{padding:10px;}}@media (max-width:464px){.docblock{margin-left:12px;}.docblock code{overflow-wrap:break-word;overflow-wrap:anywhere;}nav.sub{flex-direction:column;}.search-form{align-self:stretch;}.sub-logo-container>img{height:35px;width:35px;}#sidebar-toggle{top:10px;}.source-sidebar-expanded #sidebar-toggle{top:unset;}}.variant,.implementors-toggle>summary,.impl,#implementors-list>.docblock,.impl-items>section,.impl-items>.rustdoc-toggle>summary,.methods>section,.methods>.rustdoc-toggle>summary{margin-bottom:0.75em;}.variants>.docblock,.impl-items>.rustdoc-toggle[open]:not(:last-child),.methods>.rustdoc-toggle[open]:not(:last-child),.implementors-toggle[open]:not(:last-child){margin-bottom:2em;}#trait-implementations-list .impl-items>.rustdoc-toggle:not(:last-child),#synthetic-implementations-list .impl-items>.rustdoc-toggle:not(:last-child),#blanket-implementations-list .impl-items>.rustdoc-toggle:not(:last-child){margin-bottom:1em;}.scraped-example-list .scrape-help{margin-left:10px;padding:0 4px;font-weight:normal;font-size:12px;position:relative;bottom:1px;border-width:1px;border-style:solid;border-radius:50px;}.scraped-example{position:relative;}.scraped-example .code-wrapper{position:relative;display:flex;flex-direction:row;flex-wrap:wrap;width:100%;}.scraped-example:not(.expanded) .code-wrapper{max-height:calc(1.5em * 5 + 10px);}.scraped-example:not(.expanded) .code-wrapper pre{overflow-y:hidden;padding-bottom:0;max-height:calc(1.5em * 5 + 10px);}.more-scraped-examples .scraped-example:not(.expanded) .code-wrapper,.more-scraped-examples .scraped-example:not(.expanded) .code-wrapper pre{max-height:calc(1.5em * 10 + 10px);}.scraped-example .code-wrapper .next,.scraped-example .code-wrapper .prev,.scraped-example .code-wrapper .expand{color:var(--main-color);position:absolute;top:0.25em;z-index:1;padding:0;background:none;border:none;-webkit-appearance:none;opacity:1;}.scraped-example .code-wrapper .prev{right:2.25em;}.scraped-example .code-wrapper .next{right:1.25em;}.scraped-example .code-wrapper .expand{right:0.25em;}.scraped-example:not(.expanded) .code-wrapper:before,.scraped-example:not(.expanded) .code-wrapper:after{content:" ";width:100%;height:5px;position:absolute;z-index:1;}.scraped-example:not(.expanded) .code-wrapper:before{top:0;}.scraped-example:not(.expanded) .code-wrapper:after{bottom:0;}.scraped-example .code-wrapper .src-line-numbers{margin:0;padding:14px 0;}.scraped-example .code-wrapper .src-line-numbers a,.scraped-example .code-wrapper .src-line-numbers span{padding:0 14px;}.scraped-example .code-wrapper .example-wrap{display:grid;grid-template-columns:max-content auto;width:100%;overflow-x:auto;overflow-y:hidden;margin-bottom:0;}.scraped-example:not(.expanded) .code-wrapper .example-wrap{overflow-x:hidden;}.scraped-example .code-wrapper .example-wrap pre.rust{overflow-x:inherit;width:inherit;overflow-y:hidden;}.more-examples-toggle{max-width:calc(100% + 25px);margin-top:10px;margin-left:-25px;}.more-examples-toggle .hide-more{margin-left:25px;margin-bottom:5px;cursor:pointer;}.more-scraped-examples{margin-left:5px;display:flex;flex-direction:row;}.more-scraped-examples-inner{width:calc(100% - 20px);}.toggle-line{align-self:stretch;margin-right:10px;margin-top:5px;padding:0 4px;cursor:pointer;}.toggle-line-inner{min-width:2px;height:100%;}.more-scraped-examples .scraped-example{margin-bottom:20px;}.more-scraped-examples .scraped-example:last-child{margin-bottom:0;}.example-links a{margin-top:20px;}.example-links ul{margin-bottom:0;} \ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/static.files/scrape-examples-ef1e698c1d417c0c.js b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/static.files/scrape-examples-ef1e698c1d417c0c.js new file mode 100644 index 0000000000..ba830e3744 --- /dev/null +++ b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/static.files/scrape-examples-ef1e698c1d417c0c.js @@ -0,0 +1 @@ +"use strict";(function(){const DEFAULT_MAX_LINES=5;const HIDDEN_MAX_LINES=10;function scrollToLoc(elt,loc,isHidden){const lines=elt.querySelector(".src-line-numbers");let scrollOffset;const maxLines=isHidden?HIDDEN_MAX_LINES:DEFAULT_MAX_LINES;if(loc[1]-loc[0]>maxLines){const line=Math.max(0,loc[0]-1);scrollOffset=lines.children[line].offsetTop}else{const wrapper=elt.querySelector(".code-wrapper");const halfHeight=wrapper.offsetHeight/2;const offsetTop=lines.children[loc[0]].offsetTop;const lastLine=lines.children[loc[1]];const offsetBot=lastLine.offsetTop+lastLine.offsetHeight;const offsetMid=(offsetTop+offsetBot)/2;scrollOffset=offsetMid-halfHeight}lines.scrollTo(0,scrollOffset);elt.querySelector(".rust").scrollTo(0,scrollOffset)}function updateScrapedExample(example,isHidden){const locs=JSON.parse(example.attributes.getNamedItem("data-locs").textContent);let locIndex=0;const highlights=Array.prototype.slice.call(example.querySelectorAll(".highlight"));const link=example.querySelector(".scraped-example-title a");if(locs.length>1){const onChangeLoc=changeIndex=>{removeClass(highlights[locIndex],"focus");changeIndex();scrollToLoc(example,locs[locIndex][0],isHidden);addClass(highlights[locIndex],"focus");const url=locs[locIndex][1];const title=locs[locIndex][2];link.href=url;link.innerHTML=title};example.querySelector(".prev").addEventListener("click",()=>{onChangeLoc(()=>{locIndex=(locIndex-1+locs.length)%locs.length})});example.querySelector(".next").addEventListener("click",()=>{onChangeLoc(()=>{locIndex=(locIndex+1)%locs.length})})}const expandButton=example.querySelector(".expand");if(expandButton){expandButton.addEventListener("click",()=>{if(hasClass(example,"expanded")){removeClass(example,"expanded");scrollToLoc(example,locs[0][0],isHidden)}else{addClass(example,"expanded")}})}scrollToLoc(example,locs[0][0],isHidden)}const firstExamples=document.querySelectorAll(".scraped-example-list > .scraped-example");onEachLazy(firstExamples,el=>updateScrapedExample(el,false));onEachLazy(document.querySelectorAll(".more-examples-toggle"),toggle=>{onEachLazy(toggle.querySelectorAll(".toggle-line, .hide-more"),button=>{button.addEventListener("click",()=>{toggle.open=false})});const moreExamples=toggle.querySelectorAll(".scraped-example");toggle.querySelector("summary").addEventListener("click",()=>{setTimeout(()=>{onEachLazy(moreExamples,el=>updateScrapedExample(el,true))})},{once:true})})})() \ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/static.files/search-444266647c4dba98.js b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/static.files/search-444266647c4dba98.js new file mode 100644 index 0000000000..bf59e1d8eb --- /dev/null +++ b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/static.files/search-444266647c4dba98.js @@ -0,0 +1 @@ +"use strict";(function(){const itemTypes=["mod","externcrate","import","struct","enum","fn","type","static","trait","impl","tymethod","method","structfield","variant","macro","primitive","associatedtype","constant","associatedconstant","union","foreigntype","keyword","existential","attr","derive","traitalias",];const TY_PRIMITIVE=itemTypes.indexOf("primitive");const TY_KEYWORD=itemTypes.indexOf("keyword");const ROOT_PATH=typeof window!=="undefined"?window.rootPath:"../";function hasOwnPropertyRustdoc(obj,property){return Object.prototype.hasOwnProperty.call(obj,property)}function printTab(nb){let iter=0;let foundCurrentTab=false;let foundCurrentResultSet=false;onEachLazy(document.getElementById("titles").childNodes,elem=>{if(nb===iter){addClass(elem,"selected");foundCurrentTab=true}else{removeClass(elem,"selected")}iter+=1});iter=0;onEachLazy(document.getElementById("results").childNodes,elem=>{if(nb===iter){addClass(elem,"active");foundCurrentResultSet=true}else{removeClass(elem,"active")}iter+=1});if(foundCurrentTab&&foundCurrentResultSet){searchState.currentTab=nb}else if(nb!==0){printTab(0)}}const levenshtein_row2=[];function levenshtein(s1,s2){if(s1===s2){return 0}const s1_len=s1.length,s2_len=s2.length;if(s1_len&&s2_len){let i1=0,i2=0,a,b,c,c2;const row=levenshtein_row2;while(i1-".indexOf(c)!==-1}function isStopCharacter(c){return isWhitespace(c)||isEndCharacter(c)}function isErrorCharacter(c){return"()".indexOf(c)!==-1}function itemTypeFromName(typename){for(let i=0,len=itemTypes.length;i0){throw new Error("Cannot use literal search when there is more than one element")}parserState.pos+=1;const start=parserState.pos;const end=getIdentEndPosition(parserState);if(parserState.pos>=parserState.length){throw new Error("Unclosed `\"`")}else if(parserState.userQuery[end]!=="\""){throw new Error(`Unexpected \`${parserState.userQuery[end]}\` in a string element`)}else if(start===end){throw new Error("Cannot have empty string element")}parserState.pos+=1;query.literalSearch=true}function isPathStart(parserState){return parserState.userQuery.slice(parserState.pos,parserState.pos+2)==="::"}function isReturnArrow(parserState){return parserState.userQuery.slice(parserState.pos,parserState.pos+2)==="->"}function isIdentCharacter(c){return(c==="_"||(c>="0"&&c<="9")||(c>="a"&&c<="z")||(c>="A"&&c<="Z"))}function isSeparatorCharacter(c){return c===","||isWhitespaceCharacter(c)}function isWhitespaceCharacter(c){return c===" "||c==="\t"}function createQueryElement(query,parserState,name,generics,isInGenerics){if(name==="*"||(name.length===0&&generics.length===0)){return}if(query.literalSearch&&parserState.totalElems-parserState.genericsElems>0){throw new Error("You cannot have more than one element if you use quotes")}const pathSegments=name.split("::");if(pathSegments.length>1){for(let i=0,len=pathSegments.length;i=end){throw new Error("Found generics without a path")}parserState.pos+=1;getItemsBefore(query,parserState,generics,">")}if(start>=end&&generics.length===0){return}elems.push(createQueryElement(query,parserState,parserState.userQuery.slice(start,end),generics,isInGenerics))}function getItemsBefore(query,parserState,elems,endChar){let foundStopChar=true;while(parserState.pos"){extra="`<`"}else if(endChar===""){extra="`->`"}throw new Error("Unexpected `"+c+"` after "+extra)}if(!foundStopChar){if(endChar!==""){throw new Error(`Expected \`,\`, \` \` or \`${endChar}\`, found \`${c}\``)}throw new Error(`Expected \`,\` or \` \`, found \`${c}\``)}const posBefore=parserState.pos;getNextElem(query,parserState,elems,endChar===">");if(posBefore===parserState.pos){parserState.pos+=1}foundStopChar=false}parserState.pos+=1}function checkExtraTypeFilterCharacters(parserState){const query=parserState.userQuery;for(let pos=0;pos"){if(isReturnArrow(parserState)){break}throw new Error(`Unexpected \`${c}\` (did you mean \`->\`?)`)}throw new Error(`Unexpected \`${c}\``)}else if(c===":"&&!isPathStart(parserState)){if(parserState.typeFilter!==null){throw new Error("Unexpected `:`")}if(query.elems.length===0){throw new Error("Expected type filter before `:`")}else if(query.elems.length!==1||parserState.totalElems!==1){throw new Error("Unexpected `:`")}else if(query.literalSearch){throw new Error("You cannot use quotes on type filter")}checkExtraTypeFilterCharacters(parserState);parserState.typeFilter=query.elems.pop().name;parserState.pos+=1;parserState.totalElems=0;query.literalSearch=false;foundStopChar=true;continue}if(!foundStopChar){if(parserState.typeFilter!==null){throw new Error(`Expected \`,\`, \` \` or \`->\`, found \`${c}\``)}throw new Error(`Expected \`,\`, \` \`, \`:\` or \`->\`, found \`${c}\``)}before=query.elems.length;getNextElem(query,parserState,query.elems,false);if(query.elems.length===before){parserState.pos+=1}foundStopChar=false}while(parserState.pos`")}break}else{parserState.pos+=1}}}function newParsedQuery(userQuery){return{original:userQuery,userQuery:userQuery.toLowerCase(),typeFilter:NO_TYPE_FILTER,elems:[],returned:[],foundElems:0,literalSearch:false,error:null,}}function buildUrl(search,filterCrates){let extra="?search="+encodeURIComponent(search);if(filterCrates!==null){extra+="&filter-crate="+encodeURIComponent(filterCrates)}return getNakedUrl()+extra+window.location.hash}function getFilterCrates(){const elem=document.getElementById("crate-search");if(elem&&elem.value!=="all crates"&&hasOwnPropertyRustdoc(rawSearchIndex,elem.value)){return elem.value}return null}function parseQuery(userQuery){userQuery=userQuery.trim();const parserState={length:userQuery.length,pos:0,totalElems:0,genericsElems:0,typeFilter:null,userQuery:userQuery.toLowerCase(),};let query=newParsedQuery(userQuery);try{parseInput(query,parserState);if(parserState.typeFilter!==null){let typeFilter=parserState.typeFilter;if(typeFilter==="const"){typeFilter="constant"}query.typeFilter=itemTypeFromName(typeFilter)}}catch(err){query=newParsedQuery(userQuery);query.error=err.message;query.typeFilter=-1;return query}if(!query.literalSearch){query.literalSearch=parserState.totalElems>1}query.foundElems=query.elems.length+query.returned.length;return query}function createQueryResults(results_in_args,results_returned,results_others,parsedQuery){return{"in_args":results_in_args,"returned":results_returned,"others":results_others,"query":parsedQuery,}}function execQuery(parsedQuery,searchWords,filterCrates,currentCrate){const results_others={},results_in_args={},results_returned={};function transformResults(results){const duplicates={};const out=[];for(const result of results){if(result.id>-1){const obj=searchIndex[result.id];obj.lev=result.lev;const res=buildHrefAndPath(obj);obj.displayPath=pathSplitter(res[0]);obj.fullPath=obj.displayPath+obj.name;obj.fullPath+="|"+obj.ty;if(duplicates[obj.fullPath]){continue}duplicates[obj.fullPath]=true;obj.href=res[1];out.push(obj);if(out.length>=MAX_RESULTS){break}}}return out}function sortResults(results,isType,preferredCrate){const userQuery=parsedQuery.userQuery;const ar=[];for(const entry in results){if(hasOwnPropertyRustdoc(results,entry)){const result=results[entry];result.word=searchWords[result.id];result.item=searchIndex[result.id]||{};ar.push(result)}}results=ar;if(results.length===0){return[]}results.sort((aaa,bbb)=>{let a,b;a=(aaa.word!==userQuery);b=(bbb.word!==userQuery);if(a!==b){return a-b}a=(aaa.lev);b=(bbb.lev);if(a!==b){return a-b}a=(aaa.item.crate!==preferredCrate);b=(bbb.item.crate!==preferredCrate);if(a!==b){return a-b}a=aaa.word.length;b=bbb.word.length;if(a!==b){return a-b}a=aaa.word;b=bbb.word;if(a!==b){return(a>b?+1:-1)}a=(aaa.index<0);b=(bbb.index<0);if(a!==b){return a-b}a=aaa.index;b=bbb.index;if(a!==b){return a-b}if((aaa.item.ty===TY_PRIMITIVE&&bbb.item.ty!==TY_KEYWORD)||(aaa.item.ty===TY_KEYWORD&&bbb.item.ty!==TY_PRIMITIVE)){return-1}if((bbb.item.ty===TY_PRIMITIVE&&aaa.item.ty!==TY_PRIMITIVE)||(bbb.item.ty===TY_KEYWORD&&aaa.item.ty!==TY_KEYWORD)){return 1}a=(aaa.item.desc==="");b=(bbb.item.desc==="");if(a!==b){return a-b}a=aaa.item.ty;b=bbb.item.ty;if(a!==b){return a-b}a=aaa.item.path;b=bbb.item.path;if(a!==b){return(a>b?+1:-1)}return 0});let nameSplit=null;if(parsedQuery.elems.length===1){const hasPath=typeof parsedQuery.elems[0].path==="undefined";nameSplit=hasPath?null:parsedQuery.elems[0].path}for(const result of results){if(result.dontValidate){continue}const name=result.item.name.toLowerCase(),path=result.item.path.toLowerCase(),parent=result.item.parent;if(!isType&&!validateResult(name,path,nameSplit,parent)){result.id=-1}}return transformResults(results)}function checkGenerics(row,elem,defaultLev){if(row.generics.length===0){return elem.generics.length===0?defaultLev:MAX_LEV_DISTANCE+1}else if(row.generics.length>0&&row.generics[0].name===null){return checkGenerics(row.generics[0],elem,defaultLev)}let elem_name;if(elem.generics.length>0&&row.generics.length>=elem.generics.length){const elems=Object.create(null);for(const entry of row.generics){elem_name=entry.name;if(elem_name===""){if(checkGenerics(entry,elem,MAX_LEV_DISTANCE+1)!==0){return MAX_LEV_DISTANCE+1}continue}if(elems[elem_name]===undefined){elems[elem_name]=0}elems[elem_name]+=1}for(const generic of elem.generics){let match=null;if(elems[generic.name]){match=generic.name}else{for(elem_name in elems){if(!hasOwnPropertyRustdoc(elems,elem_name)){continue}if(elem_name===generic){match=elem_name;break}}}if(match===null){return MAX_LEV_DISTANCE+1}elems[match]-=1;if(elems[match]===0){delete elems[match]}}return 0}return MAX_LEV_DISTANCE+1}function checkIfInGenerics(row,elem){let lev=MAX_LEV_DISTANCE+1;for(const entry of row.generics){lev=Math.min(checkType(entry,elem,true),lev);if(lev===0){break}}return lev}function checkType(row,elem,literalSearch){if(row.name===null){if(row.generics.length>0){return checkIfInGenerics(row,elem)}return MAX_LEV_DISTANCE+1}let lev=levenshtein(row.name,elem.name);if(literalSearch){if(lev!==0){if(elem.generics.length===0){const checkGeneric=row.generics.length>0;if(checkGeneric&&row.generics.findIndex(tmp_elem=>tmp_elem.name===elem.name)!==-1){return 0}}return MAX_LEV_DISTANCE+1}else if(elem.generics.length>0){return checkGenerics(row,elem,MAX_LEV_DISTANCE+1)}return 0}else if(row.generics.length>0){if(elem.generics.length===0){if(lev===0){return 0}lev=checkIfInGenerics(row,elem);return lev+0.5}else if(lev>MAX_LEV_DISTANCE){return checkIfInGenerics(row,elem)}else{const tmp_lev=checkGenerics(row,elem,lev);if(tmp_lev>MAX_LEV_DISTANCE){return MAX_LEV_DISTANCE+1}return(tmp_lev+lev)/2}}else if(elem.generics.length>0){return MAX_LEV_DISTANCE+1}return lev}function findArg(row,elem,typeFilter){let lev=MAX_LEV_DISTANCE+1;if(row&&row.type&&row.type.inputs&&row.type.inputs.length>0){for(const input of row.type.inputs){if(!typePassesFilter(typeFilter,input.ty)){continue}lev=Math.min(lev,checkType(input,elem,parsedQuery.literalSearch));if(lev===0){return 0}}}return parsedQuery.literalSearch?MAX_LEV_DISTANCE+1:lev}function checkReturned(row,elem,typeFilter){let lev=MAX_LEV_DISTANCE+1;if(row&&row.type&&row.type.output.length>0){const ret=row.type.output;for(const ret_ty of ret){if(!typePassesFilter(typeFilter,ret_ty.ty)){continue}lev=Math.min(lev,checkType(ret_ty,elem,parsedQuery.literalSearch));if(lev===0){return 0}}}return parsedQuery.literalSearch?MAX_LEV_DISTANCE+1:lev}function checkPath(contains,ty){if(contains.length===0){return 0}let ret_lev=MAX_LEV_DISTANCE+1;const path=ty.path.split("::");if(ty.parent&&ty.parent.name){path.push(ty.parent.name.toLowerCase())}const length=path.length;const clength=contains.length;if(clength>length){return MAX_LEV_DISTANCE+1}for(let i=0;ilength){break}let lev_total=0;let aborted=false;for(let x=0;xMAX_LEV_DISTANCE){aborted=true;break}lev_total+=lev}if(!aborted){ret_lev=Math.min(ret_lev,Math.round(lev_total/clength))}}return ret_lev}function typePassesFilter(filter,type){if(filter<=NO_TYPE_FILTER||filter===type)return true;const name=itemTypes[type];switch(itemTypes[filter]){case"constant":return name==="associatedconstant";case"fn":return name==="method"||name==="tymethod";case"type":return name==="primitive"||name==="associatedtype";case"trait":return name==="traitalias"}return false}function createAliasFromItem(item){return{crate:item.crate,name:item.name,path:item.path,desc:item.desc,ty:item.ty,parent:item.parent,type:item.type,is_alias:true,}}function handleAliases(ret,query,filterCrates,currentCrate){const lowerQuery=query.toLowerCase();const aliases=[];const crateAliases=[];if(filterCrates!==null){if(ALIASES[filterCrates]&&ALIASES[filterCrates][lowerQuery]){const query_aliases=ALIASES[filterCrates][lowerQuery];for(const alias of query_aliases){aliases.push(createAliasFromItem(searchIndex[alias]))}}}else{Object.keys(ALIASES).forEach(crate=>{if(ALIASES[crate][lowerQuery]){const pushTo=crate===currentCrate?crateAliases:aliases;const query_aliases=ALIASES[crate][lowerQuery];for(const alias of query_aliases){pushTo.push(createAliasFromItem(searchIndex[alias]))}}})}const sortFunc=(aaa,bbb)=>{if(aaa.path{alias.alias=query;const res=buildHrefAndPath(alias);alias.displayPath=pathSplitter(res[0]);alias.fullPath=alias.displayPath+alias.name;alias.href=res[1];ret.others.unshift(alias);if(ret.others.length>MAX_RESULTS){ret.others.pop()}};aliases.forEach(pushFunc);crateAliases.forEach(pushFunc)}function addIntoResults(results,fullId,id,index,lev){if(lev===0||(!parsedQuery.literalSearch&&lev<=MAX_LEV_DISTANCE)){if(results[fullId]!==undefined){const result=results[fullId];if(result.dontValidate||result.lev<=lev){return}}results[fullId]={id:id,index:index,dontValidate:parsedQuery.literalSearch,lev:lev,}}}function handleSingleArg(row,pos,elem,results_others,results_in_args,results_returned){if(!row||(filterCrates!==null&&row.crate!==filterCrates)){return}let lev,lev_add=0,index=-1;const fullId=row.id;const in_args=findArg(row,elem,parsedQuery.typeFilter);const returned=checkReturned(row,elem,parsedQuery.typeFilter);addIntoResults(results_in_args,fullId,pos,index,in_args);addIntoResults(results_returned,fullId,pos,index,returned);if(!typePassesFilter(parsedQuery.typeFilter,row.ty)){return}const searchWord=searchWords[pos];if(parsedQuery.literalSearch){if(searchWord===elem.name){addIntoResults(results_others,fullId,pos,-1,0)}return}if(elem.name.length===0){if(row.type!==null){lev=checkGenerics(row.type,elem,MAX_LEV_DISTANCE+1);addIntoResults(results_others,fullId,pos,index,lev)}return}if(elem.fullPath.length>1){lev=checkPath(elem.pathWithoutLast,row);if(lev>MAX_LEV_DISTANCE||(parsedQuery.literalSearch&&lev!==0)){return}else if(lev>0){lev_add=lev/10}}if(searchWord.indexOf(elem.pathLast)>-1||row.normalizedName.indexOf(elem.pathLast)>-1){index=row.normalizedName.indexOf(elem.pathLast)}lev=levenshtein(searchWord,elem.pathLast);if(lev>0&&elem.pathLast.length>2&&searchWord.indexOf(elem.pathLast)>-1){if(elem.pathLast.length<6){lev=1}else{lev=0}}lev+=lev_add;if(lev>MAX_LEV_DISTANCE){return}else if(index!==-1&&elem.fullPath.length<2){lev-=1}if(lev<0){lev=0}addIntoResults(results_others,fullId,pos,index,lev)}function handleArgs(row,pos,results){if(!row||(filterCrates!==null&&row.crate!==filterCrates)){return}let totalLev=0;let nbLev=0;function checkArgs(elems,callback){for(const elem of elems){const lev=callback(row,elem,NO_TYPE_FILTER);if(lev<=1){nbLev+=1;totalLev+=lev}else{return false}}return true}if(!checkArgs(parsedQuery.elems,findArg)){return}if(!checkArgs(parsedQuery.returned,checkReturned)){return}if(nbLev===0){return}const lev=Math.round(totalLev/nbLev);addIntoResults(results,row.id,pos,0,lev)}function innerRunQuery(){let elem,i,nSearchWords,in_returned,row;if(parsedQuery.foundElems===1){if(parsedQuery.elems.length===1){elem=parsedQuery.elems[0];for(i=0,nSearchWords=searchWords.length;i0){for(i=0,nSearchWords=searchWords.length;i-1||path.indexOf(key)>-1||(parent!==undefined&&parent.name!==undefined&&parent.name.toLowerCase().indexOf(key)>-1)||levenshtein(name,key)<=MAX_LEV_DISTANCE)){return false}}return true}function nextTab(direction){const next=(searchState.currentTab+direction+3)%searchState.focusedByTab.length;searchState.focusedByTab[searchState.currentTab]=document.activeElement;printTab(next);focusSearchResult()}function focusSearchResult(){const target=searchState.focusedByTab[searchState.currentTab]||document.querySelectorAll(".search-results.active a").item(0)||document.querySelectorAll("#titles > button").item(searchState.currentTab);searchState.focusedByTab[searchState.currentTab]=null;if(target){target.focus()}}function buildHrefAndPath(item){let displayPath;let href;const type=itemTypes[item.ty];const name=item.name;let path=item.path;if(type==="mod"){displayPath=path+"::";href=ROOT_PATH+path.replace(/::/g,"/")+"/"+name+"/index.html"}else if(type==="import"){displayPath=item.path+"::";href=ROOT_PATH+item.path.replace(/::/g,"/")+"/index.html#reexport."+name}else if(type==="primitive"||type==="keyword"){displayPath="";href=ROOT_PATH+path.replace(/::/g,"/")+"/"+type+"."+name+".html"}else if(type==="externcrate"){displayPath="";href=ROOT_PATH+name+"/index.html"}else if(item.parent!==undefined){const myparent=item.parent;let anchor="#"+type+"."+name;const parentType=itemTypes[myparent.ty];let pageType=parentType;let pageName=myparent.name;if(parentType==="primitive"){displayPath=myparent.name+"::"}else if(type==="structfield"&&parentType==="variant"){const enumNameIdx=item.path.lastIndexOf("::");const enumName=item.path.substr(enumNameIdx+2);path=item.path.substr(0,enumNameIdx);displayPath=path+"::"+enumName+"::"+myparent.name+"::";anchor="#variant."+myparent.name+".field."+name;pageType="enum";pageName=enumName}else{displayPath=path+"::"+myparent.name+"::"}href=ROOT_PATH+path.replace(/::/g,"/")+"/"+pageType+"."+pageName+".html"+anchor}else{displayPath=item.path+"::";href=ROOT_PATH+item.path.replace(/::/g,"/")+"/"+type+"."+name+".html"}return[displayPath,href]}function pathSplitter(path){const tmp=""+path.replace(/::/g,"::");if(tmp.endsWith("")){return tmp.slice(0,tmp.length-6)}return tmp}function addTab(array,query,display){let extraClass="";if(display===true){extraClass=" active"}const output=document.createElement("div");let length=0;if(array.length>0){output.className="search-results "+extraClass;array.forEach(item=>{const name=item.name;const type=itemTypes[item.ty];length+=1;let extra="";if(type==="primitive"){extra=" (primitive type)"}else if(type==="keyword"){extra=" (keyword)"}const link=document.createElement("a");link.className="result-"+type;link.href=item.href;const resultName=document.createElement("div");resultName.className="result-name";if(item.is_alias){const alias=document.createElement("span");alias.className="alias";const bold=document.createElement("b");bold.innerText=item.alias;alias.appendChild(bold);alias.insertAdjacentHTML("beforeend"," - see ");resultName.appendChild(alias)}resultName.insertAdjacentHTML("beforeend",item.displayPath+""+name+extra+"");link.appendChild(resultName);const description=document.createElement("div");description.className="desc";description.insertAdjacentHTML("beforeend",item.desc);link.appendChild(description);output.appendChild(link)})}else if(query.error===null){output.className="search-failed"+extraClass;output.innerHTML="No results :(
    "+"Try on DuckDuckGo?

    "+"Or try looking in one of these:"}return[output,length]}function makeTabHeader(tabNb,text,nbElems){if(searchState.currentTab===tabNb){return""}return""}function showResults(results,go_to_first,filterCrates){const search=searchState.outputElement();if(go_to_first||(results.others.length===1&&getSettingValue("go-to-only-result")==="true"&&(!search.firstChild||search.firstChild.innerText!==searchState.loadingText))){const elem=document.createElement("a");elem.href=results.others[0].href;removeClass(elem,"active");document.body.appendChild(elem);elem.click();return}if(results.query===undefined){results.query=parseQuery(searchState.input.value)}currentResults=results.query.userQuery;const ret_others=addTab(results.others,results.query,true);const ret_in_args=addTab(results.in_args,results.query,false);const ret_returned=addTab(results.returned,results.query,false);let currentTab=searchState.currentTab;if((currentTab===0&&ret_others[1]===0)||(currentTab===1&&ret_in_args[1]===0)||(currentTab===2&&ret_returned[1]===0)){if(ret_others[1]!==0){currentTab=0}else if(ret_in_args[1]!==0){currentTab=1}else if(ret_returned[1]!==0){currentTab=2}}let crates="";const crates_list=Object.keys(rawSearchIndex);if(crates_list.length>1){crates=" in 
    "}let output=`

    Results${crates}

    `;if(results.query.error!==null){output+=`

    Query parser error: "${results.query.error}".

    `;output+="
    "+makeTabHeader(0,"In Names",ret_others[1])+"
    ";currentTab=0}else if(results.query.foundElems<=1&&results.query.returned.length===0){output+="
    "+makeTabHeader(0,"In Names",ret_others[1])+makeTabHeader(1,"In Parameters",ret_in_args[1])+makeTabHeader(2,"In Return Types",ret_returned[1])+"
    "}else{const signatureTabTitle=results.query.elems.length===0?"In Function Return Types":results.query.returned.length===0?"In Function Parameters":"In Function Signatures";output+="
    "+makeTabHeader(0,signatureTabTitle,ret_others[1])+"
    ";currentTab=0}const resultsElem=document.createElement("div");resultsElem.id="results";resultsElem.appendChild(ret_others[0]);resultsElem.appendChild(ret_in_args[0]);resultsElem.appendChild(ret_returned[0]);search.innerHTML=output;const crateSearch=document.getElementById("crate-search");if(crateSearch){crateSearch.addEventListener("input",updateCrate)}search.appendChild(resultsElem);searchState.showResults(search);const elems=document.getElementById("titles").childNodes;searchState.focusedByTab=[];let i=0;for(const elem of elems){const j=i;elem.onclick=()=>printTab(j);searchState.focusedByTab.push(null);i+=1}printTab(currentTab)}function search(e,forced){if(e){e.preventDefault()}const query=parseQuery(searchState.input.value.trim());let filterCrates=getFilterCrates();if(!forced&&query.userQuery===currentResults){if(query.userQuery.length>0){putBackSearch()}return}searchState.setLoadingSearch();const params=searchState.getQueryStringParams();if(filterCrates===null&¶ms["filter-crate"]!==undefined){filterCrates=params["filter-crate"]}searchState.title="Results for "+query.original+" - Rust";if(browserSupportsHistoryApi()){const newURL=buildUrl(query.original,filterCrates);if(!history.state&&!params.search){history.pushState(null,"",newURL)}else{history.replaceState(null,"",newURL)}}showResults(execQuery(query,searchWords,filterCrates,window.currentCrate),params.go_to_first,filterCrates)}function buildItemSearchTypeAll(types,lowercasePaths){const PATH_INDEX_DATA=0;const GENERICS_DATA=1;return types.map(type=>{let pathIndex,generics;if(typeof type==="number"){pathIndex=type;generics=[]}else{pathIndex=type[PATH_INDEX_DATA];generics=buildItemSearchTypeAll(type[GENERICS_DATA],lowercasePaths)}return{name:pathIndex===0?null:lowercasePaths[pathIndex-1].name,ty:pathIndex===0?null:lowercasePaths[pathIndex-1].ty,generics:generics,}})}function buildFunctionSearchType(functionSearchType,lowercasePaths){const INPUTS_DATA=0;const OUTPUT_DATA=1;if(functionSearchType===0){return null}let inputs,output;if(typeof functionSearchType[INPUTS_DATA]==="number"){const pathIndex=functionSearchType[INPUTS_DATA];inputs=[{name:pathIndex===0?null:lowercasePaths[pathIndex-1].name,ty:pathIndex===0?null:lowercasePaths[pathIndex-1].ty,generics:[],}]}else{inputs=buildItemSearchTypeAll(functionSearchType[INPUTS_DATA],lowercasePaths)}if(functionSearchType.length>1){if(typeof functionSearchType[OUTPUT_DATA]==="number"){const pathIndex=functionSearchType[OUTPUT_DATA];output=[{name:pathIndex===0?null:lowercasePaths[pathIndex-1].name,ty:pathIndex===0?null:lowercasePaths[pathIndex-1].ty,generics:[],}]}else{output=buildItemSearchTypeAll(functionSearchType[OUTPUT_DATA],lowercasePaths)}}else{output=[]}return{inputs,output,}}function buildIndex(rawSearchIndex){searchIndex=[];const searchWords=[];let i,word;let currentIndex=0;let id=0;for(const crate in rawSearchIndex){if(!hasOwnPropertyRustdoc(rawSearchIndex,crate)){continue}let crateSize=0;const crateCorpus=rawSearchIndex[crate];searchWords.push(crate);const crateRow={crate:crate,ty:1,name:crate,path:"",desc:crateCorpus.doc,parent:undefined,type:null,id:id,normalizedName:crate.indexOf("_")===-1?crate:crate.replace(/_/g,""),};id+=1;searchIndex.push(crateRow);currentIndex+=1;const itemTypes=crateCorpus.t;const itemNames=crateCorpus.n;const itemPaths=crateCorpus.q;const itemDescs=crateCorpus.d;const itemParentIdxs=crateCorpus.i;const itemFunctionSearchTypes=crateCorpus.f;const paths=crateCorpus.p;const aliases=crateCorpus.a;const lowercasePaths=[];let len=paths.length;for(i=0;i0?paths[itemParentIdxs[i]-1]:undefined,type:buildFunctionSearchType(itemFunctionSearchTypes[i],lowercasePaths),id:id,normalizedName:word.indexOf("_")===-1?word:word.replace(/_/g,""),};id+=1;searchIndex.push(row);lastPath=row.path;crateSize+=1}if(aliases){ALIASES[crate]=Object.create(null);for(const alias_name in aliases){if(!hasOwnPropertyRustdoc(aliases,alias_name)){continue}if(!hasOwnPropertyRustdoc(ALIASES[crate],alias_name)){ALIASES[crate][alias_name]=[]}for(const local_alias of aliases[alias_name]){ALIASES[crate][alias_name].push(local_alias+currentIndex)}}}currentIndex+=crateSize}return searchWords}function onSearchSubmit(e){e.preventDefault();searchState.clearInputTimeout();search()}function putBackSearch(){const search_input=searchState.input;if(!searchState.input){return}if(search_input.value!==""&&!searchState.isDisplayed()){searchState.showResults();if(browserSupportsHistoryApi()){history.replaceState(null,"",buildUrl(search_input.value,getFilterCrates()))}document.title=searchState.title}}function registerSearchEvents(){const params=searchState.getQueryStringParams();if(searchState.input.value===""){searchState.input.value=params.search||""}const searchAfter500ms=()=>{searchState.clearInputTimeout();if(searchState.input.value.length===0){if(browserSupportsHistoryApi()){history.replaceState(null,window.currentCrate+" - Rust",getNakedUrl()+window.location.hash)}searchState.hideResults()}else{searchState.timeout=setTimeout(search,500)}};searchState.input.onkeyup=searchAfter500ms;searchState.input.oninput=searchAfter500ms;document.getElementsByClassName("search-form")[0].onsubmit=onSearchSubmit;searchState.input.onchange=e=>{if(e.target!==document.activeElement){return}searchState.clearInputTimeout();setTimeout(search,0)};searchState.input.onpaste=searchState.input.onchange;searchState.outputElement().addEventListener("keydown",e=>{if(e.altKey||e.ctrlKey||e.shiftKey||e.metaKey){return}if(e.which===38){const previous=document.activeElement.previousElementSibling;if(previous){previous.focus()}else{searchState.focus()}e.preventDefault()}else if(e.which===40){const next=document.activeElement.nextElementSibling;if(next){next.focus()}const rect=document.activeElement.getBoundingClientRect();if(window.innerHeight-rect.bottom{if(e.which===40){focusSearchResult();e.preventDefault()}});searchState.input.addEventListener("focus",()=>{putBackSearch()});searchState.input.addEventListener("blur",()=>{searchState.input.placeholder=searchState.input.origPlaceholder});if(browserSupportsHistoryApi()){const previousTitle=document.title;window.addEventListener("popstate",e=>{const params=searchState.getQueryStringParams();document.title=previousTitle;currentResults=null;if(params.search&¶ms.search.length>0){searchState.input.value=params.search;search(e)}else{searchState.input.value="";searchState.hideResults()}})}window.onpageshow=()=>{const qSearch=searchState.getQueryStringParams().search;if(searchState.input.value===""&&qSearch){searchState.input.value=qSearch}search()}}function updateCrate(ev){if(ev.target.value==="all crates"){const params=searchState.getQueryStringParams();const query=searchState.input.value.trim();if(!history.state&&!params.search){history.pushState(null,"",buildUrl(query,null))}else{history.replaceState(null,"",buildUrl(query,null))}}currentResults=null;search(undefined,true)}const searchWords=buildIndex(rawSearchIndex);if(typeof window!=="undefined"){registerSearchEvents();if(window.searchState.getQueryStringParams().search){search()}}if(typeof exports!=="undefined"){exports.initSearch=initSearch;exports.execQuery=execQuery;exports.parseQuery=parseQuery}return searchWords}if(typeof window!=="undefined"){window.initSearch=initSearch;if(window.searchIndex!==undefined){initSearch(window.searchIndex)}}else{initSearch({})}})() \ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/static.files/settings-af96d9e2fc13e081.css b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/static.files/settings-af96d9e2fc13e081.css new file mode 100644 index 0000000000..d94744e6fa --- /dev/null +++ b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/static.files/settings-af96d9e2fc13e081.css @@ -0,0 +1,3 @@ +.setting-line{margin:0.6em 0 0.6em 0.3em;position:relative;}.setting-line .choices{display:flex;flex-wrap:wrap;}.setting-line .radio-line input,.setting-line .toggle input{margin-right:0.3em;height:1.2rem;width:1.2rem;color:inherit;border:1px solid currentColor;outline:none;-webkit-appearance:none;cursor:pointer;}.setting-line .radio-line input{border-radius:50%;}.setting-line .toggle input:checked{content:url('data:image/svg+xml,\ + \ + ');}.setting-line .radio-line input+span,.setting-line .toggle span{padding-bottom:1px;}.radio-line .setting-name{width:100%;}.radio-line .choice{margin-top:0.1em;margin-bottom:0.1em;min-width:3.8em;padding:0.3em;display:flex;align-items:center;cursor:pointer;}.radio-line .choice+.choice{margin-left:0.5em;}.toggle{position:relative;width:100%;margin-right:20px;display:flex;align-items:center;cursor:pointer;}.setting-line>.sub-settings{padding-left:42px;width:100%;display:block;}#settings .setting-line{margin:1.2em 0.6em;}.setting-line .radio-line input:checked{box-shadow:inset 0 0 0 3px var(--main-background-color);background-color:var(--settings-input-color);}.setting-line .toggle input:checked{background-color:var(--settings-input-color);}.setting-line .radio-line input:focus,.setting-line .toggle input:focus{box-shadow:0 0 1px 1px var(--settings-input-color);}.setting-line .radio-line input:checked:focus{box-shadow:inset 0 0 0 3px var(--main-background-color),0 0 2px 2px var(--settings-input-color);}.setting-line .radio-line input:hover,.setting-line .toggle input:hover{border-color:var(--settings-input-color) !important;} \ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/static.files/settings-bebeae96e00e4617.js b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/static.files/settings-bebeae96e00e4617.js new file mode 100644 index 0000000000..4d73ec358b --- /dev/null +++ b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/static.files/settings-bebeae96e00e4617.js @@ -0,0 +1,13 @@ +"use strict";(function(){const isSettingsPage=window.location.pathname.endsWith("/settings.html");function changeSetting(settingName,value){if(settingName==="theme"){const useSystem=value==="system preference"?"true":"false";updateLocalStorage("use-system-theme",useSystem)}updateLocalStorage(settingName,value);switch(settingName){case"theme":case"preferred-dark-theme":case"preferred-light-theme":updateSystemTheme();updateLightAndDark();break;case"line-numbers":if(value===true){window.rustdoc_add_line_numbers_to_examples()}else{window.rustdoc_remove_line_numbers_from_examples()}break}}function handleKey(ev){if(ev.ctrlKey||ev.altKey||ev.metaKey){return}switch(getVirtualKey(ev)){case"Enter":case"Return":case"Space":ev.target.checked=!ev.target.checked;ev.preventDefault();break}}function showLightAndDark(){removeClass(document.getElementById("preferred-light-theme").parentElement,"hidden");removeClass(document.getElementById("preferred-dark-theme").parentElement,"hidden")}function hideLightAndDark(){addClass(document.getElementById("preferred-light-theme").parentElement,"hidden");addClass(document.getElementById("preferred-dark-theme").parentElement,"hidden")}function updateLightAndDark(){const useSystem=getSettingValue("use-system-theme");if(useSystem==="true"||(useSystem===null&&getSettingValue("theme")===null)){showLightAndDark()}else{hideLightAndDark()}}function setEvents(settingsElement){updateLightAndDark();onEachLazy(settingsElement.querySelectorAll("input[type=\"checkbox\"]"),toggle=>{const settingId=toggle.id;const settingValue=getSettingValue(settingId);if(settingValue!==null){toggle.checked=settingValue==="true"}toggle.onchange=function(){changeSetting(this.id,this.checked)};toggle.onkeyup=handleKey;toggle.onkeyrelease=handleKey});onEachLazy(settingsElement.getElementsByClassName("select-wrapper"),elem=>{const select=elem.getElementsByTagName("select")[0];const settingId=select.id;const settingValue=getSettingValue(settingId);if(settingValue!==null){select.value=settingValue}select.onchange=function(){changeSetting(this.id,this.value)}});onEachLazy(settingsElement.querySelectorAll("input[type=\"radio\"]"),elem=>{const settingId=elem.name;let settingValue=getSettingValue(settingId);if(settingId==="theme"){const useSystem=getSettingValue("use-system-theme");if(useSystem==="true"||settingValue===null){if(useSystem!=="false"){settingValue="system preference"}else{settingValue="light"}}}if(settingValue!==null&&settingValue!=="null"){elem.checked=settingValue===elem.value}elem.addEventListener("change",ev=>{changeSetting(ev.target.name,ev.target.value)})})}function buildSettingsPageSections(settings){let output="";for(const setting of settings){output+="
    ";const js_data_name=setting["js_name"];const setting_name=setting["name"];if(setting["options"]!==undefined){output+=`\ +
    + ${setting_name} +
    `;onEach(setting["options"],option=>{const checked=option===setting["default"]?" checked":"";const full=`${js_data_name}-${option.replace(/ /g,"-")}`;output+=`\ +`});output+="
    "}else{const checked=setting["default"]===true?" checked":"";output+=`\ +`}output+="
    "}return output}function buildSettingsPage(){const theme_names=getVar("themes").split(",").filter(t=>t);theme_names.push("light","dark","ayu");const settings=[{"name":"Theme","js_name":"theme","default":"system preference","options":theme_names.concat("system preference"),},{"name":"Preferred light theme","js_name":"preferred-light-theme","default":"light","options":theme_names,},{"name":"Preferred dark theme","js_name":"preferred-dark-theme","default":"dark","options":theme_names,},{"name":"Auto-hide item contents for large items","js_name":"auto-hide-large-items","default":true,},{"name":"Auto-hide item methods' documentation","js_name":"auto-hide-method-docs","default":false,},{"name":"Auto-hide trait implementation documentation","js_name":"auto-hide-trait-implementations","default":false,},{"name":"Directly go to item in search if there is only one result","js_name":"go-to-only-result","default":false,},{"name":"Show line numbers on code examples","js_name":"line-numbers","default":false,},{"name":"Disable keyboard shortcuts","js_name":"disable-shortcuts","default":false,},];const elementKind=isSettingsPage?"section":"div";const innerHTML=`
    ${buildSettingsPageSections(settings)}
    `;const el=document.createElement(elementKind);el.id="settings";if(!isSettingsPage){el.className="popover"}el.innerHTML=innerHTML;if(isSettingsPage){document.getElementById(MAIN_ID).appendChild(el)}else{el.setAttribute("tabindex","-1");getSettingsButton().appendChild(el)}return el}const settingsMenu=buildSettingsPage();function displaySettings(){settingsMenu.style.display=""}function settingsBlurHandler(event){blurHandler(event,getSettingsButton(),window.hidePopoverMenus)}if(isSettingsPage){getSettingsButton().onclick=function(event){event.preventDefault()}}else{const settingsButton=getSettingsButton();const settingsMenu=document.getElementById("settings");settingsButton.onclick=function(event){if(elemIsInParent(event.target,settingsMenu)){return}event.preventDefault();const shouldDisplaySettings=settingsMenu.style.display==="none";window.hideAllModals();if(shouldDisplaySettings){displaySettings()}};settingsButton.onblur=settingsBlurHandler;settingsButton.querySelector("a").onblur=settingsBlurHandler;onEachLazy(settingsMenu.querySelectorAll("input"),el=>{el.onblur=settingsBlurHandler});settingsMenu.onblur=settingsBlurHandler}setTimeout(()=>{setEvents(settingsMenu);if(!isSettingsPage){displaySettings()}removeClass(getSettingsButton(),"rotate")},0)})() \ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/static.files/source-script-5cf2e01a42cc9858.js b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/static.files/source-script-5cf2e01a42cc9858.js new file mode 100644 index 0000000000..f033213ebb --- /dev/null +++ b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/static.files/source-script-5cf2e01a42cc9858.js @@ -0,0 +1 @@ +"use strict";(function(){const rootPath=document.getElementById("rustdoc-vars").attributes["data-root-path"].value;const NAME_OFFSET=0;const DIRS_OFFSET=1;const FILES_OFFSET=2;function closeSidebarIfMobile(){if(window.innerWidth"){window.rustdocMobileScrollLock();addClass(document.documentElement,"source-sidebar-expanded");child.innerText="<";updateLocalStorage("source-sidebar-show","true")}else{window.rustdocMobileScrollUnlock();removeClass(document.documentElement,"source-sidebar-expanded");child.innerText=">";updateLocalStorage("source-sidebar-show","false")}}function createSidebarToggle(){const sidebarToggle=document.createElement("div");sidebarToggle.id="sidebar-toggle";const inner=document.createElement("button");if(getCurrentValue("source-sidebar-show")==="true"){inner.innerText="<"}else{inner.innerText=">"}inner.onclick=toggleSidebar;sidebarToggle.appendChild(inner);return sidebarToggle}function createSourceSidebar(){const container=document.querySelector("nav.sidebar");const sidebarToggle=createSidebarToggle();container.insertBefore(sidebarToggle,container.firstChild);const sidebar=document.createElement("div");sidebar.id="source-sidebar";let hasFoundFile=false;const title=document.createElement("div");title.className="title";title.innerText="Files";sidebar.appendChild(title);Object.keys(sourcesIndex).forEach(key=>{sourcesIndex[key][NAME_OFFSET]=key;hasFoundFile=createDirEntry(sourcesIndex[key],sidebar,"",hasFoundFile)});container.appendChild(sidebar);const selected_elem=sidebar.getElementsByClassName("selected")[0];if(typeof selected_elem!=="undefined"){selected_elem.focus()}}const lineNumbersRegex=/^#?(\d+)(?:-(\d+))?$/;function highlightSourceLines(match){if(typeof match==="undefined"){match=window.location.hash.match(lineNumbersRegex)}if(!match){return}let from=parseInt(match[1],10);let to=from;if(typeof match[2]!=="undefined"){to=parseInt(match[2],10)}if(to{onEachLazy(e.getElementsByTagName("a"),i_e=>{removeClass(i_e,"line-highlighted")})});for(let i=from;i<=to;++i){elem=document.getElementById(i);if(!elem){break}addClass(elem,"line-highlighted")}}const handleSourceHighlight=(function(){let prev_line_id=0;const set_fragment=name=>{const x=window.scrollX,y=window.scrollY;if(browserSupportsHistoryApi()){history.replaceState(null,null,"#"+name);highlightSourceLines()}else{location.replace("#"+name)}window.scrollTo(x,y)};return ev=>{let cur_line_id=parseInt(ev.target.id,10);if(isNaN(cur_line_id)||ev.ctrlKey||ev.altKey||ev.metaKey){return}ev.preventDefault();if(ev.shiftKey&&prev_line_id){if(prev_line_id>cur_line_id){const tmp=prev_line_id;prev_line_id=cur_line_id;cur_line_id=tmp}set_fragment(prev_line_id+"-"+cur_line_id)}else{prev_line_id=cur_line_id;set_fragment(cur_line_id)}}}());window.addEventListener("hashchange",()=>{const match=window.location.hash.match(lineNumbersRegex);if(match){return highlightSourceLines(match)}});onEachLazy(document.getElementsByClassName("src-line-numbers"),el=>{el.addEventListener("click",handleSourceHighlight)});highlightSourceLines();window.createSourceSidebar=createSourceSidebar})() \ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/static.files/storage-d43fa987303ecbbb.js b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/static.files/storage-d43fa987303ecbbb.js new file mode 100644 index 0000000000..017aff706c --- /dev/null +++ b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/static.files/storage-d43fa987303ecbbb.js @@ -0,0 +1 @@ +"use strict";const darkThemes=["dark","ayu"];window.currentTheme=document.getElementById("themeStyle");window.mainTheme=document.getElementById("mainThemeStyle");window.RUSTDOC_MOBILE_BREAKPOINT=700;const settingsDataset=(function(){const settingsElement=document.getElementById("default-settings");if(settingsElement===null){return null}const dataset=settingsElement.dataset;if(dataset===undefined){return null}return dataset})();function getSettingValue(settingName){const current=getCurrentValue(settingName);if(current!==null){return current}if(settingsDataset!==null){const def=settingsDataset[settingName.replace(/-/g,"_")];if(def!==undefined){return def}}return null}const localStoredTheme=getSettingValue("theme");const savedHref=[];function hasClass(elem,className){return elem&&elem.classList&&elem.classList.contains(className)}function addClass(elem,className){if(!elem||!elem.classList){return}elem.classList.add(className)}function removeClass(elem,className){if(!elem||!elem.classList){return}elem.classList.remove(className)}function onEach(arr,func,reversed){if(arr&&arr.length>0&&func){if(reversed){const length=arr.length;for(let i=length-1;i>=0;--i){if(func(arr[i])){return true}}}else{for(const elem of arr){if(func(elem)){return true}}}}return false}function onEachLazy(lazyArray,func,reversed){return onEach(Array.prototype.slice.call(lazyArray),func,reversed)}function updateLocalStorage(name,value){try{window.localStorage.setItem("rustdoc-"+name,value)}catch(e){}}function getCurrentValue(name){try{return window.localStorage.getItem("rustdoc-"+name)}catch(e){return null}}function switchTheme(styleElem,mainStyleElem,newThemeName,saveTheme){if(saveTheme){updateLocalStorage("theme",newThemeName)}if(savedHref.length===0){onEachLazy(document.getElementsByTagName("link"),el=>{savedHref.push(el.href)})}const newHref=savedHref.find(url=>{const m=url.match(/static\.files\/(.*)-[a-f0-9]{16}\.css$/);if(m&&m[1]===newThemeName){return true}const m2=url.match(/\/([^/]*)\.css$/);if(m2&&m2[1].startsWith(newThemeName)){return true}});if(newHref&&newHref!==styleElem.href){styleElem.href=newHref}}function useSystemTheme(value){if(value===undefined){value=true}updateLocalStorage("use-system-theme",value);const toggle=document.getElementById("use-system-theme");if(toggle&&toggle instanceof HTMLInputElement){toggle.checked=value}}const updateSystemTheme=(function(){if(!window.matchMedia){return()=>{const cssTheme=getComputedStyle(document.documentElement).getPropertyValue("content");switchTheme(window.currentTheme,window.mainTheme,JSON.parse(cssTheme)||"light",true)}}const mql=window.matchMedia("(prefers-color-scheme: dark)");function handlePreferenceChange(mql){const use=theme=>{switchTheme(window.currentTheme,window.mainTheme,theme,true)};if(getSettingValue("use-system-theme")!=="false"){const lightTheme=getSettingValue("preferred-light-theme")||"light";const darkTheme=getSettingValue("preferred-dark-theme")||"dark";if(mql.matches){use(darkTheme)}else{use(lightTheme)}}else{use(getSettingValue("theme"))}}mql.addListener(handlePreferenceChange);return()=>{handlePreferenceChange(mql)}})();function switchToSavedTheme(){switchTheme(window.currentTheme,window.mainTheme,getSettingValue("theme")||"light",false)}if(getSettingValue("use-system-theme")!=="false"&&window.matchMedia){if(getSettingValue("use-system-theme")===null&&getSettingValue("preferred-dark-theme")===null&&darkThemes.indexOf(localStoredTheme)>=0){updateLocalStorage("preferred-dark-theme",localStoredTheme)}updateSystemTheme()}else{switchToSavedTheme()}if(getSettingValue("source-sidebar-show")==="true"){addClass(document.documentElement,"source-sidebar-expanded")}window.addEventListener("pageshow",ev=>{if(ev.persisted){setTimeout(switchToSavedTheme,0)}}) \ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/static.files/toggle-minus-31bbd6e4c77f5c96.svg b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/static.files/toggle-minus-31bbd6e4c77f5c96.svg new file mode 100644 index 0000000000..73154788a0 --- /dev/null +++ b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/static.files/toggle-minus-31bbd6e4c77f5c96.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/static.files/toggle-plus-1092eb4930d581b0.svg b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/static.files/toggle-plus-1092eb4930d581b0.svg new file mode 100644 index 0000000000..08b17033e1 --- /dev/null +++ b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/static.files/toggle-plus-1092eb4930d581b0.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/static.files/wheel-5ec35bf9ca753509.svg b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/static.files/wheel-5ec35bf9ca753509.svg new file mode 100644 index 0000000000..01da3b24c7 --- /dev/null +++ b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/static.files/wheel-5ec35bf9ca753509.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/storage.js b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/storage.js deleted file mode 100644 index 9deb649420..0000000000 --- a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/storage.js +++ /dev/null @@ -1 +0,0 @@ -var darkThemes=["dark","ayu"];window.currentTheme=document.getElementById("themeStyle");window.mainTheme=document.getElementById("mainThemeStyle");var settingsDataset=(function(){var settingsElement=document.getElementById("default-settings");if(settingsElement===null){return null}var dataset=settingsElement.dataset;if(dataset===undefined){return null}return dataset})();function getSettingValue(settingName){var current=getCurrentValue('rustdoc-'+settingName);if(current!==null){return current}if(settingsDataset!==null){var def=settingsDataset[settingName.replace(/-/g,'_')];if(def!==undefined){return def}}return null}var localStoredTheme=getSettingValue("theme");var savedHref=[];function hasClass(elem,className){return elem&&elem.classList&&elem.classList.contains(className)}function addClass(elem,className){if(!elem||!elem.classList){return}elem.classList.add(className)}function removeClass(elem,className){if(!elem||!elem.classList){return}elem.classList.remove(className)}function onEach(arr,func,reversed){if(arr&&arr.length>0&&func){var length=arr.length;var i;if(reversed){for(i=length-1;i>=0;--i){if(func(arr[i])){return true}}}else{for(i=0;i=0){updateLocalStorage("rustdoc-preferred-dark-theme",localStoredTheme)}updateSystemTheme()}else{switchToSavedTheme()}window.addEventListener("pageshow",function(ev){if(ev.persisted){setTimeout(switchToSavedTheme,0)}}) \ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/toggle-minus.svg b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/toggle-minus.svg deleted file mode 100644 index 73154788a0..0000000000 --- a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/toggle-minus.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/toggle-plus.svg b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/toggle-plus.svg deleted file mode 100644 index 08b17033e1..0000000000 --- a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/toggle-plus.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/wheel.svg b/docs/.vuepress/public/docs-rs/bdk/nightly/latest/wheel.svg deleted file mode 100644 index 01da3b24c7..0000000000 --- a/docs/.vuepress/public/docs-rs/bdk/nightly/latest/wheel.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file