Skip to content

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. Keyset 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 the sat unit is generally preferred
  • sat: Bitcoin's Minor Unit (ie: 100,000,000 sat = 1 bitcoin)
  • msat: defined as 1/1000th of a sat (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 JPY
  • bhd (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_1>, 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>,
      "keys": {
        <amount_int>: <public_key_str>,
        ...
      }
    }
  ]
}

Example response

{
  "keysets": [
    {
      "id": "009a1f293253e41e",
      "unit": "sat",
      "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",
      "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)
          ...
      }
    }
  ]
}