How to have a lightning address with your own domain that also runs a website

The objective: Allowing addresses at your domain to recieve lightning payments via BTCPayServer

LUD-16 is a specification for how to allow lightning addresses (like email addresses) to recieve bitcoin lightning payments.

In short: This specification allows to send a lightning payment to an easily remembarable lightning address like christopher@zechendorf.com. Usually those identifiers are only provided by custodial lightning wallets (like WalletOfSatoshi), but if you run a BTCPayServer instance, you can use your own domain and aliases.

If you don’t run a BTCPayServer yet, you can easily install it on a sufficiently sized VPS.

The problem: Your website runs at the domain you want to use for lightning addresses

Usually you run your BTCPayServer on a subdomain (or even a completely different domain), so the lightning addresses look something like christopher@btcpay.zechendorf.com. This is still neat, but not ideal, since your email addresses are most likely associated to the apex domain (in my case: zechendorf.com).

You can have your BTCPayServer run at your apex domain, but usually you want your website to run there.

The solution: Configure nginx to be a proxy to BTCPayServer for the LUD-16 requests

If nginx serves your website, you’re in luck: LUD-16 uses requests to a special subdirectory (`/.well-known/lnurlp/) to request lightning invoices for aliases. Since this subdirectory is not needed by your website, you can easily achieve your goal by configuring nginx to be a reverse proxy to your BTCPayServer instance for requests with that path.

Simply add the following lines within the server block for the desired domain:

location /.well-known/lnurlp/ {
  proxy_pass https://btcpay.zechendorf.com/.well-known/lnurlp/;
}

These three lines configure nginx to behave as a proxy to https://btcpay.zechendorf.com/.well-known/lnurlp/ for all requests to URLs on your domain that start with /.well-known/lnurlp/ (so the answer nginx sends will originate from your BTCPayServer).

…make sure to replace btcpay.zechendorf.com with whatever your BTCPayServer domain is (otherwise the requests will end up at my server).