CapabilitiesPayment Rail Discovery

Payment Rail Discovery (LUD-25)

Payment Rail Discovery enables recipients to advertise multiple payment protocols beyond BOLT11 Lightning — including BOLT12, Ark, Spark, Liquid, and on-chain Bitcoin.

Why It Matters

The Bitcoin payment ecosystem is expanding:

  • BOLT12 — improved privacy and reusability
  • Ark — scalable off-chain payments
  • Spark — instant settlement layer
  • Liquid — federated sidechain
  • On-chain — the base layer

With Payment Rail Discovery, your Lightning Address becomes a unified payment endpoint that supports all these protocols.

How It Works

The pay-options Endpoint

In addition to the standard /.well-known/lnurlp/<user> endpoint, servers can expose:

GET /.well-known/pay-options/<user>

This returns available payment rails:

{  "options": [    {      "type": "bolt11",      "callback": "https://domain.com/lnurlp/user/callback"    },    {      "type": "bolt12",      "offer": "lno1..."    },    {      "type": "onchain",      "address": "bc1q..."    },    {      "type": "liquid",      "address": "VJL..."    }  ]}

Option Types

| Type | Description | Fields | |------|-------------|--------| | bolt11 | Standard Lightning | callback | | bolt12 | BOLT12 offers | offer | | onchain | Bitcoin on-chain | address, bip21 | | liquid | Liquid Network | address | | ark | Ark protocol | vtxo_address | | spark | Spark protocol | endpoint |

Client Behavior

Wallets implementing LUD-25 should:

  1. Check for /.well-known/pay-options/<user> first
  2. If available, present options to the user or auto-select based on preferences
  3. Fall back to standard LNURL-pay if not available
async function resolveLightningAddress(address: string) {  const [user, domain] = address.split('@');  // Try pay-options first  try {    const payOptions = await fetch(      `https://${domain}/.well-known/pay-options/${user}`    );    if (payOptions.ok) {      return { type: 'multi-rail', data: await payOptions.json() };    }  } catch {}  // Fall back to standard LNURL-pay  const lnurl = await fetch(    `https://${domain}/.well-known/lnurlp/${user}`  );  return { type: 'lnurl', data: await lnurl.json() };}

Implementation Example

app.get('/.well-known/pay-options/:username', async (req, res) => {  const user = await getUser(req.params.username);  if (!user) {    return res.status(404).json({ status: 'ERROR', reason: 'User not found' });  }  const options = [];  // Always include BOLT11  options.push({    type: 'bolt11',    callback: `https://domain.com/lnurlp/${user.username}/callback`  });  // Add BOLT12 if user has an offer  if (user.bolt12Offer) {    options.push({      type: 'bolt12',      offer: user.bolt12Offer    });  }  // Add on-chain if user has a static address  if (user.bitcoinAddress) {    options.push({      type: 'onchain',      address: user.bitcoinAddress    });  }  res.json({ options });});

The Future of Payments

Payment Rail Discovery positions Lightning Address as the universal payment identifier:

  • One address, many rails — users share a single identifier
  • Automatic optimization — wallets can pick the best rail
  • Future-proof — new protocols can be added without changing addresses
  • Agent-friendly — programmatic rail selection for AI systems

As new Bitcoin scaling solutions emerge, they can integrate with the Lightning Address ecosystem through this discovery mechanism.