Merge #636: doc: polish the guide on restoring a Liana wallet backup with Bitcoin Core

b5b96b95937ef914aed237b7829a71ff3672c3f4 README: mention the guide on recovering a backup on Core (Antoine Poinsot)
8c7c7a71353a6054f80eeb5ce4be0f946cec89a5 doc: polish the Bitcoin Core recovery document (Antoine Poinsot)

Pull request description:

ACKs for top commit:
  darosior:
    self-ACK b5b96b95937ef914aed237b7829a71ff3672c3f4 -- it's only doc

Tree-SHA512: b51b8e0f2eac896872ca2380cf0e3f8b4e6e518232e5cbc57dbeaaa517c56dfadfa6d6165a27704ecfda0ffe6bdf5a683e1cfd15b94dedcd8480c3c58865ed51
This commit is contained in:
Antoine Poinsot 2023-08-28 13:16:11 +02:00
commit f8ca1dc212
No known key found for this signature in database
GPG Key ID: E13FC145CD3F4304
2 changed files with 164 additions and 82 deletions

View File

@ -182,6 +182,14 @@ For the daemon, see the [`createrecovery`](doc/API.md#createrecovery) command. I
sweep PSBT to the requested address with the specified feerate, filled with all available coins.
#### Recovering a Liana wallet backup on another wallet
You can always restore a Liana wallet backup using the Liana software. In the extremely unlikely
scenario that you lose access to a Liana software (all copies of the binaries and source code are
entirely wiped from the surface of the planet) or are otherwise unable to use it, we've got [a guide
on how to recover a Liana wallet backup with Bitcoin Core 25.0 and above](doc/RECOVER.md).
### Reproducible builds
Releases of Liana are reproducibly built. Linux binaries are also bootstrappable. See

View File

@ -1,48 +1,65 @@
Here a step by step walkthrough to recover a Liana wallet only using bitcoin-core and HWI utility.
Commands are given for signet, but you can run it in mainnet simply by not using the signet options.
# Recover your Liana wallet using Bitcoin Core
We assume you already have a bitcoind/bitcoin-cli running on your machine.
This document walks you through the step of recovering a Liana wallet using `bitcoind` and
`bitcoin-cli`. You will need a couple things in order to follow this guide:
- Your Liana wallet descriptor.
- The date at which you created the Liana wallet (approximately).
- The necessary signing devices. In this example we'll use a Ledger Nano S and [HWI](https://github.com/bitcoin-core/HWI).
- An address to sweep the funds to. Here we'll use `tb1qed7lyessqcecav5uxultf6zc8nefd9kalgaa7dwrglcc6ld5vd3qe20spe`.
- An installed and synchronized `bitcoind`. If you don't have Bitcoin Core yet you can download it
[here](https://bitcoincore.org/en/download/). The minimum supported version for this guide is
25.0.
### Create wallet in bitcoin core
This document **is not** about the similarly named "timelocked recovery path" feature. You can spend
your coins through (one of) the timelocked recovery path(s) using Bitcoin Core too, but this
document is about the instructions for recovering your coins using the Bitcoin Core wallet in the
improbable case you cannot access the Liana wallet for whatever reason.
Here's a list of the steps we'll undertake:
1. Create a dedicated watchonly wallet on Bitcoin Core, and import the Liana wallet descriptor there.
2. Scan the blockchain for your coins since the birthdate of your wallet.
3. Create a transaction that sweeps all your coins to the prepared address.
4. Sign this transaction using the appropriate devices.
5. Broadcast the transaction.
NB: this guide was written with an example on Linux. It should be trivial to follow on any other
operating system though, with only minor adaptations needed to the examples.
## Create a Bitcoin Core wallet and import the Liana descriptor
Your Liana wallet descriptor is probably of the form:
```
wsh(or_d(pk([a5c6b76e/48'/1'/0'/2']tpubDF5861hj6vR3iJr3aPjGJz4rNbqDCRujQ21mczzKT5SiedaQqNVgHC8HT9ceyxvMFRoPMx4P6HAcL3NZrUPhRUbwCyj3TKSa64bAfnE3sLh/<0;1>/\*),and_v(v:pkh([c477fd13/48'/1'/0'/2']tpubDFn7iPbFqGrTQ2aRACNsUK1MXQR4Z6dYfU2nD1WA9ifSaia642j3Wah4n5pBUEpERNWGJsyv3Dv5qwBabC9TLQrwSboKzukw9wmurGu7XVH/<0;1>/\*),older(3))))#8ldsjayd
```
Note the curious `<0;1>` step in the xpubs' derivation path. It's called a
[multipath](https://github.com/bitcoin/bips/blob/master/bip-0389.mediawiki), a way to compress two
derivation steps in a single expression so you only have to backup a single descriptor instead of
two (one for deriving receive addresses and the other for change addresses).
Bitcoin Core 25.0 does not yet support multipath descriptors. So we'll have to split the descriptor
in two: one for receive and one for change. To do so:
- Make two copies of your descriptor, without the checksum (the part following the `#`).
- For each of them walk through the xpubs.
- Replace each multipath expression with the first index (here `0`) for the first copy and the
second index for the second copy (here `1`).
For our example descriptor above this gives us:
```
wsh(or_d(pk([a5c6b76e/48'/1'/0'/2']tpubDF5861hj6vR3iJr3aPjGJz4rNbqDCRujQ21mczzKT5SiedaQqNVgHC8HT9ceyxvMFRoPMx4P6HAcL3NZrUPhRUbwCyj3TKSa64bAfnE3sLh/0/*),and_v(v:pkh([c477fd13/48'/1'/0'/2']tpubDFn7iPbFqGrTQ2aRACNsUK1MXQR4Z6dYfU2nD1WA9ifSaia642j3Wah4n5pBUEpERNWGJsyv3Dv5qwBabC9TLQrwSboKzukw9wmurGu7XVH/0/*),older(3))))
```
and
```
wsh(or_d(pk([a5c6b76e/48'/1'/0'/2']tpubDF5861hj6vR3iJr3aPjGJz4rNbqDCRujQ21mczzKT5SiedaQqNVgHC8HT9ceyxvMFRoPMx4P6HAcL3NZrUPhRUbwCyj3TKSa64bAfnE3sLh/1/*),and_v(v:pkh([c477fd13/48'/1'/0'/2']tpubDFn7iPbFqGrTQ2aRACNsUK1MXQR4Z6dYfU2nD1WA9ifSaia642j3Wah4n5pBUEpERNWGJsyv3Dv5qwBabC9TLQrwSboKzukw9wmurGu7XVH/1/*),older(3))))
```
We'll need a checksum for each in order to be able to import them on the Bitcoin Core wallet. For
this use the `getdescriptorinfo` command, gather the `checksum` field and append it to the
descriptor after a `#`. For instance with the first descriptor above:
```shell
bitcoin-cli -signet createwallet 'liana' true
bitcoin-cli getdescriptorinfo wsh(or_d(pk([a5c6b76e/48'/1'/0'/2']tpubDF5861hj6vR3iJr3aPjGJz4rNbqDCRujQ21mczzKT5SiedaQqNVgHC8HT9ceyxvMFRoPMx4P6HAcL3NZrUPhRUbwCyj3TKSa64bAfnE3sLh/0/*),and_v(v:pkh([c477fd13/48'/1'/0'/2']tpubDFn7iPbFqGrTQ2aRACNsUK1MXQR4Z6dYfU2nD1WA9ifSaia642j3Wah4n5pBUEpERNWGJsyv3Dv5qwBabC9TLQrwSboKzukw9wmurGu7XVH/0/*),older(3))))
```
output:
Output:
```
{
"name": "liana"
}
```
### Process & import descriptor
As PR[#22838](https://github.com/bitcoin/bitcoin/pull/22838) not (yet) merged in bitcoin core, we need to 'split'
descriptor in 2:
- 1 for receive addresses
- 1 for changes addresses.
#### Original descriptor:
- wsh(or_d(pk([a5c6b76e/48'/1'/0'/2']tpubDF5861hj6vR3iJr3aPjGJz4rNbqDCRujQ21mczzKT5SiedaQqNVgHC8HT9ceyxvMFRoPMx4P6HAcL3NZrUPhRUbwCyj3TKSa64bAfnE3sLh/`<0;1>`/\*),and_v(v:pkh([c477fd13/48'/1'/0'/2']tpubDFn7iPbFqGrTQ2aRACNsUK1MXQR4Z6dYfU2nD1WA9ifSaia642j3Wah4n5pBUEpERNWGJsyv3Dv5qwBabC9TLQrwSboKzukw9wmurGu7XVH/`<0;1>`/\*),older(3))))`#8ldsjayd`
Here we need to process 2 descriptors from the original one, replacing `<0;1>` by `0` for the receive descriptor and `1` for change descriptor, checksum might to be updated for each ones.
#### Processed descriptors:
- wsh(or_d(pk([a5c6b76e/48'/1'/0'/2']tpubDF5861hj6vR3iJr3aPjGJz4rNbqDCRujQ21mczzKT5SiedaQqNVgHC8HT9ceyxvMFRoPMx4P6HAcL3NZrUPhRUbwCyj3TKSa64bAfnE3sLh/`0`/\*),and_v(v:pkh([c477fd13/48'/1'/0'/2']tpubDFn7iPbFqGrTQ2aRACNsUK1MXQR4Z6dYfU2nD1WA9ifSaia642j3Wah4n5pBUEpERNWGJsyv3Dv5qwBabC9TLQrwSboKzukw9wmurGu7XVH/`0`/\*),older(3))))
- wsh(or_d(pk([a5c6b76e/48'/1'/0'/2']tpubDF5861hj6vR3iJr3aPjGJz4rNbqDCRujQ21mczzKT5SiedaQqNVgHC8HT9ceyxvMFRoPMx4P6HAcL3NZrUPhRUbwCyj3TKSa64bAfnE3sLh/`1`/\*),and_v(v:pkh([c477fd13/48'/1'/0'/2']tpubDFn7iPbFqGrTQ2aRACNsUK1MXQR4Z6dYfU2nD1WA9ifSaia642j3Wah4n5pBUEpERNWGJsyv3Dv5qwBabC9TLQrwSboKzukw9wmurGu7XVH/`1`/\*),older(3))))
Now we got the descriptors without checksums, we can process it using bitcoin-cli getdescriptorinfo method:
```shell
bitcoin-cli -signet getdescriptorinfo "wsh(or_d(pk([a5c6b76e/48'/1'/0'/2']tpubDF5861hj6vR3iJr3aPjGJz4rNbqDCRujQ21mczzKT5SiedaQqNVgHC8HT9ceyxvMFRoPMx4P6HAcL3NZrUPhRUbwCyj3TKSa64bAfnE3sLh/0/*),and_v(v:pkh([c477fd13/48'/1'/0'/2']tpubDFn7iPbFqGrTQ2aRACNsUK1MXQR4Z6dYfU2nD1WA9ifSaia642j3Wah4n5pBUEpERNWGJsyv3Dv5qwBabC9TLQrwSboKzukw9wmurGu7XVH/0/*),older(3))))"
```
output:
```
{
"descriptor": "wsh(or_d(pk([a5c6b76e/48'/1'/0'/2']tpubDF5861hj6vR3iJr3aPjGJz4rNbqDCRujQ21mczzKT5SiedaQqNVgHC8HT9ceyxvMFRoPMx4P6HAcL3NZrUPhRUbwCyj3TKSa64bAfnE3sLh/0/*),and_v(v:pkh([c477fd13/48'/1'/0'/2']tpubDFn7iPbFqGrTQ2aRACNsUK1MXQR4Z6dYfU2nD1WA9ifSaia642j3Wah4n5pBUEpERNWGJsyv3Dv5qwBabC9TLQrwSboKzukw9wmurGu7XVH/0/*),older(3))))#nhtumqkr",
"checksum": "nhtumqkr",
@ -51,34 +68,34 @@ output:
"hasprivatekeys": false
}
```
```shell
bitcoin-cli -signet getdescriptorinfo "wsh(or_d(pk([a5c6b76e/48'/1'/0'/2']tpubDF5861hj6vR3iJr3aPjGJz4rNbqDCRujQ21mczzKT5SiedaQqNVgHC8HT9ceyxvMFRoPMx4P6HAcL3NZrUPhRUbwCyj3TKSa64bAfnE3sLh/1/*),and_v(v:pkh([c477fd13/48'/1'/0'/2']tpubDFn7iPbFqGrTQ2aRACNsUK1MXQR4Z6dYfU2nD1WA9ifSaia642j3Wah4n5pBUEpERNWGJsyv3Dv5qwBabC9TLQrwSboKzukw9wmurGu7XVH/1/*),older(3))))"
So the resulting descriptor is
```
wsh(or_d(pk([a5c6b76e/48'/1'/0'/2']tpubDF5861hj6vR3iJr3aPjGJz4rNbqDCRujQ21mczzKT5SiedaQqNVgHC8HT9ceyxvMFRoPMx4P6HAcL3NZrUPhRUbwCyj3TKSa64bAfnE3sLh/0/*),and_v(v:pkh([c477fd13/48'/1'/0'/2']tpubDFn7iPbFqGrTQ2aRACNsUK1MXQR4Z6dYfU2nD1WA9ifSaia642j3Wah4n5pBUEpERNWGJsyv3Dv5qwBabC9TLQrwSboKzukw9wmurGu7XVH/0/*),older(3))))#nhtumqkr
```
output:
```
Make sure to do this for both descriptors, and then create the dedicated watchonly wallet on Bitcoin Core:
```shell
bitcoin-cli -signet createwallet liana_recovery true
```
Output:
```
{
"descriptor": "wsh(or_d(pk([a5c6b76e/48'/1'/0'/2']tpubDF5861hj6vR3iJr3aPjGJz4rNbqDCRujQ21mczzKT5SiedaQqNVgHC8HT9ceyxvMFRoPMx4P6HAcL3NZrUPhRUbwCyj3TKSa64bAfnE3sLh/1/*),and_v(v:pkh([c477fd13/48'/1'/0'/2']tpubDFn7iPbFqGrTQ2aRACNsUK1MXQR4Z6dYfU2nD1WA9ifSaia642j3Wah4n5pBUEpERNWGJsyv3Dv5qwBabC9TLQrwSboKzukw9wmurGu7XVH/1/*),older(3))))#vpa5k5p6",
"checksum": "vpa5k5p6",
"isrange": true,
"issolvable": true,
"hasprivatekeys": false
"name": "liana_recovery"
}
```
The command to pass to bitcoin-cli to import descriptors should look like this:
bitcoin-cli -signet -rpcwallet=liana importdescriptors "[{\"desc\": \"`<descriptor_receive>`\", \"range\": [0,10000], \"timestamp\": `<wallet_birthdate>`}, {\"desc\": \"`<descriptor_change>`\", \"range\": [0,10000], \"timestamp\": `<wallet_birthdate>`}]"
- `<wallet_birthdate>` should be replaced by unix timestamp of your wallet birthdate(if you don't know about the wallet birthdate you can use 1671577200 -Liana V0.1 birthdate-, note that using a lower timestamp than the wallet birthdate will increase the rescan duration)
- `<descriptor_receive>` and `<descriptor_change>` sould be replaced by relevant descriptors (including new generated checksums):
We are now going to import the receive and change descriptors to the wallet. This process will take
care of rescanning the block chain for transactions involving these descriptors. Make sure you have
your wallet birthdate in a timestamp format (we'll use `1682920310`, May 1st 2023). In order to do
this we are going to use the `importdescriptors` command and pass it our two descriptors (with the
checksum appended) along with the wallet birthdate as a timestamp. Note this command may take a
while as it's going to be rescanning the block chain. The farther in the past the birthdate, the
longer it will take. If the command times out you will be able to inspect the progress using the
`getwalletinfo` command.
```shell
bitcoin-cli -signet -rpcwallet=liana importdescriptors "[{\"desc\": \"wsh(or_d(pk([a5c6b76e/48'/1'/0'/2']tpubDF5861hj6vR3iJr3aPjGJz4rNbqDCRujQ21mczzKT5SiedaQqNVgHC8HT9ceyxvMFRoPMx4P6HAcL3NZrUPhRUbwCyj3TKSa64bAfnE3sLh/0/*),and_v(v:pkh([c477fd13/48'/1'/0'/2']tpubDFn7iPbFqGrTQ2aRACNsUK1MXQR4Z6dYfU2nD1WA9ifSaia642j3Wah4n5pBUEpERNWGJsyv3Dv5qwBabC9TLQrwSboKzukw9wmurGu7XVH/0/*),older(3))))#nhtumqkr\", \"range\": [0,10000], \"timestamp\": 1682920310, \"active\": true, \"internal\":false}, {\"desc\": \"wsh(or_d(pk([a5c6b76e/48'/1'/0'/2']tpubDF5861hj6vR3iJr3aPjGJz4rNbqDCRujQ21mczzKT5SiedaQqNVgHC8HT9ceyxvMFRoPMx4P6HAcL3NZrUPhRUbwCyj3TKSa64bAfnE3sLh/1/*),and_v(v:pkh([c477fd13/48'/1'/0'/2']tpubDFn7iPbFqGrTQ2aRACNsUK1MXQR4Z6dYfU2nD1WA9ifSaia642j3Wah4n5pBUEpERNWGJsyv3Dv5qwBabC9TLQrwSboKzukw9wmurGu7XVH/1/*),older(3))))#vpa5k5p6\", \"range\": [0,10000], \"timestamp\": 1682920310, \"active\": true, \"internal\":true}]"
```
output:
Output:
```shell
[
{
@ -90,14 +107,46 @@ output:
]
```
### Build the sweep transaction
```shell
bitcoin-cli -signet -rpcwallet=liana sendall '["tb1qed7lyessqcecav5uxultf6zc8nefd9kalgaa7dwrglcc6ld5vd3qe20spe"]' null "unset" 20
Alright! You should now be able to see your coins on the wallet. You can check your balance with the
`getbalance` command or list all the unspent coins using `listunspent`. For instance in our case:
```shell
$ bitcoin-cli -signet -rpcwallet=liana_recovery listunspent
[
{
"txid": "054166e08bd3e019031ec2e4f6a755913e924f218b6c0ab792c2fd4d911a1011",
"vout": 1,
"address": "tb1qhvrkp9qpzp2cmk7ct745zpkuw3ak45hwvczx5534x89ymg3ae0vsfwyd7j",
"label": "",
"witnessScript": "2103d040bf48b05dfa7234fe39240edc3d89cc909d65b4fd55338ffa162985d4c5c9ac736476a9142517bf2e04d18ae59db290617eb60183d4893f6188ad53b268",
"scriptPubKey": "0020bb0760940110558ddbd85fab4106dc747b6ad2ee66046a523531ca4da23dcbd9",
"amount": 0.00010000,
"confirmations": 152,
"spendable": true,
"solvable": true,
"desc": "wsh(or_d(pk([a5c6b76e/48'/1'/0'/2'/0/1]03d040bf48b05dfa7234fe39240edc3d89cc909d65b4fd55338ffa162985d4c5c9),and_v(v:pkh([c477fd13/48'/1'/0'/2'/0/1]02113af9bac303954c884a077e1840b98fe0b8713ccace07adcbacf322e8f72fbd),older(3))))#8vukwv7f",
"parent_descs": [
"wsh(or_d(pk([a5c6b76e/48'/1'/0'/2']tpubDF5861hj6vR3iJr3aPjGJz4rNbqDCRujQ21mczzKT5SiedaQqNVgHC8HT9ceyxvMFRoPMx4P6HAcL3NZrUPhRUbwCyj3TKSa64bAfnE3sLh/0/*),and_v(v:pkh([c477fd13/48'/1'/0'/2']tpubDFn7iPbFqGrTQ2aRACNsUK1MXQR4Z6dYfU2nD1WA9ifSaia642j3Wah4n5pBUEpERNWGJsyv3Dv5qwBabC9TLQrwSboKzukw9wmurGu7XVH/0/*),older(3))))#nhtumqkr"
],
"safe": true
}
]
```
(here we define fee at `20 sats/VBytes`)
output:
## Sweep the coins out of the wallet
### Craft the sweep transaction
We are now going to create a PSBT that spends all the coins in the wallet to the pre-defined
address. Note merging all your coins into one is usually a bad practice for privacy purpose.
You can also spend them one by one or in other way if you wish. Here we are simply going to present
the simplest way of recovering from disaster.
We'll use the `sendall` command to sweep all the funds of the wallet to the pre-defined address
using a specific feerate. We'll use `20` sats/vbyte but use anything that fits.
```shell
bitcoin-cli -signet -rpcwallet=liana -named sendall recipients='["tb1qed7lyessqcecav5uxultf6zc8nefd9kalgaa7dwrglcc6ld5vd3qe20spe"]' 20
```
Output:
```
{
"psbt": "cHNidP8BAF4CAAAAATEgOFWAFkRN09sCK0V1ES9UyMiUQRJrb0AG4j1y0q++AQAAAAD9////ARg4DwAAAAAAIgAgy33yZhAGM46ynDc+tOhYPPKWlt36O981w0fxjX20Y2IAAAAAAAEAfQIAAAABnk7wzbybA7Z6kvlO7hFYl5x2BN3L0otR5M5udXzGN/oBAAAAAP7///8CrKE2EQAAAAAWABRnUU8zi4M3eMplKigSvOdhtGuSdUBCDwAAAAAAIgAgxBhOa53udP66VGgn+vs7sboB8aXyJj4WddV6PsUjJvHoZAIAAQErQEIPAAAAAAAiACDEGE5rne50/rpUaCf6+zuxugHxpfImPhZ11Xo+xSMm8QEFQSEDFPd+lcxYMUvbhW51TN6Fzc5LFtQVTYbZBUxuEEpHHoCsc2R2qRRX/S6WeWl7J1PJvN+73IONRKHJYYitU7JoIgYDFPd+lcxYMUvbhW51TN6Fzc5LFtQVTYbZBUxuEEpHHoAcpca3bjAAAIABAACAAAAAgAIAAIAAAAAAAAAAACIGA2u7xjrIFe7ShVfXgPOqQwzKtxYkFeV52rNpNyzHfrNdHMR3/RMwAACAAQAAgAAAAIACAACAAAAAAAAAAAAAAA==",
@ -105,10 +154,19 @@ output:
}
```
### Install hwi
As [PR647(wallet policies)](https://github.com/bitcoin-core/HWI/pull/647) is not (yet) merged into HWI we need to install it from git:
### Sign the sweep transaction
#### Download the sources
This part may depend on the signing devices you used with Liana. In general there should be plenty
of documentation available for each signer about how, given a PSBT, to sign it and potentially pass
it on to the next signer. Here we'll detail the signing process with a Ledger Nano S(+).
#### Install HWI
You will need the [`HWI`](https://github.com/bitcoin-core/HWI) tool to interface with the Ledger.
However, Salvatore's wallet policies (required to sign for Miniscript descriptors) are at the time
of writing not yet merged so we'll have to use his branch.
Get the HWI-with-wallet-policy pull request code:
```shell
git clone https://github.com/bitcoin-core/HWI
cd HWI
@ -116,7 +174,7 @@ git fetch origin pull/647/head
git checkout FETCH_HEAD
```
#### Virtual environment & install
And install it in a virtual environment (you may have to install Python and `pip`):
```shell
python3 -m venv venv
. venv/bin/activate
@ -124,37 +182,54 @@ pip install poetry
poetry install
```
### Register policy on ledger nano:
#### Sign with the Ledger
Here we need to do (one more time) some processing on the descriptor format: the XPUBs might be extracted from descriptor and supplied as a list of keys (fingerprint + derivation path might be specified only for te key stored in the ledger nano)
Register the descriptor on the Ledger. It's using a specific syntax to register both descriptors at
once: the wallet policies. You'll once again have to process the descriptor:
1. Take the original descriptor (with the `<0;1>` multipaths derivation steps).
2. Replace all xpubs with an `@` followed by an index number (`@0` for the first, `@1` for the
second, etc..).
3. Compile a list of the xpubs **in the same order**.
4. Replace all `/<0;1>/*` derivation steps by `/**`. NOTE: **do not** replace those if the multipath
step is anything other than `/<0;1>/*`. For instance if it's `/<2;3>/*` **leave it intact**.
For instance in our case the result is this wallet policy:
```
wsh(or_d(pk(@0/**),and_v(v:pkh(@1/**),older(3))))
```
With the following list of xpubs:
```
["[a5c6b76e/48'/1'/0'/2']tpubDF5861hj6vR3iJr3aPjGJz4rNbqDCRujQ21mczzKT5SiedaQqNVgHC8HT9ceyxvMFRoPMx4P6HAcL3NZrUPhRUbwCyj3TKSa64bAfnE3sLh","tpubDFn7iPbFqGrTQ2aRACNsUK1MXQR4Z6dYfU2nD1WA9ifSaia642j3Wah4n5pBUEpERNWGJsyv3Dv5qwBabC9TLQrwSboKzukw9wmurGu7XVH"]
```
We can finally register it on the Ledger:
```shell
python3 -m hwi --chain test --device-type ledger registerpolicy --policy "wsh(or_d(pk(@0/**),and_v(v:pkh(@1/**),older(3))))" --name "Liana" --keys "[\"[a5c6b76e/48'/1'/0'/2']tpubDF5861hj6vR3iJr3aPjGJz4rNbqDCRujQ21mczzKT5SiedaQqNVgHC8HT9ceyxvMFRoPMx4P6HAcL3NZrUPhRUbwCyj3TKSa64bAfnE3sLh\",\"tpubDFn7iPbFqGrTQ2aRACNsUK1MXQR4Z6dYfU2nD1WA9ifSaia642j3Wah4n5pBUEpERNWGJsyv3Dv5qwBabC9TLQrwSboKzukw9wmurGu7XVH\"]"
```
output
Output
```
{"proof_of_registration": "34602db12b76200ea96386c4cd10b8b1d60b84e060d2d6120073c06367a9506d"}
```
(The resulting proof of registration will be different in your case.)
### Sign PSBT with ledger nano:
Then go ahead and sign the PSBT we've previously crafted:
```shell
python3 -m hwi --chain test --device-type ledger signtx cHNidP8BAF4CAAAAATEgOFWAFkRN09sCK0V1ES9UyMiUQRJrb0AG4j1y0q++AQAAAAD9////ARg4DwAAAAAAIgAgy33yZhAGM46ynDc+tOhYPPKWlt36O981w0fxjX20Y2IAAAAAAAEAfQIAAAABnk7wzbybA7Z6kvlO7hFYl5x2BN3L0otR5M5udXzGN/oBAAAAAP7///8CrKE2EQAAAAAWABRnUU8zi4M3eMplKigSvOdhtGuSdUBCDwAAAAAAIgAgxBhOa53udP66VGgn+vs7sboB8aXyJj4WddV6PsUjJvHoZAIAAQErQEIPAAAAAAAiACDEGE5rne50/rpUaCf6+zuxugHxpfImPhZ11Xo+xSMm8QEFQSEDFPd+lcxYMUvbhW51TN6Fzc5LFtQVTYbZBUxuEEpHHoCsc2R2qRRX/S6WeWl7J1PJvN+73IONRKHJYYitU7JoIgYDFPd+lcxYMUvbhW51TN6Fzc5LFtQVTYbZBUxuEEpHHoAcpca3bjAAAIABAACAAAAAgAIAAIAAAAAAAAAAACIGA2u7xjrIFe7ShVfXgPOqQwzKtxYkFeV52rNpNyzHfrNdHMR3/RMwAACAAQAAgAAAAIACAACAAAAAAAAAAAAAAA== --policy "wsh(or_d(pk(@0/**),and_v(v:pkh(@1/**),older(3))))" --name "Liana" --keys "[\"[a5c6b76e/48'/1'/0'/2']tpubDF5861hj6vR3iJr3aPjGJz4rNbqDCRujQ21mczzKT5SiedaQqNVgHC8HT9ceyxvMFRoPMx4P6HAcL3NZrUPhRUbwCyj3TKSa64bAfnE3sLh\",\"tpubDFn7iPbFqGrTQ2aRACNsUK1MXQR4Z6dYfU2nD1WA9ifSaia642j3Wah4n5pBUEpERNWGJsyv3Dv5qwBabC9TLQrwSboKzukw9wmurGu7XVH\"]" --extra "{\"proof_of_registration\": \"34602db12b76200ea96386c4cd10b8b1d60b84e060d2d6120073c06367a9506d\"}"
```
output:
Output:
```
{"psbt": "cHNidP8BAF4CAAAAATEgOFWAFkRN09sCK0V1ES9UyMiUQRJrb0AG4j1y0q++AQAAAAD9////ARg4DwAAAAAAIgAgy33yZhAGM46ynDc+tOhYPPKWlt36O981w0fxjX20Y2IAAAAAAAEAfQIAAAABnk7wzbybA7Z6kvlO7hFYl5x2BN3L0otR5M5udXzGN/oBAAAAAP7///8CrKE2EQAAAAAWABRnUU8zi4M3eMplKigSvOdhtGuSdUBCDwAAAAAAIgAgxBhOa53udP66VGgn+vs7sboB8aXyJj4WddV6PsUjJvHoZAIAAQErQEIPAAAAAAAiACDEGE5rne50/rpUaCf6+zuxugHxpfImPhZ11Xo+xSMm8SICAxT3fpXMWDFL24VudUzehc3OSxbUFU2G2QVMbhBKRx6ASDBFAiEA1h9wI6XI+3Jz61f3rrR9L/6guHbcG7/Dl0a2CmEhWlICIFcwZKqKWe96gUkIQctln6K9R9U4nHx3qJxrHUhmkuf/AQEFQSEDFPd+lcxYMUvbhW51TN6Fzc5LFtQVTYbZBUxuEEpHHoCsc2R2qRRX/S6WeWl7J1PJvN+73IONRKHJYYitU7JoIgYDFPd+lcxYMUvbhW51TN6Fzc5LFtQVTYbZBUxuEEpHHoAcpca3bjAAAIABAACAAAAAgAIAAIAAAAAAAAAAACIGA2u7xjrIFe7ShVfXgPOqQwzKtxYkFeV52rNpNyzHfrNdHMR3/RMwAACAAQAAgAAAAIACAACAAAAAAAAAAAAAAA==", "signed": true}
```
### Finalize PSBT:
### Broadcast the sweep transaction
Once you've gotten enough signatures for the PSBT, you are ready to broadcast the sweep transaction.
First, finalize the PSBT:
```shell
bitcoin-cli -signet finalizepsbt cHNidP8BAF4CAAAAATEgOFWAFkRN09sCK0V1ES9UyMiUQRJrb0AG4j1y0q++AQAAAAD9////ARg4DwAAAAAAIgAgy33yZhAGM46ynDc+tOhYPPKWlt36O981w0fxjX20Y2IAAAAAAAEAfQIAAAABnk7wzbybA7Z6kvlO7hFYl5x2BN3L0otR5M5udXzGN/oBAAAAAP7///8CrKE2EQAAAAAWABRnUU8zi4M3eMplKigSvOdhtGuSdUBCDwAAAAAAIgAgxBhOa53udP66VGgn+vs7sboB8aXyJj4WddV6PsUjJvHoZAIAAQErQEIPAAAAAAAiACDEGE5rne50/rpUaCf6+zuxugHxpfImPhZ11Xo+xSMm8SICAxT3fpXMWDFL24VudUzehc3OSxbUFU2G2QVMbhBKRx6ASDBFAiEA1h9wI6XI+3Jz61f3rrR9L/6guHbcG7/Dl0a2CmEhWlICIFcwZKqKWe96gUkIQctln6K9R9U4nHx3qJxrHUhmkuf/AQEFQSEDFPd+lcxYMUvbhW51TN6Fzc5LFtQVTYbZBUxuEEpHHoCsc2R2qRRX/S6WeWl7J1PJvN+73IONRKHJYYitU7JoIgYDFPd+lcxYMUvbhW51TN6Fzc5LFtQVTYbZBUxuEEpHHoAcpca3bjAAAIABAACAAAAAgAIAAIAAAAAAAAAAACIGA2u7xjrIFe7ShVfXgPOqQwzKtxYkFeV52rNpNyzHfrNdHMR3/RMwAACAAQAAgAAAAIACAACAAAAAAAAAAAAAAA==
```
output:
Output:
```
{
"hex": "02000000000101312038558016444dd3db022b4575112f54c8c89441126b6f4006e23d72d2afbe0100000000fdffffff0118380f0000000000220020cb7df2661006338eb29c373eb4e8583cf29696ddfa3bdf35c347f18d7db4636202483045022100d61f7023a5c8fb7273eb57f7aeb47d2ffea0b876dc1bbfc39746b60a61215a520220573064aa8a59ef7a81490841cb659fa2bd47d5389c7c77a89c6b1d486692e7ff0141210314f77e95cc58314bdb856e754cde85cdce4b16d4154d86d9054c6e104a471e80ac736476a91457fd2e9679697b2753c9bcdfbbdc838d44a1c96188ad53b26800000000",
@ -162,8 +237,7 @@ output:
}
```
### Broadcast PSBT:
And broadcast the resulting transaction:
```shell
bitcoin-cli -signet sendrawtransaction 02000000000101312038558016444dd3db022b4575112f54c8c89441126b6f4006e23d72d2afbe0100000000fdffffff0118380f0000000000220020cb7df2661006338eb29c373eb4e8583cf29696ddfa3bdf35c347f18d7db4636202483045022100d61f7023a5c8fb7273eb57f7aeb47d2ffea0b876dc1bbfc39746b60a61215a520220573064aa8a59ef7a81490841cb659fa2bd47d5389c7c77a89c6b1d486692e7ff0141210314f77e95cc58314bdb856e754cde85cdce4b16d4154d86d9054c6e104a471e80ac736476a91457fd2e9679697b2753c9bcdfbbdc838d44a1c96188ad53b26800000000
```
```