Setup GuideSelf-Hosted (DIY)
Self-Hosted (DIY)
Want to run your own Lightning Address on your domain? This guide walks you through setting up a self-hosted LNURL-pay server.
Requirements
- A domain you control
- A web server (or serverless platform)
- A Lightning node or custodial account to receive payments
Basic Implementation
Your server needs to handle two endpoints:
1. The Well-Known Endpoint
GET https://yourdomain.com/.well-known/lnurlp/{username}
Return:
{
"callback": "https://yourdomain.com/lnurlp/{username}/callback",
"minSendable": 1000,
"maxSendable": 100000000000,
"metadata": "[[\"text/plain\",\"Pay {username}@yourdomain.com\"]]",
"tag": "payRequest"
}
2. The Callback Endpoint
GET https://yourdomain.com/lnurlp/{username}/callback?amount={msats}
When called, generate a Lightning invoice for the requested amount and return:
{
"pr": "lnbc...",
"routes": []
}
Using LNbits
LNbits provides a ready-made LNURL-pay extension:
- Install LNbits on your server
- Enable the LNURLp extension
- Create a pay link for each user
- Point your
.well-known/lnurlpto LNbits
Using BTCPay Server
BTCPay Server supports Lightning Address natively:
- Set up BTCPay Server with Lightning
- Enable LNURL in store settings
- Configure your domain's
.well-knownto point to BTCPay
Proxy Setup
If you just need to redirect to another provider, create a simple proxy:
// Example: Cloudflare Worker
export default {
async fetch(request) {
const url = new URL(request.url);
const username = url.pathname.split('/').pop();
// Proxy to your actual provider
const upstream = `https://provider.com/.well-known/lnurlp/${username}`;
return fetch(upstream);
}
}
Security Considerations
- Always use HTTPS
- Validate usernames to prevent injection
- Rate limit requests
- Consider authentication for invoice generation
Testing
Use these tools to verify your setup:
- lnurl.fiatjaf.com — LNURL decoder and tester
- Any LNURL-compatible wallet — try sending yourself some sats