NUT-04: Mint tokens¶
mandatory
used in: NUT-20, NUT-23
Minting tokens is a two-step process: requesting a mint quote and minting new tokens. This document describes the general flow that applies to all payment methods, with specifics for each supported payment method provided in dedicated NUTs.
Supported methods¶
Method-specific NUTs describe how to handle different payment methods. The currently specified models are:
- NUT-23 for bolt11 Lightning invoices
General Flow¶
The minting process follows these steps for all payment methods:
- The wallet requests a mint quote for the
unit
to mint, specifying the paymentmethod
. - The mint responds with a quote that includes a
quote
id and a paymentrequest
. - The user pays the
request
using the specified payment method. - The wallet then requests minting of new tokens with the mint, including the
quote
id and newoutputs
. - The mint verifies payment and returns blind signatures.
Common Request and Response Formats¶
Requesting a Mint Quote¶
To request a mint quote, the wallet of Alice
makes a POST /v1/mint/quote/{method}
request where method
is the payment method requested (e.g., bolt11
, bolt12
, etc.).
POST https://mint.host:3338/v1/mint/quote/{method}
Depending on the payment method, the request structure may vary, but all methods will include at minimum:
{
"unit": <str_enum[UNIT]>
// Additional method-specific fields may be required
}
The mint Bob
responds with a quote that includes some common fields for all methods:
{
"quote": <str>,
"request": <str>,
"unit": <str_enum[UNIT]>,
// Additional method-specific fields will be included
}
Where quote
is the quote ID, request
is the payment request for the quote, and unit
corresponds to the value provided in the request.
[!CAUTION]
quote
is a unique and random id generated by the mint to internally look up the payment state.quote
MUST remain a secret between user and mint and MUST NOT be derivable from the payment request. A third party who knows thequote
ID can front-run and steal the tokens that this operation mints. To prevent this, use NUT-20 locks to enforce public key authentication during minting.
Check Mint Quote State¶
To check whether a mint quote has been paid, the wallet makes a GET /v1/mint/quote/{method}/{quote_id}
.
GET https://mint.host:3338/v1/mint/quote/{method}/{quote_id}
The mint responds with the same structure as the initial quote response.
Executing a Mint Quote¶
After requesting a mint quote and paying the request, the wallet proceeds with minting new tokens by calling the POST /v1/mint/{method}
endpoint.
POST https://mint.host:3338/v1/mint/{method}
The wallet includes the following common data in its request:
{
"quote": <str>,
"outputs": <Array[BlindedMessage]>
}
with the quote
being the quote ID from the previous step and outputs
being BlindedMessages
(see NUT-00) that the wallet requests signatures on, whose sum is amount
as requested in the quote.
The mint then responds with:
{
"signatures": <Array[BlindSignature]>
}
where signatures
is an array of blind signatures on the outputs.
Adding New Payment Methods¶
To add a new payment method (e.g., BOLT12), implement the following:
- Define the method-specific request and response structures following the pattern above
- Implement the three required endpoints: quote request, quote check, and mint execution
- Update the settings to include the new method
Settings¶
The settings for this NUT indicate the supported method-unit pairs for minting. They are part of the info response of the mint (NUT-06) which reads:
{
"4": {
"methods": [
<MintMethodSetting>,
...
],
"disabled": <bool>
}
}
MintMethodSetting
indicates supported method
and unit
pairs and additional settings of the mint. disabled
indicates whether minting is disabled.
MintMethodSetting
is of the form:
{
"method": <str>,
"unit": <str>,
"min_amount": <int|null>,
"max_amount": <int|null>,
"options": <Object|null>
}
min_amount
and max_amount
indicate the minimum and maximum amount for an operation of this method-unit pair. options
are method-specific and can be defined in method-specific NUTs.
Unblinding Signatures¶
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). The wallet then stores these Proofs
in its database.