Receiving payments using LNURL-Pay and Lightning addresses
What is a Lightning address?
A Lightning address is a human-readable identifier formatted like an email address (e.g., user@domain.com
) that can be used to receive Bitcoin payments over the Lightning Network. Behind the scenes, it uses the LNURL-Pay protocol to dynamically generate invoices when someone wants to send a payment to this address.
Configuring an LNURL server
To use Lightning addresses with the Breez SDK, you first need to supply a domain. There are two options:
- Use a hosted LNURL server: You can have your custom domain configured to an LNURL server run by Breez.
- Self-hosted LNURL server: You can run your own LNURL server in a self-hosted environment.
In case you choose to point your domain to an hosted LNURL server, you will need to add a CNAME record in your domain’s DNS settings:
- Host/Name: @ (or the subdomain you want to use, e.g., www)
- Type: CNAME
- Value/Target: breez.tips
Send us your domain name (e.g., example.com or www.example.com).
We will verify and add it to our list of allowed domains.
Configuring Lightning addresses for users
configure your domain in the SDK by passing the lnurl_domain
parameter in the SDK configuration:
let mut config = default_config(Network::Mainnet);
config.api_key = Some("your-api-key".to_string());
config.lnurl_domain = Some("yourdomain.com".to_string());
var config = defaultConfig(network: Network.mainnet)
config.apiKey = "your-api-key"
config.lnurlDomain = "yourdomain.com"
val config = defaultConfig(Network.MAINNET)
config.apiKey = "your-api-key"
config.lnurlDomain = "yourdomain.com"
let config = defaultConfig('mainnet');
config.apiKey = 'your-api-key';
config.lnurlDomain = 'yourdomain.com';
let config = defaultConfig(Network.Mainnet)
config.apiKey = 'your-api-key'
config.lnurlDomain = 'yourdomain.com'
final config = defaultConfig(network: Network.mainnet)
.copyWith(
apiKey: 'your-api-key',
lnurlDomain: 'yourdomain.com'
);
config = default_config(network=Network.MAINNET)
config.api_key = "your-api-key"
config.lnurl_domain = "yourdomain.com"
lnurlDomain := "yourdomain.com"
apiKey := "your-api-key"
config := breez_sdk_spark.DefaultConfig(breez_sdk_spark.NetworkMainnet)
config.ApiKey = &apiKey
config.LnurlDomain = &lnurlDomain
Managing Lightning addresses API docs
The SDK provides several functions to manage Lightning addresses:
Checking address availability
Before registering a Lightning address, you can check if the username is available. In your UI you can use a quick check mark to show the address is available before registering.
let request = CheckLightningAddressRequest {
username,
};
let is_available = sdk.check_lightning_address_available(request).await?;
let request = CheckLightningAddressRequest(
username: username
)
let available = try await sdk.checkLightningAddressAvailable(request: request)
val request = CheckLightningAddressRequest(
username = username
)
val available = sdk.checkLightningAddressAvailable(request)
const request = {
username
}
const available = await sdk.checkLightningAddressAvailable(request)
const request = {
username
}
const available = await sdk.checkLightningAddressAvailable(request)
final request = CheckLightningAddressRequest(
username: username,
);
final available = await sdk.checkLightningAddressAvailable(request: request);
request = CheckLightningAddressRequest(username=username)
is_available = await sdk.check_lightning_address_available(request)
request := breez_sdk_spark.CheckLightningAddressRequest{
Username: username,
}
isAvailable, err := sdk.CheckLightningAddressAvailable(request)
if err != nil {
return false, err
}
Registering a Lightning address
Once you've confirmed a username is available, you can register it by passing a username and a description. The username will be used in username@domain.com
. The description will be included in lnurl metadata and as the invoice description, so this is what the sender will see. The description is optional, and will default to Pay to username@domain.com
.
let request = RegisterLightningAddressRequest {
username,
description,
};
let address_info = sdk.register_lightning_address(request).await?;
let lightning_address = address_info.lightning_address;
let lnurl = address_info.lnurl;
let request = RegisterLightningAddressRequest(
username: username,
description: description
)
let addressInfo = try await sdk.registerLightningAddress(request: request)
let lightningAddress = addressInfo.lightningAddress
let lnurl = addressInfo.lnurl
val request = RegisterLightningAddressRequest(
username = username,
description = description
)
val addressInfo = sdk.registerLightningAddress(request)
val lightningAddress = addressInfo.lightningAddress
val lnurl = addressInfo.lnurl
const request = {
username,
description
}
const addressInfo = await sdk.registerLightningAddress(request)
const lightningAddress = addressInfo.lightningAddress
const lnurl = addressInfo.lnurl
const request = {
username,
description
}
const addressInfo = await sdk.registerLightningAddress(request)
const lightningAddress = addressInfo.lightningAddress
const lnurl = addressInfo.lnurl
final request = RegisterLightningAddressRequest(
username: username,
description: description,
);
final addressInfo = await sdk.registerLightningAddress(request: request);
final lightningAddress = addressInfo.lightningAddress;
final lnurl = addressInfo.lnurl;
request = RegisterLightningAddressRequest(
username=username,
description=description
)
address_info = await sdk.register_lightning_address(request)
lightning_address = address_info.lightning_address
lnurl = address_info.lnurl
request := breez_sdk_spark.RegisterLightningAddressRequest{
Username: username,
Description: description,
}
addressInfo, err := sdk.RegisterLightningAddress(request)
if err != nil {
return nil, err
}
_ = addressInfo.LightningAddress
_ = addressInfo.Lnurl
Retrieving Lightning address information
You can retrieve information about the currently registered Lightning address.
let address_info_opt = sdk.get_lightning_address().await?;
if let Some(info) = address_info_opt {
let lightning_address = &info.lightning_address;
let username = &info.username;
let description = &info.description;
let lnurl = &info.lnurl;
}
if let addressInfo = try await sdk.getLightningAddress() {
let lightningAddress = addressInfo.lightningAddress
let username = addressInfo.username
let description = addressInfo.description
let lnurl = addressInfo.lnurl
}
val addressInfoOpt = sdk.getLightningAddress()
if (addressInfoOpt != null) {
val lightningAddress = addressInfoOpt.lightningAddress
val username = addressInfoOpt.username
val description = addressInfoOpt.description
val lnurl = addressInfoOpt.lnurl
}
const addressInfoOpt = await sdk.getLightningAddress()
if (addressInfoOpt) {
const lightningAddress = addressInfoOpt.lightningAddress
const username = addressInfoOpt.username
const description = addressInfoOpt.description
const lnurl = addressInfoOpt.lnurl
}
const addressInfoOpt = await sdk.getLightningAddress()
if (addressInfoOpt) {
const lightningAddress = addressInfoOpt.lightningAddress
const username = addressInfoOpt.username
const description = addressInfoOpt.description
const lnurl = addressInfoOpt.lnurl
}
final addressInfoOpt = await sdk.getLightningAddress();
if (addressInfoOpt != null) {
final lightningAddress = addressInfoOpt.lightningAddress;
final username = addressInfoOpt.username;
final description = addressInfoOpt.description;
final lnurl = addressInfoOpt.lnurl;
}
address_info_opt = await sdk.get_lightning_address()
if address_info_opt is not None:
lightning_address = address_info_opt.lightning_address
username = address_info_opt.username
description = address_info_opt.description
lnurl = address_info_opt.lnurl
addressInfoOpt, err := sdk.GetLightningAddress()
if err != nil {
return nil, err
}
if addressInfoOpt != nil {
_ = addressInfoOpt.LightningAddress
_ = addressInfoOpt.Username
_ = addressInfoOpt.Description
_ = addressInfoOpt.Lnurl
}
Deleting a Lightning address
When a user no longer wants to use the Lightning address, you can delete it.
sdk.delete_lightning_address().await?;
try await sdk.deleteLightningAddress()
sdk.deleteLightningAddress()
await sdk.deleteLightningAddress()
await sdk.deleteLightningAddress()
await sdk.deleteLightningAddress();
await sdk.delete_lightning_address()
err := sdk.DeleteLightningAddress()
if err != nil {
return err
}