Cashu NUTs — Complete Protocol Reference
- Cashu NUTs — Notation, Utilization, Terminology
Cashu NUTs — Notation, Utilization, Terminology
Cashu’s protocol specifications. Equivalent to NIPs in Nostr and BOLTs in Lightning.
NUT Index
| NUT | Title | Status | Description |
|---|---|---|---|
| 00 | Base | mandatory |
Notation, data types, API endpoint model, HTTP/REST basics |
| 01 | Mint Keyset | mandatory |
Keyset format, rotation, active keys |
| 02 | Keysets | mandatory |
Multiple keyset support, keyset ID derivation |
| 03 | Swap | mandatory |
Token minting and melting (atomic swaps between ecash and BTC) |
| 04 | Mint Quotes | mandatory |
Quote-mint protocol. Bolt11 invoice generation for minting new tokens |
| 05 | Melting | mandatory |
Token destruction for receiving BTC (Lightning or on-chain) |
| 06 | Mint Info | mandatory |
Mint metadata: name, pubkey, version, contact, supported NUTs |
| 07 | Spending Conditions | optional |
P2PK (Pay to Public Key), HTLCs, timelocks on tokens |
| 08 | Overpaid Fees | optional |
Handling overpaid Lightning fees in melt operations |
| 09 | Signatures | mandatory |
Nostr-style Schnorr signatures on messages |
| 10 | Spending | mandatory |
Token transfer and verification protocol |
| 11 | P2PK | optional |
Pay-to-Public-Key locked ecash tokens. Requires signature to spend |
| 12 | Offline Ecash | optional |
Offline token verification without contacting the mint |
| 13 | Nostr | optional |
Nostr integration for Cashu: publishing tokens, DM transfers |
| 14 | Hashtag Attestations | optional |
Tag-based attestations for tokens |
| 15 | Multinut | optional |
Multiple token types in a single transaction |
| 17 | Mints DB | optional |
Mint discovery and rating database |
NUT-00: Base
Root specification. Defines:
- Data models:
Proof,Proofs,BlindedMessage,BlindedSignature - REST API: JSON over HTTP POST
- Endpoints: all mints expose a standard API
- Error format:
{"detail": "error message", "code": 10000}
NUT-03: Swap (Mint/Melt)
The core operation. Two directions:
Mint (BTC → Ecash)
1. Client requests a quote: POST /v1/mint/quote/bolt11
2. Mint returns: {"quote": "...", "request": "lnbc...", "expiry": 3600}
3. Client pays the Lightning invoice
4. Client sends blinded messages: POST /v1/mint/bolt11
5. Mint returns blind signatures
6. Client unblinds → ecash tokens
Melt (Ecash → BTC)
1. Client requests melt quote: POST /v1/melt/quote/bolt11
2. Mint returns quote with fee reserve
3. Client sends proofs (ecash tokens): POST /v1/melt/bolt11
4. Mint verifies proofs, checks double-spend list
5. Mint pays the requested Lightning invoice
NUT-07: Spending Conditions
P2PK
Token locked to a pubkey:
Secret = <data> + <pubkey>
Redeem requires signature from pubkey's private key
HTLC
Token with hash-lock and time-lock:
Secret = <data> + <pubkey> + <hash> + <timelock>
Can redeem: reveal preimage matching hash
Can refund: wait until timelock, sign with pubkey
Enables trustless atomic swaps between parties or mints.
NUT-10: Spending Protocol
When Alice sends ecash to Carol:
- Alice sends
(amount, B_, C_)tuples to Carol (blinded) - Carol contacts the mint to verify tokens are valid/unspent
- Carol unbinds (if needed) and claims ownership
Key: the mint validates but can’t link the token to Alice.
NUT-11: P2PK (Payment to Pubkey)
{
"secret": "<random-data>|<recipient-pubkey>",
"amount": 16,
"C": "<ecash-signature>"
}
To spend, recipient must:
- Sign a message with their private key
- Present the signature along with the token
- Mint verifies the signature matches the recipient pubkey in the secret
Like “endorsed ecash” — adds a second factor to ownership.
NUT-13: Nostr Integration
How Cashu tokens move on Nostr:
Token Publication (Kind 7375)
{
"kind": 7375,
"content": "<encrypted token data>",
"tags": [
["mint", "https://mint.minibits.cash"],
["amount", "16"],
["unit", "sat"]
]
}
Token Transfer via DMs
Tokens sent as encrypted NIP-17 DMs with Cashu data in the content.
Nutzaps (NIP-61, Kind 9321)
Zap-like ecash payments. Token delivery via Nostr events instead of Lightning invoices.
API Structure
All mints expose:
POST /v1/info — NUT-06: Mint metadata
POST /v1/keys — NUT-01: Current keyset
POST /v1/keysets — NUT-02: All keysets
POST /v1/mint/quote/bolt11 — NUT-04: Request mint quote
POST /v1/mint/bolt11 — NUT-03: Mint tokens after payment
POST /v1/melt/quote/bolt11 — NUT-05: Request melt quote
POST /v1/melt/bolt11 — NUT-03: Melt tokens for BTC
POST /v1/checkstate — NUT-07: Check if tokens are spent
POST /v1/swap — NUT-03: Direct swap (no Lightning)
POST /v1/restore — Restore from seed
Keysets & Rotation
- Each keyset is identified by
keyset_id = hash(keys) - Mints rotate keysets periodically (e.g., every month)
- Old keysets stay valid for redemption, not for new mints
- Input descriptors: specify which keyset to use
- Clients track active keysets via
/v1/keysand/v1/keysets
Error Codes
| Code | Meaning |
|---|---|
| 10000 | Generic / custom error |
| 11000 | Quote not found |
| 11001 | Quote expired |
| 11002 | Quote already issued |
| 11003 | Invoice not paid |
| 12000 | Proof already spent |
| 12001 | Transaction unbalanced |
| 12002 | Token not supported |
| 12003 | Keyset not active |
| 12004 | Amount out of range |
Write a comment