Since LND 0.12 released in January 2021, we’ve had the ability to open multiple channels using a single transaction, with the added bonus that the funds do not have to be within LND itself. You can fund single or multiple channels using a hardware wallet or even multisig setup.

Lightning Labs has a readme all about PSBT & LND, but I wanted to break down this specific batch open setup with a Coldcard and Electrum specifically.

Disclaimer

This approach is command line based, using lncli, so it would be good if you were comfortable with that.

Also, you have to do this within 10 minutes, but don't worry, no funds will be lost if you follow these steps using --no_publish on all but the last channel.

NOT USING THAT FLAG ON PREV CHANNELS OR PUBLISHING TX OUTSIDE LND MAY RESULT IN LOST FUNDS

If you are doing this for the first time, you may use a regtest setup like from Polar to test this out first.

Guide

This guide tries to optimize some pre setup before interacting with LND so that you may do it quickly without worrying about rushing through the transaction creation / signing parts.

Set up Electrum

First figure out what channels you want to open with and what amounts. Select a UTXO from the Electrum "Coins" tab (you may have to unhide this tab from the toolbar) that meets this amount or greater.

After selecting UTXO from Electrum's "Coins" tab, fill out the pay to tab as a one line list like so:

{Bitrefill}, 100000
{Fold}, 100000
{Acinq}, 100000
{optional refund address}, 1330000

You may exclude the refund address if you want it to refund back to the same wallet. You may have to do some calculations with the amount & fee to get this right without having an additional small refund address.

Select the fee and preview the transaction. Make sure the preview looks good, that the fee is high enough, and that, if you're manually doing a refund address, the amounts line up and an additional refund address is not automatically created.

In the end you’ll get something that looks similar to below, but we will fill in the correct addresses in the later step. This is just so you can get amounts & fee correct first.

Set up hardware wallet

Plug in your Coldcard and unlock with your pin. I believe Electrum allows you to connect the Coldcard into the computer and accessible within the app, but I typically plug it into an additional power source and manually pass PSBT’s through an SD card.

Connect w/ peers

This will make it easier and ensure the peers are actually ready before doing this.

Using lncli, connect with the peers you want to open a channel with. You may find their connection info on 1ml.com.

lncli connect [pub@address:port]

Do that for each of the peers. If for any reason one of them cannot connect, you will have to exclude them from this batch or wait for them to come back online later. If you exclude, make sure you go back and remove the line you created an “address, amount” entry for in Electrum.

Open Channel Start

You'll need to run a separate terminal (or tmux if you use that) for each channel open you want to make, because of how it requires a prompt for each one.

From the time you run the first channel command, your 10 minutes starts here. No pressure :)

First Channel

Run the following command, replacing {pub} and {amount} .

lncli openchannel --node_key {pub} --local_amt {amount} --psbt --no_publish

This will output a PSBT (the cHNidP8BADUCAAAAAAFAnAAAAAAAACIAILmJtp4EvGKFq8VV7dqlZGe4JU2BboslejqxJ8QqEeljAAAAAAAA text in the picture) you need to copy to the next channel. Keep this window open on the screen.

IMPORTANT: --no_publish is required if you’re doing multiple channels. The last channel will exclude this parameter.

Consecutive non-last channels

For each next channel you want to open, you’ll run the next command, replacing {pub}, {amount}, and {last_psbt}. If they are not the last channel, then you will again need to have the --no_publish flag.

lncli openchannel --node_key {pub} --local_amt {amount} --psbt --no_publish --base_psbt {last_psbt}

You must use the PSBT from the last channel open you made. If you are opening the 2nd channel, use the 1st PSBT output. If you are opening the 8th channel, use the 7th PSBT output. They all build on each other and get longer each time.

Last Channel

For this last channel here, it will do the publishing. Remove the --no_publish command.

lncli openchannel --node_key {pub} --local_amt {amount} --psbt --base_psbt {last_psbt}

At this point, if there had not been any errors on any of the channels, you should have a command window open for each channel, awaiting an unsigned base64 encoded PSBT.

If any channel had an error, you may have to exclude that one and move on. A common reason for a channel opening request error is if the peer has a high requirement for the minimum amount required. If you exclude any channel, make sure you go back and remove the line you made in Electrum for it.

Finish Electrum TX

In each of your channel openings, there should be an address and an amount. Now go back to Electrum and finish replacing all the addresses & amounts. Make sure the address & amount lines up if each channel is a different size.

Again, it should look similar to below.

Once everything looks good, hit the “Preview” button and ensure things look okay. If they do, save the PSBT onto your SD card.

Paste PSBT into LND

Now you have an unsigned PSBT. Each LND channel opening request wants this first before continuing. We need to first turn the PSBT file into a base64 string.

If you are on a Mac/linux, you can run the below command after replacing the location.

openssl base64 -e -A -in {location/name-of-unsigned-file}.psbt

If you are on Mac specifically, you can copy the command to your clipboard by appending | pbcopy like below:

openssl base64 -e -A -in {location/name-of-unsigned-file}.psbt | pbcopy

Once you have the text copied to your clipboard, paste it into each of the LND command windows.

Sign PSBT

Once all the LND windows are happy, you can proceed to sign the unsigned PSBT file that you created. If you are using a Coldcard, I assume you already know how to do this.

After signing, you should have a psbt-signed.psbt file on the SD card. We need this in the next step.

Warning: In no way shape or form should you broadcast this signed PSBT in anything that isn’t these next LND steps. Absolutely do not import back into Electrum or paste into a broadcast tool, you will lose funds doing so.

Create base64 signed PSBT

Using the same steps as above, create the base64 of the signed PSBT.

openssl base64 -e -A -in {location/name-of-signed-file}.psbt

Copy the output again (or add on | pbcopy if on a Mac).

Pass to LND

Starting with the first channel, paste the signed PSBT string into each command window.

At each step it’ll tell you the funding transaction id. At the very last channel, it will publish the transaction to the network.

You must do the last channel last because the negotiation needs to happen with each channel before the transaction is actually published to the network. If something screwed up before the last channel published, or you ran out of time, then you may discard the signed PSBT and try again.

Complete!

If all went well, each of your channels will be opened! Take a look at the lncli pendingchannels command to verify this. After 6 confirmations, all of them should be officially opened and usable.

Because each channel gets its own funding address, when you or your peer closing one of these channels, only the individual channel is affected. Your other channels in a batch will operate just fine.

Conclusion

I’ll be honest this is pretty complicated, but during high fee environments, it’s simply not acceptable to make 3 or 4 channel opens as individual transactions.

Hopefully more apps like RLT or Thunderhub take advantage of this, but until then, I hope this guide helps you. If anything, it’s something for me to look back on to make sure I do not screw anything up :)

Happy lightning! ⚡️