Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 20 additions & 0 deletions 20.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,26 @@ with the requested `amount`,`unit`, and `description` according to [NUT-04][04].
>
> **Privacy:** To prevent the mint from being able to link multiple mint quotes, wallets **SHOULD** generate a unique public key for each mint quote request.

### Deterministic quote locking key derivation

Wallets can deterministically generate private keys for NUT-20 quote locking from their wallet seed.

The following BIP32 derivation path is used to derive the private key:

```
m/129373'/20'/0'/0'/{counter}
```

Where:

- `129373'` is the Cashu wallet derivation namespace.
- `20'` is the wallet derivation index for NUT-20 quote locking keys.
- `{counter}` is an incrementing, non-hardened BIP32 child index.

The wallet **SHOULD** use a new counter value for each mint quote request. The NUT-20 quote locking counter is independent from NUT-13 keyset counters and other wallet derivation counters.

The wallet uses the compressed secp256k1 public key derived from the private key as the quote `pubkey`. This allows a wallet to restore the private key needed to sign for unpaid or paid NUT-20 locked mint quotes during a recovery process.

The mint `Bob` then responds with a `PostMintQuoteBolt11Response`:

```json
Expand Down
22 changes: 22 additions & 0 deletions tests/20-test.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,27 @@
# NUT-20 Test Vectors

## Deterministic quote locking key derivation

Using [NUT-20](../20.md) quote locking key derivation, we derive values starting from the following BIP39 mnemonic:

```json
{
"mnemonic": "half depart obvious quality work element tank gorilla view sugar picture humble"
}
```

The public keys derived for the first five counters from `counter=0` to `counter=4` are:

```json
{
"m/129373'/20'/0'/0'/0": "03062837166e56114b59a4d1fd3a5a812bf7aadc1dde758428cf943d80acd41539",
"m/129373'/20'/0'/0'/1": "02b47d9d41725f5ce6f08c874835cef25376cb1e95f6cb073fef52ca8fd986cf15",
"m/129373'/20'/0'/0'/2": "029acbd3a46fd75bc05ba0226d0b4d909b2fb6e96c80544a094a1a3567737e44d3",
"m/129373'/20'/0'/0'/3": "0373e4a42fbe0a4e18aadb57cf500b655f2446b4071ee579121d2ed8905bcc49c2",
"m/129373'/20'/0'/0'/4": "02b8709bfce17c10f1864f5218844533ae60930d52089669b317d8b5f474eec071"
}
```

The following is a `PostMintBolt11Request` with a valid signature. Where the `pubkey` in the `PostMintQuoteBolt11Request` is `03d56ce4e446a85bbdaa547b4ec2b073d40ff802831352b8272b7dd7a4de5a7cac`.

```json
Expand Down
Loading