LNURL is a family of procedures through which a Lightning wallet and a web service exchange the information needed for a task. Lightning is used for fast Bitcoin payments; its invoice is a payment request containing the details a wallet needs to pay. From a link, the wallet learns whether to prepare a payment, receive a withdrawal or confirm a login. The link itself is neither an invoice nor proof that money has arrived.
Imagine Anna scanning a code to support a creator, another to redeem a voucher and a third to sign in to a website. She uses her phone in the same way but approves a different action each time. LNURL distinguishes these tasks: payRequest is for paying, withdrawRequest for withdrawing and login for signing in. Documents called LUDs describe the individual procedures. These are optional conventions for applications to work together, not changes to Bitcoin’s rules. A wallet supporting one procedure does not necessarily support the others. [1] [7]
For payRequest, the service supplies a description and an allowed amount range. Anna checks the domain—the service’s web address—reads the description and chooses her contribution. Once she accepts the terms, the wallet requests a specific BOLT 11 Lightning invoice and checks its amount against her choice before paying. Underneath, it uses a callback address, minSendable and maxSendable limits and metadata for the description; it sends the chosen amount as amount and receives the invoice in pr. Amounts use msat, thousandths of a satoshi: 1000 msat = 1 sat. Others can use the same public QR code, but scanning it is not confirmation of payment. [3]
With withdrawRequest, the direction is reversed. Anna wants to withdraw a balance from the service rather than pay it. Her wallet therefore creates a receiving invoice for the service to pay. The service provides a k1 identifier, a callback address and minWithdrawable and maxWithdrawable limits in msat; after approval, the wallet submits its invoice in pr. An OK response means the service accepted the request, not that Anna has received the money. The wallet still waits for the incoming payment. A withdrawal code may act like a voucher for whoever holds it, so do not publish it as an ordinary address for receiving payments. [4]
On another website, Anna chooses LNURL-auth. Her wallet shows the domain and the purpose of the request tagged login. With her approval, it signs a one-time k1 challenge using the domain-specific private key, linkingPrivKey. It sends the service the signature and the corresponding public linkingKey, which allows the signature to be verified. It does not share the private key. The service can recognize the returning key holder, but that check alone does not reveal their real-world identity. The wallet does not send the service its seed, the secret starting value from which keys are derived, or its Seed Phrase, the words used for recovery. Technically, this is an ECDSA signature on secp256k1. The action field can request registration, login, account linking or another authorization, so the full confirmation matters. Signing this challenge is not itself a Bitcoin payment. [5]
A request, a service response and an actual movement of money are separate steps. If Anna loses her connection, she first checks the original payment in her wallet. Another attempt with a new invoice can result in another payment. Optional LUD-21 supplies a verify address for a specific invoice: settled true reports settlement, while settled false reports an invoice not yet settled. OK alone is insufficient. The response may include a preimage, the original secret value associated with the payment. The wallet calculates its hash, a value used for checking, and compares it with the payment hash in the correct invoice. Receiving just any secret value is not enough: it must match this particular payment. Checking the result does not provide service availability or inbound liquidity—the capacity to route money into the receiving wallet. [6] [3] [4]
HTTPS protects the connection between the wallet and service, not against the service itself. It may observe requests, their timing and repeat use. For login, the full domain name also matters: changing a subdomain can produce a different linkingKey, so the website may see a different user. Moving to another wallet may not restore the same login either, because applications derive keys in different ways. Before a significant change, check how to recover access to that particular account. LNURL itself does not specify who holds the Bitcoin keys; that depends on the wallet and service. [2] [5]
Basic LUD-01 represents an HTTPS or onion URL in Bech32. This is an encoding, not encryption of the address and not a BOLT 11 invoice. The wallet reads a tag directly from the link or makes a GET web request for data and learns the operation from a JSON response. JSON gives data names and a structure that applications can read. A QR image therefore does not establish the recipient’s identity. What matters is the link’s content and the domain, action and terms subsequently shown. [2]
In the payment flow, metadata is a text string containing a JSON array. It must include a text/plain description; other types are optional. The wallet should show the description alongside the domain and amount so the user knows what they are approving. Basic LNURL interprets the JSON response body, not just the HTTP status code. A reachable server therefore need not mean a successful request: the response may contain ERROR. Likewise, an invoice received in pr has not yet been paid. These are different pieces of information that an application should not collapse into one green check mark. [2] [3]
For the clearest picture, read this entry together with BOLT 11, BOLT 12, Lightning Network, Lightning Address, Bitcoin Privacy, Satoshi. The reverse links also lead from BOLT 12, Lightning Address, Confirmo.