Free Bitcoin transactions with LNbits

Salvador Guerrero
8 min readOct 2, 2023

Dear future self, I installed LNBits to send and receive Bitcoin free of transaction fees with my family and friends. This is only possible if all lightning LNbits wallets are on the same core-lightning instance.
Note that at the time of this writing, LNbit is still in beta.

For this to work, I have a full Bitcoin node running on Raspberry Pi.

I’m also running core-lightning network on the same Raspberry Pi.

I’m runnning a Ride The Lightning instance to easily manage my lightning node funds, manage lightning channels, etc.

And have all the above accessible thru Tor using its V3 Authentication system.

And finally I’m actively and securily backing up my funds using different methods.

LNbits

After all of the above is done, I installed LNbits on my external hard drive using the recommended poetry installation steps from the official Github repo. The below is a copy/paste from their instructions.

# clone the main repo
$ git clone https://github.com/lnbits/lnbits.git
$ cd lnbits

# for making sure python 3.9 is installed, skip if installed. To check your installed version: python3 --version
$ sudo apt update
$ sudo apt install software-properties-common
$ sudo add-apt-repository ppa:deadsnakes/ppa
$ sudo apt install python3.9 python3.9-distutils

$ curl -sSL https://install.python-poetry.org | python3 -
# Once the above poetry install is completed, use the installation path printed to terminal and replace in the following command
$ export PATH="/home/user/.local/bin:$PATH"
# Next command, you can exchange with python3.10 or newer versions.
# Identify your version with python3 --version and specify in the next line
# command is only needed when your default python is not ^3.9 or ^3.10
$ poetry env use python3.9
$ poetry install --only main

$ mkdir data
$ cp .env.example .env
# set funding source amongst other options
$ vi .env

Below are the things I modified on my .env file

HOST=0.0.0.0
PORT=5000

DEBUG=false

LNBITS_ALLOWED_USERS="coma separated UIDs"
LNBITS_ADMIN_USERS="My UID"
LNBITS_ADMIN_UI=false

# storing in the same drive as the installation
LNBITS_DATA_FOLDER="./data"

# no fees
LNBITS_SERVICE_FEE="0.0"

# use local core-lightning backend
LNBITS_BACKEND_WALLET_CLASS=CoreLightningWallet
CORELIGHTNING_RPC="/home/lightning/.lightning/lightning-rpc"

Notice the CORELIGHTNING_RPC value, I have the below lines in my cln config file

# /home/lightning/.lightning/config

# Set JSON-RPC socket (or /dev/tty), such as for lightning-cli(1).
rpc-file=/home/lightning/.lightning/lightning-rpc

# Set JSON-RPC socket file mode, as a 4-digit octal number.
# Default is 0600, meaning only the user that launched lightningd
# can command it.
# Set to 0660 to allow users with the same group to access the RPC
# as well.
rpc-file-mode=0666

I set mode for any user in the same computer to access the cln instance via RPC, easier for me to execute cln commands from any users (note to self: change this back to o+g, and add the lightning group to the lnbits user)

Run LNbits

$ poetry run lnbits
# To change port/host pass 'poetry run lnbits --port 9000 --host 0.0.0.0'
# adding --debug in the start-up command above to help your troubleshooting and generate a more verbose output
# Note that you have to add the line DEBUG=true in your .env file, too.

Open a browser on your mac and enter the rpi address: <LOCAL_NETWORK_IP>:5000, example 192.168.1.2:5000, this will open LNbits, as shown below

If the site doesn’t load, it may mean that you need to allow port 5000 on your firewall, I use ufw and ran the following command to add the exception: ufw allow 5000.

Restrict who has access to LNbits (Optional)

I decided to restrict access to only users that I know, I’m not going to be sharing the link of my instance to anyone I don’t know, not leaving any wholes where I’m putting my funds and those of my family and friends.

After creating a few wallets, or allowing your friends and family create their wallets ask for their user IDs’ you can find these in the URL, or you can create wallets using the User Manager Extension for them, I only use the User Manager for my family, not friends because it gives me access to their wallet funds.

After getting all the user IDs, open the .env file and fill all the IDs in the LNBITS_ALLOWED_USERS variable separated by comas

# .env
LNBITS_ALLOWED_USERS="abc123,def456"

Now that you know that LNbits is running, it’s time to set it up so that it automatically start when the raspberry pi starts using systemd service.

Autostart LNbits on boot (systemd service)

#/etc/systemd/system/lnbits.service
[Unit]
Description=LNbits
After=network.target
# I disabled the below lines because I have a password protected hsm_secret
# and I have to manually run lightnind to enter my password.
#Wants=c-lightning.service
#After=c-lightning.service
[Service]
WorkingDirectory=/mnt/sda/downloads/lnbits
ExecStart=/home/lnbits/.local/bin/poetry run lnbits
# Creates /run/lnbits owned by lnbits
RuntimeDirectory=lnbits
User=lnbits
Restart=on-failure
TimeoutSec=120
RestartSec=30
Environment=PYTHONUNBUFFERED=1
# Hardening measures
####################
# Provide a private /tmp and /var/tmp.
PrivateTmp=true
# Mount /usr, /boot/ and /etc read-only for the process.
ProtectSystem=full
# Disallow the process and all of its children to gain
# new privileges through execve().
NoNewPrivileges=true
# Use a new /dev namespace only populated with API pseudo devices
# such as /dev/null, /dev/zero and /dev/random.
PrivateDevices=true
# Allow the creation of writable and executable memory mappings.
# LNURL-P failed to install because this was set to true
MemoryDenyWriteExecute=false
[Install]
WantedBy=multi-user.target

Save the above file as /etc/systemd/system/lnbits.service, enable it and start it using:

$ sudo systemctl enable lnbits
$ sudo systemctl start lnbits

LNbits through Tor

After testing LNbits on my local network I configured LNbits so that I can access it from outside too, through a Tor Service.

First open /etc/tor/torrc and add the following lines:

HiddenServiceDir /var/lib/tor/lnbits_hidden_service/
HiddenServicePort 5000 127.0.0.1:5000

The lnbits_hidden_service folder will be created automatically.

Restart tor

$ sudo systemctl restart tor

After resting tor you will find the onion URL by printing the hostname file created within the hidden service folder as follows:

$ sudo cat /var/lib/tor/lnbits_hidden_service/hostname

Enable Tor V3 Authentication

Next, I added another layer of security to my LNbits instance by enabling V3 Authentication on the LNbits’ Tor Hidden Service.
I added this security layer because I won’t be sharing this link to anyone that I don’t know, and if the onion address gets leaked I don’t have anything to worry about. Read the following article that shows how to do just that

BlueWallet

Finally, I like to use BlueWallet on my iPhone to manage my bitcoin lightning wallets funds on the go.

After opening LNbits as admin, install the LndHub Extension.
(you can specify admins in the .env file)

After installing and activating it, it will show on the left side

Once you click it, it will show two QRCodes, use the admin to sync the LNbits wallet to BlueWallet… but wait!! don’t scan it yet, I have LNbits running behind Tor V3 Authentication, it will never find the LNbits instance if we don’t configure the phone properly.

Remember Orbot from the V3 Authentication article? Well, we need to add Orbot’s public key to the LNbits hidden service authorized_clients folder, and then turn Orbon on and have all traffic from the phone go thru Orbot, then open BlueWallet, turn Tor off from the setting so that it uses Orbot’s Tor tunnel and then scan the Admin QRCode, it’s a little confusing, so here it goes in steps:

  1. Add Orbot’s public key to authorized_clients
  2. Disable onion-only mode so that all traffic from the phone goes thru orbot’s tor tunnel

3. Disable BlueWallet’s Tor tunnel because we’re already routing everything thru tor, not disabling it will fail to connect

4. On BlueWallet import the new wallet by scan the admin QRCode shown on LndHub, make sure you select the correct LNbits wallet before scannit the code.

And that’s it for configuration!

You have to generate and add the tor public keys from all your family members and friends if you want them to be able to access your LNbits instance from their computer or from their iPhone, and show them how to connect and disconnect from Orbit if they’re using an iPhone, I don’t know how this would work on an Android, lemme know if you have successfully done thru Android and I can add the steps here.

Lightning channels

Befure you or your family sends funds to any of the LNbits wallets, you need to fund your c-lightning on-chain wallet to be able to open channels with good nodes, use 1ml to find good nodes to make connections to.

I use Ride the Lightning to fund the on-chain wallet and to create channels with nodes easily

Free bitcoin transactions!

Once you have at least one channel created, it’s time to create your family wallets or share the link to your LNbits so your friends and fam can start creating their wallets.

To send funds from my c-lightning wallet to my LNbits wallet, I created an invoice from LNbits and paid it using Ride the Lightning. We can custody as much bitcoin we have in our channels.

To receive bitcoin from other bitcoin lightning nodes, you will need inbound liquidity, you gain inbound liquidity by spending funds paying for stuff on lightning or you can rent inbound liquidity on websites like Bitrefill, but the cheapest is to ask someone to open a channel with your node.

(I’m seeking inbound liquidity, I will appreciate if you would like to open a channel to my node 🙏)

All transactions between wallets created on the same instance of LNbits will be free of fees, if you send 10 sats to another lnbits wallet custodied on the same node you will only see a 10 sats transaction and no transacion fees ✔️

Now that you’re going to be the custodian for family and friends don’t forget to safely backup your cln and lnbits.

Updates

LNbits is still in development, below are the steps on how to update it, I haven’t done any upgrades myself yet.

$ cd lnbits
# Stop LNbits with `ctrl + x` or `sudo systemctl lnbits`
$ git pull
# Keep your poetry install up to date, this can be done with `poetry self update`
$poetry install --only main
# Start LNbits with `poetry run lnbits`

And that’s it, I hope this was useful, until next time!

References

--

--

Salvador Guerrero

Computer Science Engineer, Cross-Platform App Developer, Open Source contributor. 🇲🇽🇺🇸