NUT-24: HTTP Payment required #239
No reviewers
Labels
No labels
breaking change
bug
documentation
enhancement
needs discussion
needs implementation
new nut
ready
wallet-only
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
forgejo-admin/nuts!239
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "402"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
This PR adds NUT-24 that describes how the HTTP 402 status code + an
X-Cashuheader can be used to require payment for http resourcesreadable version
The goal for this NUT is to keep it tightly coupled to HTTP and keep all communication in-band to reduce complexity.
Should we also state that the server SHOULD NOT redeem these tokens?
This should reuse the payment request from NUT-18 and specify which fields need to be set https://github.com/cashubtc/nuts/pull/243
The server might want to melt them, I think it's better to leave this to the implementor.
Looks ready. Please leave your reviews. We usually wait for an implementation before we merge.
If the tokens are to be validated offline, they should also be checked for refund keys and timelock expiry
I implied that in it MUST validate the P2PK script
This is great! I have been waiting for this. For anyone building an implementation for this, here is an endpoint to test against: https://cashu402.fly.dev/secret
Repo: https://github.com/Egge21M/cashu402
It's nice to see more people building on the
HTTP 402🎉eCash has something really distinct and it's that "the token is the money" which means that people can use it as "proof of payment" (you send it to me and I claim it instantly). This is different from other payment methods where you can do pull based payments (ex: credit cards) or push based but you need to check if the payment was completed outbound (ex: Bitcoin)
We have been working for a while with a generic flow that supports all kind of payment methods. The trade offs for ecash is
I understand why you want to create a NUT for this. Same of why x402 exists for "strictly on chain payments" but even in that case I would try to bake in the "multiple offer support" in.
If you plan to keep
a intI suggest that you clarify to specify that it befractional unitof the currency for a 402 payment required. Otherwise, you'll need afloattype, if you are going to specify a fiat currency e.g., 0.01 USDI prefer sticking to an
intso the proposed change would be:a: The amount required in the specified fractional unitFor background, every currency has a
fractional unitandnumber to baseYou can see below for example the Ukranian,
hyrvniahas a fractional unit ofkopeckand thenumber to baseis 100Similarly, the
USDis thecentand thenumber to baseis 100Others like the Uganda Shilling is 1:1 (base unit same as fractional unit)
Finally, for
BTCthe fractional unit is sat, and the number to base is 100000000I think this would be the best way to express pricing for 402 micropayment - in the fractional unit versus the base unit. A 1 cent per view versus $0.01 per view or 1 sat per view versus 0.000000000001BTC per view
You can peruse my currency table dump below for more examples.
There is no such thing in Cashu. Amounts are always integers of the specified unit
So, if "usd" can only specify whole dollars?
A single unit of "usd" represents a dollar cent. There are no floats in the Cashu protocol.
That's ok - if it's clarified in the spec. Currency is usually expressed as a main (base) unit and a fractional unit. I read the spec as the main unit, but it's actually the fractional unit. It wasn't apparent to me. Just wanting to reduce the potential confusion.
FWIW
From wikipedia
Each currency typically has a main currency unit (the dollar, for example, or the euro) and a fractional unit, often defined as 1⁄100 of the main unit: 100 cents = 1 dollar, 100 centimes = 1 franc, 100 pence = 1 pound, although units of 1⁄10 or 1⁄1000 occasionally also occur. Some currencies do not have any smaller units at all, such as the Icelandic króna and the Japanese yen.
I think this is out of scope for this NUT / PR. Cashu does not dictate anything about what "unit" can be. It can be a currency or something completely different. Also two mints can have key sets for different things that still share a name. The unit and "what it means" is only the mints responsibility and the spec can not specify anything about that.
implemented in athenut
github.com/thesimplekid/athenut-mint@723f8cd0c8Is P2PKOption defined anywhere?
Bump
Seems like this new nut is unnecessary with the change in #243 that makes the transport field optional. If the transport field in a payment request is undefined then the client can know to respond with payment in band.
This PR does define the x-cashu behavior which is useful, but I wonder if it deserves a new nut?
It helps to have the HTTP 402 process clearly spelled out in a NUT so that all servers and clients implementing it don't have to worry about 4+ different implementations ( which is usually what happens without clear instructions )
I don't know if it needs it own NUT, but it might make NUT-18 more crowded if it was merged into that
I think it is worth keeping this in a separate NUT, as it defines the header structure and protocol (both are clearly not part of NUT-18 scope).
Created an experimental blossom server using NUT-23 for payments https://github.com/hzrd149/morning-glory
Although its not running anywhere at the moment
I believe it comes from this pr: https://github.com/cashubtc/nuts/pull/243/files
We should change this to be a nut10 object like in https://github.com/cashubtc/nuts/pull/248
Would it make sense to mention using the
Authorizationheader with a bearer token as an alternative? or switching theX-Cashuheader to theAuthorizationfor client -> server requests?Routstr is using the
Authorizationheader https://docs.routstr.com/api-reference/introduction#authenticationThe biggest downside I can see to using the
Authorizationis that it would prevent clients or servers from using common authentication methods like JWT along side cashu payments. maybe they won't be used together at all but I think its worth consideringWhen I began this project here, I considered separating the Authorization header from the cashu token and came up with this solution. I introduced two distinct headers: X-PAYMENT-SATS for the payment and X-CHANGE-SATS for the change.
I'm considering whether we could use the X-Cashu header for both the payment and the change. Depending on the context, it could be interpreted as follows (if we decide on this approach, we should clarify it in the specification):
I will use this reference as a guide to implement for the client here
I use both headers simultaneously in npub.cash and I don't think
Authorizationis the right header for a payment. I don't see any benefit of switching from theX-Cashuheader.Lets rename this 24 and then I think its good to merge.
Renamed to NUT-24 👍
LGTM
LGTM