New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Cashu v1
– The Great Cleanup
#55
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A few overall comments:
- The PR description states that the new v1 routes are to be used and the old ones are deprecated. Not sure how to handle that elegantly in the NUTs. Should examples for both be given? Or all examples be migrated to the v1? If so, most of those are not yet updated.
- Breaking changes means we should update the test vectors
- How should tokens handle v1? Are there corner cases there that could create issues? What if you bundle a token with a ton of inputs, some v1 and some not? Haven't thought about this deeply, just writing down thoughts as they come to mind...
Overall some great improvements in there (also lots of new code to write for us! 😅). I suggest that if there is intention to eventually move forward with a solution to #54, it should be included here as part of this fairly wide-ranging set of breaking changes.
Great discussions over the dev call the other day. I figured I'd add a small todo list of things that might need to be addressed here before I forget. Note that not all of those might be required, and I'm going off of memory so hopefully not missing anything.
|
v1
API – The Great Cleanupv1
– The Great Cleanup
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ACK e59f284.
Major improvement of the protocol. I'm happy to see that we have a few implementations that were able to put this into code already, and looking forward to seeing what gets built on top of this. 🚀
One little thing: the test vectors should be updated (if not in this PR in a very close follow-up PR). |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good to me. Agree with tb that it would be best to include test vectors as it helps to ensure implementations are correct.
ACK e59f284
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ACK e1568fd
This is a great improvement of the cashu protocol.
The Great Cleanup
This is a PR that encapsulates a collection of changes to the protocol that will make our lives easier in the future. It cleans up early mistakes that were made as the protocol grew organically and removes implicit assumptions about the funding sources (e.g. Lightning) and currency units (e.g. "sats") used for Cashu mints that are inherent in the current protocol.
New
v1
APIWe are introducing the
v1
API where we clean up many input and output models.Click to show new endpoints
New endpoints
GET /v1/keys
andGET /v1/keys/{keyset_id}
(newKeyset
model)GET /v1/keysets
(newKeysets
model)POST /v1/swap
(newBlindedMessage
model)POST /v1/melt/quote/bolt11
(replacesGET /checkfees
)POST /v1/melt/bolt11
POST /v1/mint/quote/bolt11
(replacesGET /melt
)POST /v1/mint/bolt11
POST /v1/check
(no changes)GET /v1/info
(no changes)POST /v1/restore
(newGetInfoResponse
)Click to show error response
Error responses
Error responses of the mint are now defined as a HTTP 400 response with a JSON body
Click to show deprecated endpoints
Deprecated endpoints
GET /keys
,GET /keys/{keyset_id}
GET /keysets
POST /split
GET /mint
POST /mint
GET /checkfees
POST /melt
POST /check
GET /info
POST /restore
NUTs
GET /checkfees
endpoint (formerly NUT-03) is now retiredPOST /v1/swap
endpoint is now in NUT-03 (formerlyPOST /split
NUT-06).New request and response models
Click to show all changed models
NUT-01
GetKeysResponse
NUT-02
GetKeysetsResponse
NUT-03
PostSwapRequest
PostSwapResponse
NUT-04
PostMintQuoteBolt11Request
PostMintQuoteBolt11Response
PostMintBolt11Request
PostMintBolt11Response
NUT-05
PostMeltQuoteBolt11Request
PostMeltQuoteBolt11Response
PostMeltBolt11Request
PostMeltBolt11Response
Quotes
We are also introducing
quotes
, a general way to register a mint and melt transaction with the mint that will work across different payment methods (bolt11, bolt12, on-chain, ...) and different currency units (sat, msat, usd, ...). Quotes add the ability for Lightning backends to decide the amount and currency of the ecash they need in order to receive or pay a Lightning payment. The flow remains very similar to before and will be illustrated with two examples in the following.Mint Quotes
To mint ecash (output) via Lightning (input), the wallet first requests a
MintQuote
for a given amount of sats the wallet wants to mint. TheMintQuote
has anquote
id and includes a Lightning invoice. The user pays the Lightning invoice and then calls/v1/mint
referencing the previousquote
it corresponds to.Melt Quotes
To melt ecash (input) and make a Lightning payment (output), the wallet requests a
MeltQuote
for a given Lightning invoice it likes to pay. In theMeltQuote
, the mint tells the wallet how many sats it needs to supply and what the fee reserve is in order for the mint to fulfill this request.Diagram
Hexadecimal keyset IDs
Our keyset IDs are ugly and need special treatment for HTTP (base64 urlsafe). We switch to hexadecimal keyset IDs that are generated much like the previous ones. We also add a version byte as a prefix.
An example implementation in Python:
BlindedMessage
now has keysetid
fieldOutputs (
BlindedMessages
), now also have a keysetid
field, likeProofs
(inputs) andBlindSignatures
do. With theid
, the wallet tells the mint which keyset the client is expecting a signature from during a/v1/swap
(created outputs),/v1/melt
(change outputs), or/v1/mint
(minted outputs). The requestedid
MUST be from anactive
keyset (part of the/v1/keys
response and the/v1/keysets
response). If the wallet uses anid
that is not existent or not active (rotated-out of), the mint MUST refuse the transaction.The
BlindedMessage
becomesClick to show additional remarks
Additional remarks
Adding an
id
fixes a race condition we previously created workarounds for (see cashubtc/cashu-ts#64 for example). Essentially, the mint's keys could have rotated between the wallet sending the outputs to sign to the mint, and the mint responding with a signature. We can now get rid of this code by making it part of the protocol.Another critical issue that results from the same race condition is deterministic secret derivation: If a wallet deterministically derives secrets for keyset A, sends
BlindedMessages
to the mint and the mint rotated keys in the mean time, it would respond withBlindedSignatures
keyset B. That means the wallet has incremented its deterministic secret derivation counter on the wrong keyset ID.Standardized secrets
Wallets should use standardized secrets (32 bytes of randomness) in lowercase hex. Closes #54