-
Notifications
You must be signed in to change notification settings - Fork 81
Align NUT-04 mint quote accounting with amount_paid / amount_issued #377
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?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||
|---|---|---|---|---|
|
|
@@ -52,19 +52,47 @@ The mint `Bob` responds with a quote that includes some common fields for all me | |||
| "quote": <str>, // UUID v7 | ||||
| "request": <str>, | ||||
| "unit": <str_enum[UNIT]>, | ||||
| "amount_paid": <int>, | ||||
| "amount_issued": <int>, | ||||
| "updated_at": <int>, | ||||
| "state": <str_enum[STATE]>, // Deprecated, optional | ||||
| // Additional method-specific fields will be included | ||||
| } | ||||
| ``` | ||||
|
|
||||
| Where `quote` is the quote ID string in UUID v7 format, `request` is the payment request for the quote, and `unit` corresponds to the value provided in the request. | ||||
| Where: | ||||
|
|
||||
| - `quote` is the quote ID in UUID v7 format | ||||
| - `request` is the payment request for the quote | ||||
| - `unit` corresponds to the value provided in the request | ||||
| - `amount_paid` is the total amount that has been paid to the mint for this quote and is eligible for minting, denominated in `unit` | ||||
| - `amount_issued` is the total amount of ecash that has been issued for this quote, denominated in `unit` | ||||
| - `updated_at` is a Unix timestamp integer indicating when the quote was last updated | ||||
| - `state` is a deprecated compatibility field | ||||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||
|
|
||||
| Mints **MUST** include `amount_paid`, `amount_issued`, and `updated_at` in all mint quote responses. `amount_paid` and `amount_issued` **MUST** be non-negative integers, and `amount_issued` **MUST NOT** exceed `amount_paid`. | ||||
|
|
||||
| The amount currently mintable for a quote is `amount_paid - amount_issued`. Mints **MUST NOT** issue ecash whose total output amount exceeds `amount_paid - amount_issued`. If a wallet mints less than the currently mintable amount, `amount_issued` only increases by the amount that was issued. | ||||
|
|
||||
| `amount_paid` and `amount_issued` are the canonical way to track the state of a mint quote. The deprecated `state` field **SHOULD** be included for single-use quotes for compatibility with older clients. Wallets **SHOULD** use `amount_paid` and `amount_issued` instead of `state` whenever these fields are present. | ||||
|
|
||||
| For single-use quotes, the deprecated finite `state` can be derived from `amount_paid` and `amount_issued`: | ||||
|
|
||||
| - `"UNPAID"` if `amount_paid == 0` and `amount_issued == 0` | ||||
| - `"PAID"` if `amount_paid > amount_issued` | ||||
| - `"ISSUED"` if `amount_paid == amount_issued` and `amount_issued > 0` | ||||
|
|
||||
| For reusable quotes, no finite `state` can fully represent whether the quote may receive future payments. Wallets **MUST** use `amount_paid` and `amount_issued` to determine the currently mintable amount. | ||||
|
Comment on lines
+76
to
+85
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Nut23 specefic |
||||
|
|
||||
| Mints **MUST** update `updated_at` whenever `amount_paid` or `amount_issued` changes. Mints **SHOULD** ensure that `updated_at` monotonically increases for each quote, even if multiple updates occur within the same timestamp resolution. Wallets that receive multiple responses for the same quote **MUST NOT** replace locally stored quote data with a response whose `updated_at` is lower than the latest processed value for that quote. Wallets **MUST NOT** decrease locally stored `amount_paid` or `amount_issued` values based on stale responses. | ||||
This comment was marked as resolved.
Sorry, something went wrong.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. TBH I am not sure how to handle this properly. This document is now written in a way that makes
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. On reflection you are right. Handling out of spec older mints is not the protocol's concern. Ignore my suggestion - leave it as it was. |
||||
|
|
||||
| > [!CAUTION] | ||||
| > | ||||
| > `quote` is a **unique and random** id generated by the mint to internally look up the payment state. `quote` **SHOULD** be UUID v7 with all 74 variable bits generated by a CSPRNG and **MUST** remain a secret between user and mint and **MUST NOT** be derivable from the payment request. A third party who knows the `quote` ID can front-run and steal the tokens that this operation mints. To prevent this, use [NUT-20][20] locks to enforce public key authentication during minting. | ||||
|
|
||||
| ### Check Mint Quote State | ||||
| ### Check Mint Quote | ||||
|
|
||||
| To check whether a mint quote has been paid, the wallet makes a `GET /v1/mint/quote/{method}/{quote_id}`. | ||||
| To check the current accounting state of a mint quote, the wallet makes a `GET /v1/mint/quote/{method}/{quote_id}`. | ||||
|
|
||||
| ```http | ||||
| GET https://mint.host:3338/v1/mint/quote/{method}/{quote_id} | ||||
|
|
@@ -89,7 +117,7 @@ The wallet includes the following common data in its request: | |||
| } | ||||
| ``` | ||||
|
|
||||
| with the `quote` being the quote ID from the previous step and `outputs` being `BlindedMessages` (see [NUT-00][00]) that the wallet requests signatures on, whose sum is `amount` as requested in the quote. | ||||
| with the `quote` being the quote ID from the previous step and `outputs` being `BlindedMessages` (see [NUT-00][00]) that the wallet requests signatures on. The total output amount **MUST NOT** exceed the quote's currently mintable amount, `amount_paid - amount_issued`. | ||||
|
|
||||
| The mint then responds with: | ||||
|
|
||||
|
|
@@ -146,18 +174,7 @@ The settings for this NUT indicate the supported method-unit pairs for minting. | |||
| Upon receiving the `BlindSignatures` from the mint, the wallet unblinds them to generate `Proofs` (using the blinding factor `r` and the mint's public key `K`, see BDHKE [NUT-00][00]). The wallet then stores these `Proofs` in its database. | ||||
|
|
||||
| [00]: 00.md | ||||
| [01]: 01.md | ||||
| [02]: 02.md | ||||
| [03]: 03.md | ||||
| [04]: 04.md | ||||
| [05]: 05.md | ||||
| [06]: 06.md | ||||
| [07]: 07.md | ||||
| [08]: 08.md | ||||
| [09]: 09.md | ||||
| [10]: 10.md | ||||
| [11]: 11.md | ||||
| [12]: 12.md | ||||
| [20]: 20.md | ||||
| [23]: 23.md | ||||
| [25]: 25.md | ||||
|
|
||||
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.
State should not be in nut04 that is in nut 23 as it is bolt11 specefic.