Skip to content

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:

  1. The wallet requests a mint quote for the unit to mint, specifying the payment method.
  2. The mint responds with a quote that includes a quote id and a payment request.
  3. The user pays the request using the specified payment method.
  4. The wallet then requests minting of new tokens with the mint, including the quote id and new outputs.
  5. 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 the quote 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:

  1. Define the method-specific request and response structures following the pattern above
  2. Implement the three required endpoints: quote request, quote check, and mint execution
  3. 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.