Skip to content

NUT-05: Melting tokens

mandatory

used in: NUT-08, NUT-15, NUT-23


Melting tokens is the opposite of minting tokens (see NUT-04). Like minting tokens, melting is a two-step process: requesting a melt quote and melting tokens. This document describes the general flow that applies to all payment methods, with specifics for each supported payment method provided in dedicated method-specific 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 melting process follows these steps for all payment methods:

  1. The wallet requests a melt quote for a request it wants paid by the mint, specifying the payment method and the unit the wallet would like to spend
  2. The mint responds with a quote that includes a quote id and an amount demanded in the requested unit
  3. The wallet sends a melting request including the quote id and provides inputs of the required amount
  4. The mint executes the payment and responds with the payment state and any method-specific proof of payment

Common Request and Response Formats

Requesting a Melt Quote

To request a melt quote, the wallet of Alice makes a POST /v1/melt/quote/{method} request where method is the payment method requested (e.g., bolt11, bolt12, etc.).

POST https://mint.host:3338/v1/melt/quote/{method}

Depending on the payment method, the request structure may vary, but all methods will include at minimum:

{
  "request": <str>,
  "unit": <str_enum[UNIT]>
  // Additional method-specific fields will be required
}

The mint Bob responds with a quote that includes some common fields for all methods:

{
  "quote": <str>,
  "amount": <int>,
  "unit": <str_enum[UNIT]>,
  "state": <str_enum[STATE]>,
  "expiry": <int>
  // Additional method-specific fields will be included
}

Where quote is the quote ID, amount and unit the amount and unit that need to be provided, and expiry is the Unix timestamp until which the melt quote is valid.

state is an enum string field with possible values "UNPAID", "PENDING", "PAID":

  • "UNPAID" means that the request has not been paid yet.
  • "PENDING" means that the request is currently being paid.
  • "PAID" means that the request has been paid successfully.

Check Melt Quote State

To check whether a melt quote has been paid, the wallet makes a GET /v1/melt/quote/{method}/{quote_id}.

GET https://mint.host:3338/v1/melt/quote/{method}/{quote_id}

The mint responds with the same structure as the initial quote response.

Executing a Melt Quote

To execute the melting process, the wallet calls the POST /v1/melt/{method} endpoint.

POST https://mint.host:3338/v1/melt/{method}

[!IMPORTANT] For methods that involve external payments (like Lightning), this call may block until the payment either succeeds or fails. This can take a long time. Make sure to use no (or a very long) timeout when making this call!

The wallet includes the following common data in its request:

{
  "quote": <str>,
  "inputs": <Array[Proof]>
  // Additional method-specific fields may be required
}

where quote is the melt quote ID and inputs are the proofs with a total amount sufficient to cover the requested amount plus any fees.

The mint responds with a structure that indicates the payment state and includes any method-specific proof of payment when successful.

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 melt execution
  3. Update the settings to include the new method
  4. Document any method-specific fields or behaviors that differ from the general flow

Settings

The mint's settings for this NUT indicate the supported method-unit pairs for melting. They are part of the info response of the mint (NUT-06):

{
  "5": {
    "methods": [
      <MeltMethodSetting>,
      ...
    ],
    "disabled": <bool>
  }
}

MeltMethodSetting indicates supported method and unit pairs and additional settings of the mint. disabled indicates whether melting is disabled.

MeltMethodSetting 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.