-
Notifications
You must be signed in to change notification settings - Fork 65
NUT-XX Batched Minting #323
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
base: main
Are you sure you want to change the base?
Conversation
This commit introduces a new specification, NUT-XX, for batched mint operations. It allows wallets to mint multiple proofs in a single transaction, improving efficiency.
- specify all quotes must share same payment method and currency - expand nut-20 signature section with detailed structure and validation - clarify signature array format and per-quote mapping - add signature message construction specification - document atomicity requirement for signature validation failures - add comprehensive mint responsibilities section - update dependencies to include nut-20
- add validation requirements for empty arrays and duplicate quotes - clarify batch quote status response format per payment method - change batch mint endpoint path to include /batch suffix - add comprehensive request validation section - add error codes table and structured error response format - restructure nut-20 signature support section for clarity - add atomic processing requirement to mint responsibilities - add implementation notes for batch size limits and bolt12 support - add note on spending conditions compatibility - expand error handling documentation with examples
|
This PR replaces #273 |
xx.md
Outdated
|
|
||
| ## 1. Checking Quote Status | ||
|
|
||
| Before minting, the wallet must verify that each mint quote has been paid. |
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.
I don't think this should be a must, a wallet could know the states of the quotes by ws update why must it check again?
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.
Should be SHOULD. I think its good to mention that this endpoint is not supposed to be a batch-check
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.
this endpoint is not supposed to be a batch-check
What do you mean? I thought the purpose was to ensure that a batch was ready to mint before attempting to mint it.
| Unknown quote: | ||
| ```json | ||
| { | ||
| "code": "UNKNOWN_QUOTE", | ||
| "detail": "Quote 'abc-123' does not exist", | ||
| "quote": "abc-123" | ||
| } | ||
| ``` | ||
|
|
||
| Quote not paid: | ||
| ```json | ||
| { | ||
| "code": "QUOTE_NOT_PAID", | ||
| "detail": "Quote 'xyz-789' is not in PAID state", | ||
| "quote": "xyz-789" | ||
| } | ||
| ``` |
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.
What if multiple quotes are unknown or unpaid? I think it maybe best to not extend out error response and leave it how it is defined in nut00 without a quote id and its up to the wallet to figure it out.
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.
My thinking was that debugging one failing quote ID from a batch of 100 could be a huge pain in the ass. Best effort error reporting could help in some cases. I can see an argument for improving the batch check endpoint for this purpose instead of attempting detailed error messages in the mint endpoint. If you think we shouldn't even try, you're gonna have to convince me.
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.
as discussed in the meeting, we should remove quote ID as a field but still allow quote IDs in the description for human consumption
| ``` | ||
| msg_to_sign = quote_id[i] || B_0 || B_1 || ... || B_(n-1) | ||
| ``` | ||
|
|
||
| Where: | ||
| - `quote_id[i]` is the UTF-8 encoded quote ID at index `i` | ||
| - `B_0 ... B_(n-1)` are **all blinded messages** from the `outputs` array (regardless of amount splitting) |
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.
I don't think we need to redefine it reference the existing nut.
We should add test vectors for this.
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.
Am I missing something here? I agree that there is no need to re-define it
xx.md
Outdated
| ### BOLT12 Support | ||
|
|
||
| **Partial minting support:** | ||
|
|
||
| Mints MAY support partial minting for BOLT12 quotes, where `amount_issued` can be less than `amount_paid`. This allows: | ||
| - **Multiple batch operations**: Same BOLT12 quote can be used in multiple mint requests | ||
| - **Incremental minting**: Each batch mint increments `amount_issued` by the minted amount | ||
| - **State tracking**: Quote remains in PAID state until `amount_issued >= amount_paid` | ||
|
|
||
| The mint tracks `amount_paid` and `amount_issued` separately for this purpose. |
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.
I think we can remove this as its defined in the bolt12 nut.
Co-authored-by: tsk <tsk@thesimplekid.com> Co-authored-by: lollerfirst <43107113+lollerfirst@users.noreply.github.com>
|
@lollerfirst as discussed in a recent meeting, the wallet can specify the outputs they want to mint so this precludes the possibility of partial success. Atomic batch mint transactions also massively reduce complexity around partial success. |
- wallet SHOULD verify paid quotes, not must - remove redundant requirements and unnecessary statements - deduplicate request validation and mint responsibilities - remove http status from error codes
| "quotes": [ "quote_id_1", "quote_id_2", … ], | ||
| "quote_amounts": [ 50, 50 ], | ||
| "outputs": [ BlindedMessage_1, BlindedMessage_2, … ], | ||
| "signatures": [signature_1, signature_2, ... ] |
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.
what if some mint quotes are not locked? maybe: for a quote_id_n that does not require a NUT-20 lock, the signature at the same index should be null.
callebtc
left a comment
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.
good PR but text still reads AI-sloppy, could probably be compressed to 50% dense human spec.
| - **All quotes MUST be from the same payment method** (indicated by `{method}` in the URL path). | ||
| - **All quotes MUST use the same currency unit**. | ||
| - **quote_amounts**: array of expected mint amounts per quote, in the same order as `quote`. | ||
| - REQUIRED for bolt12 batches; OPTIONAL for bolt11. |
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.
optional quote_amounts and signatures should be annotated in the JSON itself
| { | ||
| "quotes": [ "quote_id_1", "quote_id_2", … ], | ||
| "quote_amounts": [ 50, 50 ], | ||
| "outputs": [ BlindedMessage_1, BlindedMessage_2, … ], | ||
| "signatures": [signature_1, signature_2, ... ] |
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.
should use the same JSON annotation format that we use in other specs
| - For bolt11, each entry MUST equal the quoted amount. For bolt12, each entry MUST NOT exceed the quote's remaining mintable amount. In all cases, the sum of `quote_amounts` MUST equal the sum of `outputs`. | ||
| - **outputs**: an array of blinded messages (see [NUT-00][00]). | ||
| - The total value represented by all blinded messages must equal the sum of all quote amounts. | ||
| - **signatures**: array of signatures for NUT-20 locked quotes. See [NUT-20 Support][nut-20-support] |
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.
optional
| - Array MUST NOT be empty | ||
| - All quote IDs MUST be unique (no duplicates) | ||
| - **All quotes MUST be from the same payment method** (indicated by `{method}` in the URL path). | ||
| - **All quotes MUST use the same currency unit**. |
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.
redundant here, there's a validation section below
| 4. **Payment method consistency**: All quotes MUST have the same payment method, matching `{method}` in the URL path | ||
| 5. **Currency unit consistency**: All quotes MUST use the same currency unit | ||
| 6. **Quote state**: All quotes MUST be in PAID state (or have mintable amount for BOLT12) | ||
| 7. **Amount balance**: The sum of output amounts MUST equal the sum of `quote_amounts` (bolt11) or MUST NOT exceed it (bolt12) |
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.
amounts should probably be ignored for bolt11?
| | Signature on unlocked quote | `UNEXPECTED_SIGNATURE` | | ||
| | Missing required signature | `SIGNATURE_MISSING` | | ||
|
|
||
| ### Error Response Format |
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.
this seems too excessive, would remove and use a simpler approach
| ### Signature Structure | ||
|
|
||
| **Array structure:** | ||
| - The `signature` field is an array with length equal to `quote.length` (one entry per quote) |
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.
it's called signatures (plural) above
|
|
||
| **Per-quote signatures:** | ||
| - **Locked quotes** (with `pubkey`): `signature[i]` contains the signature string | ||
| - **Unlocked quotes**: `signature[i]` is `null` |
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.
I suggested null above too, should be defined above.
|
|
||
| **Array structure:** | ||
| - The `signature` field is an array with length equal to `quote.length` (one entry per quote) | ||
| - `signature[i]` corresponds to `quote[i]` |
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.
quotes[i]
| - Total: 225 sats across 3 outputs | ||
| - Both signatures cover all 3 outputs to prevent output tampering | ||
|
|
||
| ## Mint Responsibilities |
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.
this section is not needed. atomicity should be mentioned very briefly in the first paragraph.
This document specifies NUT-XX: Batched Mint for the Cashu ecash protocol. It defines how wallets can mint multiple ecash proofs in a single atomic operation instead of individual requests.
Key components:
The spec emphasizes atomic processing (all-or-nothing), detailed error reporting, and interoperability with existing Cashu specs (NUT-04, NUT-20, NUT-11, NUT-14, NUT-25).