LUD-18: Payer identity in payRequest protocol.
August 25, 2023 ยท View on GitHub
author: akumaigorodski author: hampus_s discussion: https://t.me/lnurl/14436 author: fiatjaf author: dpad85 discussion: https://t.me/lnurl/24003 discussion: https://github.com/fiatjaf/lnurl-rfc/pull/101
The idea here is that the payer can identify itself when paying. The scope varies from free-form names (or LUD-16 internet identifiers) useful for loose identification in comments or similar things, to cryptographic keys for proof of payment, to authentication keys for future login into a SERVICE's website after a payment and other use cases.
1. payerData record
If SERVICE wants to get one or more types of payer identities from WALLET then it MUST alter its JSON response to the first callback to include a payerData field, as follows (notice that the payerData record below has a bunch of fields only for completion, an actual response will likely contain just a subset of these):
{
"callback": String,
"maxSendable": number,
"minSendable": number,
"metadata": string,
+ "payerData": {
+ "name": { "mandatory": boolean },
+ "pubkey": { "mandatory": boolean },
+ "identifier": { "mandatory": boolean },
+ "email": { "mandatory": boolean },
+ "auth": {
+ "mandatory": boolean,
+ "k1": string // hex encoded 32 bytes of challenge
+ },
+ ...other fields may be negotiated
+ },
"tag": "payRequest",
}
Notice that just including the payer id kind ("name", "pubkey" etc.) in the payerData record is enough to signal acceptance of that kind.
2. Specifying payer identity before sending a payment
In response to seeing a payerData record in the initial response from SERVICE, WALLET attaches a payerdata query parameter to LNURL-PAY callback with value set to a JSON object:
- <callback><?|&>amount=<milliSatoshi>
+ <callback><?|&>amount=<milliSatoshi>&payerdata=<urlencode({json object})>
The JSON object MUST be of the following format (notice that these fields are shown only for completion, in practice it will likely contain just a subset of these):
{
"name": string, // free form string
"pubkey": string, // hex(<randomly generated secp256k1 pubkey>),
"auth": {
"key": string, // hex(<linkingKey>)
"k1": string, // same as received from service on section 1
"sig": string, // following LUD-04: hex(sign(hexToBytes(<k1>), <linkingPrivKey>))
},
"email": string,
"identifier": string,
...other fields may be included if supported by wallet and requested by service
}
Each key in this JSON object should correspond to a requested payerdata from the payerData record received from SERVICE.
WALLET CAN send any of the payer id kinds if they are listed in the payerData record. But if any is marked as "mandatory": true then WALLET MUST send or otherwise do not proceed with the payment flow.
WALLET SHOULD NOT send payer identity types omitted in payerData record, none at all if record is not present.