Skip to content

Latest commit

 

History

History
164 lines (124 loc) · 4.98 KB

02.md

File metadata and controls

164 lines (124 loc) · 4.98 KB

NUT-02: Keysets and keyset ID

mandatory


A keyset is a set of public keys that the mint Bob generates and shares with its users. It refers to the set of public keys that each correspond to the amount values that the mint supports (e.g. 1, 2, 4, 8, ...) respectively.

Each keyset additionally indicates its keyset id, the currency unit, and whether the keyset is active or not.

Multiple keysets

Active keysets

Mints can have multiple keysets at the same time but MUST have at least one active keyset (see NUT-01). Proofs from inactive keysets are still accepted but new outputs (BlindedMessages and BlindSignatures) MUST be redeemed from active keysets only.

Currency unit

Mints MUST generate a keysets for each unit they support.

Wallet input and output construction

Wallets SHOULD store keysets the first time they encounter them along with the URL of the mint they are from. That way, wallets can choose Proofs of all keysets of a mint from their database when selecting inputs for an operation. Wallets SHOULD spend Proofs of inactive keysets first. When constructing outputs for an operation, wallets MUST choose only active keysets (see NUT-00).

Example

A wallet can ask the mint for a list of all keyset IDs via the GET /v1/keysets endpoint.

Request of Alice:

GET https://mint.host:3338/v1/keysets

With curl:

curl -X GET https://mint.host:3338/v1/keysets

Response GetKeysetsResponse of Bob:

{
  "keysets": [
    {
      "id": <keyset_id_hex_str>,
      "unit": <currency_unit_str>,
      "active": <bool>
    },
    ...
  ]
}

Example response

{
  "keysets": [
    {
      "id": "009a1f293253e41e",
      "unit": "sat",
      "active": True
    },
    {
      "id": "0042ade98b2a370a",
      "unit": "sat",
      "active": False
    },
    {
      "id": "00c074b96c7e2b0e",
      "unit": "usd",
      "active": True
    }    
  ]
}

Wallet implementation notes

Wallets can request the list of keyset IDs from the mint upon startup and load only tokens from its database that have a keyset ID supported by the mint it interacts with. This also helps wallets to determine whether the mint has rotated to a new current keyset (i.e. added new active keysets and inactivated old ones) and whether the wallet should recycle all tokens from inactive keysets to currently active ones.

Keyset ID

A keyset id is an identifier for a specific keyset. It can be derived by anyone who knows the set of public keys of a mint. Wallets CAN compute the keyset id for a given keyset by themselves to confirm that the mint is supplying the correct keyset ID.

The keyset id is in each Proof so it can be used by wallets to identify which mint and keyset it was generated from. The keyset id is also stored in BlindedMessages sent to the mint and BlindSignatures returned from the mint (see NUT-00).

Keyset ID version

Keyset IDs have a version byte (two hexadecimal characters). The currently used version byte is 00.

Deriving the keyset ID

The mint and the wallets of its users can derive a keyset ID from the keyset of the mint. The keyset ID is a lower-case hex string. To derive the keyset ID of a keyset, execute the following steps:

1 - sort public keys by their amount in ascending order
2 - concatenate all public keys to one byte array
3 - HASH_SHA256 the concatenated public keys
4 - take the first 14 characters of the hex-encoded hash
5 - prefix it with a keyset ID version byte

An example implementation in Python:

def derive_keyset_id(keys: Dict[int, PublicKey]) -> str:
    sorted_keys = dict(sorted(keys.items()))
    pubkeys_concat = b"".join([p.serialize() for p in sorted_keys.values()])
    return "00" + hashlib.sha256(pubkeys_concat).hexdigest()[:14]

Requesting public keys for a specific keyset

To receive the public keys of a specific keyset, a wallet can call the GET /v1/keys/{keyset_id} endpoint where keyset_id is the keyset ID.

Example

Request of Alice:

We request the keys for the keyset 009a1f293253e41e.

GET https://mint.host:3338/v1/keys/009a1f293253e41e

With curl:

curl -X GET https://mint.host:3338/v1/keys/009a1f293253e41e

Response of Bob (same as NUT-01):

{
  "keysets": [{
    "id": "009a1f293253e41e",
    "unit": "sat",
    "keys": {
        "1": "02194603ffa36356f4a56b7df9371fc3192472351453ec7398b8da8117e7c3e104",
        "2": "03b0f36d6d47ce14df8a7be9137712c42bcdd960b19dd02f1d4a9703b1f31d7513",
        "4": "0366be6e026e42852498efb82014ca91e89da2e7a5bd3761bdad699fa2aec9fe09",
        "8": "0253de5237f189606f29d8a690ea719f74d65f617bb1cb6fbea34f2bc4f930016d",
        ...
    }
  }, ...
  ]
}