Ride The Lightning

Salvador Guerrero
5 min readSep 15, 2023

After successfully installing Core Lightning to my Raspberry Pi I wanted to fund my node, I would have done it via the terminal, but I wanted to take it a step further and installed RTL for all my on-chain and lightning transactions. Continue reading to learn how.

User configuration

For this guide, I used two user accounts:

  • lightning — same account where core lightning runs on
  • rtl — new account where rtl will run from. Created it following these steps.

Node.js

RTL runs on node.js, so I decided to install the node version manager (nvm) on both accounts (lightning & rtl) to make it easier.

$ sudo su - lightning
$ wget -qO- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.5/install.sh | bash
$ exit

$ sudo su - rtl
$ wget -qO- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.5/install.sh | bash
$ exit

Now that you have installed nvm, go ahead and install the latest Node.js available, on both accounts.

$ sudo su - lightning
$ nvm install node
$ exit

$ sudo su - rtl
$ nvm install node
$ exit

Install and configure c-lightning-REST

RTL requires a middleware called c-lightning-REST to be able to communicate with our running Core Lightning daemon.

Switch to the lightning user that is running lightningd

$ sudo su - lightning

Download the latest version, I downloaded it and installed it on my external hard drive, below are the instructions I executed at the time of writing:

$ cd /mnt/sda/downloads

$ wget https://github.com/Ride-The-Lightning/c-lightning-REST/archive/refs/tags/v0.10.5.tar.gz
$ wget https://github.com/Ride-The-Lightning/c-lightning-REST/releases/download/v0.10.5/v0.10.5.tar.gz.asc

$ gpg --verify v0.10.5.tar.gz.asc v0.10.5.tar.gz

$ tar -xvf v0.10.5.tar.gz
$ cd c-lightning-REST-0.10.5
$ npm install --only=prod

c-lightning-REST Configuration

Before we run it, we need to configure it, rename the file sample-cl-rest-config.json to cl-rest-config.json, and enter the following properties:

$ cp sample-cl-rest-config.json cl-rest-config.json
$ vi cl-rest-config.json
{
"PORT": 3001,
"DOCPORT": 4001,
"PROTOCOL": "https",
"EXECMODE": "production",
"RPCCOMMANDS": ["*"],
"DOMAIN": "localhost",
"BIND": "::",
"LNRPCPATH": "/home/lightning/.lightning/lightning-rpc"
}

Run it

$ node cl-rest.js

If should print out something like

Reading config file
warn: --- Starting the cl-rest server ---
warn: --- cl-rest api server is ready and listening on :::3001 ---
warn: --- cl-rest doc server is ready and listening on :::4001 ---

This means you have successfully installed and configured c-lighinting-REST. Next, stop it with control+c so we can configure it as a service

$ sudo vi /etc/systemd/system/c-lightning-REST.service
[Unit]
Description=c-lightning-REST daemon
After=network.target
# enable if lightning is configured without password
# Wants=lightningd.service
# After=lightningd.service

[Service]
ExecStart=/home/lightning/.nvm/versions/node/v20.6.1/bin/node /mnt/sda/downloads/cln-rest/c-lightning-REST-0.10.5/cl-rest.js
User=lightning
Restart=always
TimeoutSec=120
RestartSec=30

# Hardening measures
####################
# Provide a private /tmp and /var/tmp.
PrivateTmp=true

# Mount /usr, /boot/ and /etc read-only for the process.
ProtectSystem=full

# Use a new /dev namespace only populated with API pseudo devices
# such as /dev/null, /dev/zero and /dev/random.
PrivateDevices=true

# NOTE: Node.js plugins might not work with lightningd.service setting
# MemoryDenyWriteExecute=true as it denies the creation of writable
# and executable memory mappings. Ref: https://github.com/Ride-The-Lightning/c-lightning-REST/issues/116
MemoryDenyWriteExecute=false

[Install]
WantedBy=multi-user.target

Enable and start the newly c-lightning-REST service

$ sudo systemctl enable c-lightning-REST
$ sudo systemctl start c-lightning-REST
$ systemctl status c-lightning-REST

Finally, let’s Install and configure RTL!

First switch to the rtl user

$ sudo su - rtl

Download the latest release

$ cd /mnt/downloads

$ wget https://github.com/Ride-The-Lightning/RTL/archive/refs/tags/v0.14.0.tar.gz
$ wget https://github.com/Ride-The-Lightning/RTL/releases/download/v0.14.0/v0.14.0.tar.gz.asc

$ gpg --verify v0.14.0.tar.gz.asc v0.14.0.tar.gz

$ tar -xvf v0.14.0.tar.gz
$ cd RTL-0.14.0
$ npm install --omit=dev --legacy-peer-deps

Configure RTL

$ cp Sample-RTL-Config.json to RTL-Config.json
$ vi RTL-Config.json
{
"multiPass": <password required for accessing RTL>,
"port": "3000",
"defaultNodeIndex": 1,
"SSO": {
"rtlSSO": 0,
"rtlCookiePath": "",
"logoutRedirectLink": ""
},
"nodes": [
{
"index": 1,
"lnNode": "Node 1",
"lnImplementation": "CLN",
"Authentication": {
"macaroonPath": "/mnt/sda/downloads/cln-rest/c-lightning-REST-0.10.5/certs/",
"configPath": "/mnt/sda/lightning/config"
},
"Settings": {
"userPersona": "MERCHANT",
"themeMode": "DAY",
"themeColor": "PURPLE",
"bitcoindConfigPath": "/mnt/sda/bitcoin/bitcoin.conf",
"logLevel": "ERROR",
"lnServerUrl": "https://127.0.0.1:3001",
"fiatConversion": false,
"unannouncedChannels": false
}
}
]
}

The above file configures RTL to use the local cln as it’s lightning node, I also optionally gave the paths to my cln and btc configuration files.

Run it

$ node rtl

If everything was configured correctly you should see an output like the following

Server is up and running, please open the UI at http://localhost:3000 or your proxy configured url.

Add port 3000 to ufw if you’re going to be accessing RTL from the local network

$ sudo ufw allow 3000
$ sudo ufw disable
$ sudo ufw enable

Now, using a browser from another computer on the same network navigate to: http://raspberrypinetworkname.local:3000/, after successful login you should see something like the following:

Now configure RTL as a service

Copy the c-lightning-REST service and modify it for RTL

$ sudo cp /etc/systemd/system/c-lightning-REST.service /etc/systemd/system/RTL.service
$ sudo vi /etc/systemd/system/RTL.service
[Unit]
Description=RTL daemon
Wants=c-lightning-REST.service
After=c-lightning-REST.service

[Service]
ExecStart=/home/rtl/.nvm/versions/node/v20.6.1/bin/node /mnt/sda/downloads/rtl/RTL-0.14.0/rtl
User=rtl
Restart=always
TimeoutSec=120
RestartSec=30

# 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

# NOTE: Node.js plugins might not work with lightningd.service setting
# MemoryDenyWriteExecute=true as it denies the creation of writable
# and executable memory mappings. Ref: https://github.com/Ride-The-Lightning/c-lightning-REST/issues/116
MemoryDenyWriteExecute=false

[Install]
WantedBy=multi-user.target

Enable and start RTL

$ sudo systemctl enable RTL
$ sudo systemctl start RTL

A way I made sure RTL configuration is working with on-chain operations, was to list on-chain addresses using lightning-cli, then create a new address from RTL and list the addresses again to see if it lists the new address

$ lightning-cli dev-listaddrs

Then I made sure lightning operations were also working by adding a new peer and then checking with lightning-cli that the peer was in fact added
I tested with 1ML, its public key is: 0217890e3aad8d35bc054f43acc00084b25229ecff0ab68debd82883ad65ee8266

$ lightning-cli listpeers

Well, that’s it, happy bitcoining!

References

--

--

Salvador Guerrero

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