github.com/decred/dcrlnd@v0.7.6/docs/psbt.md (about)

     1  # PSBT
     2  
     3  This document describes various use cases around the topic of Partially Signed
     4  Bitcoin Transactions (PSBTs). `lnd`'s wallet now features a full set of PSBT
     5  functionality, including creating, signing and funding channels with PSBTs.
     6  
     7  See [BIP174](https://github.com/bitcoin/bips/blob/master/bip-0174.mediawiki) for
     8  a full description of the PSBT format and the different _roles_ that a
     9  participant in a PSBT can have.
    10  
    11  To avoid possible malleability, all inputs to a funding transaction must be segwit
    12  spends, meaning that P2PKH and normal P2SH cannot be used. An error will be
    13  returned if any inputs are not segwit spends.
    14  
    15  ## Creating/funding a PSBT
    16  
    17  The first step for every transaction that is constructed using a PSBT flow is to
    18  select inputs (UTXOs) to fund the desired output and to add a change output that
    19  sends the remaining funds back to the own wallet.
    20  
    21  This `wallet psbt fund` command is very similar to `bitcoind`'s
    22  `walletcreatefundedpsbt` command. One main difference is that you can specify a
    23  template PSBT in the `lncli` variant that contains the output(s) and optional
    24  inputs. Another difference is that for the `--outputs` flag, `lncli` expects the
    25  amounts to be in satoshis instead of fractions of a bitcoin.
    26  
    27  ### Simple example: fund PSBT that sends to address
    28  
    29  Let's start with a very simple example and assume we want to send half a coin
    30  to the address `bcrt1qjrdns4f5zwkv29ln86plqzs092yd5fg6nsz8re`:
    31  
    32  ```shell script
    33  $ lncli wallet psbt fund --outputs='{"bcrt1qjrdns4f5zwkv29ln86plqzs092yd5fg6nsz8re":50000000}'
    34  
    35  {
    36          "psbt": "cHNidP8BAHECAAAAAeJQY2VLRtutKgQYFUajEKpjFfl0Uyrm6x23OumDpe/4AQAAAAD/////AkxREgEAAAAAFgAUv6pTgbKHN60CZ+RQn5yOuH6c2WiA8PoCAAAAABYAFJDbOFU0E6zFF/M+g/AKDyqI2iUaAAAAAAABAOsCAAAAAAEBbxqXgEf9DlzcqqNM610s5pL1X258ra6+KJ22etb7HAcBAAAAAAAAAAACACT0AAAAAAAiACC7U1W0iJGhQ6o7CexDh5k36V6v3256xpA9/xmB2BybTFZdDQQAAAAAFgAUKp2ThzhswyM2QHlyvmMB6tQB7V0CSDBFAiEA4Md8RIZYqFdUPsgDyomlzMJL9bJ6Ho23JGTihXtEelgCIAeNXRLyt88SOuuWFVn3IodCE4U5D6DojIHesRmikF28ASEDHYFzMEAxfmfq98eSSnZtUwb1w7mAtHG65y8qiRFNnIkAAAAAAQEfVl0NBAAAAAAWABQqnZOHOGzDIzZAeXK+YwHq1AHtXQEDBAEAAAAAAAA=",
    37          "change_output_index": 0,
    38          "locks": [
    39                  {
    40                          "id": "ede19a92ed321a4705f8a1cccc1d4f6182545d4bb4fae08bd5937831b7e38f98",
    41                          "outpoint": "f8efa583e93ab71debe62a5374f91563aa10a3461518042aaddb464b656350e2:1",
    42                          "expiration": 1601553408
    43                  }
    44          ]
    45  }
    46  ```
    47  
    48  The first thing we notice in the response is that an outpoint was locked.
    49  That means, the UTXO that was chosen to fund the PSBT is currently locked and
    50  cannot be used by the internal wallet or any other RPC call. This lock will be
    51  released automatically either after 10 minutes (timeout) or once a transaction
    52  that spends the UTXO is published.
    53  
    54  If we inspect the PSBT that was created, we see that the locked input was indeed
    55  selected, the UTXO information was attached and a change output (at index 0) was
    56  created as well:
    57  
    58  ```shell script
    59  $ bitcoin-cli decodepsbt cHNidP8BAHECAAAAAeJQY2VLRtutKgQYFUajEKpjFfl0Uyrm6x23OumDpe/4AQAAAAD/////AkxREgEAAAAAFgAUv6pTgbKHN60CZ+RQn5yOuH6c2WiA8PoCAAAAABYAFJDbOFU0E6zFF/M+g/AKDyqI2iUaAAAAAAABAOsCAAAAAAEBbxqXgEf9DlzcqqNM610s5pL1X258ra6+KJ22etb7HAcBAAAAAAAAAAACACT0AAAAAAAiACC7U1W0iJGhQ6o7CexDh5k36V6v3256xpA9/xmB2BybTFZdDQQAAAAAFgAUKp2ThzhswyM2QHlyvmMB6tQB7V0CSDBFAiEA4Md8RIZYqFdUPsgDyomlzMJL9bJ6Ho23JGTihXtEelgCIAeNXRLyt88SOuuWFVn3IodCE4U5D6DojIHesRmikF28ASEDHYFzMEAxfmfq98eSSnZtUwb1w7mAtHG65y8qiRFNnIkAAAAAAQEfVl0NBAAAAAAWABQqnZOHOGzDIzZAeXK+YwHq1AHtXQEDBAEAAAAAAAA=
    60  {
    61    "tx": {
    62      "txid": "33a316d62ddf74656967754d26ea83a3cb89e03ae44578d965156d4b71b1fce7",
    63      "hash": "33a316d62ddf74656967754d26ea83a3cb89e03ae44578d965156d4b71b1fce7",
    64      "version": 2,
    65      "size": 113,
    66      "vsize": 113,
    67      "weight": 452,
    68      "locktime": 0,
    69      "vin": [
    70        {
    71          "txid": "f8efa583e93ab71debe62a5374f91563aa10a3461518042aaddb464b656350e2",
    72          "vout": 1,
    73          "scriptSig": {
    74            "asm": "",
    75            "hex": ""
    76          },
    77          "sequence": 4294967295
    78        }
    79      ],
    80      "vout": [
    81        {
    82          "value": 0.17977676,
    83          "n": 0,
    84          "scriptPubKey": {
    85            "asm": "0 bfaa5381b28737ad0267e4509f9c8eb87e9cd968",
    86            "hex": "0014bfaa5381b28737ad0267e4509f9c8eb87e9cd968",
    87            "reqSigs": 1,
    88            "type": "witness_v0_keyhash",
    89            "addresses": [
    90              "bcrt1qh7498qdjsum66qn8u3gfl8ywhplfektg6mutfs"
    91            ]
    92          }
    93        },
    94        {
    95          "value": 0.50000000,
    96          "n": 1,
    97          "scriptPubKey": {
    98            "asm": "0 90db38553413acc517f33e83f00a0f2a88da251a",
    99            "hex": "001490db38553413acc517f33e83f00a0f2a88da251a",
   100            "reqSigs": 1,
   101            "type": "witness_v0_keyhash",
   102            "addresses": [
   103              "bcrt1qjrdns4f5zwkv29ln86plqzs092yd5fg6nsz8re"
   104            ]
   105          }
   106        }
   107      ]
   108    },
   109    "unknown": {
   110    },
   111    "inputs": [
   112      {
   113        "witness_utxo": {
   114  ...
   115        },
   116        "non_witness_utxo": {
   117          ...
   118        },
   119        "sighash": "ALL"
   120      }
   121    ],
   122    "outputs": [
   123  ...
   124    ],
   125    "fee": 0.00007050
   126  }
   127  ```
   128  
   129  ### Advanced example: fund PSBT with manual coin selection
   130  
   131  Let's now look at how we can implement manual coin selection by using the `fund`
   132  command. We again want to send half a coin to
   133  `bcrt1qjrdns4f5zwkv29ln86plqzs092yd5fg6nsz8re` but we want to select our inputs
   134  manually.
   135  
   136  The first step is to look at all available UTXOs and choose. To do so, we use
   137  the `listunspent` command:
   138  
   139  ```shell script
   140  $ lncli listunspent
   141  
   142  {
   143          "utxos": [
   144                  {
   145                          "address_type": 0,
   146                          "address": "bcrt1qmsq36rtc6ap3m0m6jryu0ez923et6kxrv46t4w",
   147                          "amount_sat": 100000000,
   148                          "pk_script": "0014dc011d0d78d7431dbf7a90c9c7e4455472bd58c3",
   149                          "outpoint": "3597b451ff56bc901eb806e8c644a004e934b4c208679756b4cddc455c768c48:1",
   150                          "confirmations": 6
   151                  },
   152                  {
   153                          "address_type": 0,
   154                          "address": "bcrt1q92we8pecdnpjxdjq09etuccpat2qrm2acu4256",
   155                          "amount_sat": 67984726,
   156                          "pk_script": "00142a9d9387386cc32336407972be6301ead401ed5d",
   157                          "outpoint": "f8efa583e93ab71debe62a5374f91563aa10a3461518042aaddb464b656350e2:1",
   158                          "confirmations": 24
   159                  },
   160  ...
   161          ]
   162  }
   163  ```
   164  
   165  Next, we choose these two inputs and create the PSBT:
   166  
   167  ```shell script
   168  $ lncli wallet psbt fund --outputs='{"bcrt1qjrdns4f5zwkv29ln86plqzs092yd5fg6nsz8re":50000000}' \
   169      --inputs='["3597b451ff56bc901eb806e8c644a004e934b4c208679756b4cddc455c768c48:1","f8efa583e93ab71debe62a5374f91563aa10a3461518042aaddb464b656350e2:1"]'
   170  
   171  {
   172          "psbt": "cHNidP8BAJoCAAAAAkiMdlxF3M20VpdnCMK0NOkEoETG6Aa4HpC8Vv9RtJc1AQAAAAAAAAAA4lBjZUtG260qBBgVRqMQqmMV+XRTKubrHbc66YOl7/gBAAAAAAAAAAACgPD6AgAAAAAWABSQ2zhVNBOsxRfzPoPwCg8qiNolGtIkCAcAAAAAFgAUuvRP5r7qAvj0egDxyX9/FH+vukgAAAAAAAEA3gIAAAAAAQEr9IZcho/gV/6fH8C8P+yhNRZP+l3YuxsyatdYcS0S6AEAAAAA/v///wLI/8+yAAAAABYAFDXoRFwgXNO5VVtVq2WpaENh6blAAOH1BQAAAAAWABTcAR0NeNdDHb96kMnH5EVUcr1YwwJHMEQCIDqugtYLp4ebJAZvOdieshLi1lLuPl2tHQG4jM4ybwEGAiBeMpCkbHBmzYvljxb1JBQyVAMuoco0xIfi+5OQdHuXaAEhAnH96NhTW09X0npE983YBsHUoMPI4U4xBtHenpZVTEqpVwAAAAEBHwDh9QUAAAAAFgAU3AEdDXjXQx2/epDJx+RFVHK9WMMBAwQBAAAAAAEA6wIAAAAAAQFvGpeAR/0OXNyqo0zrXSzmkvVfbnytrr4onbZ61vscBwEAAAAAAAAAAAIAJPQAAAAAACIAILtTVbSIkaFDqjsJ7EOHmTfpXq/fbnrGkD3/GYHYHJtMVl0NBAAAAAAWABQqnZOHOGzDIzZAeXK+YwHq1AHtXQJIMEUCIQDgx3xEhlioV1Q+yAPKiaXMwkv1snoejbckZOKFe0R6WAIgB41dEvK3zxI665YVWfcih0IThTkPoOiMgd6xGaKQXbwBIQMdgXMwQDF+Z+r3x5JKdm1TBvXDuYC0cbrnLyqJEU2ciQAAAAABAR9WXQ0EAAAAABYAFCqdk4c4bMMjNkB5cr5jAerUAe1dAQMEAQAAAAAAAA==",
   173          "change_output_index": 1,
   174          "locks": [
   175                  {
   176                          "id": "ede19a92ed321a4705f8a1cccc1d4f6182545d4bb4fae08bd5937831b7e38f98",
   177                          "outpoint": "3597b451ff56bc901eb806e8c644a004e934b4c208679756b4cddc455c768c48:1",
   178                          "expiration": 1601560626
   179                  },
   180                  {
   181                          "id": "ede19a92ed321a4705f8a1cccc1d4f6182545d4bb4fae08bd5937831b7e38f98",
   182                          "outpoint": "f8efa583e93ab71debe62a5374f91563aa10a3461518042aaddb464b656350e2:1",
   183                          "expiration": 1601560626
   184                  }
   185          ]
   186  }
   187  ```
   188  
   189  Inspecting this PSBT, we notice that the two inputs were chosen and a large
   190  change change output was added at index 1:
   191  
   192  ```shell script
   193  $ 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==
   194  
   195  {
   196  "tx": {
   197    "txid": "e62356b99c3097eaa1241ff8e39b996917e66b13e4c0ccba3698982d746c3b76",
   198    "hash": "e62356b99c3097eaa1241ff8e39b996917e66b13e4c0ccba3698982d746c3b76",
   199    "version": 2,
   200    "size": 154,
   201    "vsize": 154,
   202    "weight": 616,
   203    "locktime": 0,
   204    "vin": [
   205      {
   206        "txid": "3597b451ff56bc901eb806e8c644a004e934b4c208679756b4cddc455c768c48",
   207        "vout": 1,
   208        "scriptSig": {
   209          "asm": "",
   210          "hex": ""
   211        },
   212        "sequence": 0
   213      },
   214      {
   215        "txid": "f8efa583e93ab71debe62a5374f91563aa10a3461518042aaddb464b656350e2",
   216        "vout": 1,
   217        "scriptSig": {
   218          "asm": "",
   219          "hex": ""
   220        },
   221        "sequence": 0
   222      }
   223    ],
   224    "vout": [
   225      {
   226        "value": 0.50000000,
   227        "n": 0,
   228        "scriptPubKey": {
   229          "asm": "0 90db38553413acc517f33e83f00a0f2a88da251a",
   230          "hex": "001490db38553413acc517f33e83f00a0f2a88da251a",
   231          "reqSigs": 1,
   232          "type": "witness_v0_keyhash",
   233          "addresses": [
   234            "bcrt1qjrdns4f5zwkv29ln86plqzs092yd5fg6nsz8re"
   235          ]
   236        }
   237      },
   238      {
   239        "value": 1.17974226,
   240        "n": 1,
   241        "scriptPubKey": {
   242          "asm": "0 baf44fe6beea02f8f47a00f1c97f7f147fafba48",
   243          "hex": "0014baf44fe6beea02f8f47a00f1c97f7f147fafba48",
   244          "reqSigs": 1,
   245          "type": "witness_v0_keyhash",
   246          "addresses": [
   247            "bcrt1qht6yle47agp03ar6qrcujlmlz3l6lwjgjv36zl"
   248          ]
   249        }
   250      }
   251    ]
   252  },
   253  "unknown": {
   254  },
   255  "inputs": [
   256  ...
   257  ],
   258  "outputs": [
   259  ...
   260  ],
   261  "fee": 0.00010500
   262  }
   263  ```
   264  
   265  ## Signing and finalizing a PSBT
   266  
   267  Assuming we now want to sign the transaction that we created in the previous
   268  example, we simply pass it to the `finalize` sub command of the wallet:
   269  
   270  ```shell script
   271  $ 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==
   272  
   273  {
   274        "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=",
   275        "final_tx": "02000000000102488c765c45dccdb456976708c2b434e904a044c6e806b81e90bc56ff51b49735010000000000000000e25063654b46dbad2a04181546a310aa6315f974532ae6eb1db73ae983a5eff80100000000000000000280f0fa020000000016001490db38553413acc517f33e83f00a0f2a88da251ad224080700000000160014baf44fe6beea02f8f47a00f1c97f7f147fafba4802483045022100ba2bf9d885f9c1995826aa951ac40f7de43f9277823510f7e2fe72a65369b8c6022040875548631cf2928964ac604283e09586032530407803cad035c2114ec8b72501210283b3c37c613fb9446d6b9fd1e3656ca3a40a99502060c8635a55c436413fc7e402483045022100a8aec54aba967b69e89f4925f7acaedbe8125c63d83c2ed98f355910c316b696022064f30831d98496063ebb2705653ca341327789c16bee9dd37ef118570651824b0121023918248fbe57bbcf834e1f1ba98048bcdc75852c55ed54893b063a8da9ba2d8f00000000"
   276  }
   277  ```
   278  
   279  That final transaction can now, in theory, be broadcast. But **it is very
   280  important** that you **do not** publish it manually if any of the involved
   281  outputs are used to fund a channel. See
   282  [the safety warning below](#safety-warning) to learn the reason for this.
   283  
   284  ## Opening a channel by using a PSBT
   285  
   286  This is a step-by-step guide on how to open a channel with `lnd` by using a PSBT
   287  as the funding transaction.  
   288  We will use `bitcoind` to create and sign the transaction just to keep the
   289  example simple. Of course any other PSBT compatible wallet could be used and the
   290  process would likely be spread out over multiple signing steps. The goal of this
   291  example is not to cover each and every possible edge case but to help users of
   292  `lnd` understand what inputs the `lncli` utility expects.
   293  
   294  The goal is to open a channel of 1'234'567 satoshis to the node
   295  `03db1e56e5f76bc4018cf6f03d1bb98a7ae96e3f18535e929034f85e7f1ca2b8ac` by using
   296  a PSBT. That means, `lnd` can have a wallet balance of `0` and is still able to
   297  open a channel. We'll jump into an example right away.
   298  
   299  The new funding flow has a small caveat: _Time matters_.
   300    
   301  When opening a channel using the PSBT flow, we start the negotiation
   302  with the remote peer immediately so we can obtain their multisig key they are
   303  going to use for the channel. Then we pause the whole process until we get a
   304  fully signed transaction back from the user. Unfortunately there is no reliable
   305  way to know after how much time the remote node starts to clean up and "forgets"
   306  about the pending channel. If the remote node is an `lnd` node, we know it's
   307  after 10 minutes. **So as long as the whole process takes less than 10 minutes,
   308  everything should work fine.**
   309  
   310  ### Safety warning
   311  
   312  **DO NOT PUBLISH** the finished transaction by yourself or with another tool.
   313  lnd MUST publish it in the proper funding flow order **OR THE FUNDS CAN BE
   314  LOST**!
   315  
   316  This is very important to remember when using wallets like `Wasabi` for
   317  instance, where the "publish" button is very easy to hit by accident.
   318  
   319  ### 1. Use the new `--psbt` flag in `lncli openchannel`
   320  
   321  The new `--psbt` flag in the `openchannel` command starts an interactive dialog
   322  between `lncli` and the user. Below the command you see an example output from
   323  a regtest setup. Of course all values will be different.
   324  
   325  ```shell script
   326  $ lncli openchannel --node_key 03db1e56e5f76bc4018cf6f03d1bb98a7ae96e3f18535e929034f85e7f1ca2b8ac --local_amt 1234567 --psbt
   327  
   328  Starting PSBT funding flow with pending channel ID fc7853889a04d33b8115bd79ebc99c5eea80d894a0bead40fae5a06bcbdccd3d.
   329  PSBT funding initiated with peer 03db1e56e5f76bc4018cf6f03d1bb98a7ae96e3f18535e929034f85e7f1ca2b8ac.
   330  Please create a PSBT that sends 0.01234567 BTC (1234567 satoshi) to the funding address bcrt1qh33ghvgjj3ef625nl9jxz6nnrz2z9e65vsdey7w5msrklgr6rc0sv0s08q.
   331  
   332  Example with bitcoind:
   333          bitcoin-cli walletcreatefundedpsbt [] '[{"bcrt1qh33ghvgjj3ef625nl9jxz6nnrz2z9e65vsdey7w5msrklgr6rc0sv0s08q":0.01234567}]'
   334  
   335  Or if you are using a wallet that can fund a PSBT directly (currently not
   336  possible with bitcoind), you can use this PSBT that contains the same address
   337  and amount: cHNidP8BADUCAAAAAAGH1hIAAAAAACIAILxii7ESlHKdKpP5ZGFqcxiUIudUZBuSedTcB2+geh4fAAAAAAAA
   338  
   339  Paste the funded PSBT here to continue the funding flow.
   340  Base64 encoded PSBT:
   341  ```
   342  
   343  The command line now waits until a PSBT is entered. We'll create one in the next
   344  step. Make sure to use a new shell window/tab for the next commands and leave
   345  the prompt from the `openchannel` running as is.
   346  
   347  ### 2a. Use `bitcoind` to create a funding transaction
   348  
   349  The output of the last command already gave us an example command to use with
   350  `bitcoind`. We'll go ahead and execute it now. The meaning of this command is
   351  something like "bitcoind, give me a PSBT that sends the given amount to the
   352  given address, choose any input you see fit":
   353  
   354  ```shell script
   355  $ bitcoin-cli walletcreatefundedpsbt [] '[{"bcrt1qh33ghvgjj3ef625nl9jxz6nnrz2z9e65vsdey7w5msrklgr6rc0sv0s08q":0.01234567}]'
   356  
   357  {
   358    "psbt": "cHNidP8BAH0CAAAAAbxLLf9+AYfqfF69QAQuETnL6cas7GDiWBZF+3xxc/Y/AAAAAAD+////AofWEgAAAAAAIgAgvGKLsRKUcp0qk/lkYWpzGJQi51RkG5J51NwHb6B6Hh+1If0jAQAAABYAFL+6THEGhybJnOkFGSRFbtCcPOG8AAAAAAABAR8wBBAkAQAAABYAFHemJ11XF7CU7WXBIJLD/qZF+6jrAAAA",
   359    "fee": 0.00003060,
   360    "changepos": 1
   361  }
   362  ```
   363  
   364  We see that `bitcoind` has given us a transaction that would pay `3060` satoshi
   365  in fees. Fee estimation/calculation can be changed with parameters of the 
   366  `walletcreatefundedpsbt` command. To see all options, use
   367  `bitcoin-cli help walletcreatefundedpsbt`.
   368  
   369  If we want to know what exactly is in this PSBT, we can look at it with the
   370  `decodepsbt` command:
   371  
   372  ```shell script
   373  $ bitcoin-cli decodepsbt cHNidP8BAH0CAAAAAbxLLf9+AYfqfF69QAQuETnL6cas7GDiWBZF+3xxc/Y/AAAAAAD+////AofWEgAAAAAAIgAgvGKLsRKUcp0qk/lkYWpzGJQi51RkG5J51NwHb6B6Hh+1If0jAQAAABYAFL+6THEGhybJnOkFGSRFbtCcPOG8AAAAAAABAR8wBBAkAQAAABYAFHemJ11XF7CU7WXBIJLD/qZF+6jrAAAA
   374  
   375  {
   376    "tx": {
   377      "txid": "374504e4246a93a45b4a2c2bc31d8adc8525aa101c7b9065db6dc01c4bdfce0a",
   378      "hash": "374504e4246a93a45b4a2c2bc31d8adc8525aa101c7b9065db6dc01c4bdfce0a",
   379      "version": 2,
   380      "size": 125,
   381      "vsize": 125,
   382      "weight": 500,
   383      "locktime": 0,
   384      "vin": [
   385        {
   386          "txid": "3ff673717cfb451658e260ecacc6e9cb39112e0440bd5e7cea87017eff2d4bbc",
   387          "vout": 0,
   388          "scriptSig": {
   389            "asm": "",
   390            "hex": ""
   391          },
   392          "sequence": 4294967294
   393        }
   394      ],
   395      "vout": [
   396        {
   397          "value": 0.01234567,
   398          "n": 0,
   399          "scriptPubKey": {
   400            "asm": "0 bc628bb11294729d2a93f964616a73189422e754641b9279d4dc076fa07a1e1f",
   401            "hex": "0020bc628bb11294729d2a93f964616a73189422e754641b9279d4dc076fa07a1e1f",
   402            "reqSigs": 1,
   403            "type": "witness_v0_scripthash",
   404            "addresses": [
   405              "bcrt1qh33ghvgjj3ef625nl9jxz6nnrz2z9e65vsdey7w5msrklgr6rc0sv0s08q"
   406            ]
   407          }
   408        },
   409        {
   410          "value": 48.98759093,
   411          "n": 1,
   412          "scriptPubKey": {
   413            "asm": "0 bfba4c71068726c99ce9051924456ed09c3ce1bc",
   414            "hex": "0014bfba4c71068726c99ce9051924456ed09c3ce1bc",
   415            "reqSigs": 1,
   416            "type": "witness_v0_keyhash",
   417            "addresses": [
   418              "bcrt1qh7aycugxsunvn88fq5vjg3tw6zwrecduvvgre5"
   419            ]
   420          }
   421        }
   422      ]
   423    },
   424    "unknown": {
   425    },
   426    "inputs": [
   427      {
   428        "witness_utxo": {
   429          "amount": 48.99996720,
   430          "scriptPubKey": {
   431            "asm": "0 77a6275d5717b094ed65c12092c3fea645fba8eb",
   432            "hex": "001477a6275d5717b094ed65c12092c3fea645fba8eb",
   433            "type": "witness_v0_keyhash",
   434            "address": "bcrt1qw7nzwh2hz7cffmt9cysf9sl75ezlh28tzl4n4e"
   435          }
   436        }
   437      }
   438    ],
   439    "outputs": [
   440      {
   441      },
   442      {
   443      }
   444    ],
   445    "fee": 0.00003060
   446  }
   447  ```
   448  
   449  This tells us that we got a PSBT with a big input, the channel output and a
   450  change output for the rest. Everything is there but the signatures/witness data,
   451  which is exactly what we need.
   452  
   453  ### 2b. Use `lnd` to create a funding transaction
   454  
   455  Starting with version `v0.12.0`, `lnd` can also create PSBTs. This assumes a
   456  scenario where one instance of `lnd` only has public keys (watch only mode) and
   457  a secondary, hardened and firewalled `lnd` instance has the corresponding
   458  private keys. On the watching only mode, the following command can be used to
   459  create the funding PSBT:
   460  
   461  ```shell script
   462  $ lncli wallet psbt fund --outputs='{"bcrt1qh33ghvgjj3ef625nl9jxz6nnrz2z9e65vsdey7w5msrklgr6rc0sv0s08q":1234567}'
   463  
   464  {
   465          "psbt": "cHNidP8BAH0CAAAAAUiMdlxF3M20VpdnCMK0NOkEoETG6Aa4HpC8Vv9RtJc1AQAAAAD/////AofWEgAAAAAAIgAgvGKLsRKUcp0qk/lkYWpzGJQi51RkG5J51NwHb6B6Hh+X7OIFAAAAABYAFNigOB6EbCLRi+Evlv4r2yJx63NxAAAAAAABAN4CAAAAAAEBK/SGXIaP4Ff+nx/AvD/soTUWT/pd2LsbMmrXWHEtEugBAAAAAP7///8CyP/PsgAAAAAWABQ16ERcIFzTuVVbVatlqWhDYem5QADh9QUAAAAAFgAU3AEdDXjXQx2/epDJx+RFVHK9WMMCRzBEAiA6roLWC6eHmyQGbznYnrIS4tZS7j5drR0BuIzOMm8BBgIgXjKQpGxwZs2L5Y8W9SQUMlQDLqHKNMSH4vuTkHR7l2gBIQJx/ejYU1tPV9J6RPfN2AbB1KDDyOFOMQbR3p6WVUxKqVcAAAABAR8A4fUFAAAAABYAFNwBHQ1410Mdv3qQycfkRVRyvVjDAQMEAQAAAAAAAA==",
   466          "change_output_index": 1,
   467          "locks": [
   468                  {
   469                          "id": "ede19a92ed321a4705f8a1cccc1d4f6182545d4bb4fae08bd5937831b7e38f98",
   470                          "outpoint": "3597b451ff56bc901eb806e8c644a004e934b4c208679756b4cddc455c768c48:1",
   471                          "expiration": 1601562037
   472                  }
   473          ]
   474  }
   475  ```
   476  
   477  ### 3. Verify and sign the PSBT
   478  
   479  Now that we have a valid PSBT that has everything but the final
   480  signatures/witness data, we can paste it into the prompt in `lncli` that is
   481  still waiting for our input.
   482  
   483  ```shell script
   484  ...
   485  Base64 encoded PSBT: cHNidP8BAH0CAAAAAbxLLf9+AYfqfF69QAQuETnL6cas7GDiWBZF+3xxc/Y/AAAAAAD+////AofWEgAAAAAAIgAgvGKLsRKUcp0qk/lkYWpzGJQi51RkG5J51NwHb6B6Hh+1If0jAQAAABYAFL+6THEGhybJnOkFGSRFbtCcPOG8AAAAAAABAR8wBBAkAQAAABYAFHemJ11XF7CU7WXBIJLD/qZF+6jrAAAA
   486  
   487  PSBT verified by lnd, please continue the funding flow by signing the PSBT by
   488  all required parties/devices. Once the transaction is fully signed, paste it
   489  again here.
   490  
   491  Base64 encoded PSBT:
   492  ```
   493  
   494  We can now go ahead and sign the transaction. We are going to use `bitcoind` for
   495  this again, but in practice this would now happen on a hardware wallet and
   496  perhaps `bitcoind` would only know the public keys and couldn't sign for the
   497  transaction itself. Again, this is only an example and can't reflect all
   498  real-world use cases.
   499  
   500  ```shell script
   501  $ bitcoin-cli walletprocesspsbt cHNidP8BAH0CAAAAAbxLLf9+AYfqfF69QAQuETnL6cas7GDiWBZF+3xxc/Y/AAAAAAD+////AofWEgAAAAAAIgAgvGKLsRKUcp0qk/lkYWpzGJQi51RkG5J51NwHb6B6Hh+1If0jAQAAABYAFL+6THEGhybJnOkFGSRFbtCcPOG8AAAAAAABAR8wBBAkAQAAABYAFHemJ11XF7CU7WXBIJLD/qZF+6jrAAAA
   502  
   503  {
   504  "psbt": "cHNidP8BAH0CAAAAAbxLLf9+AYfqfF69QAQuETnL6cas7GDiWBZF+3xxc/Y/AAAAAAD+////AofWEgAAAAAAIgAgvGKLsRKUcp0qk/lkYWpzGJQi51RkG5J51NwHb6B6Hh+1If0jAQAAABYAFL+6THEGhybJnOkFGSRFbtCcPOG8AAAAAAABAR8wBBAkAQAAABYAFHemJ11XF7CU7WXBIJLD/qZF+6jrAQhrAkcwRAIgHKQbenZYvgADRd9TKGVO36NnaIgW3S12OUg8XGtSrE8CICmeaYoJ/U7Ecm+/GneY8i2hu2QCaQnuomJgzn+JAnrDASEDUBmCLcsybA5qXSRBBdZ0Uk/FQiay9NgOpv4D26yeJpAAAAA=",
   505  "complete": true
   506  }
   507  ```
   508  
   509  If you are using the two `lnd` node model as described in
   510  [2b](#2b-use-lnd-to-create-a-funding-transaction), you can achieve the same
   511  result with the following command:
   512  
   513  ```shell script
   514  $ lncli wallet psbt finalize cHNidP8BAH0CAAAAAUiMdlxF3M20VpdnCMK0NOkEoETG6Aa4HpC8Vv9RtJc1AQAAAAD/////AofWEgAAAAAAIgAgvGKLsRKUcp0qk/lkYWpzGJQi51RkG5J51NwHb6B6Hh+X7OIFAAAAABYAFNigOB6EbCLRi+Evlv4r2yJx63NxAAAAAAABAN4CAAAAAAEBK/SGXIaP4Ff+nx/AvD/soTUWT/pd2LsbMmrXWHEtEugBAAAAAP7///8CyP/PsgAAAAAWABQ16ERcIFzTuVVbVatlqWhDYem5QADh9QUAAAAAFgAU3AEdDXjXQx2/epDJx+RFVHK9WMMCRzBEAiA6roLWC6eHmyQGbznYnrIS4tZS7j5drR0BuIzOMm8BBgIgXjKQpGxwZs2L5Y8W9SQUMlQDLqHKNMSH4vuTkHR7l2gBIQJx/ejYU1tPV9J6RPfN2AbB1KDDyOFOMQbR3p6WVUxKqVcAAAABAR8A4fUFAAAAABYAFNwBHQ1410Mdv3qQycfkRVRyvVjDAQMEAQAAAAAAAA==
   515  
   516  {
   517          "psbt": "cHNidP8BAH0CAAAAAUiMdlxF3M20VpdnCMK0NOkEoETG6Aa4HpC8Vv9RtJc1AQAAAAD/////AofWEgAAAAAAIgAgvGKLsRKUcp0qk/lkYWpzGJQi51RkG5J51NwHb6B6Hh+X7OIFAAAAABYAFNigOB6EbCLRi+Evlv4r2yJx63NxAAAAAAABAN4CAAAAAAEBK/SGXIaP4Ff+nx/AvD/soTUWT/pd2LsbMmrXWHEtEugBAAAAAP7///8CyP/PsgAAAAAWABQ16ERcIFzTuVVbVatlqWhDYem5QADh9QUAAAAAFgAU3AEdDXjXQx2/epDJx+RFVHK9WMMCRzBEAiA6roLWC6eHmyQGbznYnrIS4tZS7j5drR0BuIzOMm8BBgIgXjKQpGxwZs2L5Y8W9SQUMlQDLqHKNMSH4vuTkHR7l2gBIQJx/ejYU1tPV9J6RPfN2AbB1KDDyOFOMQbR3p6WVUxKqVcAAAABAR8A4fUFAAAAABYAFNwBHQ1410Mdv3qQycfkRVRyvVjDAQhrAkcwRAIgU3Ow7cLkKrg8BJe0U0n9qFLPizqEzY0JtjVlpWOEk14CID/4AFNfgwNENN2LoOs0C6uHgt4sk8rNoZG+VMGzOC/HASECg7PDfGE/uURta5/R42Vso6QKmVAgYMhjWlXENkE/x+QAAAA=",
   518          "final_tx": "02000000000101488c765c45dccdb456976708c2b434e904a044c6e806b81e90bc56ff51b497350100000000ffffffff0287d6120000000000220020bc628bb11294729d2a93f964616a73189422e754641b9279d4dc076fa07a1e1f97ece20500000000160014d8a0381e846c22d18be12f96fe2bdb2271eb73710247304402205373b0edc2e42ab83c0497b45349fda852cf8b3a84cd8d09b63565a56384935e02203ff800535f83034434dd8ba0eb340bab8782de2c93cacda191be54c1b3382fc701210283b3c37c613fb9446d6b9fd1e3656ca3a40a99502060c8635a55c436413fc7e400000000"
   519  }
   520  ```
   521  
   522  Interpreting the output, we now have a complete, final, and signed transaction
   523  inside the PSBT.
   524  
   525  **!!! WARNING !!!**
   526  
   527  **DO NOT PUBLISH** the finished transaction by yourself or with another tool.
   528  lnd MUST publish it in the proper funding flow order **OR THE FUNDS CAN BE
   529  LOST**!
   530  
   531  Let's give it to `lncli` to continue:
   532  
   533  ```shell script
   534  ...
   535  Base64 encoded PSBT: cHNidP8BAH0CAAAAAbxLLf9+AYfqfF69QAQuETnL6cas7GDiWBZF+3xxc/Y/AAAAAAD+////AofWEgAAAAAAIgAgvGKLsRKUcp0qk/lkYWpzGJQi51RkG5J51NwHb6B6Hh+1If0jAQAAABYAFL+6THEGhybJnOkFGSRFbtCcPOG8AAAAAAABAR8wBBAkAQAAABYAFHemJ11XF7CU7WXBIJLD/qZF+6jrAQhrAkcwRAIgHKQbenZYvgADRd9TKGVO36NnaIgW3S12OUg8XGtSrE8CICmeaYoJ/U7Ecm+/GneY8i2hu2QCaQnuomJgzn+JAnrDASEDUBmCLcsybA5qXSRBBdZ0Uk/FQiay9NgOpv4D26yeJpAAAAA=
   536  {
   537          "funding_txid": "374504e4246a93a45b4a2c2bc31d8adc8525aa101c7b9065db6dc01c4bdfce0a"
   538  }
   539  ```
   540  
   541  Success! We now have the final transaction ID of the published funding
   542  transaction. Now we only have to wait for some confirmations, then we can start
   543  using the freshly created channel.
   544  
   545  ## Batch opening channels
   546  
   547  The PSBT channel funding flow makes it possible to open multiple channels in one
   548  transaction. This can be achieved by taking the initial PSBT returned by the
   549  `openchannel` and feed it into the `--base_psbt` parameter of the next
   550  `openchannel` command. This won't work with `bitcoind` though, as it cannot take
   551  a PSBT as partial input for the `walletcreatefundedpsbt` command.
   552  
   553  However, the `bitcoin-cli` examples from the command line can be combined into
   554  a single command. For example:
   555  
   556  Channel 1:
   557  ```shell script
   558  $ bitcoin-cli walletcreatefundedpsbt [] '[{"tb1qywvazres587w9wyy8uw03q8j9ek6gc9crwx4jvhqcmew4xzsvqcq3jjdja":0.01000000}]'
   559  ```
   560  
   561  Channel 2:
   562  ```shell script
   563  $ bitcoin-cli walletcreatefundedpsbt [] '[{"tb1q53626fcwwtcdc942zaf4laqnr3vg5gv4g0hakd2h7fw2pmz6428sk3ezcx":0.01000000}]'
   564  ```
   565  
   566  Combined command to get batch PSBT:
   567  ```shell script
   568  $ bitcoin-cli walletcreatefundedpsbt [] '[{"tb1q53626fcwwtcdc942zaf4laqnr3vg5gv4g0hakd2h7fw2pmz6428sk3ezcx":0.01000000},{"tb1qywvazres587w9wyy8uw03q8j9ek6gc9crwx4jvhqcmew4xzsvqcq3jjdja":0.01000000}]'
   569  ```
   570  
   571  ### Safety warning about batch transactions
   572  
   573  As mentioned before, the PSBT channel funding flow works by pausing the funding
   574  negotiation with the remote peer directly after the multisig keys have been
   575  exchanged. That means, the channel isn't fully opened yet at the time the PSBT
   576  is signed. This is fine for a single channel because the signed transaction is
   577  only published after the counter-signed commitment transactions were exchanged
   578  and the funds can be spent again by both parties.
   579  
   580  When doing batch transactions, **publishing** the whole transaction with
   581  multiple channel funding outputs **too early could lead to loss of funds**!
   582  
   583  For example, let's say we want to open two channels. We call `openchannel --psbt`
   584  two times, combine the funding addresses as shown above, verify the PSBT, sign
   585  it and finally paste it into the terminal of the first command. `lnd` then goes
   586  ahead and finishes the negotiations with peer 1. If successful, `lnd` publishes
   587  the transaction. In the meantime we paste the same PSBT into the second terminal
   588  window. But by now, the peer 2 for channel 2 has timed out our funding flow and
   589  aborts the negotiation. Normally this would be fine, we would just not publish
   590  the funding transaction. But in the batch case, channel 1 has already published
   591  the transaction that contains both channel outputs. But because we never got a
   592  signature from peer 2 to spend the funds now locked in a 2-of-2 multisig, the
   593  fund are lost (unless peer 2 cooperates in a complicated, manual recovery
   594  process).
   595  
   596  ### Use --no_publish for batch transactions
   597  
   598  To mitigate the problem described in the section above, when open multiple
   599  channels in one batch transaction, it is **imperative to use the
   600  `--no_publish`** flag for each channel but the very last. This prevents the
   601  full batch transaction to be published before each and every single channel has
   602  fully completed its funding negotiation.
   603  
   604  ### Use the BatchOpenChannel RPC for safe batch channel funding
   605  
   606  If `lnd`'s internal wallet should fund the batch channel open transaction then
   607  the safest option is the `BatchOpenChannel` RPC (and its
   608  `lncli batchopenchannel` counterpart).
   609  The `BatchOpenChannel` RPC accepts a list of node pubkeys and amounts and will
   610  try to atomically open channels in a single transaction to all of the nodes. If
   611  any of the individual channel negotiations fails (for example because of a
   612  minimum channel size not being met) then the whole batch is aborted and
   613  lingering reservations/intents/pending channels are cleaned up.
   614  
   615  **Example using the CLI**:
   616  
   617  ```shell
   618  ⛰  lncli batchopenchannel --sat_per_vbyte=5 '[{
   619      "node_pubkey": "02c95fd94d2a40e483e8a14be1625ad8a82263b37b6a32162170d8d4c13080bedb",
   620      "local_funding_amount": 500000,
   621      "private": true,
   622      "close_address": "2NCJnjD4CZ5JvmkEo1D3QfDM57GX62LUbep"
   623    }, {
   624      "node_pubkey": "032d57116b92b5f64f022271ebd5e9e23826c0f34ff5ae3e742ad329e0dc5ddff8",
   625      "local_funding_amount": 600000,
   626      "remote_csv_delay": 288
   627    }, {
   628      "node_pubkey": "03475f7b07f79672b9a1fd2a3a2350bc444980fe06eb3ae38b132c6f43f958947b",
   629      "local_funding_amount": 700000
   630    }, {
   631      "node_pubkey": "027f013b5cf6b7035744fd8d7d756e05675bf6e829bb75a80be5b9e8e641d20562",
   632      "local_funding_amount": 800000
   633    }]'
   634  ```
   635  
   636  **NOTE**: You must be connected to each of the nodes you want to open channels
   637  to before you run the command.
   638  
   639  ### Example Node.JS script
   640  
   641  To demonstrate how the PSBT funding API can be used with JavaScript, we add a
   642  simple example script that imitates the behavior of `lncli` but **does not
   643  publish** the final transaction itself. This allows the app creator to publish
   644  the transaction whenever everything is ready.
   645  
   646  > multi-channel-funding.js
   647  ```js
   648  const fs = require('fs');
   649  const grpc = require('@grpc/grpc-js');
   650  const protoLoader = require('@grpc/proto-loader');
   651  const Buffer = require('safe-buffer').Buffer;
   652  const randomBytes = require('random-bytes').sync;
   653  const prompt = require('prompt');
   654  
   655  const LND_DIR = '/home/myuser/.lnd';
   656  const LND_HOST = 'localhost:10009';
   657  const NETWORK = 'regtest';
   658  const LNRPC_PROTO_DIR = '/home/myuser/projects/go/lnd/lnrpc';
   659  
   660  const grpcOptions = {
   661      keepCase: true,
   662      longs: String,
   663      enums: String,
   664      defaults: true,
   665      oneofs: true,
   666      includeDirs: [LNRPC_PROTO_DIR],
   667  };
   668  
   669  const packageDefinition = protoLoader.loadSync(`${LNRPC_PROTO_DIR}/rpc.proto`, grpcOptions);
   670  const lnrpc = grpc.loadPackageDefinition(packageDefinition).lnrpc;
   671  
   672  process.env.GRPC_SSL_CIPHER_SUITES = 'HIGH+ECDSA';
   673  
   674  const adminMac = fs.readFileSync(`${LND_DIR}/data/chain/bitcoin/${NETWORK}/admin.macaroon`);
   675  const metadata = new grpc.Metadata();
   676  metadata.add('macaroon', adminMac.toString('hex'));
   677  const macaroonCreds = grpc.credentials.createFromMetadataGenerator((_args, callback) => {
   678      callback(null, metadata);
   679  });
   680  
   681  const lndCert = fs.readFileSync(`${LND_DIR}/tls.cert`);
   682  const sslCreds = grpc.credentials.createSsl(lndCert);
   683  const credentials = grpc.credentials.combineChannelCredentials(sslCreds, macaroonCreds);
   684  
   685  const client = new lnrpc.Lightning(LND_HOST, credentials);
   686  
   687  const params = process.argv.slice(2);
   688  
   689  if (params.length % 2 !== 0) {
   690      console.log('Usage: node multi-channel-funding.js pubkey amount [pubkey amount]...')
   691  }
   692  
   693  const channels = [];
   694  for (let i = 0; i < params.length; i += 2) {
   695      channels.push({
   696          pubKey: Buffer.from(params[i], 'hex'),
   697          amount: parseInt(params[i + 1], 10),
   698          pendingChanID: randomBytes(32),
   699          outputAddr: '',
   700          finalized: false,
   701          chanPending: null,
   702          cleanedUp: false,
   703      });
   704  }
   705  
   706  channels.forEach(c => {
   707      const openChannelMsg = {
   708          node_pubkey: c.pubKey,
   709          local_funding_amount: c.amount,
   710          funding_shim: {
   711              psbt_shim: {
   712                  pending_chan_id: c.pendingChanID,
   713                  no_publish: true,
   714              }
   715          }
   716      };
   717      const openChannelCall = client.OpenChannel(openChannelMsg);
   718      openChannelCall.on('data', function (update) {
   719          if (update.psbt_fund && update.psbt_fund.funding_address) {
   720              console.log('Got funding addr for PSBT: ' + update.psbt_fund.funding_address);
   721              c.outputAddr = update.psbt_fund.funding_address;
   722              maybeFundPSBT();
   723          }
   724          if (update.chan_pending) {
   725              c.chanPending = update.chan_pending;
   726              const txidStr = update.chan_pending.txid.reverse().toString('hex');
   727              console.log(`
   728  Channels are now pending!
   729  Expected TXID of published final transaction: ${txidStr}
   730  `);
   731              process.exit(0);
   732          }
   733      });
   734      openChannelCall.on('error', function (e) {
   735          console.log('Error on open channel call: ' + e);
   736          tryCleanup();
   737      });
   738  });
   739  
   740  function tryCleanup() {
   741      function maybeExit() {
   742          for (let i = 0; i < channels.length; i++) {
   743              if (!channels[i].cleanedUp) {
   744                  // Not all channels are cleaned up yet.
   745                  return;
   746              }
   747          }
   748      }
   749      channels.forEach(c => {
   750          if (c.cleanedUp) {
   751              return;
   752          }
   753          if (c.chanPending === null) {
   754              console.log("Cleaning up channel, shim cancel")
   755              // The channel never made it into the pending state, let's try to
   756              // remove the funding shim. This is best effort. Depending on the
   757              // state of the channel this might fail so we don't log any errors
   758              // here.
   759              client.FundingStateStep({
   760                  shim_cancel: {
   761                      pending_chan_id: c.pendingChanID,
   762                  }
   763              }, () => {
   764                  c.cleanedUp = true;
   765                  maybeExit();
   766              });
   767          } else {
   768              // The channel is pending but since we aborted will never make it
   769              // to be confirmed. We need to tell lnd to abandon this channel
   770              // otherwise it will show in the pending channels for forever.
   771              console.log("Cleaning up channel, abandon channel")
   772              client.AbandonChannel({
   773                  channel_point: {
   774                      funding_txid: {
   775                          funding_txid_bytes: c.chanPending.txid,
   776                      },
   777                      output_index: c.chanPending.output_index,
   778                  },
   779                  i_know_what_i_am_doing: true,
   780              }, () => {
   781                  c.cleanedUp = true;
   782                  maybeExit();
   783              });
   784          }
   785      });
   786  }
   787  
   788  function maybeFundPSBT() {
   789      const outputsBitcoind = [];
   790      const outputsLnd = {};
   791      for (let i = 0; i < channels.length; i++) {
   792          const c = channels[i];
   793          if (c.outputAddr === '') {
   794              // Not all channels did get a funding address yet.
   795              return;
   796          }
   797  
   798          outputsBitcoind.push({
   799              [c.outputAddr]: c.amount / 100000000,
   800          });
   801          outputsLnd[c.outputAddr] = c.amount;
   802      }
   803  
   804      console.log(`
   805  Channels ready for funding transaction.
   806  Please create a funded PSBT now.
   807  Examples:
   808  
   809  bitcoind:
   810      bitcoin-cli walletcreatefundedpsbt '[]' '${JSON.stringify(outputsBitcoind)}' 0 '{"fee_rate": 15}'
   811  
   812  lnd:
   813      lncli wallet psbt fund --outputs='${JSON.stringify(outputsLnd)}' --sat_per_vbyte=15
   814  `);
   815  
   816      prompt.get([{name: 'funded_psbt'}], (err, result) => {
   817          if (err) {
   818              console.log(err);
   819  
   820              tryCleanup();
   821              return;
   822          }
   823          channels.forEach(c => {
   824              const verifyMsg = {
   825                  psbt_verify: {
   826                      funded_psbt: Buffer.from(result.funded_psbt, 'base64'),
   827                      pending_chan_id: c.pendingChanID,
   828                      skip_finalize: true
   829                  }
   830              };
   831              client.FundingStateStep(verifyMsg, (err, res) => {
   832                  if (err) {
   833                      console.log(err);
   834  
   835                      tryCleanup();
   836                      return;
   837                  }
   838                  if (res) {
   839                      c.finalized = true;
   840                      maybePublishPSBT();
   841                  }
   842              });
   843          });
   844      });
   845  }
   846  
   847  function maybePublishPSBT() {
   848      for (let i = 0; i < channels.length; i++) {
   849          const c = channels[i];
   850          if (!channels[i].finalized) {
   851              // Not all channels are verified/finalized yet.
   852              return;
   853          }
   854      }
   855  
   856      console.log(`
   857  PSBT verification successful!
   858  You can now sign and publish the transaction.
   859  Make sure the TXID does not change!
   860  `);
   861  }
   862  ```