NUT-01: Mint public key exchange
mandatory
This document outlines the exchange of the public keys of the
mint Bob with the wallet user Alice.
Alice uses the keys to unblind Bob’s
blind signatures (see NUT-00).
Description
Wallet user Alice receives public keys from mint
Bob via GET /v1/keys. The set of all
public keys for a set of amounts is called a keyset.
The mint responds only with its active keysets.
Keysets are active if the mint will sign outputs with
it. The mint will accept tokens from inactive keysets as inputs
but will not sign with them for new outputs. The
active keysets can change over time, for example due
to key rotation. A list of all keysets, active and inactive, can
be requested separately (see NUT-02).
Note that a mint can support multiple keysets at the same time
but will only respond with the active keysets on the endpoint
GET /v1/keys. A wallet can ask for the keys of a
specific (active or inactive) keyset via the endpoint
GET /v1/keys/{keyset_id} (see NUT-02).
Supported Currency Units
A mint may support any currency unit(s) they can mint (NUT-04) and melt (NUT-05), either directly or indirectly, including:
btc: Bitcoin (Minor Unit: 8) - though use of thesatunit is generally preferredsat: Bitcoin’s Minor Unit (ie:100,000,000 sat = 1 bitcoin)msat: defined as 1/1000th of asat(ie:1,000 msat = 1 sat)auth: reserved for Blind Authentication (see NUT-22).- ISO
4217 currency codes (eg:
usd,eur,gbp) - Stablecoin currency codes (eg:
usdt,usdc,eurc,gyen)
[!IMPORTANT] For Bitcoin, ISO 4217 currencies (and stablecoins pegged to those currencies), Keyset amount values MUST represent an amount in the Minor Unit of that currency. Where the Minor Unit of a currency is “
0”, amounts represent whole units. For example:
usd(Minor Unit: 2)<amount_1> = 1 cent (0.01 USD)jpy(Minor Unit: 0)<amount_1> = 1 JPYbhd(Minor Unit: 3)<amount_1> = 1 fils (0.001 BHD)btc(Minor Unit: 8)<amount_1> = 1 sat (0.00000001 BTC)eurc(Pegged to EUR, so Minor Unit: 2)<amount_1> = 1 cent (0.01 EURC)gyen(Pegged to JPY, so Minor Unit: 0)<amount_1> = 1 GYEN
Keyset generation
Keysets are generated by the mint. The mint is free to use any
key generation method they like. Each keyset is identified by its
keyset id which can be computed by anyone from its
public keys (see NUT-02).
Keys in Keysets are maps of the form
{<amount_1> : <mint_pubkey_1>, <amount_2> : <mint_pubkey_2>, ...}
for each <amount_i> of the amounts the mint
Bob supports and the corresponding public key
<mint_pubkey_i>, that is K_i (see
NUT-00). The mint MUST
use the compressed
Secp256k1 public key format to represent its public keys.
Example
Request of Alice:
GET https://mint.host:3338/v1/keys
With curl:
curl -X GET https://mint.host:3338/v1/keys
Response GetKeysResponse of Bob:
{
"keysets": [
{
"id": <keyset_id_hex_str>,
"unit": <currency_unit_str>,
"active": <bool>,
"input_fee_ppk": <int|null>,
"final_expiry": <unix_timestamp_int|null>,
"keys": {
<amount_int>: <public_key_str>,
...
}
}
]
}
Here, active indicates whether the mint will sign
new outputs with this keyset, and input_fee_ppk is
the fee in parts per thousand (ppk) per input spent from this
keyset (see NUT-02).
Example response
{
"keysets": [
{
"id": "009a1f293253e41e",
"unit": "sat",
"active": true,
"input_fee_ppk": 100,
"final_expiry": 1896187313,
"keys": {
"1": "02194603ffa36356f4a56b7df9371fc3192472351453ec7398b8da8117e7c3e104",
"2": "03b0f36d6d47ce14df8a7be9137712c42bcdd960b19dd02f1d4a9703b1f31d7513",
"4": "0366be6e026e42852498efb82014ca91e89da2e7a5bd3761bdad699fa2aec9fe09",
"8": "0253de5237f189606f29d8a690ea719f74d65f617bb1cb6fbea34f2bc4f930016d",
...
}
}
]
}
Note that for a keyset in an ISO 4217 currency, the key amounts represent values in the Minor Unit of that currency (keys truncated and comments added for clarity):
{
"keysets": [
{
"id": "00a2f293253e41f9",
"unit": "usd",
"active": true,
"input_fee_ppk": 100,
"final_expiry": 1896187313,
"keys": {
"1": "0229...e101", // 1 cent (0.01 USD)
"2": "03c0...7512", // 2 cents (0.02 USD)
"4": "0376...fe00", // 4 cents (0.04 USD)
"8": "0263...016e", // 8 cents (0.08 USD)
...
}
}
]
}