diff --git a/06.md b/06.md index 85aff01..0fdfe33 100644 --- a/06.md +++ b/06.md @@ -7,7 +7,7 @@ LUD-06: `payRequest` base spec. The idea here is that a wallet can scan a static QR code or click on a static LNURL address and get back details about a payment that is expected. The details may include much more extensive metadata than a normal Lightning invoice. And the amounts may be fixed or within a range. -Then, once the user accepts the terms (and choose an amount, if that is not fixed), the wallet will call the service and get a Lightning invoice specific for that payment, containing a hash of the metadata as its [`h` tag (`description_hash`)](https://github.com/lightningnetwork/lightning-rfc/blob/master/11-payment-encoding.md#requirements-3) and proceed to pay the invoice if it matches the expected amount and hash. +Then, once the user accepts the terms (and choose an amount, if that is not fixed), the wallet will call the service and get a Lightning invoice specific for that payment and proceed to pay the invoice if it matches the expected amount. ## Pay to static QR/NFC/link @@ -22,7 +22,7 @@ Then, once the user accepts the terms (and choose an amount, if that is not fixe "callback": string, // The URL from LN SERVICE which will accept the pay request parameters "maxSendable": number, // Max millisatoshi amount LN SERVICE is willing to receive "minSendable": number, // Min millisatoshi amount LN SERVICE is willing to receive, can not be less than 1 or more than `maxSendable` - "metadata": string, // Metadata json which must be presented as raw string here, this is required to pass signature verification at a later step + "metadata": string, // Metadata json which must be presented as raw string here "tag": "payRequest" // Type of LNURL } ``` @@ -69,7 +69,7 @@ Then, once the user accepts the terms (and choose an amount, if that is not fixe "[[\"text/plain\", \"lorem ipsum blah blah\"]]" ``` -3. `LN WALLET` displays a payment dialog where user can specify an exact sum to be sent which would be bounded by: +4. `LN WALLET` displays a payment dialog where user can specify an exact sum to be sent which would be bounded by: ``` max can send = min(maxSendable, local estimation of how much can be sent from wallet) @@ -82,7 +82,7 @@ Then, once the user accepts the terms (and choose an amount, if that is not fixe And it may include: - An image element with the contents of `image/png` or `image/jpeg`. -4. `LN WALLET` makes a GET request using +5. `LN WALLET` makes a GET request using ``` amount= @@ -90,7 +90,7 @@ Then, once the user accepts the terms (and choose an amount, if that is not fixe `amount` being the amount specified by the user in millisatoshis. -5. `LN Service` takes the GET request and returns JSON response of form: +6. `LN Service` takes the GET request and returns JSON response of form: ```Typescript { @@ -105,17 +105,5 @@ Then, once the user accepts the terms (and choose an amount, if that is not fixe {"status":"ERROR", "reason":"error details..."} ``` -6. `LN WALLET` Verifies that `h` tag in provided invoice is a hash of `metadata` string converted to byte array in UTF-8 encoding. 7. `LN WALLET` Verifies that amount in provided invoice equals the amount previously specified by user. -10. `LN WALLET` pays the invoice, no additional user confirmation is required at this point. - -## Notes on metadata for server-side LNURL-PAY - -### When client makes a first call: - -Construct a metadata object, turn it into json, then include it into parent json as a string. - -### When client makes a second call - -1. Make a hash as follows: `sha256(utf8ByteArray(unescaped_metadata_string))`. -2. Generate a payment request using an obtained hash. +8. `LN WALLET` pays the invoice, no additional user confirmation is required at this point. diff --git a/18.md b/18.md index fb6030f..16f52fc 100644 --- a/18.md +++ b/18.md @@ -7,8 +7,6 @@ LUD-18: Payer identity in `payRequest` protocol. The idea here is that the payer can identify itself when paying. The scope varies from free-form names (or [LUD-16](16.md) 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. -Aside from that, the payer ids are also committed to the invoice by means of the `descriptionHash` property, which ensures strong cryptographic guarantees for proof of payment. - ## 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): @@ -67,33 +65,3 @@ Each key in this JSON object should correspond to a requested payerdata from the `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. - -## 3. Committing payer to the invoice - -If `SERVICE` requests (section 1) and `WALLET` sends a `payerdata` record in the callback (section 2), the payer ids MUST be committed to the metadata before the invoice is created. - -`SERVICE` MUST append it to the metadata as it was received (after url-decoding), as in the following example: - -```diff - [["text/plain", "description"], ["image/png;base64", "AAA=="]] -+[["text/plain", "description"], ["image/png;base64", "AAA=="]]{} -``` - -After doing that, `SERVICE` proceeds to hash the metadata and include that hash in the generated BOLT11 invoice as the `descriptionHash` field. - -On its own side, `WALLET` MUST do the same thing before hashing the metadata and checking its hashed value against the `descriptionHash` field of the invoice received from `SERVICE`. - -Even if `WALLET` sends more `payerdata` fields than requested by `SERVICE`, `SERVICE` MUST still append everything as received. - -`WALLET` MUST NOT expect `SERVICE` to append the identity records to the metadata if `SERVICE` hadn't included the `payerData` record in the first response, as that would mean `SERVICE` doesn't understand LUD-18 at all. - -### Pseudocode example for calculating `descriptionHash` with `payerdata` - -``` -originalServiceMetadata = '[["text/plain", "description"], ["image/png;base64", "AAA=="]]' -urlEncodedPayerIds = '%7B%22name%22%3A%22bob%22%2C%22auth%22%3A%7B%22key%22%3A%2202c9323d02fc164f89c8f688dbfba8aad69a96fa8f6253ba8cce2c6f1546073fa3%22%2C%22sig%22%3A%222afd21794e2a801d0d516584ceebe1a24ed8991dd5ec708259aeaee5c0d2d1437542b689ee5d39e619a01a257142d49c18a4af3088c46ce87e2d941a1bcc7210%22%7D%2C%22identifier%22%3A%22bob%40bob.com%22%2C%22pubkey%22%3A%2203ee58475055820fbfa52e356a8920f62f8316129c39369dbdde3e5d0198a9e315%22%7D' -payerData = urldecode(urlEncodedPayerIds) -descriptionToBeHashed = metadata + payerData -descriptionToBeHashed == '[["text/plain", "description"], ["image/png;base64", "AAA=="]]{"name":"bob","auth":{"key":"02c9323d02fc164f89c8f688dbfba8aad69a96fa8f6253ba8cce2c6f1546073fa3","sig":"2afd21794e2a801d0d516584ceebe1a24ed8991dd5ec708259aeaee5c0d2d1437542b689ee5d39e619a01a257142d49c18a4af3088c46ce87e2d941a1bcc7210"},"identifier":"bob@bob.com","pubkey":"03ee58475055820fbfa52e356a8920f62f8316129c39369dbdde3e5d0198a9e315"}' -descriptionHash = sha256(utf8(descriptionToBeHashed)) -```