Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

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:

  1. Use a hosted LNURL server: You can have your custom domain configured to an LNURL server run by Breez.
  2. 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:

Rust
let mut config = default_config(Network::Mainnet);
config.api_key = Some("your-api-key".to_string());
config.lnurl_domain = Some("yourdomain.com".to_string());
Swift
var config = defaultConfig(network: Network.mainnet)
config.apiKey = "your-api-key"
config.lnurlDomain = "yourdomain.com"
Kotlin
val config = defaultConfig(Network.MAINNET)
config.apiKey = "your-api-key"
config.lnurlDomain = "yourdomain.com"
Javascript
let config = defaultConfig('mainnet');
config.apiKey = 'your-api-key';
config.lnurlDomain = 'yourdomain.com';
React Native
let config = defaultConfig(Network.Mainnet)
config.apiKey = 'your-api-key'
config.lnurlDomain = 'yourdomain.com'
Flutter
final config = defaultConfig(network: Network.mainnet)
    .copyWith(
      apiKey: 'your-api-key',
      lnurlDomain: 'yourdomain.com'
    );
Python
config = default_config(network=Network.MAINNET)
config.api_key = "your-api-key"
config.lnurl_domain = "yourdomain.com"
Go
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.

Rust
let request = CheckLightningAddressRequest {
    username,
};

let is_available = sdk.check_lightning_address_available(request).await?;
Swift
let request = CheckLightningAddressRequest(
    username: username
)

let available = try await sdk.checkLightningAddressAvailable(request: request)
Kotlin
val request = CheckLightningAddressRequest(
    username = username
)

val available = sdk.checkLightningAddressAvailable(request)
Javascript
const request = {
  username
}

const available = await sdk.checkLightningAddressAvailable(request)
React Native
const request = {
  username
}

const available = await sdk.checkLightningAddressAvailable(request)
Flutter
final request = CheckLightningAddressRequest(
  username: username,
);

final available = await sdk.checkLightningAddressAvailable(request: request);
Python
request = CheckLightningAddressRequest(username=username)
is_available = await sdk.check_lightning_address_available(request)
Go
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.

Rust
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;
Swift
let request = RegisterLightningAddressRequest(
    username: username,
    description: description
)

let addressInfo = try await sdk.registerLightningAddress(request: request)
let lightningAddress = addressInfo.lightningAddress
let lnurl = addressInfo.lnurl
Kotlin
val request = RegisterLightningAddressRequest(
    username = username,
    description = description
)

val addressInfo = sdk.registerLightningAddress(request)
val lightningAddress = addressInfo.lightningAddress
val lnurl = addressInfo.lnurl
Javascript
const request = {
  username,
  description
}

const addressInfo = await sdk.registerLightningAddress(request)
const lightningAddress = addressInfo.lightningAddress
const lnurl = addressInfo.lnurl
React Native
const request = {
  username,
  description
}

const addressInfo = await sdk.registerLightningAddress(request)
const lightningAddress = addressInfo.lightningAddress
const lnurl = addressInfo.lnurl
Flutter
final request = RegisterLightningAddressRequest(
  username: username,
  description: description,
);

final addressInfo = await sdk.registerLightningAddress(request: request);
final lightningAddress = addressInfo.lightningAddress;
final lnurl = addressInfo.lnurl;
Python
request = RegisterLightningAddressRequest(
    username=username,
    description=description
)

address_info = await sdk.register_lightning_address(request)
lightning_address = address_info.lightning_address
lnurl = address_info.lnurl
Go
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.

Rust
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;
}
Swift
if let addressInfo = try await sdk.getLightningAddress() {
    let lightningAddress = addressInfo.lightningAddress
    let username = addressInfo.username
    let description = addressInfo.description
    let lnurl = addressInfo.lnurl
}
Kotlin
val addressInfoOpt = sdk.getLightningAddress()

if (addressInfoOpt != null) {
    val lightningAddress = addressInfoOpt.lightningAddress
    val username = addressInfoOpt.username
    val description = addressInfoOpt.description
    val lnurl = addressInfoOpt.lnurl
}
Javascript
const addressInfoOpt = await sdk.getLightningAddress()

if (addressInfoOpt) {
  const lightningAddress = addressInfoOpt.lightningAddress
  const username = addressInfoOpt.username
  const description = addressInfoOpt.description
  const lnurl = addressInfoOpt.lnurl
}
React Native
const addressInfoOpt = await sdk.getLightningAddress()

if (addressInfoOpt) {
  const lightningAddress = addressInfoOpt.lightningAddress
  const username = addressInfoOpt.username
  const description = addressInfoOpt.description
  const lnurl = addressInfoOpt.lnurl
}
Flutter
final addressInfoOpt = await sdk.getLightningAddress();

if (addressInfoOpt != null) {
  final lightningAddress = addressInfoOpt.lightningAddress;
  final username = addressInfoOpt.username;
  final description = addressInfoOpt.description;
  final lnurl = addressInfoOpt.lnurl;
}
Python
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
Go
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.

Rust
sdk.delete_lightning_address().await?;
Swift
try await sdk.deleteLightningAddress()
Kotlin
sdk.deleteLightningAddress()
Javascript
await sdk.deleteLightningAddress()
React Native
await sdk.deleteLightningAddress()
Flutter
await sdk.deleteLightningAddress();
Python
await sdk.delete_lightning_address()
Go
err := sdk.DeleteLightningAddress()
if err != nil {
    return err
}