Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Creating a Core Lightning channel funded by JoinMarket

Software Version

bitcoin core: 0.21.0
core lightning: 0.11.1
joinmarket: 0.9.6

Step 1:

Connect to the peer node:

lightning-cli connect 036g....(target_node_public_key)  

Start the open channel negotiation with the peer node, and get the funding address

lightning-cli fundchannel_start 036g....(target_node_public_key) \
1000000(amount in satoshis) \
normal(fee_rate, can also be numbers like 3000, which means 3000 sats per kilobyte) \
true(public channel) \
return_address(pick an external address of joinmarket)

Result is something like this:

{
   "funding_address": "bc1qypf...",
   "scriptpubkey": "0020...",
   "close_to": "0014...",
   "warning_usage": "The funding transaction MUST NOT be broadcast until after channel establishment has been successfully completed by running `fundchannel_complete`"
}

[Optional] Set a label in JM for the return_address

Set a label for the return address so that you remember not to reuse that particular address:

python wallet-tool.py wallet.jmdat setlabel \
bc1qypf...(return_address) \
lightning-close-target(the label for the address in JM)

Step 2:

In joinmarket, create a PSBT that is funded by the joinmarket fund. Do Not Broadcast this transaction yet!

python sendpayment.py wallet.jmdat [-m 3](optional, the target mixdepth) \
-N 0 (no coinjoin, coinjoin isn't allowed when creating psbt tx in JM) \
--psbt 0.01 (The amount to send in Bitcoin, must be equal to the amount of step 1) \
bc1qypf...(The funding address returned in step 1)

The result should be similar to the following:

2022-08-20 16:45:29,576 [INFO]  Using a change value of: 0.xxxxxxxx BTC (xxx sat).
Completed PSBT created: 
{
    "psbt-version": 0,
...
}
2022-08-20 16:45:29,706 [INFO]  This PSBT is fully signed and can be sent externally for broadcasting:
2022-08-20 16:45:29,707 [INFO]  cHNidAbC......
done

Step 3:

Complete the open channel negotiation with the peer node, get them to sign the commitment transaction, so that the funding transaction would then be safe to be broadcasted.

lightning-cli fundchannel_complete 036g....(target_node_public_key) "cHNidAbC..."(The signed PSBT returned in Step 2)

Step 4:

Finalize the PSBT to a raw transaction so that it can be broadcasted.

bitcoin-cli finalizepsbt "cHNidAbC...."(The signed PSBT returned in Step 2)

Optional Step:

Decode the raw transaction, make sure the txid is consistent with the funding_txid that lightningd is expecting.

bitcoin-cli decoderawtransaction "020000000001018....." (The raw transaction returned in Step 4)
lightning-cli listpeers

Step 5:

All preparations are done, broadcast the transaction, wait for 3 confirmations, and the channel will be open. When the channel is closed, your own balance would be returned to the JoinMarket address you specified in Step 1. Using this process, all your on-chain balances can be kept inside JoinMarket, and you don't need to worry about transfering fund between your lightning node and your JoinMarket wallet.

bitcoin-cli sendrawtransaction "020000000001018....." (The raw transaction returned in Step 4)
@openoms
Copy link

openoms commented Jun 29, 2022

Great guide, thank you!
Some notes:

  • make sure to note the external address specified in step 1 to avoid reuse. Might dedicate a mixdepth solely for this, but still need to keep track of the addresses used in the open channels. Could use Specter / Sparrow /Electrum to construct the PSBT and keep the custom labels.
  • The funds only return to the predefined address in case of a cooperative close. Funds from a force close are always destined to the internal wallet of CLN (or same with LND).

@openoms
Copy link

openoms commented Jul 4, 2022

If creating the PSBT in Sparrow convert it to the unpadded base64 format for signing with:
base64 -w 0 UNSIGNED.psbt

@openoms
Copy link

openoms commented Jul 4, 2022

Decode the raw transaction, make sure the txid is consistent with the funding_txid that lightningd is expecting.

The funding_txid is not known by lightningd yet, but need to check for the scriptpubkey returned in Step 1.

@BitcoinWukong
Copy link
Author

BitcoinWukong commented Jul 6, 2022

The funding_txid is not known by lightningd yet, but need to check for the scriptpubkey returned in Step 1.

It would be known after fundchannel_complete is successfully executed. You can find the funding_txid in the output of the lightning-cli listpeers command. Specifically, you'll be able to see the "pending channel" that has a status of "waiting for 3 confirmations", and in that section, you should be able to see the funding_txid as a detail of that channel.

The reason we needed segwit for lighting is so that we could know funding_txid at this point, so that your counter party could sign their commitment transaction on top of this funding transaction. And only after we received their signature, the fundchannel_complete step is then completed, because we would be able to take back the fund if the counter went missing, we can now safely broadcast the funding transaction.

@BitcoinWukong
Copy link
Author

BitcoinWukong commented Aug 21, 2022

make sure to note the external address specified in step 1 to avoid reuse. Might dedicate a mixdepth solely for this, but still need to keep track of the addresses used in the open channels. Could use Specter / Sparrow /Electrum to construct the PSBT and keep the custom labels.

Updated the gist to include using the JoinMarket command setlabel to label the used addresses.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment