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 ```