nips
nips copied to clipboard
[NIP-96] Adding payment requirements and payment_request field
Objective
The objective of this proposal is to introduce a payment requirement mechanism for file storage on the server, ensuring a smooth adaptation process for clients while maintaining backward compatibility.
Proposed Changes
-
Using actual spec header:
402 Payment Required: Payment is required by the server.
-
Adding a New Field to the Server's JSON Response:
payment_request: A string representing a bolt11 invoice, e.g.,"lnbc1...".
Payment Required
Some servers may require payment for file storage. In that case, the server SHOULD serve the normal response with a 402 Payment Required status code and the payment_request field filled. The payment_request field MUST be a standard BOLT11 invoice.
Until the payment is completed, the server SHOULD display a QR code (or another useful information) in the URL tag of the NIP-94 event response. When the payment is done, the server MUST swap the QR code for the uploaded file.
Clients SHOULD check the payment_request field and display the QR code to the user if the field is present.
Example
Here is an example of a QR code generated by nostrcheck-server for the url field as long as a payment has not been made:
Compatibility
This proposal maintains backward compatibility. If a client does not adopt this change but a server requires payment for its services, the resulting URL will display the QR code until someone pays the invoice. This ensures a smooth adaptation process for clients, as the system will function correctly without breaking existing functionality.
@arthurfranca @v0l @vitorpamplona @fishcakeday @sant0s12
Nice! This will resolve a lot of the UX friction on larger files.
I just don't know about the invoice image. If displayed on their phones, people wouldn't have another phone to take the picture of them. I would prefer that the server sent a regular kind 1-like content with the explanation and links to pay so that clients can just render it as a kind 1 post.
https://github.com/nostr-protocol/nips/pull/901 is similar, but for relay payment. The kind 1 content works really well.
Hello Vitor. I have tested it on my iphone and (in my case) I can copy the QR code and paste it on my LN wallet.
https://github.com/nostr-protocol/nips/assets/125748180/e266800c-e27c-49c3-9f78-a877b374cbc2
But anyway, the payment_request field returns the invoice, so the client simply can check this field, if it is filled, it shows the option to pay the invoice with the user's wallet.
If I understand correctly, you propose that in case of requesting a payment, a JSON with a signed kind 1 note with the payment instructions and the 402 header is returned. Is this correct? It seems to me a more complete solution but I see the disadvantage of nostr clients who do not adapt to this new flow.
I think I like more the image/video because we don't break with old nostr clients, they expect an image/video and that's what I return them, but with the QR. Is there a possibility to try it on an Android phone?
What happens after the payment is processed? What happens if you get 10, 100, 1000, ... concurrent requests or the same in a very short period of time?
The server swaps the file, as described for example in the "delayed processing" section. It simply clears cache and displays the final file (either processed or the original by no_transform, in this case it does not affect).
I have tested it with requests every 100ms and my server is holding up well.
By the way, this is implemented in nostrcheck-server, if you want we can do a live test and stress me the server between all, that if, paying the invoices 🤣 (just kidding)
So, this is specifically for upload of the files, not for the payment to see the file, right? If so, then it is probably OK, if for viewing, then how do you track who sees what?
If it is for viewing, and you intend to generate an invoice per user per file, then no LN node will handle it without Bolt12.
It is terribly simple. If there is a payment_request, the server can display a QR as I propose, it can display the "fuzzy" file, as the server wants.
Here the key is in the payment_request field that is returned along with the rest of the fields and how the nostr cliends handle this information.
The QR is just to be able to implement this without having to wait for all the nostr clients to adapt to the eventual change of NIP96. Once the invoice is paid, the next time the image (or video) is loaded it is displayed as normal, nothing else, very simple.
I can copy the QR code and paste it on my LN wallet.
That's way too much friction yet. You want just a simple button saying Pay to Host, one click, and done without leaving the app. Opening the QR in a wallet is not that usable. My recommendation is to reduce sales friction to ZERO instead of just swapping to another procedure people need to go through. The QR image might stay there as a fallback, but the default for supporters of this NIP should be to make the payment just a zap away.
If I understand correctly, you propose that in case of requesting a payment, a JSON with a signed kind 1 note with the payment instructions and the 402 header is returned.
It doesn't need to be a signed event. NOTIFY only returns a formatted message from the relay that is ready to be displayed on any client that supports a Kind1 type of payload.
It is terribly simple. If there is a payment_request, the server can display a QR as I propose, it can display the "fuzzy" file, as the server wants.
Here the key is in the payment_request field that is returned along with the rest of the fields and how the nostr cliends handle this information.
The QR is just to be able to implement this without having to wait for all the nostr clients to adapt to the eventual change of NIP96. Once the invoice is paid, the next time the image (or video) is loaded it is displayed as normal, nothing else, very simple.
So who is supposed to pay what and who is supposed to get paid in this case? I am trying to understand what the payment is for. It may be simple to you, but it is not explicit in this case and I have no idea what the payment is for or who is obligated to pay it.
I can copy the QR code and paste it on my LN wallet.
That's way too much friction yet. You want just a simple button saying Pay to Host, one click, and done without leaving the app. Opening the QR in a wallet is not that usable. My recommendation is to reduce sales friction to ZERO instead of just swapping to another procedure people need to go through. The QR image might stay there as a fallback, but the default for supporters of this NIP should be to make the payment just a zap away.
If I understand correctly, you propose that in case of requesting a payment, a JSON with a signed kind 1 note with the payment instructions and the 402 header is returned.
It doesn't need to be a signed event. NOTIFY only returns a formatted message from the relay that is ready to be displayed on any client that supports a Kind1 type of payload.
In this case, the client must interpret the payment_request field and proceed to display a small popup or button (or however you want) to pay the invoice.
I agree that the QR should remain as a fallback, I showed it just to demonstrate a use case when a nostr client is not adapted.
So who is supposed to pay what and who is supposed to get paid in this case? I am trying to understand what the payment is for. It may be simple to you, but it is not explicit in this case and I have no idea what the payment is for or who is obligated to pay it.
This is irrelevant to the NIP. In this case, the payment_request is requested to the person who is trying to upload a file to your server, it could be for example that the user has no space (I think you work like that in nostr-build) and then you ask the user for a small invoice to be able to continue using your service.
This person may consider that the payment is too high and not pay the invoice but publish the note with the URL anyway, another person can pay it on his behalf without friction.
There are many ways to take advantage of it, also for the users. I have a lot of ideas about this, but if I tell you, I'm giving you a lot of clues 🤣🤣🙏💜🐶
I'm open to changes, of course, if someone wants to modify something it would be great!! 😀
In this case, the client must interpret the payment_request field and proceed to display a small popup or button (or however you want) to pay the invoice.
What I like about #901 is that it gives you the ability to write a message together with the invoice to explain what is being purchased, why and for which account. You could offer an invoice just for this picture, but you can also offer a monthly subscription in the same message. You can just explain it nicely to your user with one or more invoice links inside the kind 1 message.
So who is supposed to pay what and who is supposed to get paid in this case? I am trying to understand what the payment is for. It may be simple to you, but it is not explicit in this case and I have no idea what the payment is for or who is obligated to pay it.
This is irrelevant to the NIP. In this case, the
payment_requestis requested to the person who is trying to upload a file to your server, it could be for example that he has no space (I think you work like that in nostr-build) and then you ask him for a small invoice to be able to continue using your service.This person may consider that the payment is too high and not pay the invoice but publish the note with the URL anyway, another person can pay it on his behalf without friction.
There are many ways to take advantage of it, also for the users. I have a lot of ideas about this, but if I tell you, I'm giving you a lot of clues 🤣🤣🙏💜🐶
Then this makes no sense to me, since the payment should be requested before the upload is even allowed. Otherwise, you are opening yourself to a lot of problems and a lot of abuses.
Also, since the internet and usage of services is not reserved for the male population, you should use “they, them, user, uploader, etc.” instead of always using “he, him”, just saying.
Also, since the internet and usage of services is not reserved for the male population, you should use “they, them, user, uploader, etc.” instead of always using “he, him”, just saying.
My native language is not English, I apologize in advance for this kind of thing.
What I like about #901 is that it gives you the ability to write a message together with the invoice to explain what is being purchased, why and for which account. You could offer an invoice just for this picture, but you can also offer a monthly subscription in the same message. You can just explain it nicely to your user with one or more invoice links inside the kind 1 message.
In this case, the message field could be used to display instructions or other ways to subscribe. I insist on keeping it simple. An upload of a file, if payment_request exists, the invoice is sent to the client in a return field.
NIP-88 makes sense, but there is no NOTIFY event for HTTP requests. (I might be wrong). For this scenario, would the message and payment_request fields be sufficient? It would really be the same behavior.
Then this makes no sense to me, since the payment should be requested before the upload is even allowed. Otherwise, you are opening yourself to a lot of problems and a lot of abuses.
It's a shame not to have your support, I thought you would consider it a simple and effective way to finance an online service without large annual, monthly payments, or subscriptions. Pay per use, in fact, on nostrcheck-server it's pay per "weight". Setting a maximum of satoshis by the server administrator for the largest acceptable file.
Then this makes no sense to me, since the payment should be requested before the upload is even allowed. Otherwise, you are opening yourself to a lot of problems and a lot of abuses.
It's a shame not to have your support, I thought you would consider it a simple and effective way to finance an online service without large annual, monthly payments, or subscriptions. Pay per use, in fact, on nostrcheck-server it's pay per "weight". Setting a maximum of satoshis by the server administrator for the largest acceptable file.
What I meant was that it makes no sense to present the user with the URL to a file and hide it behind a paywall. I think I've mentioned that it is better to block an upload until the payment is made, if you are trying to implement pay-as-you-go style charging. I am definitely thinking that #901 is a good way to present it to a user.