Merge pull request #4926 from guggero/doc-code-blocks

docs: unify code block formatting
This commit is contained in:
Johan T. Halseth 2021-01-22 09:39:02 +01:00 committed by GitHub
commit 39f51b5568
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
32 changed files with 426 additions and 453 deletions

@ -13,7 +13,7 @@ user addresses. Additionally, BIP39 use a very weak [KDF](https://en.wikipedia.o
scrypt with modern parameters (n=32768, r=8, p=1). A set of benchmarks has scrypt with modern parameters (n=32768, r=8, p=1). A set of benchmarks has
been added, on my laptop I get about 100ms per attempt): been added, on my laptop I get about 100ms per attempt):
```bash ```shell
⛰ go test -run=XXX -bench=. ⛰ go test -run=XXX -bench=.
goos: linux goos: linux

@ -23,6 +23,6 @@ between network enabled programs.
## Installation and Updating ## Installation and Updating
```bash ```shell
$ go get -u github.com/lightningnetwork/lnd/brontide go get -u github.com/lightningnetwork/lnd/brontide
``` ```

@ -25,6 +25,6 @@ implementation of the `ChainNotifier` interface depends on `btcd`.
## Installation and Updating ## Installation and Updating
```bash ```shell
$ go get -u github.com/lightningnetwork/lnd/chainntnfs go get -u github.com/lightningnetwork/lnd/chainntnfs
``` ```

@ -19,6 +19,6 @@ node and channel announcements, outgoing payments, and invoices
## Installation and Updating ## Installation and Updating
```bash ```shell
$ go get -u github.com/lightningnetwork/lnd/channeldb go get -u github.com/lightningnetwork/lnd/channeldb
``` ```

@ -31,7 +31,7 @@ next versions will use the started `btcd` bitcoin node in `testnet` and
In the workflow below, we describe the steps required to recreate the following In the workflow below, we describe the steps required to recreate the following
topology, and send a payment from `Alice` to `Bob`. topology, and send a payment from `Alice` to `Bob`.
``` ```text
+ ----- + + --- + + ----- + + --- +
| Alice | <--- channel ---> | Bob | <--- Bob and Alice are the lightning network daemons which | Alice | <--- channel ---> | Bob | <--- Bob and Alice are the lightning network daemons which
+ ----- + + --- + create channels and interact with each other using the + ----- + + --- + create channels and interact with each other using the
@ -59,47 +59,46 @@ topology, and send a payment from `Alice` to `Bob`.
Start `btcd`, and then create an address for `Alice` that we'll directly mine Start `btcd`, and then create an address for `Alice` that we'll directly mine
bitcoin into. bitcoin into.
```bash ```shell
# Init bitcoin network env variable: # Init bitcoin network env variable:
$ export NETWORK="simnet" export NETWORK="simnet"
# Create persistent volumes for alice and bob. # Create persistent volumes for alice and bob.
$ docker volume create simnet_lnd_alice docker volume create simnet_lnd_alice
$ docker volume create simnet_lnd_bob docker volume create simnet_lnd_bob
# Run the "Alice" container and log into it: # Run the "Alice" container and log into it:
$ docker-compose run -d --name alice --volume simnet_lnd_alice:/root/.lnd lnd docker-compose run -d --name alice --volume simnet_lnd_alice:/root/.lnd lnd
$ docker exec -i -t alice bash docker exec -i -t alice bash
# Generate a new backward compatible nested p2sh address for Alice: # Generate a new backward compatible nested p2sh address for Alice:
alice$ lncli --network=simnet newaddress np2wkh alice lncli --network=simnet newaddress np2wkh
# Recreate "btcd" node and set Alice's address as mining address: # Recreate "btcd" node and set Alice's address as mining address:
$ MINING_ADDRESS=<alice_address> docker-compose up -d btcd MINING_ADDRESS=<alice_address> docker-compose up -d btcd
# Generate 400 blocks (we need at least "100 >=" blocks because of coinbase # Generate 400 blocks (we need at least "100 >=" blocks because of coinbase
# block maturity and "300 ~=" in order to activate segwit): # block maturity and "300 ~=" in order to activate segwit):
$ docker exec -it btcd /start-btcctl.sh generate 400 docker exec -it btcd /start-btcctl.sh generate 400
# Check that segwit is active: # Check that segwit is active:
$ docker exec -it btcd /start-btcctl.sh getblockchaininfo | grep -A 1 segwit docker exec -it btcd /start-btcctl.sh getblockchaininfo | grep -A 1 segwit
``` ```
Check `Alice` balance: Check `Alice` balance:
``` ```shell
alice$ lncli --network=simnet walletbalance alice lncli --network=simnet walletbalance
``` ```
Connect `Bob` node to `Alice` node. Connect `Bob` node to `Alice` node.
```bash ```shell
# Run "Bob" node and log into it: # Run "Bob" node and log into it:
$ docker-compose run -d --name bob --volume simnet_lnd_bob:/root/.lnd lnd docker-compose run -d --name bob --volume simnet_lnd_bob:/root/.lnd lnd
$ docker exec -i -t bob bash docker exec -i -t bob bash
# Get the identity pubkey of "Bob" node: # Get the identity pubkey of "Bob" node:
bob$ lncli --network=simnet getinfo bob ⛰ lncli --network=simnet getinfo
{ {
----->"identity_pubkey": "0343bc80b914aebf8e50eb0b8e445fc79b9e6e8e5e018fa8c5f85c7d429c117b38", ----->"identity_pubkey": "0343bc80b914aebf8e50eb0b8e445fc79b9e6e8e5e018fa8c5f85c7d429c117b38",
"alias": "", "alias": "",
@ -117,13 +116,13 @@ bob$ lncli --network=simnet getinfo
} }
# Get the IP address of "Bob" node: # Get the IP address of "Bob" node:
$ docker inspect bob | grep IPAddress docker inspect bob | grep IPAddress
# Connect "Alice" to the "Bob" node: # Connect "Alice" to the "Bob" node:
alice$ lncli --network=simnet connect <bob_pubkey>@<bob_host> alice lncli --network=simnet connect <bob_pubkey>@<bob_host>
# Check list of peers on "Alice" side: # Check list of peers on "Alice" side:
alice$ lncli --network=simnet listpeers alice lncli --network=simnet listpeers
{ {
"peers": [ "peers": [
{ {
@ -140,7 +139,7 @@ alice$ lncli --network=simnet listpeers
} }
# Check list of peers on "Bob" side: # Check list of peers on "Bob" side:
bob$ lncli --network=simnet listpeers bob lncli --network=simnet listpeers
{ {
"peers": [ "peers": [
{ {
@ -158,15 +157,15 @@ bob$ lncli --network=simnet listpeers
``` ```
Create the `Alice<->Bob` channel. Create the `Alice<->Bob` channel.
```bash ```shell
# Open the channel with "Bob": # Open the channel with "Bob":
alice$ lncli --network=simnet openchannel --node_key=<bob_identity_pubkey> --local_amt=1000000 alice lncli --network=simnet openchannel --node_key=<bob_identity_pubkey> --local_amt=1000000
# Include funding transaction in block thereby opening the channel: # Include funding transaction in block thereby opening the channel:
$ docker exec -it btcd /start-btcctl.sh generate 3 docker exec -it btcd /start-btcctl.sh generate 3
# Check that channel with "Bob" was opened: # Check that channel with "Bob" was opened:
alice$ lncli --network=simnet listchannels alice lncli --network=simnet listchannels
{ {
"channels": [ "channels": [
{ {
@ -193,31 +192,31 @@ alice$ lncli --network=simnet listchannels
``` ```
Send the payment from `Alice` to `Bob`. Send the payment from `Alice` to `Bob`.
```bash ```shell
# Add invoice on "Bob" side: # Add invoice on "Bob" side:
bob$ lncli --network=simnet addinvoice --amt=10000 bob lncli --network=simnet addinvoice --amt=10000
{ {
"r_hash": "<your_random_rhash_here>", "r_hash": "<your_random_rhash_here>",
"pay_req": "<encoded_invoice>", "pay_req": "<encoded_invoice>",
} }
# Send payment from "Alice" to "Bob": # Send payment from "Alice" to "Bob":
alice$ lncli --network=simnet sendpayment --pay_req=<encoded_invoice> alice lncli --network=simnet sendpayment --pay_req=<encoded_invoice>
# Check "Alice"'s channel balance # Check "Alice"'s channel balance
alice$ lncli --network=simnet channelbalance alice lncli --network=simnet channelbalance
# Check "Bob"'s channel balance # Check "Bob"'s channel balance
bob$ lncli --network=simnet channelbalance bob lncli --network=simnet channelbalance
``` ```
Now we have open channel in which we sent only one payment, let's imagine Now we have open channel in which we sent only one payment, let's imagine
that we sent lots of them and we'd now like to close the channel. Let's do that we sent lots of them and we'd now like to close the channel. Let's do
it! it!
```bash ```shell
# List the "Alice" channel and retrieve "channel_point" which represents # List the "Alice" channel and retrieve "channel_point" which represents
# the opened channel: # the opened channel:
alice$ lncli --network=simnet listchannels alice lncli --network=simnet listchannels
{ {
"channels": [ "channels": [
{ {
@ -244,17 +243,17 @@ alice$ lncli --network=simnet listchannels
# Channel point consists of two numbers separated by a colon. The first one # Channel point consists of two numbers separated by a colon. The first one
# is "funding_txid" and the second one is "output_index": # is "funding_txid" and the second one is "output_index":
alice$ lncli --network=simnet closechannel --funding_txid=<funding_txid> --output_index=<output_index> alice lncli --network=simnet closechannel --funding_txid=<funding_txid> --output_index=<output_index>
# Include close transaction in a block thereby closing the channel: # Include close transaction in a block thereby closing the channel:
$ docker exec -it btcd /start-btcctl.sh generate 3 docker exec -it btcd /start-btcctl.sh generate 3
# Check "Alice" on-chain balance was credited by her settled amount in the channel: # Check "Alice" on-chain balance was credited by her settled amount in the channel:
alice$ lncli --network=simnet walletbalance alice lncli --network=simnet walletbalance
# Check "Bob" on-chain balance was credited with the funds he received in the # Check "Bob" on-chain balance was credited with the funds he received in the
# channel: # channel:
bob$ lncli --network=simnet walletbalance bob lncli --network=simnet walletbalance
{ {
"total_balance": "10000", "total_balance": "10000",
"confirmed_balance": "10000", "confirmed_balance": "10000",
@ -270,7 +269,7 @@ In this section we will try to connect our node to the faucet/hub node
which we will create a channel with and send some amount of which we will create a channel with and send some amount of
bitcoins. The schema will be following: bitcoins. The schema will be following:
``` ```text
+ ----- + + ------ + (1) + --- + + ----- + + ------ + (1) + --- +
| Alice | <--- channel ---> | Faucet | <--- channel ---> | Bob | | Alice | <--- channel ---> | Faucet | <--- channel ---> | Bob |
+ ----- + + ------ + + --- + + ----- + + ------ + + --- +
@ -297,21 +296,21 @@ bitcoins. The schema will be following:
First of all you need to run `btcd` node in `testnet` and wait for it to be First of all you need to run `btcd` node in `testnet` and wait for it to be
synced with test network (`May the Force and Patience be with you`). synced with test network (`May the Force and Patience be with you`).
```bash ```shell
# Init bitcoin network env variable: # Init bitcoin network env variable:
$ NETWORK="testnet" docker-compose up NETWORK="testnet" docker-compose up
``` ```
After `btcd` synced, connect `Alice` to the `Faucet` node. After `btcd` synced, connect `Alice` to the `Faucet` node.
The `Faucet` node address can be found at the [Faucet Lightning Community webpage](https://faucet.lightning.community). The `Faucet` node address can be found at the [Faucet Lightning Community webpage](https://faucet.lightning.community).
```bash ```shell
# Run "Alice" container and log into it: # Run "Alice" container and log into it:
$ docker-compose run -d --name alice lnd_btc; docker exec -i -t "alice" bash docker-compose run -d --name alice lnd_btc; docker exec -i -t "alice" bash
# Connect "Alice" to the "Faucet" node: # Connect "Alice" to the "Faucet" node:
alice$ lncli --network=testnet connect <faucet_identity_address>@<faucet_host> alice lncli --network=testnet connect <faucet_identity_address>@<faucet_host>
``` ```
After a connection is achieved, the `Faucet` node should create the channel After a connection is achieved, the `Faucet` node should create the channel
@ -332,6 +331,6 @@ production), outside of `docker-compose`, see the
[![Irc](https://img.shields.io/badge/chat-on%20freenode-brightgreen.svg)](https://webchat.freenode.net/?channels=lnd) [![Irc](https://img.shields.io/badge/chat-on%20freenode-brightgreen.svg)](https://webchat.freenode.net/?channels=lnd)
* How to see `alice` | `bob` | `btcd` logs? * How to see `alice` | `bob` | `btcd` logs?
```bash ```shell
docker-compose logs <alice|bob|btcd> docker-compose logs <alice|bob|btcd>
``` ```

@ -12,8 +12,8 @@ There are two flavors of Dockerfiles available:
To build a standalone development image from the local source directory, use the To build a standalone development image from the local source directory, use the
following command: following command:
``` ```shell
$ docker build --tag=myrepository/lnd-dev -f dev.Dockerfile . docker build --tag=myrepository/lnd-dev -f dev.Dockerfile .
``` ```
There is also a `docker-compose` setup available for development or testing that There is also a `docker-compose` setup available for development or testing that
@ -28,16 +28,16 @@ Docker container, adding the appropriate command-line options as parameters.
You first need to build the `lnd` docker image: You first need to build the `lnd` docker image:
``` ```shell
$ docker build --tag=myrepository/lnd --build-arg checkout=v0.11.1-beta . docker build --tag=myrepository/lnd --build-arg checkout=v0.11.1-beta .
``` ```
It is recommended that you checkout the latest released tag. It is recommended that you checkout the latest released tag.
You can continue by creating and running the container: You can continue by creating and running the container:
``` ```shell
$ docker run myrepository/lnd [command-line options] docker run myrepository/lnd [command-line options]
``` ```
## Production (official images) ## Production (official images)
@ -49,8 +49,8 @@ images of `lnd` available in the
You can just pull those images by specifying a release tag: You can just pull those images by specifying a release tag:
```shell ```shell
$ docker pull lightninglabs/lnd:v0.12.0-beta docker pull lightninglabs/lnd:v0.12.0-beta
$ docker run lightninglabs/lnd [command-line options] docker run lightninglabs/lnd [command-line options]
``` ```
### Verifying docker images ### Verifying docker images
@ -61,11 +61,11 @@ script in the image that can be called (before starting the container for
example): example):
```shell ```shell
$ docker pull lightninglabs/lnd:v0.12.0-beta docker pull lightninglabs/lnd:v0.12.0-beta
$ docker run --rm --entrypoint="" lightninglabs/lnd:v0.12.0-beta /verify-install.sh docker run --rm --entrypoint="" lightninglabs/lnd:v0.12.0-beta /verify-install.sh
$ OK=$? OK=$?
$ if [ "$OK" -ne "0" ]; then echo "Verification failed!"; exit 1; done if [ "$OK" -ne "0" ]; then echo "Verification failed!"; exit 1; done
$ docker run lightninglabs/lnd [command-line options] docker run lightninglabs/lnd [command-line options]
``` ```
## Volumes ## Volumes
@ -75,28 +75,28 @@ persist through container restarts.
You can also optionally manually specify a local folder to be used as a volume: You can also optionally manually specify a local folder to be used as a volume:
``` ```shell
$ docker create --name=mylndcontainer -v /media/lnd-docker/:/root/.lnd myrepository/lnd [command-line options] docker create --name=mylndcontainer -v /media/lnd-docker/:/root/.lnd myrepository/lnd [command-line options]
``` ```
## Example ## Example
Here is an example testnet `lnd` that uses Neutrino: Here is an example testnet `lnd` that uses Neutrino:
``` ```shell
$ docker run --name lnd-testnet myrepository/lnd --bitcoin.active --bitcoin.testnet --bitcoin.node=neutrino --neutrino.connect=faucet.lightning.community docker run --name lnd-testnet myrepository/lnd --bitcoin.active --bitcoin.testnet --bitcoin.node=neutrino --neutrino.connect=faucet.lightning.community
``` ```
Create a wallet (and write down the seed): Create a wallet (and write down the seed):
``` ```shell
$ docker exec -it lnd-testnet lncli create docker exec -it lnd-testnet lncli create
``` ```
Confirm `lnd` has begun to synchronize: Confirm `lnd` has begun to synchronize:
``` ```shell
$ docker logs lnd-testnet docker logs lnd-testnet
[snipped] [snipped]
2018-05-01 02:28:01.201 [INF] RPCS: RPC server listening on 127.0.0.1:10009 2018-05-01 02:28:01.201 [INF] RPCS: RPC server listening on 127.0.0.1:10009
2018-05-01 02:28:01.201 [INF] LTND: Waiting for chain backend to finish sync, start_height=2546 2018-05-01 02:28:01.201 [INF] LTND: Waiting for chain backend to finish sync, start_height=2546
@ -113,24 +113,24 @@ to expose RPC ports, use `btcd` or `bitcoind`, or add additional chains.
To test the Docker production image locally, run the following from To test the Docker production image locally, run the following from
the project root: the project root:
``` ```shell
$ docker build . -t myrepository/lnd:master docker build . -t myrepository/lnd:master
``` ```
To choose a specific branch or tag instead, use the "checkout" build-arg. For example, to build the latest commits in master: To choose a specific branch or tag instead, use the "checkout" build-arg. For example, to build the latest commits in master:
``` ```shell
$ docker build . --build-arg checkout=v0.8.0-beta -t myrepository/lnd:v0.8.0-beta docker build . --build-arg checkout=v0.8.0-beta -t myrepository/lnd:v0.8.0-beta
``` ```
To build the image using the most current tag: To build the image using the most current tag:
``` ```shell
$ docker build . --build-arg checkout=$(git describe --tags `git rev-list --tags --max-count=1`) -t myrepository/lnd:latest-tag docker build . --build-arg checkout=$(git describe --tags `git rev-list --tags --max-count=1`) -t myrepository/lnd:latest-tag
``` ```
Once the image has been built and tagged locally, start the container: Once the image has been built and tagged locally, start the container:
``` ```shell
docker run --name=lnd-testnet -it myrepository/lnd:latest-tag --bitcoin.active --bitcoin.testnet --bitcoin.node=neutrino --neutrino.connect=faucet.lightning.community docker run --name=lnd-testnet -it myrepository/lnd:latest-tag --bitcoin.active --bitcoin.testnet --bitcoin.node=neutrino --neutrino.connect=faucet.lightning.community
``` ```

@ -67,10 +67,10 @@ To build a specific git tag of `lnd`, simply run the following steps (assuming
`v0.x.y-beta` is the tagged version to build): `v0.x.y-beta` is the tagged version to build):
```shell ```shell
git clone https://github.com/lightningnetwork/lnd git clone https://github.com/lightningnetwork/lnd
cd lnd cd lnd
git checkout v0.x.y-beta git checkout v0.x.y-beta
make docker-release tag=v0.x.y-beta make docker-release tag=v0.x.y-beta
``` ```
This will create a directory called `lnd-v0.x.y-beta` that contains the release This will create a directory called `lnd-v0.x.y-beta` that contains the release
@ -150,9 +150,9 @@ version if there are database migrations present.
`~/go`. You will also need to add `$GOPATH/bin` to your `PATH`. This ensures `~/go`. You will also need to add `$GOPATH/bin` to your `PATH`. This ensures
that your shell will be able to detect the binaries you install. that your shell will be able to detect the binaries you install.
```bash ```shell
export GOPATH=~/gocode export GOPATH=~/gocode
export PATH=$PATH:$GOPATH/bin export PATH=$PATH:$GOPATH/bin
``` ```
We recommend placing the above in your .bashrc or in a setup script so that We recommend placing the above in your .bashrc or in a setup script so that
@ -169,10 +169,10 @@ version if there are database migrations present.
With the preliminary steps completed, to install `lnd`, `lncli`, and all With the preliminary steps completed, to install `lnd`, `lncli`, and all
related dependencies run the following commands: related dependencies run the following commands:
``` ```shell
git clone https://github.com/lightningnetwork/lnd git clone https://github.com/lightningnetwork/lnd
cd lnd cd lnd
make install make install
``` ```
The command above will install the current _master_ branch of `lnd`. If you The command above will install the current _master_ branch of `lnd`. If you
@ -181,11 +181,11 @@ unstable), then [visit then release page to locate the latest
release](https://github.com/lightningnetwork/lnd/releases). Assuming the name release](https://github.com/lightningnetwork/lnd/releases). Assuming the name
of the release is `v0.x.x`, then you can compile this release from source with of the release is `v0.x.x`, then you can compile this release from source with
a small modification to the above command: a small modification to the above command:
``` ```shell
git clone https://github.com/lightningnetwork/lnd git clone https://github.com/lightningnetwork/lnd
cd lnd cd lnd
git checkout v0.x.x git checkout v0.x.x
make install make install
``` ```
@ -197,35 +197,35 @@ For Windows WSL users, make will need to be referenced directly via
/usr/bin/make/, or alternatively by wrapping quotation marks around make, /usr/bin/make/, or alternatively by wrapping quotation marks around make,
like so: like so:
``` ```shell
/usr/bin/make && /usr/bin/make install /usr/bin/make && /usr/bin/make install
"make" && "make" install "make" && "make" install
``` ```
On FreeBSD, use gmake instead of make. On FreeBSD, use gmake instead of make.
Alternatively, if one doesn't wish to use `make`, then the `go` commands can be Alternatively, if one doesn't wish to use `make`, then the `go` commands can be
used directly: used directly:
``` ```shell
GO111MODULE=on go install -v ./... GO111MODULE=on go install -v ./...
``` ```
**Updating** **Updating**
To update your version of `lnd` to the latest version run the following To update your version of `lnd` to the latest version run the following
commands: commands:
``` ```shell
cd $GOPATH/src/github.com/lightningnetwork/lnd cd $GOPATH/src/github.com/lightningnetwork/lnd
git pull git pull
make clean && make && make install make clean && make && make install
``` ```
On FreeBSD, use gmake instead of make. On FreeBSD, use gmake instead of make.
Alternatively, if one doesn't wish to use `make`, then the `go` commands can be Alternatively, if one doesn't wish to use `make`, then the `go` commands can be
used directly: used directly:
``` ```shell
cd $GOPATH/src/github.com/lightningnetwork/lnd cd $GOPATH/src/github.com/lightningnetwork/lnd
git pull git pull
GO111MODULE=on go install -v ./... GO111MODULE=on go install -v ./...

@ -3,10 +3,10 @@ Makefile
To build, verify, and install `lnd` from source, use the following To build, verify, and install `lnd` from source, use the following
commands: commands:
``` ```shell
make make
make check make check
make install make install
``` ```
The command `make check` requires `bitcoind` (almost any version should do) to The command `make check` requires `bitcoind` (almost any version should do) to
@ -144,7 +144,7 @@ until an error occurs. Useful for hunting flakes.
Example: Example:
```shell ```shell
$ make flakehunter-parallel icase='(data_loss_protection|channel_backup)' backend=neutrino make flakehunter-parallel icase='(data_loss_protection|channel_backup)' backend=neutrino
``` ```
`lint` `lint`

@ -1,29 +1,27 @@
### Table of Contents # Table of Contents
1. [Overview](#Overview)<br /> 1. [Overview](#overview)
2. [Minimum Recommended Skillset](#MinSkillset)<br /> 2. [Minimum Recommended Skillset](#minimum-recommended-skillset)
3. [Required Reading](#ReqReading)<br /> 3. [Required Reading](#required-reading)
4. [Development Practices](#DevelopmentPractices)<br /> 4. [Development Practices](#development-practices)
4.1. [Share Early, Share Often](#ShareEarly)<br /> 1. [Share Early, Share Often](#share-early-share-often)
4.2. [Testing](#Testing)<br /> 1. [Testing](#testing)
4.3. [Code Documentation and Commenting](#CodeDocumentation)<br /> 1. [Code Documentation and Commenting](#code-documentation-and-commenting)
4.4. [Model Git Commit Messages](#ModelGitCommitMessages)<br /> 1. [Model Git Commit Messages](#model-git-commit-messages)
4.5. [Ideal Git Commit Structure](#IdealGitCommitStructure)<br /> 1. [Ideal Git Commit Structure](#ideal-git-commit-structure)
4.6. [Code Spacing](#CodeSpacing)<br /> 1. [Code Spacing](#code-spacing)
4.7. [Protobuf Compilation](#Protobuf)<br /> 1. [Protobuf Compilation](#protobuf-compilation)
4.8. [Additional Style Constraints On Top of gofmt](ExtraGoFmtStyle)<br /> 1. [Additional Style Constraints On Top of gofmt](#additional-style-constraints-on-top-of-gofmt)
4.9. [Pointing to Remote Dependant Branches in Go Modules](ModulesReplace)<br /> 1. [Pointing to Remote Dependant Branches in Go Modules](#pointing-to-remote-dependant-branches-in-go-modules)
4.10. [Use of Log Levels](#LogLevels)<br /> 1. [Use of Log Levels](#use-of-log-levels)
5. [Code Approval Process](#CodeApproval)<br /> 5. [Code Approval Process](#code-approval-process)
5.1. [Code Review](#CodeReview)<br /> 1. [Code Review](#code-review)
5.2. [Rework Code (if needed)](#CodeRework)<br /> 1. [Rework Code (if needed)](#rework-code-if-needed)
5.3. [Acceptance](#CodeAcceptance)<br /> 1. [Acceptance](#acceptance)
6. [Contribution Standards](#Standards)<br /> 6. [Contribution Standards](#contribution-standards)
6.1. [Contribution Checklist](#Checklist)<br /> 1. [Contribution Checklist](#contribution-checklist)
6.2. [Licensing of Contributions](#Licensing)<br /> 1. [Licensing of Contributions](#licensing-of-contributions)
<a name="Overview" /> # Overview
### 1. Overview
Developing cryptocurrencies is an exciting endeavor that touches a wide variety Developing cryptocurrencies is an exciting endeavor that touches a wide variety
of areas such as wire protocols, peer-to-peer networking, databases, of areas such as wire protocols, peer-to-peer networking, databases,
@ -49,9 +47,7 @@ development process (heavily inspired by
We highly encourage code contributions, however it is imperative that you adhere We highly encourage code contributions, however it is imperative that you adhere
to the guidelines established on this page. to the guidelines established on this page.
<a name="MinSkillset" /> # Minimum Recommended Skillset
### 2. Minimum Recommended Skillset
The following list is a set of core competencies that we recommend you possess The following list is a set of core competencies that we recommend you possess
before you really start attempting to contribute code to the project. These are before you really start attempting to contribute code to the project. These are
@ -63,7 +59,7 @@ of low hanging fruit which can be tackled without having full competency in the
areas mentioned below. areas mentioned below.
- A reasonable understanding of bitcoin at a high level (see the - A reasonable understanding of bitcoin at a high level (see the
[Required Reading](#ReqReading) section for the original white paper) [Required Reading](#required-reading) section for the original white paper)
- A reasonable understanding of the Lightning Network at a high level - A reasonable understanding of the Lightning Network at a high level
- Experience in some type of C-like language - Experience in some type of C-like language
- An understanding of data structures and their performance implications - An understanding of data structures and their performance implications
@ -78,9 +74,7 @@ if you wish to contribute to the cryptography code, you should have a good
understanding of the various aspects involved with cryptography such as the understanding of the various aspects involved with cryptography such as the
security and performance implications. security and performance implications.
<a name="ReqReading" /> # Required Reading
### 3. Required Reading
- [Effective Go](http://golang.org/doc/effective_go.html) - The entire `lnd` - [Effective Go](http://golang.org/doc/effective_go.html) - The entire `lnd`
project follows the guidelines in this document. For your code to be accepted, project follows the guidelines in this document. For your code to be accepted,
@ -103,17 +97,13 @@ Once the specification is finalized, it will be the most up-to-date
comprehensive document explaining the Lightning Network. As a result, it will comprehensive document explaining the Lightning Network. As a result, it will
be recommended for newcomers to read first in order to get up to speed. be recommended for newcomers to read first in order to get up to speed.
<a name="DevelopmentPractices" /> # Development Practices
### 4. Development Practices
Developers are expected to work in their own trees and submit pull requests when Developers are expected to work in their own trees and submit pull requests when
they feel their feature or bug fix is ready for integration into the master they feel their feature or bug fix is ready for integration into the master
branch. branch.
<a name="ShareEarly" /> ## Share Early, Share Often
#### 4.1. Share Early, Share Often
We firmly believe in the share early, share often approach. The basic premise We firmly believe in the share early, share often approach. The basic premise
of the approach is to announce your plans **before** you start work, and once of the approach is to announce your plans **before** you start work, and once
@ -132,9 +122,7 @@ This approach has several benefits:
- The quicker your changes are merged to master, the less time you will need to - The quicker your changes are merged to master, the less time you will need to
spend rebasing and otherwise trying to keep up with the main code base spend rebasing and otherwise trying to keep up with the main code base
<a name="Testing" /> ## Testing
#### 4.2. Testing
One of the major design goals of all of `lnd`'s packages and the daemon itself is One of the major design goals of all of `lnd`'s packages and the daemon itself is
to aim for a high degree of test coverage. This is financial software so bugs to aim for a high degree of test coverage. This is financial software so bugs
@ -168,15 +156,13 @@ A quick summary of test practices follows:
contained within `lnd`. For example integration tests, see contained within `lnd`. For example integration tests, see
[`lnd_test.go`](https://github.com/lightningnetwork/lnd/blob/master/lnd_test.go#L181). [`lnd_test.go`](https://github.com/lightningnetwork/lnd/blob/master/lnd_test.go#L181).
- The itest log files are automatically scanned for `[ERR]` lines. There - The itest log files are automatically scanned for `[ERR]` lines. There
shouldn't be any of those in the logs, see [Use of Log Levels](#LogLevels). shouldn't be any of those in the logs, see [Use of Log Levels](#use-of-log-levels).
Throughout the process of contributing to `lnd`, you'll likely also be Throughout the process of contributing to `lnd`, you'll likely also be
extensively using the commands within our `Makefile`. As a result, we recommend extensively using the commands within our `Makefile`. As a result, we recommend
[perusing the make file documentation](https://github.com/lightningnetwork/lnd/blob/master/docs/MAKEFILE.md). [perusing the make file documentation](https://github.com/lightningnetwork/lnd/blob/master/docs/MAKEFILE.md).
<a name="CodeDocumentation" /> ## Code Documentation and Commenting
#### 4.3. Code Documentation and Commenting
- At a minimum every function must be commented with its intended purpose and - At a minimum every function must be commented with its intended purpose and
any assumptions that it makes any assumptions that it makes
@ -226,7 +212,7 @@ func DeriveRevocationPubkey(commitPubKey *btcec.PublicKey,
obvious<br /><br /> obvious<br /><br />
**WRONG** **WRONG**
```Go ```go
// return err if amt is less than 546 // return err if amt is less than 546
if amt < 546 { if amt < 546 {
return err return err
@ -244,9 +230,7 @@ if amt < 546 {
but it was left as a magic number to show how much of a difference a good but it was left as a magic number to show how much of a difference a good
comment can make. comment can make.
<a name="ModelGitCommitMessages" /> ## Model Git Commit Messages
#### 4.4. Model Git Commit Messages
This project prefers to keep a clean commit history with well-formed commit This project prefers to keep a clean commit history with well-formed commit
messages. This section illustrates a model commit message and provides a bit messages. This section illustrates a model commit message and provides a bit
@ -256,7 +240,7 @@ being provided here.
Heres a model Git commit message: Heres a model Git commit message:
``` ```text
Short (50 chars or less) summary of changes Short (50 chars or less) summary of changes
More detailed explanatory text, if necessary. Wrap it to about 72 More detailed explanatory text, if necessary. Wrap it to about 72
@ -300,9 +284,7 @@ either a '+' or a ','. This prefix seems minor but can be extremely helpful in
determining the scope of a commit at a glance, or when bug hunting to find a determining the scope of a commit at a glance, or when bug hunting to find a
commit which introduced a bug or regression. commit which introduced a bug or regression.
<a name="IdealGitCommitStructure" /> ## Ideal Git Commit Structure
#### 4.5. Ideal Git Commit Structure
Within the project we prefer small, contained commits for a pull request over a Within the project we prefer small, contained commits for a pull request over a
single giant commit that touches several files/packages. Ideal commits build on single giant commit that touches several files/packages. Ideal commits build on
@ -335,9 +317,7 @@ Examples of common patterns w.r.t commit structures within the project:
induvidual commits that begin to intergrate the functionality within the induvidual commits that begin to intergrate the functionality within the
codebase. codebase.
<a name="CodeSpacing" /> ## Code Spacing
#### 4.6. Code Spacing
Blocks of code within `lnd` should be segmented into logical stanzas of Blocks of code within `lnd` should be segmented into logical stanzas of
operation. Such spacing makes the code easier to follow at a skim, and reduces operation. Such spacing makes the code easier to follow at a skim, and reduces
@ -444,9 +424,7 @@ the comment body.
} }
``` ```
<a name="Protobuf" /> ## Protobuf Compilation
#### 4.7. Protobuf Compilation
The `lnd` project uses `protobuf`, and its extension [`gRPC`](www.grpc.io) in The `lnd` project uses `protobuf`, and its extension [`gRPC`](www.grpc.io) in
several areas and as the primary RPC interface. In order to ensure uniformity several areas and as the primary RPC interface. In order to ensure uniformity
@ -464,9 +442,7 @@ otherwise the CI pipeline on Travis will fail:
For detailed instructions on how to compile modifications to `lnd`'s `protobuf` For detailed instructions on how to compile modifications to `lnd`'s `protobuf`
definitions, check out the [lnrpc README](https://github.com/lightningnetwork/lnd/blob/master/lnrpc/README.md). definitions, check out the [lnrpc README](https://github.com/lightningnetwork/lnd/blob/master/lnrpc/README.md).
<a name="ExtraGoFmtStyle" /> ## Additional Style Constraints On Top of `gofmt`
#### 4.8. Additional Style Constraints On Top of `gofmt`
Before a PR is submitted, the proposer should ensure that the file passes the Before a PR is submitted, the proposer should ensure that the file passes the
set of linting scripts run by `make lint`. These include `gofmt`. In addition set of linting scripts run by `make lint`. These include `gofmt`. In addition
@ -496,9 +472,7 @@ Note that the above guidelines don't apply to log messages. For log messages,
committers should attempt to minimize the of number lines utilized, while still committers should attempt to minimize the of number lines utilized, while still
adhering to the 80-character column limit. adhering to the 80-character column limit.
<a name="ModulesReplace" /> ## Pointing to Remote Dependant Branches in Go Modules
#### 4.9 Pointing to Remote Dependant Branches in Go Modules
It's common that a developer may need to make a change in a dependent project It's common that a developer may need to make a change in a dependent project
of `lnd` such as `btcd`, `neutrino`, `btcwallet`, etc. In order to test changes of `lnd` such as `btcd`, `neutrino`, `btcwallet`, etc. In order to test changes
@ -506,18 +480,16 @@ with out testing infrastructure, or simply make a PR into `lnd` that will build
without any further work, the `go.mod` and `go.sum` files will need to be without any further work, the `go.mod` and `go.sum` files will need to be
updated. Luckily, the `go mod` command has a handy tool to do this updated. Luckily, the `go mod` command has a handy tool to do this
automatically so developers don't need to manually edit the `go.mod` file: automatically so developers don't need to manually edit the `go.mod` file:
``` ```shell
go mod edit -replace=IMPORT-PATH-IN-LND@LND-VERSION=DEV-FORK-IMPORT-PATH@DEV-FORK-VERSION go mod edit -replace=IMPORT-PATH-IN-LND@LND-VERSION=DEV-FORK-IMPORT-PATH@DEV-FORK-VERSION
``` ```
Here's an example replacing the `lightning-onion` version checked into `lnd` with a version in roasbeef's fork: Here's an example replacing the `lightning-onion` version checked into `lnd` with a version in roasbeef's fork:
``` ```shell
go mod edit -replace=github.com/lightningnetwork/lightning-onion@v0.0.0-20180605012408-ac4d9da8f1d6=github.com/roasbeef/lightning-onion@2e5ae87696046298365ab43bcd1cf3a7a1d69695 go mod edit -replace=github.com/lightningnetwork/lightning-onion@v0.0.0-20180605012408-ac4d9da8f1d6=github.com/roasbeef/lightning-onion@2e5ae87696046298365ab43bcd1cf3a7a1d69695
``` ```
<a name="LogLevels" /> ## Use of Log Levels
#### 4.10 Use of Log Levels
There are six log levels available: `trace`, `debug`, `info`, `warn`, `error` and `critical`. There are six log levels available: `trace`, `debug`, `info`, `warn`, `error` and `critical`.
@ -525,22 +497,18 @@ Only use `error` for internal errors that are never expected to happen during
normal operation. No event triggered by external sources (rpc, chain backend, normal operation. No event triggered by external sources (rpc, chain backend,
etc) should lead to an `error` log. etc) should lead to an `error` log.
<a name="CodeApproval" /> # Code Approval Process
### 5. Code Approval Process
This section describes the code approval process that is used for code This section describes the code approval process that is used for code
contributions. This is how to get your changes into `lnd`. contributions. This is how to get your changes into `lnd`.
<a name="CodeReview" /> ## Code Review
#### 5.1. Code Review
All code which is submitted will need to be reviewed before inclusion into the All code which is submitted will need to be reviewed before inclusion into the
master branch. This process is performed by the project maintainers and usually master branch. This process is performed by the project maintainers and usually
other committers who are interested in the area you are working in as well. other committers who are interested in the area you are working in as well.
##### Code Review Timeframe ### Code Review Timeframe
The timeframe for a code review will vary greatly depending on factors such as The timeframe for a code review will vary greatly depending on factors such as
the number of other pull requests which need to be reviewed, the size and the number of other pull requests which need to be reviewed, the size and
@ -553,14 +521,15 @@ manageable, commits.
Keeping the above in mind, most small changes will be reviewed within a few Keeping the above in mind, most small changes will be reviewed within a few
days, while large or far reaching changes may take weeks. This is a good reason days, while large or far reaching changes may take weeks. This is a good reason
to stick with the [Share Early, Share Often](#ShareEarly) development practice to stick with the [Share Early, Share Often](#share-early-share-often)
outlined above. development practice outlined above.
##### What is the review looking for? ### What is the review looking for?
The review is mainly ensuring the code follows the [Development Practices](#DevelopmentPractices) The review is mainly ensuring the code follows the
and [Code Contribution Standards](#Standards). However, there are a few other [Development Practices](#development-practices) and
checks which are generally performed as follows: [Code Contribution Standards](#contribution-standards). However, there are a few
other checks which are generally performed as follows:
- The code is stable and has no stability or security concerns - The code is stable and has no stability or security concerns
- The code is properly using existing APIs and generally fits well into the - The code is properly using existing APIs and generally fits well into the
@ -568,9 +537,7 @@ checks which are generally performed as follows:
- The change is not something which is deemed inappropriate by community - The change is not something which is deemed inappropriate by community
consensus consensus
<a name="CodeRework" /> ## Rework Code (if needed)
#### 5.2. Rework Code (if needed)
After the code review, the change will be accepted immediately if no issues are After the code review, the change will be accepted immediately if no issues are
found. If there are any concerns or questions, you will be provided with found. If there are any concerns or questions, you will be provided with
@ -588,9 +555,7 @@ can set it to auto squash the fix up commits on rebase.
This process will continue until the code is finally accepted. This process will continue until the code is finally accepted.
<a name="CodeAcceptance" /> ## Acceptance
#### 5.3. Acceptance
Once your code is accepted, it will be integrated with the master branch. After Once your code is accepted, it will be integrated with the master branch. After
2+ (sometimes 1) LGTM's (approvals) are given on a PR, it's eligible to land in 2+ (sometimes 1) LGTM's (approvals) are given on a PR, it's eligible to land in
@ -603,16 +568,13 @@ these signatures intact, we prefer using merge commits. PR proposers can use
Rejoice as you will now be listed as a [contributor](https://github.com/lightningnetwork/lnd/graphs/contributors)! Rejoice as you will now be listed as a [contributor](https://github.com/lightningnetwork/lnd/graphs/contributors)!
<a name="Standards" /> # Contribution Standards
### 6. Contribution Standards ## Contribution Checklist
<a name="Checklist" />
#### 6.1. Contribution Checklist
- [&nbsp;&nbsp;] All changes are Go version 1.12 compliant - [&nbsp;&nbsp;] All changes are Go version 1.12 compliant
- [&nbsp;&nbsp;] The code being submitted is commented according to [Code Documentation and Commenting](#CodeDocumentation) - [&nbsp;&nbsp;] The code being submitted is commented according to
[Code Documentation and Commenting](#code-documentation-and-commenting)
- [&nbsp;&nbsp;] For new code: Code is accompanied by tests which exercise both - [&nbsp;&nbsp;] For new code: Code is accompanied by tests which exercise both
the positive and negative (error paths) conditions (if applicable) the positive and negative (error paths) conditions (if applicable)
- [&nbsp;&nbsp;] For bug fixes: Code is accompanied by new tests which trigger - [&nbsp;&nbsp;] For bug fixes: Code is accompanied by new tests which trigger
@ -630,18 +592,17 @@ Rejoice as you will now be listed as a [contributor](https://github.com/lightnin
- [&nbsp;&nbsp;] All commits build properly and pass tests. Only in exceptional - [&nbsp;&nbsp;] All commits build properly and pass tests. Only in exceptional
cases it can be justifiable to violate this condition. In that case, the cases it can be justifiable to violate this condition. In that case, the
reason should be stated in the commit message. reason should be stated in the commit message.
- [&nbsp;&nbsp;] Commits have a logical structure according to [Ideal Git Commit Structure](#IdealGitCommitStructure). - [&nbsp;&nbsp;] Commits have a logical structure according to
[Ideal Git Commit Structure](#ideal-git-commit-structure).
<a name="Licensing" /> ## Licensing of Contributions
#### 6.2. Licensing of Contributions
**** ****
All contributions must be licensed with the All contributions must be licensed with the
[MIT license](https://github.com/lightningnetwork/lnd/blob/master/LICENSE). This is [MIT license](https://github.com/lightningnetwork/lnd/blob/master/LICENSE). This is
the same license as all of the code found within lnd. the same license as all of the code found within lnd.
## Acknowledgements # Acknowledgements
This document was heavily inspired by a [similar document outlining the code This document was heavily inspired by a [similar document outlining the code
contribution](https://github.com/btcsuite/btcd/blob/master/docs/code_contribution_guidelines.md) contribution](https://github.com/btcsuite/btcd/blob/master/docs/code_contribution_guidelines.md)
guidelines for btcd. guidelines for btcd.

@ -37,7 +37,7 @@ First, you'll want to run `tor` locally before starting up `lnd`. Depending on
how you installed Tor, you'll find the configuration file at how you installed Tor, you'll find the configuration file at
`/usr/local/etc/tor/torrc`. Here's an example configuration file that we'll be `/usr/local/etc/tor/torrc`. Here's an example configuration file that we'll be
using for the remainder of the tutorial: using for the remainder of the tutorial:
``` ```text
SOCKSPort 9050 SOCKSPort 9050
Log notice stdout Log notice stdout
ControlPort 9051 ControlPort 9051
@ -45,7 +45,7 @@ CookieAuthentication 1
``` ```
With the configuration file created, you'll then want to start the Tor daemon: With the configuration file created, you'll then want to start the Tor daemon:
``` ```shell
⛰ tor ⛰ tor
Feb 05 17:02:06.501 [notice] Tor 0.3.1.8 (git-ad5027f7dc790624) running on Darwin with Libevent 2.1.8-stable, OpenSSL 1.0.2l, Zlib 1.2.8, Liblzma N/A, and Libzstd N/A. Feb 05 17:02:06.501 [notice] Tor 0.3.1.8 (git-ad5027f7dc790624) running on Darwin with Libevent 2.1.8-stable, OpenSSL 1.0.2l, Zlib 1.2.8, Liblzma N/A, and Libzstd N/A.
Feb 05 17:02:06.502 [notice] Tor can't help you if you use it wrong! Learn how to be safe at https://www.torproject.org/download/download#warning Feb 05 17:02:06.502 [notice] Tor can't help you if you use it wrong! Learn how to be safe at https://www.torproject.org/download/download#warning
@ -55,7 +55,7 @@ Feb 05 17:02:06.506 [notice] Opening Control listener on 127.0.0.1:9051
``` ```
Once the `tor` daemon has started and it has finished bootstrapping, you'll see this in the logs: Once the `tor` daemon has started and it has finished bootstrapping, you'll see this in the logs:
``` ```text
Feb 05 17:02:06.000 [notice] Bootstrapped 0%: Starting Feb 05 17:02:06.000 [notice] Bootstrapped 0%: Starting
Feb 05 17:02:07.000 [notice] Starting with guard context "default" Feb 05 17:02:07.000 [notice] Starting with guard context "default"
Feb 05 17:02:07.000 [notice] Bootstrapped 80%: Connecting to the Tor network Feb 05 17:02:07.000 [notice] Bootstrapped 80%: Connecting to the Tor network
@ -68,7 +68,7 @@ Feb 05 17:02:11.000 [notice] Bootstrapped 100%: Done
This indicates the daemon is fully bootstrapped and ready to proxy connections. This indicates the daemon is fully bootstrapped and ready to proxy connections.
At this point, we can now start `lnd` with the relevant arguments: At this point, we can now start `lnd` with the relevant arguments:
``` ```shell
⛰ ./lnd -h ⛰ ./lnd -h
<snip> <snip>
@ -132,7 +132,7 @@ circuit.
Activating stream isolation is very straightforward, we only require the Activating stream isolation is very straightforward, we only require the
specification of an additional argument: specification of an additional argument:
``` ```shell
⛰ ./lnd --tor.active --tor.streamisolation ⛰ ./lnd --tor.active --tor.streamisolation
``` ```
@ -170,7 +170,7 @@ To prevent unintentional leaking of identifying information, it is also necessar
to add the flag `listen=localhost`. to add the flag `listen=localhost`.
For example, v3 onion services can be used with the following flags: For example, v3 onion services can be used with the following flags:
``` ```shell
⛰ ./lnd --tor.active --tor.v3 --listen=localhost ⛰ ./lnd --tor.active --tor.v3 --listen=localhost
``` ```

@ -15,14 +15,14 @@ data ahead of time.
You can enable debug logging in `lnd` by passing the `--debuglevel` flag. For You can enable debug logging in `lnd` by passing the `--debuglevel` flag. For
example, to increase the log level from `info` to `debug`: example, to increase the log level from `info` to `debug`:
``` ```shell
$ lnd --debuglevel=debug lnd --debuglevel=debug
``` ```
You may also specify logging per-subsystem, like this: You may also specify logging per-subsystem, like this:
``` ```shell
$ lnd --debuglevel=<subsystem>=<level>,<subsystem2>=<level>,... lnd --debuglevel=<subsystem>=<level>,<subsystem2>=<level>,...
``` ```
## Capturing pprof data with `lnd` ## Capturing pprof data with `lnd`
@ -34,14 +34,14 @@ Go. The profiler has negligible performance overhead during normal operations
To enable this ability, start `lnd` with the `--profile` option using a free port. To enable this ability, start `lnd` with the `--profile` option using a free port.
``` ```shell
$ lnd --profile=9736 lnd --profile=9736
``` ```
Now, with `lnd` running, you can use the pprof endpoint on port 9736 to collect Now, with `lnd` running, you can use the pprof endpoint on port 9736 to collect
runtime profiling data. You can fetch this data using `curl` like so: runtime profiling data. You can fetch this data using `curl` like so:
``` ```shell
$ curl http://localhost:9736/debug/pprof/goroutine?debug=1 curl http://localhost:9736/debug/pprof/goroutine?debug=1
... ...
``` ```

@ -14,8 +14,8 @@ on bitcoin mainnet.
To create a dev build of LND with etcd support use the following command: To create a dev build of LND with etcd support use the following command:
``` ```shell
make tags="kvdb_etcd" make tags="kvdb_etcd"
``` ```
The important tag is the `kvdb_etcd`, without which the binary is built without The important tag is the `kvdb_etcd`, without which the binary is built without
@ -29,8 +29,8 @@ directory.
To start your local etcd instance for testing run: To start your local etcd instance for testing run:
``` ```shell
./etcd \ ./etcd \
--auto-tls \ --auto-tls \
--advertise-client-urls=https://127.0.0.1:2379 \ --advertise-client-urls=https://127.0.0.1:2379 \
--listen-client-urls=https://0.0.0.0:2379 \ --listen-client-urls=https://0.0.0.0:2379 \
@ -51,8 +51,8 @@ through command line flags or in `lnd.conf`.
Sample command line: Sample command line:
``` ```shell
./lnd-debug \ ./lnd-debug \
--db.backend=etcd \ --db.backend=etcd \
--db.etcd.host=127.0.0.1:2379 \ --db.etcd.host=127.0.0.1:2379 \
--db.etcd.certfile=/home/user/etcd/bin/default.etcd/fixtures/client/cert.pem \ --db.etcd.certfile=/home/user/etcd/bin/default.etcd/fixtures/client/cert.pem \
@ -62,7 +62,7 @@ Sample command line:
Sample `lnd.conf` (with other setting omitted): Sample `lnd.conf` (with other setting omitted):
``` ```text
[db] [db]
backend=etcd backend=etcd
etcd.host=127.0.0.1:2379 etcd.host=127.0.0.1:2379

@ -6,24 +6,24 @@ The `fuzz` package is organized into subpackages which are named after the `lnd`
This section will cover setup and installation of `go-fuzz` and fuzzing binaries. This section will cover setup and installation of `go-fuzz` and fuzzing binaries.
* First, we must get `go-fuzz`. * First, we must get `go-fuzz`.
``` ```shell
$ go get -u github.com/dvyukov/go-fuzz/... go get -u github.com/dvyukov/go-fuzz/...
``` ```
* The following is a command to build all fuzzing harnesses for a specific package. * The following is a command to build all fuzzing harnesses for a specific package.
``` ```shell
$ cd fuzz/<package> cd fuzz/<package>
$ find * -maxdepth 1 -regex '[A-Za-z0-9\-_.]'* -not -name fuzz_utils.go | sed 's/\.go$//1' | xargs -I % sh -c 'go-fuzz-build -func Fuzz_% -o <package>-%-fuzz.zip github.com/lightningnetwork/lnd/fuzz/<package>' find * -maxdepth 1 -regex '[A-Za-z0-9\-_.]'* -not -name fuzz_utils.go | sed 's/\.go$//1' | xargs -I % sh -c 'go-fuzz-build -func Fuzz_% -o <package>-%-fuzz.zip github.com/lightningnetwork/lnd/fuzz/<package>'
``` ```
* This may take a while since this will create zip files associated with each fuzzing target. * This may take a while since this will create zip files associated with each fuzzing target.
* Now, run `go-fuzz` with `workdir` set as below! * Now, run `go-fuzz` with `workdir` set as below!
``` ```shell
$ go-fuzz -bin=<.zip archive here> -workdir=<harness> -procs=<num workers> go-fuzz -bin=<.zip archive here> -workdir=<harness> -procs=<num workers>
``` ```
`go-fuzz` will print out log lines every couple of seconds. Example output: `go-fuzz` will print out log lines every couple of seconds. Example output:
``` ```text
2017/09/19 17:44:23 workers: 8, corpus: 23 (3s ago), crashers: 1, restarts: 1/748, execs: 400690 (16694/sec), cover: 394, uptime: 24s 2017/09/19 17:44:23 workers: 8, corpus: 23 (3s ago), crashers: 1, restarts: 1/748, execs: 400690 (16694/sec), cover: 394, uptime: 24s
``` ```
Corpus is the number of items in the corpus. `go-fuzz` may add valid inputs to Corpus is the number of items in the corpus. `go-fuzz` may add valid inputs to
@ -41,7 +41,7 @@ Fuzzing generally works best with a corpus that is of minimal size while achievi
### Test Harness ### ### Test Harness ###
If you take a look at the test harnesses that are used, you will see that they all consist of one function: If you take a look at the test harnesses that are used, you will see that they all consist of one function:
``` ```go
func Fuzz(data []byte) int func Fuzz(data []byte) int
``` ```
If: If:

@ -21,22 +21,22 @@ Create a new `.net core` console application called `lndclient` at your root dir
Create a folder `Grpc` in the root of your project and fetch the lnd proto files Create a folder `Grpc` in the root of your project and fetch the lnd proto files
```bash ```shell
mkdir Grpc mkdir Grpc
curl -o Grpc/rpc.proto -s https://raw.githubusercontent.com/lightningnetwork/lnd/master/lnrpc/rpc.proto curl -o Grpc/rpc.proto -s https://raw.githubusercontent.com/lightningnetwork/lnd/master/lnrpc/rpc.proto
``` ```
Install `Grpc.Tools`, `Google.Protobuf`, `Grpc.Core` using NuGet or manually with `dotnet add`: Install `Grpc.Tools`, `Google.Protobuf`, `Grpc.Core` using NuGet or manually with `dotnet add`:
```bash ```shell
dotnet add package Grpc.Tools dotnet add package Grpc.Tools
dotnet add package Google.Protobuf dotnet add package Google.Protobuf
dotnet add package Grpc.Core dotnet add package Grpc.Core
``` ```
Add the `rpc.proto` file to the `.csproj` file in an ItemGroup. (In Visual Studio you can do this by unloading the project, editing the `.csproj` file and then reloading it) Add the `rpc.proto` file to the `.csproj` file in an ItemGroup. (In Visual Studio you can do this by unloading the project, editing the `.csproj` file and then reloading it)
``` ```xml
<ItemGroup> <ItemGroup>
<Protobuf Include="Grpc\rpc.proto" GrpcServices="Client" /> <Protobuf Include="Grpc\rpc.proto" GrpcServices="Client" />
</ItemGroup> </ItemGroup>
@ -48,8 +48,7 @@ You're done! Build the project and verify that it works.
Use the code below to set up a channel and client to connect to your `lnd` node: Use the code below to set up a channel and client to connect to your `lnd` node:
```c# ```cs
using System.Collections.Generic; using System.Collections.Generic;
using System.IO; using System.IO;
using System.Threading.Tasks; using System.Threading.Tasks;
@ -69,7 +68,6 @@ var cert = File.ReadAllText(<Tls_Cert_Location>);
var sslCreds = new SslCredentials(cert); var sslCreds = new SslCredentials(cert);
var channel = new Grpc.Core.Channel("localhost:10009", sslCreds); var channel = new Grpc.Core.Channel("localhost:10009", sslCreds);
var client = new Lnrpc.Lightning.LightningClient(channel); var client = new Lnrpc.Lightning.LightningClient(channel);
``` ```
### Examples ### Examples
@ -78,7 +76,7 @@ Let's walk through some examples of C# `gRPC` clients. These examples assume tha
#### Simple RPC #### Simple RPC
```c# ```cs
// Retrieve and display the wallet balance // Retrieve and display the wallet balance
// Use "WalletBalanceAsync" if in async context // Use "WalletBalanceAsync" if in async context
var response = client.WalletBalance(new WalletBalanceRequest()); var response = client.WalletBalance(new WalletBalanceRequest());
@ -87,7 +85,7 @@ Console.WriteLine(response);
#### Response-streaming RPC #### Response-streaming RPC
```c# ```cs
var request = new InvoiceSubscription(); var request = new InvoiceSubscription();
using (var call = client.SubscribeInvoices(request)) using (var call = client.SubscribeInvoices(request))
{ {
@ -100,20 +98,20 @@ using (var call = client.SubscribeInvoices(request))
``` ```
Now, create an invoice for your node at `localhost:10009` and send a payment to it from another node. Now, create an invoice for your node at `localhost:10009` and send a payment to it from another node.
```bash ```shell
$ lncli addinvoice --amt=100 lncli addinvoice --amt=100
{ {
"r_hash": <R_HASH>, "r_hash": <R_HASH>,
"pay_req": <PAY_REQ> "pay_req": <PAY_REQ>
} }
$ lncli sendpayment --pay_req=<PAY_REQ> lncli sendpayment --pay_req=<PAY_REQ>
``` ```
Your console should now display the details of the recently satisfied invoice. Your console should now display the details of the recently satisfied invoice.
#### Bidirectional-streaming RPC #### Bidirectional-streaming RPC
```c# ```cs
using (var call = client.SendPayment()) using (var call = client.SendPayment())
{ {
var responseReaderTask = Task.Run(async () => var responseReaderTask = Task.Run(async () =>
@ -155,7 +153,7 @@ This example will send a payment of 100 satoshis every 2 seconds.
To authenticate using macaroons you need to include the macaroon in the metadata of the request. To authenticate using macaroons you need to include the macaroon in the metadata of the request.
```c# ```cs
// Lnd admin macaroon is at <LND_DIR>/data/chain/bitcoin/simnet/admin.macaroon on Windows // Lnd admin macaroon is at <LND_DIR>/data/chain/bitcoin/simnet/admin.macaroon on Windows
// ~/.lnd/data/chain/bitcoin/simnet/admin.macaroon on Linux and ~/Library/Application Support/Lnd/data/chain/bitcoin/simnet/admin.macaroon on Mac // ~/.lnd/data/chain/bitcoin/simnet/admin.macaroon on Linux and ~/Library/Application Support/Lnd/data/chain/bitcoin/simnet/admin.macaroon on Mac
byte[] macaroonBytes = File.ReadAllBytes("<LND_DIR>/data/chain/bitcoin/simnet/admin.macaroon"); byte[] macaroonBytes = File.ReadAllBytes("<LND_DIR>/data/chain/bitcoin/simnet/admin.macaroon");
@ -164,13 +162,13 @@ var macaroon = BitConverter.ToString(macaroonBytes).Replace("-", ""); // hex for
The simplest approach to use the macaroon is to include the metadata in each request as shown below. The simplest approach to use the macaroon is to include the metadata in each request as shown below.
```c# ```cs
client.GetInfo(new GetInfoRequest(), new Metadata() { new Metadata.Entry("macaroon", macaroon) }); client.GetInfo(new GetInfoRequest(), new Metadata() { new Metadata.Entry("macaroon", macaroon) });
``` ```
However, this can get tiresome to do for each request, so to avoid explicitly including the macaroon we can update the credentials to include it automatically. However, this can get tiresome to do for each request, so to avoid explicitly including the macaroon we can update the credentials to include it automatically.
```c# ```cs
// build ssl credentials using the cert the same as before // build ssl credentials using the cert the same as before
var sslCreds = new SslCredentials(cert); var sslCreds = new SslCredentials(cert);

@ -11,7 +11,7 @@ with lnd in Java. We'll be using Maven as our build tool.
### Setup and Installation ### Setup and Installation
#### Project Structure #### Project Structure
``` ```text
. .
├── pom.xml ├── pom.xml
└── src └── src
@ -34,13 +34,13 @@ Note the ***proto*** folder, where all the proto files are kept.
- [http.proto](https://github.com/grpc-ecosystem/grpc-gateway/blob/master/third_party/googleapis/google/api/http.proto) - [http.proto](https://github.com/grpc-ecosystem/grpc-gateway/blob/master/third_party/googleapis/google/api/http.proto)
#### pom.xml #### pom.xml
``` ```xml
<properties> <properties>
<grpc.version>1.8.0</grpc.version> <grpc.version>1.8.0</grpc.version>
</properties> </properties>
``` ```
The following dependencies are required. The following dependencies are required.
``` ```xml
<dependencies> <dependencies>
<dependency> <dependency>
<groupId>io.grpc</groupId> <groupId>io.grpc</groupId>
@ -70,7 +70,7 @@ The following dependencies are required.
</dependencies> </dependencies>
``` ```
In the build section, we'll need to configure the following things : In the build section, we'll need to configure the following things :
``` ```xml
<build> <build>
<extensions> <extensions>
<extension> <extension>
@ -184,11 +184,11 @@ public class Main {
``` ```
#### Running the example #### Running the example
Execute the following command in the directory where the **pom.xml** file is located. Execute the following command in the directory where the **pom.xml** file is located.
``` ```shell
mvn compile exec:java -Dexec.mainClass="Main" -Dexec.cleanupDaemonThreads=false mvn compile exec:java -Dexec.mainClass="Main" -Dexec.cleanupDaemonThreads=false
``` ```
##### Sample output ##### Sample output
``` ```text
[INFO] Scanning for projects... [INFO] Scanning for projects...
[INFO] ------------------------------------------------------------------------ [INFO] ------------------------------------------------------------------------
[INFO] Detecting the operating system and CPU architecture [INFO] Detecting the operating system and CPU architecture

@ -121,7 +121,7 @@ invoice.
This example has a few dependencies: This example has a few dependencies:
```shell ```shell
npm install --save async lodash bytebuffer npm install --save async lodash bytebuffer
``` ```
You can run the following in your shell or put it in a program and run it like You can run the following in your shell or put it in a program and run it like

@ -10,32 +10,32 @@ based on protocol buffers and as such, you will need to compile the lnd proto
file in Python before you can use it to communicate with lnd. file in Python before you can use it to communicate with lnd.
1. Create a virtual environment for your project 1. Create a virtual environment for your project
``` ```shell
$ virtualenv lnd virtualenv lnd
``` ```
2. Activate the virtual environment 2. Activate the virtual environment
``` ```shell
$ source lnd/bin/activate source lnd/bin/activate
``` ```
3. Install dependencies (googleapis-common-protos is required due to the use of 3. Install dependencies (googleapis-common-protos is required due to the use of
google/api/annotations.proto) google/api/annotations.proto)
``` ```shell
(lnd)$ pip install grpcio grpcio-tools googleapis-common-protos lnd ⛰ pip install grpcio grpcio-tools googleapis-common-protos
``` ```
4. Clone the google api's repository (required due to the use of 4. Clone the google api's repository (required due to the use of
google/api/annotations.proto) google/api/annotations.proto)
``` ```shell
(lnd)$ git clone https://github.com/googleapis/googleapis.git lnd ⛰ git clone https://github.com/googleapis/googleapis.git
``` ```
5. Copy the lnd rpc.proto file (you'll find this at 5. Copy the lnd rpc.proto file (you'll find this at
[lnrpc/rpc.proto](https://github.com/lightningnetwork/lnd/blob/master/lnrpc/rpc.proto)) [lnrpc/rpc.proto](https://github.com/lightningnetwork/lnd/blob/master/lnrpc/rpc.proto))
or just download it or just download it
``` ```shell
(lnd)$ curl -o rpc.proto -s https://raw.githubusercontent.com/lightningnetwork/lnd/master/lnrpc/rpc.proto lnd ⛰ curl -o rpc.proto -s https://raw.githubusercontent.com/lightningnetwork/lnd/master/lnrpc/rpc.proto
``` ```
6. Compile the proto file 6. Compile the proto file
``` ```shell
(lnd)$ python -m grpc_tools.protoc --proto_path=googleapis:. --python_out=. --grpc_python_out=. rpc.proto lnd ⛰ python -m grpc_tools.protoc --proto_path=googleapis:. --python_out=. --grpc_python_out=. rpc.proto
``` ```
After following these steps, two files `rpc_pb2.py` and `rpc_pb2_grpc.py` will After following these steps, two files `rpc_pb2.py` and `rpc_pb2_grpc.py` will
@ -52,9 +52,9 @@ For example, if you want to generate the RPC modules for the `Router` subserver
extra steps (after completing all 6 step described above) to get the extra steps (after completing all 6 step described above) to get the
`router_pb2.py` and `router_pb2_grpc.py`: `router_pb2.py` and `router_pb2_grpc.py`:
``` ```shell
(lnd)$ curl -o router.proto -s https://raw.githubusercontent.com/lightningnetwork/lnd/master/lnrpc/routerrpc/router.proto lnd ⛰ curl -o router.proto -s https://raw.githubusercontent.com/lightningnetwork/lnd/master/lnrpc/routerrpc/router.proto
(lnd)$ python -m grpc_tools.protoc --proto_path=googleapis:. --python_out=. --grpc_python_out=. router.proto lnd ⛰ python -m grpc_tools.protoc --proto_path=googleapis:. --python_out=. --grpc_python_out=. router.proto
``` ```
### Imports and Client ### Imports and Client
@ -105,13 +105,13 @@ for invoice in stub.SubscribeInvoices(request):
Now, create an invoice for your node at `localhost:10009`and send a payment to Now, create an invoice for your node at `localhost:10009`and send a payment to
it from another node. it from another node.
```bash ```shell
$ lncli addinvoice --amt=100 lnd ⛰ lncli addinvoice --amt=100
{ {
"r_hash": <R_HASH>, "r_hash": <R_HASH>,
"pay_req": <PAY_REQ> "pay_req": <PAY_REQ>
} }
$ lncli sendpayment --pay_req=<PAY_REQ> lnd ⛰ lncli sendpayment --pay_req=<PAY_REQ>
``` ```
Your Python console should now display the details of the recently satisfied Your Python console should now display the details of the recently satisfied

@ -14,27 +14,27 @@ the `lnd` proto file in Ruby before you can use it to communicate with `lnd`.
Install gRPC rubygems: Install gRPC rubygems:
``` ```shell
$ gem install grpc gem install grpc
$ gem install grpc-tools gem install grpc-tools
``` ```
Clone the Google APIs repository: Clone the Google APIs repository:
``` ```shell
$ git clone https://github.com/googleapis/googleapis.git git clone https://github.com/googleapis/googleapis.git
``` ```
Fetch the `rpc.proto` file (or copy it from your local source directory): Fetch the `rpc.proto` file (or copy it from your local source directory):
``` ```shell
$ curl -o rpc.proto -s https://raw.githubusercontent.com/lightningnetwork/lnd/master/lnrpc/rpc.proto curl -o rpc.proto -s https://raw.githubusercontent.com/lightningnetwork/lnd/master/lnrpc/rpc.proto
``` ```
Compile the proto file: Compile the proto file:
``` ```shell
$ grpc_tools_ruby_protoc --proto_path googleapis:. --ruby_out=. --grpc_out=. rpc.proto grpc_tools_ruby_protoc --proto_path googleapis:. --ruby_out=. --grpc_out=. rpc.proto
``` ```
Two files will be generated in the current directory: Two files will be generated in the current directory:
@ -98,8 +98,8 @@ end
Now, create an invoice on your node: Now, create an invoice on your node:
```bash ```shell
$ lncli addinvoice --amt=590 lncli addinvoice --amt=590
{ {
"r_hash": <R_HASH>, "r_hash": <R_HASH>,
"pay_req": <PAY_REQ> "pay_req": <PAY_REQ>
@ -108,8 +108,8 @@ $ lncli addinvoice --amt=590
Next send a payment to it from another node: Next send a payment to it from another node:
``` ```shell
$ lncli sendpayment --pay_req=<PAY_REQ> lncli sendpayment --pay_req=<PAY_REQ>
``` ```
You should now see the details of the settled invoice appear. You should now see the details of the settled invoice appear.

@ -146,11 +146,17 @@ To avoid leaking the macaroon information, `lnd` supports the so called
Examples: Examples:
* Create a new wallet stateless (first run): * Create a new wallet stateless (first run):
* `lncli create --stateless_init --save_to=/safe/location/admin.macaroon` ```shell
⛰ lncli create --stateless_init --save_to=/safe/location/admin.macaroon
```
* Unlock a wallet that has previously been initialized stateless: * Unlock a wallet that has previously been initialized stateless:
* `lncli unlock --stateless_init` ```shell
⛰ lncli unlock --stateless_init
```
* Use the created macaroon: * Use the created macaroon:
* `lncli --macaroonpath=/safe/location/admin.macaroon getinfo` ```shell
⛰ lncli --macaroonpath=/safe/location/admin.macaroon getinfo
```
## Using Macaroons with GRPC clients ## Using Macaroons with GRPC clients
@ -158,14 +164,18 @@ When interacting with `lnd` using the GRPC interface, the macaroons are encoded
as a hex string over the wire and can be passed to `lnd` by specifying the as a hex string over the wire and can be passed to `lnd` by specifying the
hex-encoded macaroon as GRPC metadata: hex-encoded macaroon as GRPC metadata:
```text
GET https://localhost:8080/v1/getinfo GET https://localhost:8080/v1/getinfo
Grpc-Metadata-macaroon: <macaroon> Grpc-Metadata-macaroon: <macaroon>
```
Where `<macaroon>` is the hex encoded binary data from the macaroon file itself. Where `<macaroon>` is the hex encoded binary data from the macaroon file itself.
A very simple example using `curl` may look something like this: A very simple example using `curl` may look something like this:
curl --insecure --header "Grpc-Metadata-macaroon: $(xxd -ps -u -c 1000 $HOME/.lnd/data/chain/bitcoin/simnet/admin.macaroon)" https://localhost:8080/v1/getinfo ```shell
⛰ curl --insecure --header "Grpc-Metadata-macaroon: $(xxd -ps -u -c 1000 $HOME/.lnd/data/chain/bitcoin/simnet/admin.macaroon)" https://localhost:8080/v1/getinfo
```
Have a look at the [Java GRPC example](/docs/grpc/java.md) for programmatic usage details. Have a look at the [Java GRPC example](/docs/grpc/java.md) for programmatic usage details.

@ -5,7 +5,7 @@ the time of writing this documentation, UPnP and NAT-PMP are supported. NAT
traversal can be enabled through `lnd`'s `--nat` flag. traversal can be enabled through `lnd`'s `--nat` flag.
```shell ```shell
$ lnd ... --nat lnd ... --nat
``` ```
On startup, `lnd` will try the different techniques until one is found that's On startup, `lnd` will try the different techniques until one is found that's

@ -25,9 +25,8 @@ amounts to be in satoshis instead of fractions of a bitcoin.
Let's start with a very simple example and assume we want to send half a coin Let's start with a very simple example and assume we want to send half a coin
to the address `bcrt1qjrdns4f5zwkv29ln86plqzs092yd5fg6nsz8re`: to the address `bcrt1qjrdns4f5zwkv29ln86plqzs092yd5fg6nsz8re`:
```shell script ```shell
$ lncli wallet psbt fund --outputs='{"bcrt1qjrdns4f5zwkv29ln86plqzs092yd5fg6nsz8re":50000000}' ⛰ lncli wallet psbt fund --outputs='{"bcrt1qjrdns4f5zwkv29ln86plqzs092yd5fg6nsz8re":50000000}'
{ {
"psbt": "cHNidP8BAHECAAAAAeJQY2VLRtutKgQYFUajEKpjFfl0Uyrm6x23OumDpe/4AQAAAAD/////AkxREgEAAAAAFgAUv6pTgbKHN60CZ+RQn5yOuH6c2WiA8PoCAAAAABYAFJDbOFU0E6zFF/M+g/AKDyqI2iUaAAAAAAABAOsCAAAAAAEBbxqXgEf9DlzcqqNM610s5pL1X258ra6+KJ22etb7HAcBAAAAAAAAAAACACT0AAAAAAAiACC7U1W0iJGhQ6o7CexDh5k36V6v3256xpA9/xmB2BybTFZdDQQAAAAAFgAUKp2ThzhswyM2QHlyvmMB6tQB7V0CSDBFAiEA4Md8RIZYqFdUPsgDyomlzMJL9bJ6Ho23JGTihXtEelgCIAeNXRLyt88SOuuWFVn3IodCE4U5D6DojIHesRmikF28ASEDHYFzMEAxfmfq98eSSnZtUwb1w7mAtHG65y8qiRFNnIkAAAAAAQEfVl0NBAAAAAAWABQqnZOHOGzDIzZAeXK+YwHq1AHtXQEDBAEAAAAAAAA=", "psbt": "cHNidP8BAHECAAAAAeJQY2VLRtutKgQYFUajEKpjFfl0Uyrm6x23OumDpe/4AQAAAAD/////AkxREgEAAAAAFgAUv6pTgbKHN60CZ+RQn5yOuH6c2WiA8PoCAAAAABYAFJDbOFU0E6zFF/M+g/AKDyqI2iUaAAAAAAABAOsCAAAAAAEBbxqXgEf9DlzcqqNM610s5pL1X258ra6+KJ22etb7HAcBAAAAAAAAAAACACT0AAAAAAAiACC7U1W0iJGhQ6o7CexDh5k36V6v3256xpA9/xmB2BybTFZdDQQAAAAAFgAUKp2ThzhswyM2QHlyvmMB6tQB7V0CSDBFAiEA4Md8RIZYqFdUPsgDyomlzMJL9bJ6Ho23JGTihXtEelgCIAeNXRLyt88SOuuWFVn3IodCE4U5D6DojIHesRmikF28ASEDHYFzMEAxfmfq98eSSnZtUwb1w7mAtHG65y8qiRFNnIkAAAAAAQEfVl0NBAAAAAAWABQqnZOHOGzDIzZAeXK+YwHq1AHtXQEDBAEAAAAAAAA=",
"change_output_index": 0, "change_output_index": 0,
@ -51,8 +50,8 @@ If we inspect the PSBT that was created, we see that the locked input was indeed
selected, the UTXO information was attached and a change output (at index 0) was selected, the UTXO information was attached and a change output (at index 0) was
created as well: created as well:
```shell script ```shell
$ bitcoin-cli decodepsbt cHNidP8BAHECAAAAAeJQY2VLRtutKgQYFUajEKpjFfl0Uyrm6x23OumDpe/4AQAAAAD/////AkxREgEAAAAAFgAUv6pTgbKHN60CZ+RQn5yOuH6c2WiA8PoCAAAAABYAFJDbOFU0E6zFF/M+g/AKDyqI2iUaAAAAAAABAOsCAAAAAAEBbxqXgEf9DlzcqqNM610s5pL1X258ra6+KJ22etb7HAcBAAAAAAAAAAACACT0AAAAAAAiACC7U1W0iJGhQ6o7CexDh5k36V6v3256xpA9/xmB2BybTFZdDQQAAAAAFgAUKp2ThzhswyM2QHlyvmMB6tQB7V0CSDBFAiEA4Md8RIZYqFdUPsgDyomlzMJL9bJ6Ho23JGTihXtEelgCIAeNXRLyt88SOuuWFVn3IodCE4U5D6DojIHesRmikF28ASEDHYFzMEAxfmfq98eSSnZtUwb1w7mAtHG65y8qiRFNnIkAAAAAAQEfVl0NBAAAAAAWABQqnZOHOGzDIzZAeXK+YwHq1AHtXQEDBAEAAAAAAAA= bitcoin-cli decodepsbt cHNidP8BAHECAAAAAeJQY2VLRtutKgQYFUajEKpjFfl0Uyrm6x23OumDpe/4AQAAAAD/////AkxREgEAAAAAFgAUv6pTgbKHN60CZ+RQn5yOuH6c2WiA8PoCAAAAABYAFJDbOFU0E6zFF/M+g/AKDyqI2iUaAAAAAAABAOsCAAAAAAEBbxqXgEf9DlzcqqNM610s5pL1X258ra6+KJ22etb7HAcBAAAAAAAAAAACACT0AAAAAAAiACC7U1W0iJGhQ6o7CexDh5k36V6v3256xpA9/xmB2BybTFZdDQQAAAAAFgAUKp2ThzhswyM2QHlyvmMB6tQB7V0CSDBFAiEA4Md8RIZYqFdUPsgDyomlzMJL9bJ6Ho23JGTihXtEelgCIAeNXRLyt88SOuuWFVn3IodCE4U5D6DojIHesRmikF28ASEDHYFzMEAxfmfq98eSSnZtUwb1w7mAtHG65y8qiRFNnIkAAAAAAQEfVl0NBAAAAAAWABQqnZOHOGzDIzZAeXK+YwHq1AHtXQEDBAEAAAAAAAA=
{ {
"tx": { "tx": {
"txid": "33a316d62ddf74656967754d26ea83a3cb89e03ae44578d965156d4b71b1fce7", "txid": "33a316d62ddf74656967754d26ea83a3cb89e03ae44578d965156d4b71b1fce7",
@ -132,9 +131,8 @@ manually.
The first step is to look at all available UTXOs and choose. To do so, we use The first step is to look at all available UTXOs and choose. To do so, we use
the `listunspent` command: the `listunspent` command:
```shell script ```shell
$ lncli listunspent ⛰ lncli listunspent
{ {
"utxos": [ "utxos": [
{ {
@ -160,10 +158,9 @@ $ lncli listunspent
Next, we choose these two inputs and create the PSBT: Next, we choose these two inputs and create the PSBT:
```shell script ```shell
$ lncli wallet psbt fund --outputs='{"bcrt1qjrdns4f5zwkv29ln86plqzs092yd5fg6nsz8re":50000000}' \ lncli wallet psbt fund --outputs='{"bcrt1qjrdns4f5zwkv29ln86plqzs092yd5fg6nsz8re":50000000}' \
--inputs='["3597b451ff56bc901eb806e8c644a004e934b4c208679756b4cddc455c768c48:1","f8efa583e93ab71debe62a5374f91563aa10a3461518042aaddb464b656350e2:1"]' --inputs='["3597b451ff56bc901eb806e8c644a004e934b4c208679756b4cddc455c768c48:1","f8efa583e93ab71debe62a5374f91563aa10a3461518042aaddb464b656350e2:1"]'
{ {
"psbt": "cHNidP8BAJoCAAAAAkiMdlxF3M20VpdnCMK0NOkEoETG6Aa4HpC8Vv9RtJc1AQAAAAAAAAAA4lBjZUtG260qBBgVRqMQqmMV+XRTKubrHbc66YOl7/gBAAAAAAAAAAACgPD6AgAAAAAWABSQ2zhVNBOsxRfzPoPwCg8qiNolGtIkCAcAAAAAFgAUuvRP5r7qAvj0egDxyX9/FH+vukgAAAAAAAEA3gIAAAAAAQEr9IZcho/gV/6fH8C8P+yhNRZP+l3YuxsyatdYcS0S6AEAAAAA/v///wLI/8+yAAAAABYAFDXoRFwgXNO5VVtVq2WpaENh6blAAOH1BQAAAAAWABTcAR0NeNdDHb96kMnH5EVUcr1YwwJHMEQCIDqugtYLp4ebJAZvOdieshLi1lLuPl2tHQG4jM4ybwEGAiBeMpCkbHBmzYvljxb1JBQyVAMuoco0xIfi+5OQdHuXaAEhAnH96NhTW09X0npE983YBsHUoMPI4U4xBtHenpZVTEqpVwAAAAEBHwDh9QUAAAAAFgAU3AEdDXjXQx2/epDJx+RFVHK9WMMBAwQBAAAAAAEA6wIAAAAAAQFvGpeAR/0OXNyqo0zrXSzmkvVfbnytrr4onbZ61vscBwEAAAAAAAAAAAIAJPQAAAAAACIAILtTVbSIkaFDqjsJ7EOHmTfpXq/fbnrGkD3/GYHYHJtMVl0NBAAAAAAWABQqnZOHOGzDIzZAeXK+YwHq1AHtXQJIMEUCIQDgx3xEhlioV1Q+yAPKiaXMwkv1snoejbckZOKFe0R6WAIgB41dEvK3zxI665YVWfcih0IThTkPoOiMgd6xGaKQXbwBIQMdgXMwQDF+Z+r3x5JKdm1TBvXDuYC0cbrnLyqJEU2ciQAAAAABAR9WXQ0EAAAAABYAFCqdk4c4bMMjNkB5cr5jAerUAe1dAQMEAQAAAAAAAA==", "psbt": "cHNidP8BAJoCAAAAAkiMdlxF3M20VpdnCMK0NOkEoETG6Aa4HpC8Vv9RtJc1AQAAAAAAAAAA4lBjZUtG260qBBgVRqMQqmMV+XRTKubrHbc66YOl7/gBAAAAAAAAAAACgPD6AgAAAAAWABSQ2zhVNBOsxRfzPoPwCg8qiNolGtIkCAcAAAAAFgAUuvRP5r7qAvj0egDxyX9/FH+vukgAAAAAAAEA3gIAAAAAAQEr9IZcho/gV/6fH8C8P+yhNRZP+l3YuxsyatdYcS0S6AEAAAAA/v///wLI/8+yAAAAABYAFDXoRFwgXNO5VVtVq2WpaENh6blAAOH1BQAAAAAWABTcAR0NeNdDHb96kMnH5EVUcr1YwwJHMEQCIDqugtYLp4ebJAZvOdieshLi1lLuPl2tHQG4jM4ybwEGAiBeMpCkbHBmzYvljxb1JBQyVAMuoco0xIfi+5OQdHuXaAEhAnH96NhTW09X0npE983YBsHUoMPI4U4xBtHenpZVTEqpVwAAAAEBHwDh9QUAAAAAFgAU3AEdDXjXQx2/epDJx+RFVHK9WMMBAwQBAAAAAAEA6wIAAAAAAQFvGpeAR/0OXNyqo0zrXSzmkvVfbnytrr4onbZ61vscBwEAAAAAAAAAAAIAJPQAAAAAACIAILtTVbSIkaFDqjsJ7EOHmTfpXq/fbnrGkD3/GYHYHJtMVl0NBAAAAAAWABQqnZOHOGzDIzZAeXK+YwHq1AHtXQJIMEUCIQDgx3xEhlioV1Q+yAPKiaXMwkv1snoejbckZOKFe0R6WAIgB41dEvK3zxI665YVWfcih0IThTkPoOiMgd6xGaKQXbwBIQMdgXMwQDF+Z+r3x5JKdm1TBvXDuYC0cbrnLyqJEU2ciQAAAAABAR9WXQ0EAAAAABYAFCqdk4c4bMMjNkB5cr5jAerUAe1dAQMEAQAAAAAAAA==",
"change_output_index": 1, "change_output_index": 1,
@ -185,9 +182,8 @@ $ lncli wallet psbt fund --outputs='{"bcrt1qjrdns4f5zwkv29ln86plqzs092yd5fg6nsz8
Inspecting this PSBT, we notice that the two inputs were chosen and a large Inspecting this PSBT, we notice that the two inputs were chosen and a large
change change output was added at index 1: change change output was added at index 1:
```shell script ```shell
$ bitcoin-cli decodepsbt cHNidP8BAJoCAAAAAkiMdlxF3M20VpdnCMK0NOkEoETG6Aa4HpC8Vv9RtJc1AQAAAAAAAAAA4lBjZUtG260qBBgVRqMQqmMV+XRTKubrHbc66YOl7/gBAAAAAAAAAAACgPD6AgAAAAAWABSQ2zhVNBOsxRfzPoPwCg8qiNolGtIkCAcAAAAAFgAUuvRP5r7qAvj0egDxyX9/FH+vukgAAAAAAAEA3gIAAAAAAQEr9IZcho/gV/6fH8C8P+yhNRZP+l3YuxsyatdYcS0S6AEAAAAA/v///wLI/8+yAAAAABYAFDXoRFwgXNO5VVtVq2WpaENh6blAAOH1BQAAAAAWABTcAR0NeNdDHb96kMnH5EVUcr1YwwJHMEQCIDqugtYLp4ebJAZvOdieshLi1lLuPl2tHQG4jM4ybwEGAiBeMpCkbHBmzYvljxb1JBQyVAMuoco0xIfi+5OQdHuXaAEhAnH96NhTW09X0npE983YBsHUoMPI4U4xBtHenpZVTEqpVwAAAAEBHwDh9QUAAAAAFgAU3AEdDXjXQx2/epDJx+RFVHK9WMMBAwQBAAAAAAEA6wIAAAAAAQFvGpeAR/0OXNyqo0zrXSzmkvVfbnytrr4onbZ61vscBwEAAAAAAAAAAAIAJPQAAAAAACIAILtTVbSIkaFDqjsJ7EOHmTfpXq/fbnrGkD3/GYHYHJtMVl0NBAAAAAAWABQqnZOHOGzDIzZAeXK+YwHq1AHtXQJIMEUCIQDgx3xEhlioV1Q+yAPKiaXMwkv1snoejbckZOKFe0R6WAIgB41dEvK3zxI665YVWfcih0IThTkPoOiMgd6xGaKQXbwBIQMdgXMwQDF+Z+r3x5JKdm1TBvXDuYC0cbrnLyqJEU2ciQAAAAABAR9WXQ0EAAAAABYAFCqdk4c4bMMjNkB5cr5jAerUAe1dAQMEAQAAAAAAAA== ⛰ bitcoin-cli decodepsbt cHNidP8BAJoCAAAAAkiMdlxF3M20VpdnCMK0NOkEoETG6Aa4HpC8Vv9RtJc1AQAAAAAAAAAA4lBjZUtG260qBBgVRqMQqmMV+XRTKubrHbc66YOl7/gBAAAAAAAAAAACgPD6AgAAAAAWABSQ2zhVNBOsxRfzPoPwCg8qiNolGtIkCAcAAAAAFgAUuvRP5r7qAvj0egDxyX9/FH+vukgAAAAAAAEA3gIAAAAAAQEr9IZcho/gV/6fH8C8P+yhNRZP+l3YuxsyatdYcS0S6AEAAAAA/v///wLI/8+yAAAAABYAFDXoRFwgXNO5VVtVq2WpaENh6blAAOH1BQAAAAAWABTcAR0NeNdDHb96kMnH5EVUcr1YwwJHMEQCIDqugtYLp4ebJAZvOdieshLi1lLuPl2tHQG4jM4ybwEGAiBeMpCkbHBmzYvljxb1JBQyVAMuoco0xIfi+5OQdHuXaAEhAnH96NhTW09X0npE983YBsHUoMPI4U4xBtHenpZVTEqpVwAAAAEBHwDh9QUAAAAAFgAU3AEdDXjXQx2/epDJx+RFVHK9WMMBAwQBAAAAAAEA6wIAAAAAAQFvGpeAR/0OXNyqo0zrXSzmkvVfbnytrr4onbZ61vscBwEAAAAAAAAAAAIAJPQAAAAAACIAILtTVbSIkaFDqjsJ7EOHmTfpXq/fbnrGkD3/GYHYHJtMVl0NBAAAAAAWABQqnZOHOGzDIzZAeXK+YwHq1AHtXQJIMEUCIQDgx3xEhlioV1Q+yAPKiaXMwkv1snoejbckZOKFe0R6WAIgB41dEvK3zxI665YVWfcih0IThTkPoOiMgd6xGaKQXbwBIQMdgXMwQDF+Z+r3x5JKdm1TBvXDuYC0cbrnLyqJEU2ciQAAAAABAR9WXQ0EAAAAABYAFCqdk4c4bMMjNkB5cr5jAerUAe1dAQMEAQAAAAAAAA==
{ {
"tx": { "tx": {
"txid": "e62356b99c3097eaa1241ff8e39b996917e66b13e4c0ccba3698982d746c3b76", "txid": "e62356b99c3097eaa1241ff8e39b996917e66b13e4c0ccba3698982d746c3b76",
@ -263,9 +259,8 @@ $ bitcoin-cli decodepsbt cHNidP8BAJoCAAAAAkiMdlxF3M20VpdnCMK0NOkEoETG6Aa4HpC8Vv
Assuming we now want to sign the transaction that we created in the previous Assuming we now want to sign the transaction that we created in the previous
example, we simply pass it to the `finalize` sub command of the wallet: example, we simply pass it to the `finalize` sub command of the wallet:
```shell script ```shell
$ lncli wallet psbt finalize cHNidP8BAJoCAAAAAkiMdlxF3M20VpdnCMK0NOkEoETG6Aa4HpC8Vv9RtJc1AQAAAAAAAAAA4lBjZUtG260qBBgVRqMQqmMV+XRTKubrHbc66YOl7/gBAAAAAAAAAAACgPD6AgAAAAAWABSQ2zhVNBOsxRfzPoPwCg8qiNolGtIkCAcAAAAAFgAUuvRP5r7qAvj0egDxyX9/FH+vukgAAAAAAAEA3gIAAAAAAQEr9IZcho/gV/6fH8C8P+yhNRZP+l3YuxsyatdYcS0S6AEAAAAA/v///wLI/8+yAAAAABYAFDXoRFwgXNO5VVtVq2WpaENh6blAAOH1BQAAAAAWABTcAR0NeNdDHb96kMnH5EVUcr1YwwJHMEQCIDqugtYLp4ebJAZvOdieshLi1lLuPl2tHQG4jM4ybwEGAiBeMpCkbHBmzYvljxb1JBQyVAMuoco0xIfi+5OQdHuXaAEhAnH96NhTW09X0npE983YBsHUoMPI4U4xBtHenpZVTEqpVwAAAAEBHwDh9QUAAAAAFgAU3AEdDXjXQx2/epDJx+RFVHK9WMMBAwQBAAAAAAEA6wIAAAAAAQFvGpeAR/0OXNyqo0zrXSzmkvVfbnytrr4onbZ61vscBwEAAAAAAAAAAAIAJPQAAAAAACIAILtTVbSIkaFDqjsJ7EOHmTfpXq/fbnrGkD3/GYHYHJtMVl0NBAAAAAAWABQqnZOHOGzDIzZAeXK+YwHq1AHtXQJIMEUCIQDgx3xEhlioV1Q+yAPKiaXMwkv1snoejbckZOKFe0R6WAIgB41dEvK3zxI665YVWfcih0IThTkPoOiMgd6xGaKQXbwBIQMdgXMwQDF+Z+r3x5JKdm1TBvXDuYC0cbrnLyqJEU2ciQAAAAABAR9WXQ0EAAAAABYAFCqdk4c4bMMjNkB5cr5jAerUAe1dAQMEAQAAAAAAAA== ⛰ lncli wallet psbt finalize cHNidP8BAJoCAAAAAkiMdlxF3M20VpdnCMK0NOkEoETG6Aa4HpC8Vv9RtJc1AQAAAAAAAAAA4lBjZUtG260qBBgVRqMQqmMV+XRTKubrHbc66YOl7/gBAAAAAAAAAAACgPD6AgAAAAAWABSQ2zhVNBOsxRfzPoPwCg8qiNolGtIkCAcAAAAAFgAUuvRP5r7qAvj0egDxyX9/FH+vukgAAAAAAAEA3gIAAAAAAQEr9IZcho/gV/6fH8C8P+yhNRZP+l3YuxsyatdYcS0S6AEAAAAA/v///wLI/8+yAAAAABYAFDXoRFwgXNO5VVtVq2WpaENh6blAAOH1BQAAAAAWABTcAR0NeNdDHb96kMnH5EVUcr1YwwJHMEQCIDqugtYLp4ebJAZvOdieshLi1lLuPl2tHQG4jM4ybwEGAiBeMpCkbHBmzYvljxb1JBQyVAMuoco0xIfi+5OQdHuXaAEhAnH96NhTW09X0npE983YBsHUoMPI4U4xBtHenpZVTEqpVwAAAAEBHwDh9QUAAAAAFgAU3AEdDXjXQx2/epDJx+RFVHK9WMMBAwQBAAAAAAEA6wIAAAAAAQFvGpeAR/0OXNyqo0zrXSzmkvVfbnytrr4onbZ61vscBwEAAAAAAAAAAAIAJPQAAAAAACIAILtTVbSIkaFDqjsJ7EOHmTfpXq/fbnrGkD3/GYHYHJtMVl0NBAAAAAAWABQqnZOHOGzDIzZAeXK+YwHq1AHtXQJIMEUCIQDgx3xEhlioV1Q+yAPKiaXMwkv1snoejbckZOKFe0R6WAIgB41dEvK3zxI665YVWfcih0IThTkPoOiMgd6xGaKQXbwBIQMdgXMwQDF+Z+r3x5JKdm1TBvXDuYC0cbrnLyqJEU2ciQAAAAABAR9WXQ0EAAAAABYAFCqdk4c4bMMjNkB5cr5jAerUAe1dAQMEAQAAAAAAAA==
{ {
"psbt": "cHNidP8BAJoCAAAAAkiMdlxF3M20VpdnCMK0NOkEoETG6Aa4HpC8Vv9RtJc1AQAAAAAAAAAA4lBjZUtG260qBBgVRqMQqmMV+XRTKubrHbc66YOl7/gBAAAAAAAAAAACgPD6AgAAAAAWABSQ2zhVNBOsxRfzPoPwCg8qiNolGtIkCAcAAAAAFgAUuvRP5r7qAvj0egDxyX9/FH+vukgAAAAAAAEA3gIAAAAAAQEr9IZcho/gV/6fH8C8P+yhNRZP+l3YuxsyatdYcS0S6AEAAAAA/v///wLI/8+yAAAAABYAFDXoRFwgXNO5VVtVq2WpaENh6blAAOH1BQAAAAAWABTcAR0NeNdDHb96kMnH5EVUcr1YwwJHMEQCIDqugtYLp4ebJAZvOdieshLi1lLuPl2tHQG4jM4ybwEGAiBeMpCkbHBmzYvljxb1JBQyVAMuoco0xIfi+5OQdHuXaAEhAnH96NhTW09X0npE983YBsHUoMPI4U4xBtHenpZVTEqpVwAAAAEBHwDh9QUAAAAAFgAU3AEdDXjXQx2/epDJx+RFVHK9WMMBCGwCSDBFAiEAuiv52IX5wZlYJqqVGsQPfeQ/kneCNRD34v5yplNpuMYCIECHVUhjHPKSiWSsYEKD4JWGAyUwQHgDytA1whFOyLclASECg7PDfGE/uURta5/R42Vso6QKmVAgYMhjWlXENkE/x+QAAQDrAgAAAAABAW8al4BH/Q5c3KqjTOtdLOaS9V9ufK2uviidtnrW+xwHAQAAAAAAAAAAAgAk9AAAAAAAIgAgu1NVtIiRoUOqOwnsQ4eZN+ler99uesaQPf8Zgdgcm0xWXQ0EAAAAABYAFCqdk4c4bMMjNkB5cr5jAerUAe1dAkgwRQIhAODHfESGWKhXVD7IA8qJpczCS/Wyeh6NtyRk4oV7RHpYAiAHjV0S8rfPEjrrlhVZ9yKHQhOFOQ+g6IyB3rEZopBdvAEhAx2BczBAMX5n6vfHkkp2bVMG9cO5gLRxuucvKokRTZyJAAAAAAEBH1ZdDQQAAAAAFgAUKp2ThzhswyM2QHlyvmMB6tQB7V0BCGwCSDBFAiEAqK7FSrqWe2non0kl96yu2+gSXGPYPC7ZjzVZEMMWtpYCIGTzCDHZhJYGPrsnBWU8o0Eyd4nBa+6d037xGFcGUYJLASECORgkj75Xu8+DTh8bqYBIvNx1hSxV7VSJOwY6jam6LY8AAAA=", "psbt": "cHNidP8BAJoCAAAAAkiMdlxF3M20VpdnCMK0NOkEoETG6Aa4HpC8Vv9RtJc1AQAAAAAAAAAA4lBjZUtG260qBBgVRqMQqmMV+XRTKubrHbc66YOl7/gBAAAAAAAAAAACgPD6AgAAAAAWABSQ2zhVNBOsxRfzPoPwCg8qiNolGtIkCAcAAAAAFgAUuvRP5r7qAvj0egDxyX9/FH+vukgAAAAAAAEA3gIAAAAAAQEr9IZcho/gV/6fH8C8P+yhNRZP+l3YuxsyatdYcS0S6AEAAAAA/v///wLI/8+yAAAAABYAFDXoRFwgXNO5VVtVq2WpaENh6blAAOH1BQAAAAAWABTcAR0NeNdDHb96kMnH5EVUcr1YwwJHMEQCIDqugtYLp4ebJAZvOdieshLi1lLuPl2tHQG4jM4ybwEGAiBeMpCkbHBmzYvljxb1JBQyVAMuoco0xIfi+5OQdHuXaAEhAnH96NhTW09X0npE983YBsHUoMPI4U4xBtHenpZVTEqpVwAAAAEBHwDh9QUAAAAAFgAU3AEdDXjXQx2/epDJx+RFVHK9WMMBCGwCSDBFAiEAuiv52IX5wZlYJqqVGsQPfeQ/kneCNRD34v5yplNpuMYCIECHVUhjHPKSiWSsYEKD4JWGAyUwQHgDytA1whFOyLclASECg7PDfGE/uURta5/R42Vso6QKmVAgYMhjWlXENkE/x+QAAQDrAgAAAAABAW8al4BH/Q5c3KqjTOtdLOaS9V9ufK2uviidtnrW+xwHAQAAAAAAAAAAAgAk9AAAAAAAIgAgu1NVtIiRoUOqOwnsQ4eZN+ler99uesaQPf8Zgdgcm0xWXQ0EAAAAABYAFCqdk4c4bMMjNkB5cr5jAerUAe1dAkgwRQIhAODHfESGWKhXVD7IA8qJpczCS/Wyeh6NtyRk4oV7RHpYAiAHjV0S8rfPEjrrlhVZ9yKHQhOFOQ+g6IyB3rEZopBdvAEhAx2BczBAMX5n6vfHkkp2bVMG9cO5gLRxuucvKokRTZyJAAAAAAEBH1ZdDQQAAAAAFgAUKp2ThzhswyM2QHlyvmMB6tQB7V0BCGwCSDBFAiEAqK7FSrqWe2non0kl96yu2+gSXGPYPC7ZjzVZEMMWtpYCIGTzCDHZhJYGPrsnBWU8o0Eyd4nBa+6d037xGFcGUYJLASECORgkj75Xu8+DTh8bqYBIvNx1hSxV7VSJOwY6jam6LY8AAAA=",
"final_tx": "02000000000102488c765c45dccdb456976708c2b434e904a044c6e806b81e90bc56ff51b49735010000000000000000e25063654b46dbad2a04181546a310aa6315f974532ae6eb1db73ae983a5eff80100000000000000000280f0fa020000000016001490db38553413acc517f33e83f00a0f2a88da251ad224080700000000160014baf44fe6beea02f8f47a00f1c97f7f147fafba4802483045022100ba2bf9d885f9c1995826aa951ac40f7de43f9277823510f7e2fe72a65369b8c6022040875548631cf2928964ac604283e09586032530407803cad035c2114ec8b72501210283b3c37c613fb9446d6b9fd1e3656ca3a40a99502060c8635a55c436413fc7e402483045022100a8aec54aba967b69e89f4925f7acaedbe8125c63d83c2ed98f355910c316b696022064f30831d98496063ebb2705653ca341327789c16bee9dd37ef118570651824b0121023918248fbe57bbcf834e1f1ba98048bcdc75852c55ed54893b063a8da9ba2d8f00000000" "final_tx": "02000000000102488c765c45dccdb456976708c2b434e904a044c6e806b81e90bc56ff51b49735010000000000000000e25063654b46dbad2a04181546a310aa6315f974532ae6eb1db73ae983a5eff80100000000000000000280f0fa020000000016001490db38553413acc517f33e83f00a0f2a88da251ad224080700000000160014baf44fe6beea02f8f47a00f1c97f7f147fafba4802483045022100ba2bf9d885f9c1995826aa951ac40f7de43f9277823510f7e2fe72a65369b8c6022040875548631cf2928964ac604283e09586032530407803cad035c2114ec8b72501210283b3c37c613fb9446d6b9fd1e3656ca3a40a99502060c8635a55c436413fc7e402483045022100a8aec54aba967b69e89f4925f7acaedbe8125c63d83c2ed98f355910c316b696022064f30831d98496063ebb2705653ca341327789c16bee9dd37ef118570651824b0121023918248fbe57bbcf834e1f1ba98048bcdc75852c55ed54893b063a8da9ba2d8f00000000"
@ -318,9 +313,8 @@ The new `--psbt` flag in the `openchannel` command starts an interactive dialog
between `lncli` and the user. Below the command you see an example output from between `lncli` and the user. Below the command you see an example output from
a regtest setup. Of course all values will be different. a regtest setup. Of course all values will be different.
```shell script ```shell
$ lncli openchannel --node_key 03db1e56e5f76bc4018cf6f03d1bb98a7ae96e3f18535e929034f85e7f1ca2b8ac --local_amt 1234567 --psbt ⛰ lncli openchannel --node_key 03db1e56e5f76bc4018cf6f03d1bb98a7ae96e3f18535e929034f85e7f1ca2b8ac --local_amt 1234567 --psbt
Starting PSBT funding flow with pending channel ID fc7853889a04d33b8115bd79ebc99c5eea80d894a0bead40fae5a06bcbdccd3d. Starting PSBT funding flow with pending channel ID fc7853889a04d33b8115bd79ebc99c5eea80d894a0bead40fae5a06bcbdccd3d.
PSBT funding initiated with peer 03db1e56e5f76bc4018cf6f03d1bb98a7ae96e3f18535e929034f85e7f1ca2b8ac. PSBT funding initiated with peer 03db1e56e5f76bc4018cf6f03d1bb98a7ae96e3f18535e929034f85e7f1ca2b8ac.
Please create a PSBT that sends 0.01234567 BTC (1234567 satoshi) to the funding address bcrt1qh33ghvgjj3ef625nl9jxz6nnrz2z9e65vsdey7w5msrklgr6rc0sv0s08q. Please create a PSBT that sends 0.01234567 BTC (1234567 satoshi) to the funding address bcrt1qh33ghvgjj3ef625nl9jxz6nnrz2z9e65vsdey7w5msrklgr6rc0sv0s08q.
@ -347,9 +341,8 @@ The output of the last command already gave us an example command to use with
something like "bitcoind, give me a PSBT that sends the given amount to the something like "bitcoind, give me a PSBT that sends the given amount to the
given address, choose any input you see fit": given address, choose any input you see fit":
```shell script ```shell
$ bitcoin-cli walletcreatefundedpsbt [] '[{"bcrt1qh33ghvgjj3ef625nl9jxz6nnrz2z9e65vsdey7w5msrklgr6rc0sv0s08q":0.01234567}]' ⛰ bitcoin-cli walletcreatefundedpsbt [] '[{"bcrt1qh33ghvgjj3ef625nl9jxz6nnrz2z9e65vsdey7w5msrklgr6rc0sv0s08q":0.01234567}]'
{ {
"psbt": "cHNidP8BAH0CAAAAAbxLLf9+AYfqfF69QAQuETnL6cas7GDiWBZF+3xxc/Y/AAAAAAD+////AofWEgAAAAAAIgAgvGKLsRKUcp0qk/lkYWpzGJQi51RkG5J51NwHb6B6Hh+1If0jAQAAABYAFL+6THEGhybJnOkFGSRFbtCcPOG8AAAAAAABAR8wBBAkAQAAABYAFHemJ11XF7CU7WXBIJLD/qZF+6jrAAAA", "psbt": "cHNidP8BAH0CAAAAAbxLLf9+AYfqfF69QAQuETnL6cas7GDiWBZF+3xxc/Y/AAAAAAD+////AofWEgAAAAAAIgAgvGKLsRKUcp0qk/lkYWpzGJQi51RkG5J51NwHb6B6Hh+1If0jAQAAABYAFL+6THEGhybJnOkFGSRFbtCcPOG8AAAAAAABAR8wBBAkAQAAABYAFHemJ11XF7CU7WXBIJLD/qZF+6jrAAAA",
"fee": 0.00003060, "fee": 0.00003060,
@ -365,9 +358,8 @@ in fees. Fee estimation/calculation can be changed with parameters of the
If we want to know what exactly is in this PSBT, we can look at it with the If we want to know what exactly is in this PSBT, we can look at it with the
`decodepsbt` command: `decodepsbt` command:
```shell script ```shell
$ bitcoin-cli decodepsbt cHNidP8BAH0CAAAAAbxLLf9+AYfqfF69QAQuETnL6cas7GDiWBZF+3xxc/Y/AAAAAAD+////AofWEgAAAAAAIgAgvGKLsRKUcp0qk/lkYWpzGJQi51RkG5J51NwHb6B6Hh+1If0jAQAAABYAFL+6THEGhybJnOkFGSRFbtCcPOG8AAAAAAABAR8wBBAkAQAAABYAFHemJ11XF7CU7WXBIJLD/qZF+6jrAAAA ⛰ bitcoin-cli decodepsbt cHNidP8BAH0CAAAAAbxLLf9+AYfqfF69QAQuETnL6cas7GDiWBZF+3xxc/Y/AAAAAAD+////AofWEgAAAAAAIgAgvGKLsRKUcp0qk/lkYWpzGJQi51RkG5J51NwHb6B6Hh+1If0jAQAAABYAFL+6THEGhybJnOkFGSRFbtCcPOG8AAAAAAABAR8wBBAkAQAAABYAFHemJ11XF7CU7WXBIJLD/qZF+6jrAAAA
{ {
"tx": { "tx": {
"txid": "374504e4246a93a45b4a2c2bc31d8adc8525aa101c7b9065db6dc01c4bdfce0a", "txid": "374504e4246a93a45b4a2c2bc31d8adc8525aa101c7b9065db6dc01c4bdfce0a",
@ -454,9 +446,8 @@ a secondary, hardened and firewalled `lnd` instance has the corresponding
private keys. On the watching only mode, the following command can be used to private keys. On the watching only mode, the following command can be used to
create the funding PSBT: create the funding PSBT:
```shell script ```shell
$ lncli wallet psbt fund --outputs='{"bcrt1qh33ghvgjj3ef625nl9jxz6nnrz2z9e65vsdey7w5msrklgr6rc0sv0s08q":1234567}' ⛰ lncli wallet psbt fund --outputs='{"bcrt1qh33ghvgjj3ef625nl9jxz6nnrz2z9e65vsdey7w5msrklgr6rc0sv0s08q":1234567}'
{ {
"psbt": "cHNidP8BAH0CAAAAAUiMdlxF3M20VpdnCMK0NOkEoETG6Aa4HpC8Vv9RtJc1AQAAAAD/////AofWEgAAAAAAIgAgvGKLsRKUcp0qk/lkYWpzGJQi51RkG5J51NwHb6B6Hh+X7OIFAAAAABYAFNigOB6EbCLRi+Evlv4r2yJx63NxAAAAAAABAN4CAAAAAAEBK/SGXIaP4Ff+nx/AvD/soTUWT/pd2LsbMmrXWHEtEugBAAAAAP7///8CyP/PsgAAAAAWABQ16ERcIFzTuVVbVatlqWhDYem5QADh9QUAAAAAFgAU3AEdDXjXQx2/epDJx+RFVHK9WMMCRzBEAiA6roLWC6eHmyQGbznYnrIS4tZS7j5drR0BuIzOMm8BBgIgXjKQpGxwZs2L5Y8W9SQUMlQDLqHKNMSH4vuTkHR7l2gBIQJx/ejYU1tPV9J6RPfN2AbB1KDDyOFOMQbR3p6WVUxKqVcAAAABAR8A4fUFAAAAABYAFNwBHQ1410Mdv3qQycfkRVRyvVjDAQMEAQAAAAAAAA==", "psbt": "cHNidP8BAH0CAAAAAUiMdlxF3M20VpdnCMK0NOkEoETG6Aa4HpC8Vv9RtJc1AQAAAAD/////AofWEgAAAAAAIgAgvGKLsRKUcp0qk/lkYWpzGJQi51RkG5J51NwHb6B6Hh+X7OIFAAAAABYAFNigOB6EbCLRi+Evlv4r2yJx63NxAAAAAAABAN4CAAAAAAEBK/SGXIaP4Ff+nx/AvD/soTUWT/pd2LsbMmrXWHEtEugBAAAAAP7///8CyP/PsgAAAAAWABQ16ERcIFzTuVVbVatlqWhDYem5QADh9QUAAAAAFgAU3AEdDXjXQx2/epDJx+RFVHK9WMMCRzBEAiA6roLWC6eHmyQGbznYnrIS4tZS7j5drR0BuIzOMm8BBgIgXjKQpGxwZs2L5Y8W9SQUMlQDLqHKNMSH4vuTkHR7l2gBIQJx/ejYU1tPV9J6RPfN2AbB1KDDyOFOMQbR3p6WVUxKqVcAAAABAR8A4fUFAAAAABYAFNwBHQ1410Mdv3qQycfkRVRyvVjDAQMEAQAAAAAAAA==",
"change_output_index": 1, "change_output_index": 1,
@ -476,7 +467,7 @@ Now that we have a valid PSBT that has everything but the final
signatures/witness data, we can paste it into the prompt in `lncli` that is signatures/witness data, we can paste it into the prompt in `lncli` that is
still waiting for our input. still waiting for our input.
```shell script ```shell
... ...
Base64 encoded PSBT: cHNidP8BAH0CAAAAAbxLLf9+AYfqfF69QAQuETnL6cas7GDiWBZF+3xxc/Y/AAAAAAD+////AofWEgAAAAAAIgAgvGKLsRKUcp0qk/lkYWpzGJQi51RkG5J51NwHb6B6Hh+1If0jAQAAABYAFL+6THEGhybJnOkFGSRFbtCcPOG8AAAAAAABAR8wBBAkAQAAABYAFHemJ11XF7CU7WXBIJLD/qZF+6jrAAAA Base64 encoded PSBT: cHNidP8BAH0CAAAAAbxLLf9+AYfqfF69QAQuETnL6cas7GDiWBZF+3xxc/Y/AAAAAAD+////AofWEgAAAAAAIgAgvGKLsRKUcp0qk/lkYWpzGJQi51RkG5J51NwHb6B6Hh+1If0jAQAAABYAFL+6THEGhybJnOkFGSRFbtCcPOG8AAAAAAABAR8wBBAkAQAAABYAFHemJ11XF7CU7WXBIJLD/qZF+6jrAAAA
@ -493,9 +484,8 @@ perhaps `bitcoind` would only know the public keys and couldn't sign for the
transaction itself. Again, this is only an example and can't reflect all transaction itself. Again, this is only an example and can't reflect all
real-world use cases. real-world use cases.
```shell script ```shell
$ bitcoin-cli walletprocesspsbt cHNidP8BAH0CAAAAAbxLLf9+AYfqfF69QAQuETnL6cas7GDiWBZF+3xxc/Y/AAAAAAD+////AofWEgAAAAAAIgAgvGKLsRKUcp0qk/lkYWpzGJQi51RkG5J51NwHb6B6Hh+1If0jAQAAABYAFL+6THEGhybJnOkFGSRFbtCcPOG8AAAAAAABAR8wBBAkAQAAABYAFHemJ11XF7CU7WXBIJLD/qZF+6jrAAAA ⛰ bitcoin-cli walletprocesspsbt cHNidP8BAH0CAAAAAbxLLf9+AYfqfF69QAQuETnL6cas7GDiWBZF+3xxc/Y/AAAAAAD+////AofWEgAAAAAAIgAgvGKLsRKUcp0qk/lkYWpzGJQi51RkG5J51NwHb6B6Hh+1If0jAQAAABYAFL+6THEGhybJnOkFGSRFbtCcPOG8AAAAAAABAR8wBBAkAQAAABYAFHemJ11XF7CU7WXBIJLD/qZF+6jrAAAA
{ {
"psbt": "cHNidP8BAH0CAAAAAbxLLf9+AYfqfF69QAQuETnL6cas7GDiWBZF+3xxc/Y/AAAAAAD+////AofWEgAAAAAAIgAgvGKLsRKUcp0qk/lkYWpzGJQi51RkG5J51NwHb6B6Hh+1If0jAQAAABYAFL+6THEGhybJnOkFGSRFbtCcPOG8AAAAAAABAR8wBBAkAQAAABYAFHemJ11XF7CU7WXBIJLD/qZF+6jrAQhrAkcwRAIgHKQbenZYvgADRd9TKGVO36NnaIgW3S12OUg8XGtSrE8CICmeaYoJ/U7Ecm+/GneY8i2hu2QCaQnuomJgzn+JAnrDASEDUBmCLcsybA5qXSRBBdZ0Uk/FQiay9NgOpv4D26yeJpAAAAA=", "psbt": "cHNidP8BAH0CAAAAAbxLLf9+AYfqfF69QAQuETnL6cas7GDiWBZF+3xxc/Y/AAAAAAD+////AofWEgAAAAAAIgAgvGKLsRKUcp0qk/lkYWpzGJQi51RkG5J51NwHb6B6Hh+1If0jAQAAABYAFL+6THEGhybJnOkFGSRFbtCcPOG8AAAAAAABAR8wBBAkAQAAABYAFHemJ11XF7CU7WXBIJLD/qZF+6jrAQhrAkcwRAIgHKQbenZYvgADRd9TKGVO36NnaIgW3S12OUg8XGtSrE8CICmeaYoJ/U7Ecm+/GneY8i2hu2QCaQnuomJgzn+JAnrDASEDUBmCLcsybA5qXSRBBdZ0Uk/FQiay9NgOpv4D26yeJpAAAAA=",
"complete": true "complete": true
@ -506,9 +496,8 @@ If you are using the two `lnd` node model as described in
[2b](#2b-use-lnd-to-create-a-funding-transaction), you can achieve the same [2b](#2b-use-lnd-to-create-a-funding-transaction), you can achieve the same
result with the following command: result with the following command:
```shell script ```shell
$ lncli wallet psbt finalize cHNidP8BAH0CAAAAAUiMdlxF3M20VpdnCMK0NOkEoETG6Aa4HpC8Vv9RtJc1AQAAAAD/////AofWEgAAAAAAIgAgvGKLsRKUcp0qk/lkYWpzGJQi51RkG5J51NwHb6B6Hh+X7OIFAAAAABYAFNigOB6EbCLRi+Evlv4r2yJx63NxAAAAAAABAN4CAAAAAAEBK/SGXIaP4Ff+nx/AvD/soTUWT/pd2LsbMmrXWHEtEugBAAAAAP7///8CyP/PsgAAAAAWABQ16ERcIFzTuVVbVatlqWhDYem5QADh9QUAAAAAFgAU3AEdDXjXQx2/epDJx+RFVHK9WMMCRzBEAiA6roLWC6eHmyQGbznYnrIS4tZS7j5drR0BuIzOMm8BBgIgXjKQpGxwZs2L5Y8W9SQUMlQDLqHKNMSH4vuTkHR7l2gBIQJx/ejYU1tPV9J6RPfN2AbB1KDDyOFOMQbR3p6WVUxKqVcAAAABAR8A4fUFAAAAABYAFNwBHQ1410Mdv3qQycfkRVRyvVjDAQMEAQAAAAAAAA== ⛰ lncli wallet psbt finalize cHNidP8BAH0CAAAAAUiMdlxF3M20VpdnCMK0NOkEoETG6Aa4HpC8Vv9RtJc1AQAAAAD/////AofWEgAAAAAAIgAgvGKLsRKUcp0qk/lkYWpzGJQi51RkG5J51NwHb6B6Hh+X7OIFAAAAABYAFNigOB6EbCLRi+Evlv4r2yJx63NxAAAAAAABAN4CAAAAAAEBK/SGXIaP4Ff+nx/AvD/soTUWT/pd2LsbMmrXWHEtEugBAAAAAP7///8CyP/PsgAAAAAWABQ16ERcIFzTuVVbVatlqWhDYem5QADh9QUAAAAAFgAU3AEdDXjXQx2/epDJx+RFVHK9WMMCRzBEAiA6roLWC6eHmyQGbznYnrIS4tZS7j5drR0BuIzOMm8BBgIgXjKQpGxwZs2L5Y8W9SQUMlQDLqHKNMSH4vuTkHR7l2gBIQJx/ejYU1tPV9J6RPfN2AbB1KDDyOFOMQbR3p6WVUxKqVcAAAABAR8A4fUFAAAAABYAFNwBHQ1410Mdv3qQycfkRVRyvVjDAQMEAQAAAAAAAA==
{ {
"psbt": "cHNidP8BAH0CAAAAAUiMdlxF3M20VpdnCMK0NOkEoETG6Aa4HpC8Vv9RtJc1AQAAAAD/////AofWEgAAAAAAIgAgvGKLsRKUcp0qk/lkYWpzGJQi51RkG5J51NwHb6B6Hh+X7OIFAAAAABYAFNigOB6EbCLRi+Evlv4r2yJx63NxAAAAAAABAN4CAAAAAAEBK/SGXIaP4Ff+nx/AvD/soTUWT/pd2LsbMmrXWHEtEugBAAAAAP7///8CyP/PsgAAAAAWABQ16ERcIFzTuVVbVatlqWhDYem5QADh9QUAAAAAFgAU3AEdDXjXQx2/epDJx+RFVHK9WMMCRzBEAiA6roLWC6eHmyQGbznYnrIS4tZS7j5drR0BuIzOMm8BBgIgXjKQpGxwZs2L5Y8W9SQUMlQDLqHKNMSH4vuTkHR7l2gBIQJx/ejYU1tPV9J6RPfN2AbB1KDDyOFOMQbR3p6WVUxKqVcAAAABAR8A4fUFAAAAABYAFNwBHQ1410Mdv3qQycfkRVRyvVjDAQhrAkcwRAIgU3Ow7cLkKrg8BJe0U0n9qFLPizqEzY0JtjVlpWOEk14CID/4AFNfgwNENN2LoOs0C6uHgt4sk8rNoZG+VMGzOC/HASECg7PDfGE/uURta5/R42Vso6QKmVAgYMhjWlXENkE/x+QAAAA=", "psbt": "cHNidP8BAH0CAAAAAUiMdlxF3M20VpdnCMK0NOkEoETG6Aa4HpC8Vv9RtJc1AQAAAAD/////AofWEgAAAAAAIgAgvGKLsRKUcp0qk/lkYWpzGJQi51RkG5J51NwHb6B6Hh+X7OIFAAAAABYAFNigOB6EbCLRi+Evlv4r2yJx63NxAAAAAAABAN4CAAAAAAEBK/SGXIaP4Ff+nx/AvD/soTUWT/pd2LsbMmrXWHEtEugBAAAAAP7///8CyP/PsgAAAAAWABQ16ERcIFzTuVVbVatlqWhDYem5QADh9QUAAAAAFgAU3AEdDXjXQx2/epDJx+RFVHK9WMMCRzBEAiA6roLWC6eHmyQGbznYnrIS4tZS7j5drR0BuIzOMm8BBgIgXjKQpGxwZs2L5Y8W9SQUMlQDLqHKNMSH4vuTkHR7l2gBIQJx/ejYU1tPV9J6RPfN2AbB1KDDyOFOMQbR3p6WVUxKqVcAAAABAR8A4fUFAAAAABYAFNwBHQ1410Mdv3qQycfkRVRyvVjDAQhrAkcwRAIgU3Ow7cLkKrg8BJe0U0n9qFLPizqEzY0JtjVlpWOEk14CID/4AFNfgwNENN2LoOs0C6uHgt4sk8rNoZG+VMGzOC/HASECg7PDfGE/uURta5/R42Vso6QKmVAgYMhjWlXENkE/x+QAAAA=",
"final_tx": "02000000000101488c765c45dccdb456976708c2b434e904a044c6e806b81e90bc56ff51b497350100000000ffffffff0287d6120000000000220020bc628bb11294729d2a93f964616a73189422e754641b9279d4dc076fa07a1e1f97ece20500000000160014d8a0381e846c22d18be12f96fe2bdb2271eb73710247304402205373b0edc2e42ab83c0497b45349fda852cf8b3a84cd8d09b63565a56384935e02203ff800535f83034434dd8ba0eb340bab8782de2c93cacda191be54c1b3382fc701210283b3c37c613fb9446d6b9fd1e3656ca3a40a99502060c8635a55c436413fc7e400000000" "final_tx": "02000000000101488c765c45dccdb456976708c2b434e904a044c6e806b81e90bc56ff51b497350100000000ffffffff0287d6120000000000220020bc628bb11294729d2a93f964616a73189422e754641b9279d4dc076fa07a1e1f97ece20500000000160014d8a0381e846c22d18be12f96fe2bdb2271eb73710247304402205373b0edc2e42ab83c0497b45349fda852cf8b3a84cd8d09b63565a56384935e02203ff800535f83034434dd8ba0eb340bab8782de2c93cacda191be54c1b3382fc701210283b3c37c613fb9446d6b9fd1e3656ca3a40a99502060c8635a55c436413fc7e400000000"
@ -526,7 +515,7 @@ LOST**!
Let's give it to `lncli` to continue: Let's give it to `lncli` to continue:
```shell script ```shell
... ...
Base64 encoded PSBT: cHNidP8BAH0CAAAAAbxLLf9+AYfqfF69QAQuETnL6cas7GDiWBZF+3xxc/Y/AAAAAAD+////AofWEgAAAAAAIgAgvGKLsRKUcp0qk/lkYWpzGJQi51RkG5J51NwHb6B6Hh+1If0jAQAAABYAFL+6THEGhybJnOkFGSRFbtCcPOG8AAAAAAABAR8wBBAkAQAAABYAFHemJ11XF7CU7WXBIJLD/qZF+6jrAQhrAkcwRAIgHKQbenZYvgADRd9TKGVO36NnaIgW3S12OUg8XGtSrE8CICmeaYoJ/U7Ecm+/GneY8i2hu2QCaQnuomJgzn+JAnrDASEDUBmCLcsybA5qXSRBBdZ0Uk/FQiay9NgOpv4D26yeJpAAAAA= Base64 encoded PSBT: cHNidP8BAH0CAAAAAbxLLf9+AYfqfF69QAQuETnL6cas7GDiWBZF+3xxc/Y/AAAAAAD+////AofWEgAAAAAAIgAgvGKLsRKUcp0qk/lkYWpzGJQi51RkG5J51NwHb6B6Hh+1If0jAQAAABYAFL+6THEGhybJnOkFGSRFbtCcPOG8AAAAAAABAR8wBBAkAQAAABYAFHemJ11XF7CU7WXBIJLD/qZF+6jrAQhrAkcwRAIgHKQbenZYvgADRd9TKGVO36NnaIgW3S12OUg8XGtSrE8CICmeaYoJ/U7Ecm+/GneY8i2hu2QCaQnuomJgzn+JAnrDASEDUBmCLcsybA5qXSRBBdZ0Uk/FQiay9NgOpv4D26yeJpAAAAA=
{ {
@ -550,18 +539,18 @@ However, the `bitcoin-cli` examples from the command line can be combined into
a single command. For example: a single command. For example:
Channel 1: Channel 1:
```shell script ```shell
$ bitcoin-cli walletcreatefundedpsbt [] '[{"tb1qywvazres587w9wyy8uw03q8j9ek6gc9crwx4jvhqcmew4xzsvqcq3jjdja":0.01000000}]' bitcoin-cli walletcreatefundedpsbt [] '[{"tb1qywvazres587w9wyy8uw03q8j9ek6gc9crwx4jvhqcmew4xzsvqcq3jjdja":0.01000000}]'
``` ```
Channel 2: Channel 2:
```shell script ```shell
$ bitcoin-cli walletcreatefundedpsbt [] '[{"tb1q53626fcwwtcdc942zaf4laqnr3vg5gv4g0hakd2h7fw2pmz6428sk3ezcx":0.01000000}]' bitcoin-cli walletcreatefundedpsbt [] '[{"tb1q53626fcwwtcdc942zaf4laqnr3vg5gv4g0hakd2h7fw2pmz6428sk3ezcx":0.01000000}]'
``` ```
Combined command to get batch PSBT: Combined command to get batch PSBT:
```shell script ```shell
$ bitcoin-cli walletcreatefundedpsbt [] '[{"tb1q53626fcwwtcdc942zaf4laqnr3vg5gv4g0hakd2h7fw2pmz6428sk3ezcx":0.01000000},{"tb1qywvazres587w9wyy8uw03q8j9ek6gc9crwx4jvhqcmew4xzsvqcq3jjdja":0.01000000}]' bitcoin-cli walletcreatefundedpsbt [] '[{"tb1q53626fcwwtcdc942zaf4laqnr3vg5gv4g0hakd2h7fw2pmz6428sk3ezcx":0.01000000},{"tb1qywvazres587w9wyy8uw03q8j9ek6gc9crwx4jvhqcmew4xzsvqcq3jjdja":0.01000000}]'
``` ```
### Safety warning about batch transactions ### Safety warning about batch transactions

@ -43,7 +43,7 @@ When a new `lnd` node is created, it's given a 24-word seed phrase, called an
The two seed formats look similar, but the only commonality they share are The two seed formats look similar, but the only commonality they share are
using the same default English dictionary. A valid seed phrase obtained over using the same default English dictionary. A valid seed phrase obtained over
the CLI `lncli create` command looks something like: the CLI `lncli create` command looks something like:
``` ```text
!!!YOU MUST WRITE DOWN THIS SEED TO BE ABLE TO RESTORE THE WALLET!!! !!!YOU MUST WRITE DOWN THIS SEED TO BE ABLE TO RESTORE THE WALLET!!!
---------------BEGIN LND CIPHER SEED--------------- ---------------BEGIN LND CIPHER SEED---------------
@ -62,7 +62,7 @@ the CLI `lncli create` command looks something like:
During the creation process, users are first prompted to enter a **wallet During the creation process, users are first prompted to enter a **wallet
password**: password**:
``` ```text
Input wallet password: Input wallet password:
Confirm wallet password: Confirm wallet password:
``` ```
@ -72,7 +72,7 @@ derived master private keys or public key data.
Users can also _optionally_ enter a second passphrase which we call the _cipher Users can also _optionally_ enter a second passphrase which we call the _cipher
seed passphrase_: seed passphrase_:
``` ```text
Your cipher seed can optionally be encrypted. Your cipher seed can optionally be encrypted.
Input your passphrase if you wish to encrypt it (or press enter to proceed without a cipher seed passphrase): Input your passphrase if you wish to encrypt it (or press enter to proceed without a cipher seed passphrase):
``` ```
@ -90,30 +90,30 @@ silently decrypt to a new (likely empty) wallet.
The initial entry point to trigger recovery of on-chain funds in the command The initial entry point to trigger recovery of on-chain funds in the command
line is the `lncli create` command. line is the `lncli create` command.
``` ```shell
⛰ lncli create ⛰ lncli create
``` ```
Next, one can enter a _new_ wallet password to encrypt any newly derived keys Next, one can enter a _new_ wallet password to encrypt any newly derived keys
as a result of the recovery process. as a result of the recovery process.
``` ```text
Input wallet password: Input wallet password:
Confirm wallet password: Confirm wallet password:
``` ```
Once a new wallet password has been obtained, the user will be prompted for Once a new wallet password has been obtained, the user will be prompted for
their _existing_ cipher seed: their _existing_ cipher seed:
``` ```text
Input your 24-word mnemonic separated by spaces: ability noise lift document certain month shoot perfect matrix mango excess turkey river pitch fluid rack drill text buddy pool soul fatal ship jelly Input your 24-word mnemonic separated by spaces: ability noise lift document certain month shoot perfect matrix mango excess turkey river pitch fluid rack drill text buddy pool soul fatal ship jelly
``` ```
If a _cipher seed passphrase_ was used when the seed was created, it MUST be entered now: If a _cipher seed passphrase_ was used when the seed was created, it MUST be entered now:
``` ```text
Input your cipher seed passphrase (press enter if your seed doesn't have a passphrase): Input your cipher seed passphrase (press enter if your seed doesn't have a passphrase):
``` ```
Finally, the user has an option to choose a _recovery window_: Finally, the user has an option to choose a _recovery window_:
``` ```text
Input an optional address look-ahead used to scan for used keys (default 2500): Input an optional address look-ahead used to scan for used keys (default 2500):
``` ```
@ -126,7 +126,7 @@ default value.
If all the information provided was valid, then you'll be presented with the If all the information provided was valid, then you'll be presented with the
seed again: seed again:
``` ```text
!!!YOU MUST WRITE DOWN THIS SEED TO BE ABLE TO RESTORE THE WALLET!!! !!!YOU MUST WRITE DOWN THIS SEED TO BE ABLE TO RESTORE THE WALLET!!!
@ -145,7 +145,7 @@ lnd successfully initialized!
``` ```
In `lnd`'s logs, you should see something along the lines of (irrelevant lines skipped): In `lnd`'s logs, you should see something along the lines of (irrelevant lines skipped):
``` ```text
[INF] LNWL: Opened wallet [INF] LNWL: Opened wallet
[INF] LTND: Wallet recovery mode enabled with address lookahead of 2500 addresses [INF] LTND: Wallet recovery mode enabled with address lookahead of 2500 addresses
[INF] LNWL: RECOVERY MODE ENABLED -- rescanning for used addresses with recovery_window=2500 [INF] LNWL: RECOVERY MODE ENABLED -- rescanning for used addresses with recovery_window=2500
@ -166,7 +166,8 @@ window. Depending on how old the wallet is (the cipher seed stores the wallet's
birthday!) and how many addresses were used, the rescan may take anywhere from birthday!) and how many addresses were used, the rescan may take anywhere from
a few minutes to a few hours. To track the recovery progress, one can use the a few minutes to a few hours. To track the recovery progress, one can use the
command `lncli getrecoveryinfo`. When finished, the following is returned, command `lncli getrecoveryinfo`. When finished, the following is returned,
``` ```shell
⛰ lncli getrecoveryinfo
{ {
"recovery_mode": true, "recovery_mode": true,
"recovery_finished": true, "recovery_finished": true,
@ -177,7 +178,7 @@ command `lncli getrecoveryinfo`. When finished, the following is returned,
If the rescan wasn't able to complete fully (`lnd` was shutdown for example), If the rescan wasn't able to complete fully (`lnd` was shutdown for example),
then from `lncli unlock`, it's possible to _restart_ the rescan from where it then from `lncli unlock`, it's possible to _restart_ the rescan from where it
left off with the `--recovery-window` argument: left off with the `--recovery-window` argument:
``` ```shell
⛰ lncli unlock --recovery_window=2500 ⛰ lncli unlock --recovery_window=2500
``` ```
@ -191,7 +192,7 @@ The recovery methods described above assume a clean slate for a node, so
there's no existing UTXO or key data in the node's database. However, there're there's no existing UTXO or key data in the node's database. However, there're
times when an _existing_ node may want to _manually_ rescan the chain. We have times when an _existing_ node may want to _manually_ rescan the chain. We have
a command line flag for that! Just start `lnd` and add the following flag: a command line flag for that! Just start `lnd` and add the following flag:
``` ```shell
⛰ lnd --reset-wallet-transactions ⛰ lnd --reset-wallet-transactions
``` ```
@ -202,7 +203,7 @@ some older wallets).
Just run `lnd` with the flag, unlock it, then the wallet should begin Just run `lnd` with the flag, unlock it, then the wallet should begin
rescanning. An entry resembling the following will show up in the logs once it's rescanning. An entry resembling the following will show up in the logs once it's
complete: complete:
``` ```text
[INF] LNWL: Finished rescan for 800 addresses (synced to block 3032830c812a4a6ea305d8ead13b52e9e69d6400ff3c997970b6f76fbc770920, height 748) [INF] LNWL: Finished rescan for 800 addresses (synced to block 3032830c812a4a6ea305d8ead13b52e9e69d6400ff3c997970b6f76fbc770920, height 748)
``` ```
@ -247,9 +248,7 @@ entries for _all_ currently open channels. Each time a channel is opened or
closed, this file is updated on disk in a safe manner (atomic file rename). As closed, this file is updated on disk in a safe manner (atomic file rename). As
a result, unlike the `channel.db` file, it's _always_ safe to copy this file a result, unlike the `channel.db` file, it's _always_ safe to copy this file
for backup at ones desired location. The default location on Linux is: for backup at ones desired location. The default location on Linux is:
``` `~/.lnd/data/chain/bitcoin/mainnet/channel.backup`
~/.lnd/data/chain/bitcoin/mainnet/channel.backup
```
An example of using file system level notification to [copy the backup to a An example of using file system level notification to [copy the backup to a
distinct volume/partition/drive can be found distinct volume/partition/drive can be found
@ -259,7 +258,7 @@ here](https://gist.github.com/alexbosworth/2c5e185aedbdac45a03655b709e255a3).
Another way to obtain SCBS for all or a target channel is via the new Another way to obtain SCBS for all or a target channel is via the new
`exportchanbackup` `lncli` command: `exportchanbackup` `lncli` command:
``` ```shell
⛰ lncli --network=simnet exportchanbackup --chan_point=29be6d259dc71ebdf0a3a0e83b240eda78f9023d8aeaae13c89250c7e59467d5:0 ⛰ lncli --network=simnet exportchanbackup --chan_point=29be6d259dc71ebdf0a3a0e83b240eda78f9023d8aeaae13c89250c7e59467d5:0
{ {
"chan_point": "29be6d259dc71ebdf0a3a0e83b240eda78f9023d8aeaae13c89250c7e59467d5:0", "chan_point": "29be6d259dc71ebdf0a3a0e83b240eda78f9023d8aeaae13c89250c7e59467d5:0",
@ -293,13 +292,13 @@ schemes, compared to the file system notification based approach.
If a node is being created from scratch, then it's possible to pass in an If a node is being created from scratch, then it's possible to pass in an
existing SCB using the `lncli create` or `lncli unlock` commands: existing SCB using the `lncli create` or `lncli unlock` commands:
``` ```shell
⛰ lncli create -multi_file=channels.backup ⛰ lncli create -multi_file=channels.backup
``` ```
Alternatively, the `restorechanbackup` command can be used if `lnd` has already Alternatively, the `restorechanbackup` command can be used if `lnd` has already
been created at the time of SCB restoration: been created at the time of SCB restoration:
``` ```shell
⛰ lncli restorechanbackup -h ⛰ lncli restorechanbackup -h
NAME: NAME:
lncli restorechanbackup - Restore an existing single or multi-channel static channel backup lncli restorechanbackup - Restore an existing single or multi-channel static channel backup

@ -19,10 +19,12 @@ helper image.
To build a release, run the following commands: To build a release, run the following commands:
1. `git clone https://github.com/lightningnetwork/lnd.git` ```shell
2. `cd lnd` ⛰ git clone https://github.com/lightningnetwork/lnd.git
3. `git checkout <TAG> # <TAG> is the name of the next release/tag` ⛰ cd lnd
4. `make docker-release tag=<TAG>` ⛰ git checkout <TAG> # <TAG> is the name of the next release/tag
⛰ make docker-release tag=<TAG>
```
Where `<TAG>` is the name of the next release of `lnd`. Where `<TAG>` is the name of the next release of `lnd`.
@ -33,10 +35,12 @@ release binaries. However, on Windows, the only way to build the release
binaries at the moment is by using the Windows Subsystem Linux. One can build binaries at the moment is by using the Windows Subsystem Linux. One can build
the release binaries following these steps: the release binaries following these steps:
1. `git clone https://github.com/lightningnetwork/lnd.git` ```shell
2. `cd lnd` ⛰ git clone https://github.com/lightningnetwork/lnd.git
3. `git checkout <TAG> # <TAG> is the name of the next release/tag` ⛰ cd lnd
4. `make release tag=<TAG>` ⛰ git checkout <TAG> # <TAG> is the name of the next release/tag
⛰ make release tag=<TAG>
```
This will then create a directory of the form `lnd-<TAG>` containing archives This will then create a directory of the form `lnd-<TAG>` containing archives
of the release binaries for each supported operating system and architecture, of the release binaries for each supported operating system and architecture,

@ -44,8 +44,8 @@ The minimal configuration needed to activate the tower is `watchtower.active=1`.
Retrieving information about your towers configurations can be done using Retrieving information about your towers configurations can be done using
`lncli tower info`: `lncli tower info`:
``` ```shell
🏔 lncli tower info lncli tower info
{ {
"pubkey": "03281d603b2c5e19b8893a484eb938d7377179a9ef1a6bca4c0bcbbfc291657b63", "pubkey": "03281d603b2c5e19b8893a484eb938d7377179a9ef1a6bca4c0bcbbfc291657b63",
"listeners": [ "listeners": [
@ -58,7 +58,9 @@ Retrieving information about your towers configurations can be done using
The entire set of watchtower configuration options can be found using The entire set of watchtower configuration options can be found using
`lnd -h`: `lnd -h`:
``` ```shell
⛰ lncli -h
...
watchtower: watchtower:
--watchtower.active If the watchtower should be active or not --watchtower.active If the watchtower should be active or not
--watchtower.towerdir= Directory of the watchtower.db (default: $HOME/.lnd/data/watchtower) --watchtower.towerdir= Directory of the watchtower.db (default: $HOME/.lnd/data/watchtower)
@ -66,6 +68,7 @@ watchtower:
--watchtower.externalip= Add interfaces/ports where the watchtower can accept peer connections --watchtower.externalip= Add interfaces/ports where the watchtower can accept peer connections
--watchtower.readtimeout= Duration the watchtower server will wait for messages to be received before hanging up on client connections --watchtower.readtimeout= Duration the watchtower server will wait for messages to be received before hanging up on client connections
--watchtower.writetimeout= Duration the watchtower server will wait for messages to be written before hanging up on client connections --watchtower.writetimeout= Duration the watchtower server will wait for messages to be written before hanging up on client connections
...
``` ```
### Listening Interfaces ### Listening Interfaces
@ -83,7 +86,8 @@ Additionally, users can specify their towers external IP address(es) using
`watchtower.externalip=`, which will expose the full tower URIs `watchtower.externalip=`, which will expose the full tower URIs
(pubkey@host:port) over RPC or `lncli tower info`: (pubkey@host:port) over RPC or `lncli tower info`:
``` ```shell
⛰ lncli tower info
... ...
"uris": [ "uris": [
"03281d603b2c5e19b8893a484eb938d7377179a9ef1a6bca4c0bcbbfc291657b63@1.2.3.4:9911" "03281d603b2c5e19b8893a484eb938d7377179a9ef1a6bca4c0bcbbfc291657b63@1.2.3.4:9911"
@ -93,8 +97,8 @@ Additionally, users can specify their towers external IP address(es) using
The watchtower's URIs can be given to clients in order to connect and use the The watchtower's URIs can be given to clients in order to connect and use the
tower with the following command: tower with the following command:
``` ```shell
🏔 lncli wtclient add 03281d603b2c5e19b8893a484eb938d7377179a9ef1a6bca4c0bcbbfc291657b63@1.2.3.4:9911 lncli wtclient add 03281d603b2c5e19b8893a484eb938d7377179a9ef1a6bca4c0bcbbfc291657b63@1.2.3.4:9911
``` ```
If the watchtower's clients will need remote access, be sure to either: If the watchtower's clients will need remote access, be sure to either:
@ -107,13 +111,14 @@ If the watchtower's clients will need remote access, be sure to either:
Watchtowers have tor hidden service support and can automatically generate a Watchtowers have tor hidden service support and can automatically generate a
hidden service on startup with the following flags: hidden service on startup with the following flags:
``` ```shell
🏔 lnd --tor.active --tor.v3 --watchtower.active lnd --tor.active --tor.v3 --watchtower.active
``` ```
The onion address is then shown in the "uris" field when queried with `lncli tower info`: The onion address is then shown in the "uris" field when queried with `lncli tower info`:
``` ```shell
⛰ lncli tower info
... ...
"uris": [ "uris": [
"03281d603b2c5e19b8893a484eb938d7377179a9ef1a6bca4c0bcbbfc291657b63@bn2kxggzjysvsd5o3uqe4h7655u7v2ydhxzy7ea2fx26duaixlwuguad.onion:9911" "03281d603b2c5e19b8893a484eb938d7377179a9ef1a6bca4c0bcbbfc291657b63@bn2kxggzjysvsd5o3uqe4h7655u7v2ydhxzy7ea2fx26duaixlwuguad.onion:9911"
@ -135,10 +140,7 @@ chains, so setting `watchtower.towerdir=/path/to/towerdir` will yield a
watchtower database at `/path/to/towerdir/bitcoin/mainnet/watchtower.db`. watchtower database at `/path/to/towerdir/bitcoin/mainnet/watchtower.db`.
On Linux, for example, the default watchtower database will be located at: On Linux, for example, the default watchtower database will be located at:
`/home/$USER/.lnd/data/watchtower/bitcoin/mainnet/watchtower.db`
```
/$USER/.lnd/data/watchtower/bitcoin/mainnet/watchtower.db
```
## Configuring a Watchtower Client ## Configuring a Watchtower Client
@ -146,14 +148,14 @@ In order to set up a watchtower client, youll need two things:
1. The watchtower client must be enabled with the `--wtclient.active` flag. 1. The watchtower client must be enabled with the `--wtclient.active` flag.
``` ```shell
🏔 lnd --wtclient.active lnd --wtclient.active
``` ```
2. The watchtower URI of an active watchtower. 2. The watchtower URI of an active watchtower.
``` ```shell
🏔 lncli wtclient add 03281d603b2c5e19b8893a484eb938d7377179a9ef1a6bca4c0bcbbfc291657b63@1.2.3.4:9911 lncli wtclient add 03281d603b2c5e19b8893a484eb938d7377179a9ef1a6bca4c0bcbbfc291657b63@1.2.3.4:9911
``` ```
Multiple watchtowers can be configured through this method. Multiple watchtowers can be configured through this method.
@ -177,8 +179,8 @@ number of sessions currently negotiated with the watchtower added above and
determine whether it is currently being used for backups through the determine whether it is currently being used for backups through the
`active_session_candidate` value. `active_session_candidate` value.
``` ```shell
🏔 lncli wtclient tower 03281d603b2c5e19b8893a484eb938d7377179a9ef1a6bca4c0bcbbfc291657b63 lncli wtclient tower 03281d603b2c5e19b8893a484eb938d7377179a9ef1a6bca4c0bcbbfc291657b63
{ {
"pubkey": "03281d603b2c5e19b8893a484eb938d7377179a9ef1a6bca4c0bcbbfc291657b63", "pubkey": "03281d603b2c5e19b8893a484eb938d7377179a9ef1a6bca4c0bcbbfc291657b63",
"addresses": [ "addresses": [
@ -193,8 +195,8 @@ determine whether it is currently being used for backups through the
To obtain information about the watchtower's sessions, users can use the To obtain information about the watchtower's sessions, users can use the
`--include_sessions` flag. `--include_sessions` flag.
``` ```shell
🏔 lncli wtclient tower --include_sessions 03281d603b2c5e19b8893a484eb938d7377179a9ef1a6bca4c0bcbbfc291657b63 lncli wtclient tower --include_sessions 03281d603b2c5e19b8893a484eb938d7377179a9ef1a6bca4c0bcbbfc291657b63
{ {
"pubkey": "03281d603b2c5e19b8893a484eb938d7377179a9ef1a6bca4c0bcbbfc291657b63", "pubkey": "03281d603b2c5e19b8893a484eb938d7377179a9ef1a6bca4c0bcbbfc291657b63",
"addresses": [ "addresses": [
@ -216,7 +218,8 @@ To obtain information about the watchtower's sessions, users can use the
The entire set of watchtower client configuration options can be found with The entire set of watchtower client configuration options can be found with
`lncli wtclient -h`: `lncli wtclient -h`:
``` ```shell
⛰ lncli wtclient -h
NAME: NAME:
lncli wtclient - Interact with the watchtower client. lncli wtclient - Interact with the watchtower client.

@ -147,8 +147,8 @@ description):
## Installation and Updating ## Installation and Updating
```bash ```shell
$ go get -u github.com/lightningnetwork/lnd/lnrpc go get -u github.com/lightningnetwork/lnd/lnrpc
``` ```
## Generate protobuf definitions ## Generate protobuf definitions
@ -160,40 +160,42 @@ build. Just run the following command (requires `sudo` permissions and the tools
`make`, `go`, `wget` and `unzip` to be installed) from the repository's root `make`, `go`, `wget` and `unzip` to be installed) from the repository's root
folder: folder:
`./scripts/install_travis_proto.sh` ```shell
⛰ ./scripts/install_travis_proto.sh
```
### MacOS / Unix like systems ### MacOS / Unix like systems
1. Download [v.3.4.0](https://github.com/google/protobuf/releases/tag/v3.4.0) of 1. Download [v.3.4.0](https://github.com/google/protobuf/releases/tag/v3.4.0) of
`protoc` for your operating system and add it to your `PATH`. `protoc` for your operating system and add it to your `PATH`.
For example, if using macOS: For example, if using macOS:
```bash ```shell
$ curl -LO https://github.com/google/protobuf/releases/download/v3.4.0/protoc-3.4.0-osx-x86_64.zip curl -LO https://github.com/google/protobuf/releases/download/v3.4.0/protoc-3.4.0-osx-x86_64.zip
$ unzip protoc-3.4.0-osx-x86_64.zip -d protoc unzip protoc-3.4.0-osx-x86_64.zip -d protoc
$ export PATH=$PWD/protoc/bin:$PATH export PATH=$PWD/protoc/bin:$PATH
``` ```
2. Install `golang/protobuf` at version `v1.3.2`. 2. Install `golang/protobuf` at version `v1.3.2`.
```bash ```shell
$ git clone https://github.com/golang/protobuf $GOPATH/src/github.com/golang/protobuf git clone https://github.com/golang/protobuf $GOPATH/src/github.com/golang/protobuf
$ cd $GOPATH/src/github.com/golang/protobuf cd $GOPATH/src/github.com/golang/protobuf
$ git reset --hard v1.3.2 git reset --hard v1.3.2
$ make make
``` ```
3. Install 'genproto' at commit `20e1ac93f88cf06d2b1defb90b9e9e126c7dfff6`. 3. Install 'genproto' at commit `20e1ac93f88cf06d2b1defb90b9e9e126c7dfff6`.
```bash ```shell
$ go get google.golang.org/genproto go get google.golang.org/genproto
$ cd $GOPATH/src/google.golang.org/genproto cd $GOPATH/src/google.golang.org/genproto
$ git reset --hard 20e1ac93f88cf06d2b1defb90b9e9e126c7dfff6 git reset --hard 20e1ac93f88cf06d2b1defb90b9e9e126c7dfff6
``` ```
4. Install `grpc-ecosystem/grpc-gateway` at version `v1.14.3`. 4. Install `grpc-ecosystem/grpc-gateway` at version `v1.14.3`.
```bash ```shell
$ git clone https://github.com/grpc-ecosystem/grpc-gateway $GOPATH/src/github.com/grpc-ecosystem/grpc-gateway git clone https://github.com/grpc-ecosystem/grpc-gateway $GOPATH/src/github.com/grpc-ecosystem/grpc-gateway
$ cd $GOPATH/src/github.com/grpc-ecosystem/grpc-gateway cd $GOPATH/src/github.com/grpc-ecosystem/grpc-gateway
$ git reset --hard v1.14.3 git reset --hard v1.14.3
$ go install ./protoc-gen-grpc-gateway ./protoc-gen-swagger go install ./protoc-gen-grpc-gateway ./protoc-gen-swagger
``` ```
5. Run [`gen_protos.sh`](https://github.com/lightningnetwork/lnd/blob/master/lnrpc/gen_protos.sh) 5. Run [`gen_protos.sh`](https://github.com/lightningnetwork/lnd/blob/master/lnrpc/gen_protos.sh)

@ -21,6 +21,6 @@ with the interface.
## Installation and Updating ## Installation and Updating
```bash ```shell
$ go get -u github.com/lightningnetwork/lnd/lnwallet go get -u github.com/lightningnetwork/lnd/lnwallet
``` ```

@ -13,6 +13,6 @@ protocol level.
## Installation and Updating ## Installation and Updating
```bash ```shell
$ go get -u github.com/lightningnetwork/lnd/lnwire go get -u github.com/lightningnetwork/lnd/lnwire
``` ```

@ -98,13 +98,17 @@ default macaroons (`admin`, `invoice` and `readonly`) are not sufficient.
For example, a macaroon that is only allowed to manage peers with a default root For example, a macaroon that is only allowed to manage peers with a default root
key `0` would be created with the following command: key `0` would be created with the following command:
`lncli bakemacaroon peers:read peers:write` ```shell
⛰ lncli bakemacaroon peers:read peers:write
```
For even more fine-grained permission control, it is also possible to specify For even more fine-grained permission control, it is also possible to specify
single RPC method URIs that are allowed to be accessed by a macaroon. This can single RPC method URIs that are allowed to be accessed by a macaroon. This can
be achieved by passing `uri:<methodURI>` pairs to `bakemacaroon`, for example: be achieved by passing `uri:<methodURI>` pairs to `bakemacaroon`, for example:
`lncli bakemacaroon uri:/lnrpc.Lightning/GetInfo uri:/verrpc.Versioner/GetVersion` ```shell
⛰ lncli bakemacaroon uri:/lnrpc.Lightning/GetInfo uri:/verrpc.Versioner/GetVersion
```
The macaroon created by this call would only be allowed to call the `GetInfo` and The macaroon created by this call would only be allowed to call the `GetInfo` and
`GetVersion` methods instead of all methods that have similar permissions (like `GetVersion` methods instead of all methods that have similar permissions (like
@ -132,11 +136,15 @@ To manage the root keys used by macaroons, there are `listmacaroonids` and
`deletemacaroonid` available through gPRC and command line. `deletemacaroonid` available through gPRC and command line.
Users can view a list of all macaroon root key IDs that are in use using: Users can view a list of all macaroon root key IDs that are in use using:
`lncli listmacaroonids` ```shell
⛰ lncli listmacaroonids
```
And remove a specific macaroon root key ID using command: And remove a specific macaroon root key ID using command:
`lncli deletemacaroonid root_key_id` ```shell
⛰ lncli deletemacaroonid root_key_id
```
Be careful with the `deletemacaroonid` command as when a root key is deleted, Be careful with the `deletemacaroonid` command as when a root key is deleted,
**all the macaroons created from it are invalidated**. **all the macaroons created from it are invalidated**.

@ -16,18 +16,18 @@ point.
#### falafel #### falafel
Install [`falafel`](https://github.com/lightninglabs/falafel): Install [`falafel`](https://github.com/lightninglabs/falafel):
``` ```shell
go get -u -v github.com/lightninglabs/falafel go get -u -v github.com/lightninglabs/falafel
``` ```
### Building `lnd` for iOS ### Building `lnd` for iOS
``` ```shell
make ios make ios
``` ```
### Building `lnd` for Android ### Building `lnd` for Android
``` ```shell
make android make android
``` ```
`make mobile` will build both iOS and Android libs. `make mobile` will build both iOS and Android libs.
@ -52,15 +52,15 @@ Swift, add `--swift_out=.` and run `make rpc`.
Similar to lnd, subservers can be conditionally compiled with the build by Similar to lnd, subservers can be conditionally compiled with the build by
setting the tags argument: setting the tags argument:
``` ```shell
make ios make ios
``` ```
To support subservers that have APIs with name conflicts, pass the "prefix" To support subservers that have APIs with name conflicts, pass the "prefix"
flag. This will add the subserver name as a prefix to each method name: flag. This will add the subserver name as a prefix to each method name:
``` ```shell
make ios prefix=1 make ios prefix=1
``` ```
### API docs ### API docs

@ -12,6 +12,6 @@ channel graph state.
## Installation and Updating ## Installation and Updating
```bash ```shell
$ go get -u github.com/lightningnetwork/lnd/routing go get -u github.com/lightningnetwork/lnd/routing
``` ```

@ -16,6 +16,6 @@ onion services, asynchronous messages, etc.
## Installation and Updating ## Installation and Updating
```bash ```shell
$ go get -u github.com/lightningnetwork/lnd/tor go get -u github.com/lightningnetwork/lnd/tor
``` ```

@ -17,6 +17,6 @@ to send.
## Installation and Updating ## Installation and Updating
```bash ```shell
$ go get -u github.com/lightningnetwork/lnd/zpay32 go get -u github.com/lightningnetwork/lnd/zpay32
``` ```