author: akumaigorodski
diagram: johnpaulkiser
Today users are asked to provide a withdrawal Lightning invoice to a service. This requires some effort and is especially painful when users try to withdraw funds into mobile wallets while using a desktop website. Instead of asking for Lightning invoice a service could display a "withdraw" QR code which contains a specialized LNURL.
sequenceDiagram
actor Alice
participant Wallet
participant LN Service
Alice->>LN Service: initiates LNURL withdrawRequest
Note over LN Service: displays <br/>encoded LNURL
Wallet->>LN Service: Scans QR or copies encoded LNURL
Note over Wallet: decodes LNURL
Wallet->>LN Service: makes GET to LNURL
alt Success
LN Service--)Wallet: returns JSON response
Note left of LN Service: {<br/>"callback": string, <br /> "k1": string, <br/> "minWithdrawable": number, <br/> "maxWithdrawable": number, <br/> ...<br/>}
Wallet->>Alice: display withdrawal dialog
Alice->>Wallet: specify exact withdrawal amount
Note over Wallet: creates BOLT-11 invoice
Wallet->>LN Service: makes GET to: callback URL with query params k1 & pr=<BOLT-11 invoice>
alt Success
LN Service--)Wallet: returns JSON response
Note left of LN Service: {"status": "OK"}
Wallet--)Wallet: waits for payment
Wallet->>Alice: notifies of successful withdrawal
Note over Alice: END
else Failure
LN Service--)Wallet: returns JSON response
Note left of LN Service: {<br/>"status": "ERROR", <br /> "reason": string <br/> }
Wallet->>Alice: notifies of unsuccessful withdrawal
Note over Alice: END
end
else Failure
LN Service--)Wallet: returns JSON response
Note left of LN Service: {<br/>"status": "ERROR", <br /> "reason": string <br/> }
Wallet->>Alice: notifies of unsuccessful withdrawal
Note over Alice: END
end
-
User scans a LNURL QR code or accesses an
lightning:LNURL..link withLN WALLETandLN WALLETdecodes LNURL. -
LN WALLETmakes a GET request toLN SERVICEusing the decoded LNURL. -
LN WALLETgets JSON response fromLN SERVICEof form:{ "tag": "withdrawRequest", // type of LNURL "callback": string, // The URL which LN SERVICE would accept a withdrawal Lightning invoice as query parameter "k1": string, // Random or non-random string to identify the user's LN WALLET when using the callback URL "defaultDescription": string, // A default withdrawal invoice description "minWithdrawable": number, // Min amount (in millisatoshis) the user can withdraw from LN SERVICE, or 0 "maxWithdrawable": number, // Max amount (in millisatoshis) the user can withdraw from LN SERVICE, or equal to minWithdrawable if the user has no choice over the amounts }
or
{"status": "ERROR", "reason": "error details..."} -
LN WALLETDisplays a withdraw dialog where user can specify an exact sum to be withdrawn which would be bounded by:max can receive = min(maxWithdrawable, local estimation of how much can be routed into wallet) min can receive = max(minWithdrawable, local minimal value allowed by wallet) -
Once accepted by the user,
LN WALLETsends a GET toLN SERVICEin the form of<callback> <?|&> // either '?' or '&' depending on whether there is a query string already in the callback k1=<k1> // the k1 specified in the response above &pr=<lightning invoice> // the payment request generated by the wallet -
LN SERVICEsends a{"status": "OK"}or{"status": "ERROR", "reason": "error details..."}JSON response and then attempts to pay the invoices asynchronously. -
LN WALLETawaits for incoming payment if response was successful.
Note that service will withdraw funds to anyone who can provide a valid ephemeral k1. In order to harden this a service may require authorization (LNURL-auth, email link etc.) before displaying a withdraw QR.