DEV Community

Cover image for Simulate your first Lightning transaction on the Bitcoin regtest network Part 3 (MacOS)
Abba Adamu
Abba Adamu

Posted on

Simulate your first Lightning transaction on the Bitcoin regtest network Part 3 (MacOS)

πŸ“œObjective

The goal of this article is to help you

  • Connect the lightning nodes to form a peer
  • Open a payment channel between lnd1 and lnd2 nodes
  • Add some confirmations to the block that the channel opening transaction was mined on
  • Check the list of channels to ensure our channel is ready and funded
  • Create an invoice on lnd2
  • inspect the invoice created above from lnd1
  • Pay or satisfy the invoice created by lnd2 via lnd1
  • Close the payment channels, kill both Bitcoin and lightning daemons
  • Celebrate the success of this tutorial with a cold bottle of beer.

πŸ“œ Introduction

Hey there, welcome to the final part of this 3 part series on simulating your first lightning transaction.

dancing

If you are as happy as I am to finally wrap up the series, let's get right to it....

Prerequisites

To be successful in this tutorial in case if you haven't already gone through the previous parts leading up to this one, ensure you;

  • βœ… checkout Part 1
  • βœ… checkout Part 2
  • βœ… Have a running Bitcoin network daemon (on regtest)
  • βœ… Have two active and running lightning node instances as lnd1 and lnd2

If the above prerequisites list has been satisfied then you can proceed beyond this point.

πŸ“œ Connect the lightning nodes to form a peer

Now that both of our nodes are ready for some action, we need to connect them to form a peer-to-peer network this would enable our nodes to communicate with each other on the network by opening and closing channels.

From lnd1 run

command:

lncli1 listpeers
Enter fullscreen mode Exit fullscreen mode

output:

{
  "peers": [] //πŸ‘ˆπŸΏ no peers for now...let's fix that.
}
Enter fullscreen mode Exit fullscreen mode

From lnd2 run the command below to get its identity_pubkey which we would use in connecting the node to lnd1

command:

lncli2 getinfo
Enter fullscreen mode Exit fullscreen mode

output:

{
    "version":  "0.17.0-beta commit=fn/v1.0.1-85-ge31d15989",
    "commit_hash":  "e31d1598932a814c2d44b774e5110746295df711",
    "identity_pubkey":  "024baa5e16c118f42cddd95fd828b32fa8dfcfea55fa384e89e2da0f3b96fc4579",//πŸ‘ˆπŸΏ copy this
    "alias":  "024baa5e16c118f42cdd",
...
}
Enter fullscreen mode Exit fullscreen mode

Now let's connect lnd2 to lnd1 by passing the identity_pubkey, IP address and port

command:

 lncli1 connect 024baa5e16c118f42cddd95fd828b32fa8dfcfea55fa384e89e2da0f3b96fc4579@localhost:9734
Enter fullscreen mode Exit fullscreen mode

output:

{} //πŸ‘ˆπŸΏ don't worry this is the correct output.
Enter fullscreen mode Exit fullscreen mode

Let's check for the list of peers once again at lnd1

command:

  lncli1 listpeers
Enter fullscreen mode Exit fullscreen mode

output:

{
    "peers":  [
        {
            "pub_key":  "024baa5e16c118f42cddd95fd828b32fa8dfcfea55fa384e89e2da0f3b96fc4579",
            "address":  "127.0.0.1:9734",
            "bytes_sent":  "394",
            "bytes_recv":  "394",
            "sat_sent":  "0",
            "sat_recv":  "0",
            "inbound":  false,
            "ping_time":  "-1",
            "sync_type":  "ACTIVE_SYNC",
            .....
}]}
Enter fullscreen mode Exit fullscreen mode

πŸŽ‰ Both Nodes are now successfully connected as a peer on our local lightning network.

connected

πŸ“œ Open a payment channel between lnd1 and lnd2 nodes

Now let's open up a payment channel between lnd1 and lnd2

Quick note: A payment channel on the lightning network is a two-way connection between two parties (lightning nodes) that enables them to exchange bitcoin.

To create a payment channel between lnd1 and lnd2, we'll be making use of the pub_key of lnd2 and we'll then be funding the channel with 100,000 SAT. the 100,000 SAT is lnd1's contribution to the channel

command:

 lncli1 openchannel 024baa5e16c118f42cddd95fd828b32fa8dfcfea55fa384e89e2da0f3b96fc4579 100000
Enter fullscreen mode Exit fullscreen mode

output:

{
  "funding_txid": "0e5e4d4f8f793cddd9370eb81140d5bc168b0e32200a3a17177d9e4da26607b0"
}
Enter fullscreen mode Exit fullscreen mode

πŸ“œ Mine some blocks to increase the confirmations for the Channel opening transaction

Once the channel has been created and lnd1's BTC contribution has been added to the channel, we need to mine/generate some blocks to increase confirmations for the Channel opening transaction.

command:

   bitcoin-cli -generate 10
Enter fullscreen mode Exit fullscreen mode

output:

{
  "address": "bcrt1q5ltxhvn3essvq5ldzpfrvlhul73auec4ekg4fk",
  "blocks": [
    "518ab6ab9e6e93ef03be2da8a8f728358cb0d4270126d1770cdb223df52f9f11",
    "01f8a4a87c0c8c98697458e42bdb459af095ba90ad9ae165ac3c31be9addf447",
    "3880fe05eaf1cff356d7b035d619704a6b93893b225fb31a938ca7275488229c",
    "11e52d12e2d7547dd1f47a44d088bd59fd73c7c436b4076c03e51d78a3fba25e",
    ...
  ]
}
Enter fullscreen mode Exit fullscreen mode

πŸ“œ Check the list of channels

Run the command below to check the list of active channels and to confirm that the channel between both nodes is well-funded and ready.

command:

    lncli1 listchannels
Enter fullscreen mode Exit fullscreen mode

output:

{
    "channels":  [
        {
            "active":  true,
            "remote_pubkey":  "024baa5e16c118f42cddd95fd828b32fa8dfcfea55fa384e89e2da0f3b96fc4579",
            "channel_point":  "0e5e4d4f8f793cddd9370eb81140d5bc168b0e32200a3a17177d9e4da26607b0:0",
            "chan_id":  "735573279047680",
            "capacity":  "100000",
            "local_balance":  "96530",
            "remote_balance":  "0",
            "commit_fee":  "3140",
            "commit_weight":  "772",
            "fee_per_kw":  "2500",
            "unsettled_balance":  "0",
            "total_satoshis_sent":  "0",
            "total_satoshis_received":  "0",
            ...
        }
    ]
}
Enter fullscreen mode Exit fullscreen mode

πŸ“œ Create an invoice on lnd2

Now that we have confirmed that our channel is ready for transactions, let's go ahead and create a payable invoice for an amount of 50,000 SAT on lnd2

command:

   lncli2 addinvoice --amt 50000
Enter fullscreen mode Exit fullscreen mode

output:

{
  "r_hash": "28f35ccf79cfc8545351ae362b4fdb0f85437ddf452c1aebd399227607e0eb6e",
  "payment_request": "lnbcrt500u1pja5y06pp59re4enmeely9g5634cmzkn7mp7z5xlwlg5kp467nny38vplqadhqdqqcqzzsxqyz5vqsp58p5xllcxwt76rt7hjtjwuec2n5sfgv2t9kkc6vplrhsk2edj6ndq9qyysgqs8aysfmfz60jexh03kq27cmpym5qw8hw55wac4mqmj6t684t48u89kqaw0m7y0xuyygh5uuj95643gde3vse7zxgtu4aycfwfwk5z3cqfwmtp7",
  "add_index": "1", //πŸ‘ˆπŸΏ total amount of invoices created.
  "payment_addr": "38686fff0672fda1afd792e4ee670a9d2094314b2dad8d303f1de16565b2d4da"
}
Enter fullscreen mode Exit fullscreen mode

Let's quickly inspect or confirm the details of this newly created invoice from lnd1 by making use of the invoice's payment_request

command:

   lncli1 decodepayreq lnbcrt500u1pja5y06pp59re4enmeely9g5634cmzkn7mp7z5xlwlg5kp467nny38vplqadhqdqqcqzzsxqyz5vqsp58p5xllcxwt76rt7hjtjwuec2n5sfgv2t9kkc6vplrhsk2edj6ndq9qyysgqs8aysfmfz60jexh03kq27cmpym5qw8hw55wac4mqmj6t684t48u89kqaw0m7y0xuyygh5uuj95643gde3vse7zxgtu4aycfwfwk5z3cqfwmtp7
Enter fullscreen mode Exit fullscreen mode

output:

{
    "destination":  "024baa5e16c118f42cddd95fd828b32fa8dfcfea55fa384e89e2da0f3b96fc4579",
    "payment_hash":  "28f35ccf79cfc8545351ae362b4fdb0f85437ddf452c1aebd399227607e0eb6e",
    "num_satoshis":  "50000",
    "timestamp":  "1708790266",
    "expiry":  "86400",
    "description":  "",
    "description_hash":  "",
    "fallback_addr":  "",
    "cltv_expiry":  "80",
    "route_hints":  [],
    "payment_addr":  "38686fff0672fda1afd792e4ee670a9d2094314b2dad8d303f1de16565b2d4da",
    "num_msat":  "50000000",
    "features":  {
        "8":  {
            "name":  "tlv-onion",
            "is_required":  true,
            "is_known":  true
        },
        ...
    }
    ...
}
Enter fullscreen mode Exit fullscreen mode

πŸ“œ Pay or satisfy the invoice created by lnd2 via lnd1

Time for lnd1 to pay up 🧾

payment

Run the command below and follow the prompts to confirm payment

command:

  lncli1 payinvoice lnbcrt500u1pja5y06pp59re4enmeely9g5634cmzkn7mp7z5xlwlg5kp467nny38vplqadhqdqqcqzzsxqyz5vqsp58p5xllcxwt76rt7hjtjwuec2n5sfgv2t9kkc6vplrhsk2edj6ndq9qyysgqs8aysfmfz60jexh03kq27cmpym5qw8hw55wac4mqmj6t684t48u89kqaw0m7y0xuyygh5uuj95643gde3vse7zxgtu4aycfwfwk5z3cqfwmtp7
Enter fullscreen mode Exit fullscreen mode

output:

Payment hash: 28f35ccf79cfc8545351ae362b4fdb0f85437ddf452c1aebd399227607e0eb6e
Description:
Amount (in satoshis): 50000
Fee limit (in satoshis): 2500
Destination: 024baa5e16c118f42cddd95fd828b32fa8dfcfea55fa384e89e2da0f3b96fc4579
Confirm payment (yes/no): yes
+------------+--------------+--------------+--------------+-----+----------+-----------------+----------------------+
| HTLC_STATE | ATTEMPT_TIME | RESOLVE_TIME | RECEIVER_AMT | FEE | TIMELOCK | CHAN_OUT | ROUTE |
+------------+--------------+--------------+--------------+-----+----------+-----------------+----------------------+
| SUCCEEDED | 0.086 | 0.565 | 50000 | 0 | 761 | 735573279047680 | 024baa5e16c118f42cdd |
+------------+--------------+--------------+--------------+-----+----------+-----------------+----------------------+
Amount + fee: 50000 + 0 sat
Payment hash: 28f35ccf79cfc8545351ae362b4fdb0f85437ddf452c1aebd399227607e0eb6e
Payment status: SUCCEEDED, preimage: 071ae531770166a26d7b42a82a6215776a4f90f1e9935c1f225077158b3782c9
Enter fullscreen mode Exit fullscreen mode

Now that we have made payment, let's look up the invoice on lnd2 we'll be using the payment hash above

command:

    lncli2 lookupinvoice 28f35ccf79cfc8545351ae362b4fdb0f85437ddf452c1aebd399227607e0eb6e
Enter fullscreen mode Exit fullscreen mode

output:

 {
    "memo":  "",
    "r_preimage":  "071ae531770166a26d7b42a82a6215776a4f90f1e9935c1f225077158b3782c9",
    "r_hash":  "28f35ccf79cfc8545351ae362b4fdb0f85437ddf452c1aebd399227607e0eb6e",
    "value":  "50000",
    "value_msat":  "50000000",
    "settled":  true,// πŸ‘ˆπŸΏ the invoice has been fulfilled βœ…
    "creation_date":  "1708790266",
    "settle_date":  "1708793723",
    "payment_request":  "lnbcrt500u1pja5y06pp59re4enmeely9g5634cmzkn7mp7z5xlwlg5kp467nny38vplqadhqdqqcqzzsxqyz5vqsp58p5xllcxwt76rt7hjtjwuec2n5sfgv2t9kkc6vplrhsk2edj6ndq9qyysgqs8aysfmfz60jexh03kq27cmpym5qw8hw55wac4mqmj6t684t48u89kqaw0m7y0xuyygh5uuj95643gde3vse7zxgtu4aycfwfwk5z3cqfwmtp7",
    "description_hash":  "",
    "expiry":  "86400",
    "fallback_addr":  "",
    "cltv_expiry":  "80",
    "route_hints":  [],
...
}
Enter fullscreen mode Exit fullscreen mode

πŸ“œ Close the payment channel, kill both Bitcoin and lightning daemons

"Eventually, all good things must come to an end"

explosion

We are finally done with all lightning transactions so let's go ahead and close the payment channel and kill all running lightning and Bitcoin daemons as we close for the day.

Run the command below from any of the two nodes

command:

    lncli2 closeallchannels
Enter fullscreen mode Exit fullscreen mode

output:

{
  "remote_pub_key": "02e0810d836946eebaeb9186c45ebb0c2d17294890ec67f488c9127de4d51dd3cd",
  "channel_point": "0e5e4d4f8f793cddd9370eb81140d5bc168b0e32200a3a17177d9e4da26607b0:0",
  "closing_txid": "9b9e88eec1d3708d97588088e6e40cd0d3cc65163baabb5215445785268f5b78",
  "error": ""
}
Enter fullscreen mode Exit fullscreen mode

Check the list of channels

command:

    lncli2 listchannels
Enter fullscreen mode Exit fullscreen mode

output:

{
  "channels": [] //πŸ‘ˆπŸΏ no active channel
}
Enter fullscreen mode Exit fullscreen mode

Run the command below to kill all running daemons

command:

     lncli1 stop && lncli2 stop && bitcoin-cli stop
Enter fullscreen mode Exit fullscreen mode

output:

Bitcoin Core stopping
Enter fullscreen mode Exit fullscreen mode

πŸ“œ Conclusion

Finally, an amazing end to a three part journey.

happy

I hope this article helped you gain some hands-on experience in working with the lightning network. Remember, Lightning payments are faster, cheaper and less complex than the conventional bitcoin transaction. see you in the next one πŸ‘‹πŸΏ

Top comments (0)