LnAddress.Net is a service that allows you to receive Lightning payments using any username at your domain. For
example: username@your.domain.
- Docker Image: A pre-built Docker image is available at ngoline/lnaddress.net.
- Configuration Reference: Review the docker-compose.yml file for a complete list of environment variables and configuration options.
- Reverse Proxy Setup: An example Nginx configuration is provided in example.nginx.
-
Pull the Docker Image:
docker pull ngoline/lnaddress.net:latest
-
Review Configuration Variables:
Check the docker-compose.yml file for environment variables. These variables allow you to:
- Choose the Lightning backend (
LIGHTNING__BACKEND):lnd(default) orcln(Core Lightning). - Configure connection details to your LND or Core Lightning instance.
- Adjust limits for payment amounts or comment fields.
- Choose the Lightning backend (
-
Set Up Nginx (Optional):
For a production setup, use example.nginx as a guide to set up a reverse proxy with TLS termination.
This is the default backend (LIGHTNING__BACKEND=lnd). To enable Lightning payments, you need to connect
LnAddress.Net to your LND instance. You will need:
- The TLS certificate (
tls.cert) - A macaroon baked with the permissions the service needs, in base64 format
- The LND RPC server endpoint
Steps to Obtain LND Credentials:
-
TLS Certificate:
Extract the certificate content between the
-----BEGIN CERTIFICATE-----and-----END CERTIFICATE-----lines.cat /.lnd/tls.cert
Copy only the certificate portion without the header and footer lines.
-
Macaroon:
Bake a macaroon that grants only what the service needs:
invoices:writeto create invoices,invoices:readto look them up for the verify endpoint, andinfo:readfor/health:lncli bakemacaroon --save_to=lnaddress.macaroon invoices:read invoices:write info:read
Then convert it to a single-line base64 string:
base64 lnaddress.macaroon | tr -d '\n'
Don't use the stock
invoice.macaroon: it lacksinfo:read, so invoices work but/healthfails and the Docker healthcheck marks the container unhealthy. Avoidadmin.macaroontoo, since it grants full control of the node, including spending funds. -
RPC Server URL:
Set your LND RPC endpoint, for example:
https://<lnd-ip>:10009
Ensure your
lnd.confincludes:rpclisten=0.0.0.0:10009This makes LND’s RPC interface accessible to LnAddress.Net.
Set LIGHTNING__BACKEND=cln to use Core Lightning instead of LND. LnAddress.Net talks to the
cln-grpc plugin, which authenticates
clients with mutual TLS. You will need:
- The CA certificate (
ca.pem) - A client certificate and key signed by that CA (
client.pemandclient-key.pem) - The cln-grpc endpoint
Steps to Obtain CLN Credentials:
-
Enable the gRPC plugin:
Add the following to your CLN config (or pass them as command line flags) and restart
lightningd:grpc-port=9736 grpc-host=0.0.0.0
Leave
grpc-hostunset if LnAddress.Net runs on the same host as CLN (the plugin listens on localhost by default). On first start the plugin generatesca.pem,client.pemandclient-key.pemin the network directory, for example~/.lightning/bitcoin/. -
Certificates:
Convert each PEM file to a single-line base64 string:
base64 ~/.lightning/bitcoin/ca.pem | tr -d '\n' base64 ~/.lightning/bitcoin/client.pem | tr -d '\n' base64 ~/.lightning/bitcoin/client-key.pem | tr -d '\n'
Raw PEM text (including the
-----BEGIN ...-----lines) is accepted as well. -
RPC Server URL:
Set your cln-grpc endpoint, for example:
https://<cln-ip>:9736
The server certificate is validated against
ca.pem, so the hostname does not need to match the certificate.
Environment variables:
docker run -d \
-p 80:80 \
-e LIGHTNING__BACKEND=cln \
-e CLN__RPCADDRESS="https://<cln-ip>:9736" \
-e CLN__CACERT="<base64_ca_pem>" \
-e CLN__CLIENTCERT="<base64_client_pem>" \
-e CLN__CLIENTKEY="<base64_client_key_pem>" \
ngoline/lnaddress.net:latest-
LUD-06:
payRequestbase spec. -
LUD-12: comments in
payRequest, enabled byINVOICE__MAXCOMMENTALLOWED. -
LUD-16: Lightning Address,
username@your.domain. -
LUD-21:
verifybase spec. The callback response carries averifyURL (https://your.domain/lnurl/verify/<payment_hash>) that anyone holding the invoice can poll to learn whether it was settled. Once paid, the response includes the preimage:{"status": "OK", "settled": true, "preimage": "<hex>", "pr": "lnbc..."}Unknown payment hashes return
{"status": "ERROR", "reason": "Not found"}. The endpoint needs no authentication. It looks up the hash on the backend node, so it answers for any invoice on that node, not only the ones LnAddress created. For invoices LnAddress issued, it only reveals data the payer already holds.Use a dedicated node. If other apps (a shop, a wallet, ...) create invoices on the same node, anyone who learns one of their payment hashes can read the full bolt11 (amount and description), and once it is paid, the preimage, which serves as proof of payment. Run LnAddress against a node used only for it, or don't expose
/lnurl/verifypublicly.
- MinSendable: 1,000 millisatoshis (1 satoshi)
- MaxSendable: 100,000,000 millisatoshis (100,000 satoshis)
- MaxCommentAllowed: 0 (no comments accepted)
If these defaults don’t meet your needs, adjust them via environment variables as shown in docker-compose.yml.
Once you have your environment variables set and Docker is ready, you can run:
docker-compose up -dor, if running standalone:
docker run -d \
-p 80:80 \
-e LND__CERT="<base64_tls_cert>" \
-e LND__MACAROON="<base64_macaroon>" \
-e LND__RPCADDRESS="https://<lnd-ip>:10009" \
ngoline/lnaddress.net:latestReplace the environment variables with your actual values.
You’re now set up to receive Lightning payments via username addresses on your domain!