mandatory
used in: NUT-08, NUT-15
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. Here, we describe both steps.
In the first request the wallet asks the mint for a quote for a request
it wants paid by the mint and the unit
the wallet would like to spend as inputs. The mint responds with a quote that includes a quote
id and an amount
the mint demands in the requested unit. For the method bolt11
, the mint includes a fee_reserve
field indicating the reserve fee for a Lightning payment.
In the second request, the wallet includes the quote
id and provides inputs
that sum up to amount+fee_reserve
in the first response. For the method bolt11
, the wallet can also include outputs
in order for the mint to return overpaid Lightning fees (see NUT-08). The mint responds with a payment state
. If the state
is "PAID"
the response includes a payment_preimage
as a proof of payment. If the request included outputs
, the mint may respond with change
for the overpaid fees (see NUT-08).
We limit this document to mint quotes of unit="sat"
and method="bolt11"
which requests a bolt11 Lightning payment (typically paid by the mint from its Bitcoin reserves) using ecash denominated in Satoshis.
To request a melt quote, the wallet of Alice
makes a POST /v1/melt/quote/{method}
request where method
is the payment method requested (here bolt11
).
POST https://mint.host:3338/v1/melt/quote/bolt11
The wallet Alice
includes the following PostMeltQuoteBolt11Request
data in its request:
{
"request": <str>,
"unit": <str_enum["sat"]>
}
Here, request
is the bolt11 Lightning invoice to be paid and unit
is the unit the wallet would like to pay with.
The mint Bob
then responds with a PostMeltQuoteBolt11Response
:
{
"quote": <str>,
"amount": <int>,
"fee_reserve": <int>,
"state": <str_enum[STATE]>,
"expiry": <int>,
"payment_preimage": <str|null>
}
Where quote
is the quote ID, amount
the amount that needs to be provided, and fee_reserve
the additional fee reserve that is required. The mint expects Alice
to include Proofs
of at least total_amount = amount + fee_reserve
. expiry
is the Unix timestamp until which the melt quote is valid. payment_preimage
is the bolt11 payment preimage in case of a successful payment.
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.
Request of Alice
with curl:
curl -X POST https://mint.host:3338/v1/melt/quote/bolt11 -d \
{
"request": "lnbc100n1p3kdrv5sp5lpdxzghe5j67q...",
"unit": "sat"
}
Response of Bob
:
{
"quote": "TRmjduhIsPxd...",
"amount": 10,
"fee_reserve": 2,
"state": "UNPAID",
"expiry": 1701704757
}
To check whether a melt quote has been paid, Alice
makes a GET /v1/melt/quote/bolt11/{quote_id}
.
GET https://mint.host:3338/v1/melt/quote/bolt11/{quote_id}
Like before, the mint Bob
responds with a PostMeltQuoteBolt11Response
.
Example request of Alice
with curl:
curl -X GET http://localhost:3338/v1/melt/quote/bolt11/TRmjduhIsPxd...
Now that Alice
knows what the total amount is (amount + fee_reserve
) in her requested unit
, she can proceed to melting tokens for which a payment will be executed by the mint. She calls the POST /v1/melt/{method}
endpoint where method
is the payment method requested (here bolt11
).
POST https://mint.host:3338/v1/melt/bolt11
The wallet of Alice
includes the following PostMeltBolt11Request
data in its request
{
"quote": <str>,
"inputs": <Array[Proof]>
}
Here, quote
is the melt quote ID to be paid and inputs
are the proofs with a total amount of at least amount + fee_reserve
(see previous melt quote response).
Like before, the mint Bob
then responds with a PostMeltQuoteBolt11Response
. If the payment was successful, the state
field is set to "PAID"
and the response includes the payment_preimage
field containing the payment secret of the bolt11 payment.
If state=="PAID"
, Alice
's wallet can delete the inputs
from her database (or move them to a history). If state=="UNPAID"
, Alice
can repeat the same request again until the payment is successful.
Request of Alice
with curl:
curl -X POST https://mint.host:3338/v1/melt/bolt11 -d \
'{
"quote": "od4CN5smMMS3K3QVHkbGGNCTxfcAIyIXeq8IrfhP",
"inputs": [
{
"amount": 4,
"id": "009a1f293253e41e",
"secret": "429700b812a58436be2629af8731a31a37fce54dbf8cbbe90b3f8553179d23f5",
"C": "03b01869f528337e161a6768b480fcf9f75fd248b649c382f5e352489fd84fd011",
},
{
"amount": 8,
"id": "009a1f293253e41e",
"secret": "4f3155acef6481108fcf354f6d06e504ce8b441e617d30c88924991298cdbcad",
"C": "0278ab1c1af35487a5ea903b693e96447b2034d0fd6bac529e753097743bf73ca9",
}
]
}'
Response PostMeltQuoteBolt11Response
of Bob
:
{
"quote": "TRmjduhIsPxd...",
"amount": 10,
"fee_reserve": 2,
"state": "PAID",
"expiry": 1701704757,
"payment_preimage": "c5a1ae1f639e1f4a3872e81500fd028bece7bedc1152f740cba5c3417b748c1b"
}
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) which in this case reads
{
"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>
}
min_amount
and max_amount
indicate the minimum and maximum amount for an operation of this method-unit pair.
Example MeltMethodSetting
:
{
"method": "bolt11",
"unit": "sat",
"min_amount": 100,
"max_amount": 10000
}