Add Cashu ecash protocol and cashu-ts library skills

Added comprehensive Claude Code skills for working with the Cashu ecash protocol:

## Cashu Protocol Skill (.claude/skills/cashu/)
- Complete Cashu protocol documentation with BDHKE cryptography
- All NUT specifications (00-27) with detailed descriptions
- Core operations: minting, sending, receiving, melting
- Token formats (V3 JSON and V4 CBOR serialization)
- Security best practices and implementation patterns
- Reference documents for NUTs overview and common patterns

## cashu-ts Library Skill (.claude/skills/cashu-ts/)
- Comprehensive cashu-ts API documentation
- CashuWallet and CashuMint class usage
- Complete wallet operations with code examples
- Token encoding/decoding utilities
- Advanced features: P2PK, BOLT12, deterministic secrets
- TypeScript type definitions and patterns
- Multi-mint wallet implementation
- Backup and recovery strategies

## Reference Materials
- nuts-overview.md: Detailed NUT specifications (mandatory & optional)
- common-patterns.md: Implementation patterns, security, performance

These skills enable Claude to provide expert assistance with:
- Building Cashu wallets and mints
- Understanding blind signature cryptography
- Implementing privacy-preserving Bitcoin payments
- Working with Lightning Network integration
- Token management and serialization
- Wallet backup and recovery

Resources: cashu.space, docs.cashu.space, github.com/cashubtc
This commit is contained in:
Claude
2026-01-15 12:10:13 +00:00
parent 571e7a0d14
commit bcc90b8de5
6 changed files with 4053 additions and 0 deletions

View File

@@ -0,0 +1,96 @@
# cashu-ts Library Skill
Expert knowledge of cashu-ts, the official TypeScript/JavaScript library for building Cashu wallets and applications.
## What is cashu-ts?
cashu-ts is a JavaScript library for Cashu wallets written in TypeScript. It provides a complete implementation of the Cashu protocol with a clean, intuitive API for minting, sending, receiving, and melting ecash tokens.
## When to Use This Skill
Use this skill when you need help with:
- Building Cashu wallets (web, mobile, desktop)
- Implementing ecash operations in TypeScript/JavaScript
- Using the CashuWallet and CashuMint classes
- Encoding and decoding tokens
- Managing proofs and wallet state
- Integrating Lightning payments
- Implementing wallet backup and recovery
- Working with P2PK and spending conditions
## What This Skill Covers
### Core Classes
- **CashuWallet**: Main wallet interface for all operations
- **CashuMint**: HTTP client for mint API communication
- **WalletOps**: Builder pattern for complex transactions
### Wallet Operations
- **Minting**: Create quotes, check payment status, mint proofs
- **Sending**: Coin selection, amount splitting, token encoding
- **Receiving**: Token decoding, proof swapping for security
- **Melting**: Lightning invoice payment, fee handling, change management
- **State Checking**: Verify proof validity and spent status
### Token Management
- **Encoding**: V4 (CBOR) and V3 (JSON) token formats
- **Decoding**: Parse and validate token strings
- **Proof utilities**: Sum amounts, split by keyset, validate structure
- **Denomination handling**: Binary decomposition for efficiency
### Advanced Features
- **Deterministic Secrets**: BIP39-based wallet backup
- **Counter Management**: For wallet recovery (NUT-09, NUT-13)
- **P2PK Locking**: Lock tokens to specific public keys (NUT-11)
- **BOLT12 Support**: Lightning offers for reusable payments
- **Multi-mint**: Handle tokens from multiple mints
### TypeScript Types
Complete type definitions for all protocol data structures:
- `Proof`, `Token`, `MintKeys`, `BlindedMessage`
- `MintQuoteResponse`, `MeltQuoteResponse`, `SendResponse`
- `ProofState`, `MintInfo`, and more
## Installation
```bash
npm install @cashu/cashu-ts
```
## Quick Example
```typescript
import { CashuWallet, CashuMint } from '@cashu/cashu-ts';
// Create wallet
const wallet = new CashuWallet(new CashuMint('https://mint.example.com'));
await wallet.loadMint();
// Mint tokens
const quote = await wallet.createMintQuote(1000);
// ... user pays invoice ...
const { proofs } = await wallet.mintProofs(1000, quote.quote);
// Send tokens
const { send } = await wallet.send(100, proofs);
const token = getEncodedTokenV4({ token: [{ mint: mintUrl, proofs: send }] });
```
## Related Skills
- **cashu**: Core Cashu protocol and NUT specifications
- **react**: Building wallet UIs with React
- **nostr**: Nostr integration for wallet backups
## Resources
- **GitHub**: https://github.com/cashubtc/cashu-ts
- **Documentation**: https://cashubtc.github.io/cashu-ts/docs/
- **NPM Package**: https://www.npmjs.com/package/@cashu/cashu-ts
- **Examples**: Integration tests in GitHub repo

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,67 @@
# Cashu Protocol Skill
Expert knowledge of the Cashu ecash protocol, a free and open-source Chaumian ecash system built for Bitcoin.
## What is Cashu?
Cashu is an ecash protocol based on Blind Diffie-Hellman Key Exchange (BDHKE), enabling private, instant, and nearly free transactions over Bitcoin's Lightning Network. It uses blind signatures to preserve user privacy while maintaining Bitcoin backing through custodial mints.
## When to Use This Skill
Use this skill when you need help with:
- Understanding Cashu protocol fundamentals
- Implementing Cashu wallets or mints
- Working with blind signatures and BDHKE
- Learning about NUT (Notation, Usage, and Terminology) specifications
- Building privacy-preserving payment applications
- Integrating Lightning Network with ecash
- Token serialization and encoding
## What This Skill Covers
### Core Concepts
- **Blind Signatures**: How BDHKE enables privacy-preserving token issuance
- **Token Format**: Proofs, BlindedMessages, and BlindSignatures
- **Serialization**: V3 (JSON) and V4 (CBOR) token formats
- **Keysets**: How mints manage keys for different denominations
### Operations
- **Minting**: Deposit Bitcoin via Lightning, receive ecash
- **Sending**: Transfer ecash tokens between users
- **Receiving**: Accept ecash and swap for new secrets
- **Melting**: Withdraw Bitcoin by melting ecash
### NUT Specifications
- **Mandatory NUTs** (NUT-00 through NUT-06): Core protocol
- **Optional NUTs**: Extended features (P2PK, HTLC, DLEQ, etc.)
- Complete reference in `references/nuts-overview.md`
### Best Practices
- Wallet implementation patterns
- Security considerations
- Error handling
- Performance optimization
- Multi-mint support
## Reference Files
- **SKILL.md**: Complete protocol documentation
- **references/nuts-overview.md**: Detailed NUT specifications
- **references/common-patterns.md**: Implementation patterns and code examples
## Related Skills
- **cashu-ts**: TypeScript/JavaScript library for building Cashu applications
- **nostr**: Nostr protocol (for NUT-25 wallet backups)
## Resources
- **Official Website**: https://cashu.space
- **Documentation**: https://docs.cashu.space
- **NUTs Repository**: https://github.com/cashubtc/nuts
- **Protocol Spec**: https://docs.cashu.space/protocol

View File

@@ -0,0 +1,840 @@
---
name: cashu
description: This skill should be used when working with the Cashu ecash protocol, implementing Cashu wallets or mints, handling ecash tokens, or discussing Cashu NUT specifications. Provides comprehensive knowledge of Chaumian blind signatures, Bitcoin Lightning integration, and privacy-preserving digital cash.
---
# Cashu Protocol Expert
## Purpose
This skill provides expert-level assistance with the Cashu protocol, a free and open-source Chaumian ecash system built for Bitcoin. The protocol enables private, instant, and nearly free transactions using blind signatures over the Lightning Network.
## When to Use
Activate this skill when:
- Implementing Cashu wallets or mints
- Working with ecash tokens and blind signatures
- Handling minting and melting operations
- Implementing any Cashu NUT specification
- Building privacy-preserving payment applications
- Integrating Lightning Network with ecash
- Discussing cryptographic operations (BDHKE, blind signatures)
- Working with token serialization and encoding
## Core Concepts
### Protocol Foundation
Cashu is built on **Blind Diffie-Hellman Key Exchange (BDHKE)**, a variant of David Wagner's Chaumian blinding scheme. The protocol involves three parties:
1. **Alice (User)** - Holds secrets and creates blinded messages
2. **Bob (Mint)** - Issues blind signatures and manages private keys
3. **Carol (Recipient)** - Receives and verifies tokens
Key principles:
- Privacy through blind signatures (mint can't link tokens to users)
- Instant and final transactions (like physical cash)
- Bitcoin-backed via Lightning Network
- Custodial model (mint holds Bitcoin)
- Open protocol (anyone can run a mint)
### Ecash System Architecture
**Mint (Server):**
- Holds Bitcoin in custody
- Issues blind signatures for denominations
- Manages private keys per denomination
- Provides Lightning endpoints for deposits/withdrawals
- Cannot track token ownership or transaction history
**Wallet (Client):**
- Generates secrets and blinding factors
- Creates blinded messages for minting
- Unblinds signatures to create valid tokens
- Stores proofs (ecash tokens)
- Handles sending and receiving
- Melts tokens back to Lightning
### Cryptographic Operations (BDHKE)
#### Key Generation
```
Mint generates:
k = private key (scalar)
K = k·G = public key (point on secp256k1)
G = generator point
```
#### Blinding Protocol (5 Steps)
**1. Blinding (Alice → Bob)**
```
Alice generates:
x = secret (random 32 bytes)
r = blinding factor (random scalar)
Y = hash_to_curve(x)
B_ = Y + r·G (blinded message)
Alice sends B_ to Bob
```
**2. Signing (Bob → Alice)**
```
Bob computes:
C_ = k·B_ (blind signature)
Bob sends C_ to Alice
```
**3. Unblinding (Alice)**
```
Alice computes:
C = C_ - r·K = k·Y (unblinded signature)
Result: Proof = (x, C)
```
**4. Transfer (Alice → Carol)**
```
Alice sends proof (x, C) to Carol
Carol sends to Bob for verification
```
**5. Verification (Bob)**
```
Bob checks:
k·hash_to_curve(x) == C
x not in spent secrets database
If valid, Bob marks x as spent
```
#### Hash-to-Curve Function
Deterministic mapping from secret to curve point:
```
msg_hash = SHA256(DOMAIN_SEPARATOR || x)
DOMAIN_SEPARATOR = b"Secp256k1_HashToCurve_Cashu_"
counter = 0
loop:
candidate = SHA256(msg_hash || counter)
try:
Y = PublicKey('02' || candidate) // Compressed point
if valid: return Y
counter += 1
```
### Token Format
#### Proof Structure
A **Proof** is an unblinded signature representing value:
```json
{
"amount": 8, // Token denomination
"secret": "9a3b2c1d...", // 64-char hex (or UTF-8)
"C": "02ab3c4d5e...", // Unblinded signature (33-byte compressed point)
"id": "00ffd48b78a7b2f4" // Keyset ID (identifies mint's key)
}
```
**Proof Fields:**
- `amount`: Denomination in base unit (sats)
- `secret`: Random hex string (must be unique)
- `C`: secp256k1 point (hex-encoded compressed format)
- `id`: Keyset identifier (8-byte hex)
#### BlindedMessage Structure
Sent by wallet to request blind signature:
```json
{
"amount": 8,
"id": "00ffd48b78a7b2f4", // Keyset ID
"B_": "02c1a3b5d7..." // Blinded secret (33-byte point)
}
```
#### BlindSignature (Promise)
Returned by mint after blinding:
```json
{
"amount": 8,
"id": "00ffd48b78a7b2f4",
"C_": "03ab5c7d9e..." // Blinded signature
}
```
### Token Serialization
#### V4 Tokens (Current Standard)
Format: `cashuB[base64_urlsafe_cbor]`
**Structure (CBOR-encoded):**
```json
{
"t": [ // Token array
{
"m": "https://mint.host", // Mint URL
"u": "sat", // Unit (sat, usd, etc.)
"d": "Thanks!", // Optional memo
"t": [ // Token entries
{
"i": "00ffd48b", // Keyset ID (short form)
"p": [ // Proofs array
{
"a": 8, // Amount
"s": "9a3b2c...", // Secret
"c": "02ab3c..." // Signature
}
]
}
]
}
]
}
```
**Binary Encoding:**
```
"cashu" (UTF-8) + "B" + CBOR(token_object)
```
**Advantages:**
- Space-efficient (CBOR vs JSON)
- Abbreviated keys (single letters)
- Short keyset IDs (8 bytes instead of 16)
- Multi-mint support in single token
#### V3 Tokens (Deprecated)
Format: `cashuA[base64_urlsafe_json]`
JSON-based with full field names. Still readable but less efficient.
### Keysets and Denominations
**Keyset**: Set of public keys for different amounts
```json
{
"id": "00ffd48b78a7b2f4", // Keyset identifier
"unit": "sat", // Currency unit
"keys": {
"1": "02ab3c4d...", // Public key for 1 sat
"2": "03bc5d6e...", // Public key for 2 sats
"4": "02cd7e8f...", // Public key for 4 sats
"8": "03de9f0a...", // Public key for 8 sats
// ... powers of 2
}
}
```
**Why Powers of 2?**
- Any amount can be represented as sum of powers of 2
- Efficient coin selection
- Example: 13 sats = 8 + 4 + 1 (3 proofs)
**Keyset ID Derivation:**
```
id = SHA256(sorted_pubkeys_concatenated)[:16] // First 16 bytes (hex)
```
## Cashu NUTs (Specifications)
### Mandatory NUTs (Must Implement)
All wallets and mints **MUST** implement these:
#### NUT-00: Cryptography and Models
- BDHKE blind signature scheme
- Token data structures (Proof, BlindedMessage, BlindSignature)
- Token serialization (V3 and V4 formats)
- Hash-to-curve function
- Error codes and responses
#### NUT-01: Mint Public Keys
- **Endpoint**: `GET /v1/keys`
- **Response**: Keyset with public keys for each amount
- Allows wallet to unblind signatures
- Supports key rotation
#### NUT-02: Keysets and Fees
- **Endpoint**: `GET /v1/keysets`
- Lists all active and inactive keysets
- Fee structure per keyset
- Unit specification (sat, msat, usd, etc.)
#### NUT-03: Swapping Tokens
- **Endpoint**: `POST /v1/swap`
- Exchange proofs for new proofs (same total value)
- Used for: sending specific amounts, combining/splitting, key rotation
- Atomic operation (all or nothing)
#### NUT-04: Minting Tokens
- **Endpoint**: `POST /v1/mint/quote/bolt11` (create quote)
- **Endpoint**: `POST /v1/mint/bolt11` (mint tokens)
- Deposit Bitcoin via Lightning
- Receive blinded signatures (promises)
- Unblind to get valid proofs
#### NUT-05: Melting Tokens
- **Endpoint**: `POST /v1/melt/quote/bolt11` (create quote)
- **Endpoint**: `POST /v1/melt/bolt11` (melt tokens)
- Withdraw Bitcoin via Lightning
- Provide proofs to cover amount + fee
- Receive change if overpaid
#### NUT-06: Mint Information
- **Endpoint**: `GET /v1/info`
- Mint metadata (name, description, version)
- Supported NUTs
- Contact information
- Message of the day (MOTD)
### Optional NUTs (Recommended)
#### NUT-07: Token State Check
- **Endpoint**: `POST /v1/checkstate`
- Check if secrets are spent or pending
- Returns state: `UNSPENT`, `SPENT`, `PENDING`
- Useful for wallet recovery
#### NUT-08: Overpaid Lightning Fees
- **Endpoint**: `POST /v1/melt/quote/bolt11` returns fee_reserve
- Return change when actual fee < fee_reserve
- Prevents fee overpayment
#### NUT-09: Restore Signatures
- **Endpoint**: `POST /v1/restore`
- Recover lost proofs using deterministic secrets
- Requires counter-based secret generation
- Useful for wallet backup/recovery
#### NUT-10: Spending Conditions
- P2PK (Pay-to-Public-Key) locking
- HTLC (Hashed Timelock Contracts)
- Custom spending conditions on proofs
- Enhanced security and programmability
#### NUT-11: Pay-to-Public-Key (P2PK)
- Lock proofs to specific pubkey
- Requires signature to spend
- Format: `["P2PK", {"nonce": "...", "data": "pubkey", "tags": [...]}]`
- Prevents theft if proofs leaked
#### NUT-12: DLEQ Proofs
- Discrete Log Equality Proofs
- Proves mint signed correctly without revealing key
- Prevents mint from creating unbacked tokens
- Optional but increases trust
#### NUT-13: Deterministic Secrets
- Generate secrets from counter + seed
- Enables deterministic wallet recovery
- Works with NUT-09 for backup
- Format: `secret = hash(seed || counter)`
#### NUT-14: Hashed Timelock Contracts (HTLC)
- Time-locked proofs
- Preimage reveals spending ability
- Useful for atomic swaps, escrow
- Format: `["HTLC", {"nonce": "...", "data": "hash", "tags": [["locktime", "timestamp"]]}]`
#### NUT-15: Multi-Path Payments (MPP)
- Split payment across multiple routes
- Improves Lightning payment success rate
- Coordination between wallet and mint
### Extended NUTs
- **NUT-16**: Animated QR codes for large tokens
- **NUT-17**: WebSocket subscriptions for real-time updates
- **NUT-18**: Payment requests (invoicing)
- **NUT-19**: Cached responses for performance
- **NUT-20**: Multiple signature methods
- **NUT-21**: BOLT11 Lightning invoices (mandatory for Lightning)
- **NUT-22**: BOLT12 Lightning offers
- **NUT-23**: HTTP 402 Payment Required
- **NUT-24**: Bech32m encoding for tokens
- **NUT-25**: Nostr-based wallet backup
## Core Operations
### 1. Minting (Deposit Bitcoin → Get Ecash)
**Flow:**
```
1. Wallet creates mint quote
POST /v1/mint/quote/bolt11 {amount: 1000}
→ {quote: "quote_id", request: "lnbc...", paid: false}
2. User pays Lightning invoice (external)
3. Wallet generates secrets and blinds them
secrets = [random_32_bytes() for _ in amounts]
blinded_messages = [blind(secret, amount) for secret, amount in zip(secrets, amounts)]
4. Wallet requests signatures
POST /v1/mint/bolt11 {quote: "quote_id", outputs: blinded_messages}
→ {signatures: [blind_signatures]}
5. Wallet unblinds signatures
proofs = [unblind(signature, secret) for signature, secret in zip(signatures, secrets)]
6. Wallet stores proofs
```
**Example (1000 sats → proofs for 512, 256, 128, 64, 32, 8):**
```typescript
// Step 1: Create quote
const quote = await mint.createMintQuote(1000);
console.log("Pay invoice:", quote.request);
// Step 2: Wait for payment
await waitForPayment(quote.quote);
// Step 3-4: Generate blinded messages
const outputs = generateBlindedMessages([512, 256, 128, 64, 32, 8]);
// Step 4: Request signatures
const { signatures } = await mint.mintTokens(quote.quote, outputs);
// Step 5: Unblind
const proofs = unblindSignatures(signatures, secrets);
```
### 2. Sending (Transfer Ecash)
**Flow:**
```
1. Select proofs totaling send_amount (+ optional fee)
selected = coin_select(proofs, send_amount)
2. If exact amount: send proofs directly
If over: swap to get exact amount + change
3. Create swap request
POST /v1/swap {
inputs: selected_proofs,
outputs: blinded_messages_for(send_amount + change)
}
→ {signatures: [...]}
4. Unblind signatures
send_proofs = unblind(signatures[:send_count])
keep_proofs = unblind(signatures[send_count:])
5. Encode send_proofs as token
token = encode_token_v4(send_proofs, mint_url)
6. Share token with recipient (QR, text, NFC)
```
**Example (send 100 sats, have proofs for 128):**
```typescript
// Swap 128 proof into 100 (send) + 28 (change)
const { keep, send } = await wallet.send(100, proofs);
const token = getEncodedTokenV4({ mint: mintUrl, proofs: send });
console.log("Send this:", token); // cashuB...
```
### 3. Receiving (Accept Ecash)
**Flow:**
```
1. Decode token
decoded = decode_token_v4(token_string)
→ {mint: "url", proofs: [...]}
2. Verify mint URL (trust check)
3. Swap received proofs for new ones (prevents double-spend)
POST /v1/swap {
inputs: decoded.proofs,
outputs: blinded_messages_for_same_total
}
→ {signatures: [...]}
4. Unblind signatures
new_proofs = unblind(signatures)
5. Store new_proofs in wallet
```
**Why swap on receive?**
- Sender knows the secrets, could double-spend
- Swapping creates new secrets only recipient knows
- Makes tokens truly bearer assets after swap
**Example:**
```typescript
const token = getDecodedToken(tokenString);
const newProofs = await wallet.receive(token);
// newProofs are now safe to spend
```
### 4. Melting (Withdraw Ecash → Get Bitcoin)
**Flow:**
```
1. Create melt quote with Lightning invoice
POST /v1/melt/quote/bolt11 {request: "lnbc..."}
→ {quote: "quote_id", amount: 1000, fee_reserve: 10}
2. Select proofs for amount + fee_reserve
proofs = coin_select(wallet.proofs, 1010)
3. Melt tokens
POST /v1/melt/bolt11 {
quote: "quote_id",
inputs: proofs
}
→ {paid: true, payment_preimage: "...", change: [signatures]}
4. If overpaid, unblind change
if change:
change_proofs = unblind(change)
store(change_proofs)
5. Lightning payment is now complete
```
**Example (pay 1000 sat invoice with 1024 sats of proofs):**
```typescript
const invoice = "lnbc1000...";
const meltQuote = await mint.createMeltQuote(invoice);
// meltQuote.amount = 1000, meltQuote.fee_reserve = 24
const proofs = selectProofs(1024); // Cover amount + fee
const meltResult = await mint.meltTokens(meltQuote.quote, proofs);
if (meltResult.change) {
const changeProofs = unblind(meltResult.change);
// Actual fee was less, got change back
}
```
### 5. Checking Token State
**Flow:**
```
POST /v1/checkstate {
Ys: [hash_to_curve(secret1), hash_to_curve(secret2), ...]
}
→ {
states: [
{Y: "02ab...", state: "UNSPENT", witness: null},
{Y: "03cd...", state: "SPENT", witness: null},
{Y: "02ef...", state: "PENDING", witness: null}
]
}
```
**States:**
- `UNSPENT`: Token valid and unspent
- `SPENT`: Token already redeemed
- `PENDING`: Token in pending transaction
## Implementation Best Practices
### For Wallets
1. **Key Management**
- Generate cryptographically secure random secrets
- Never reuse secrets (prevents linking)
- Store proofs encrypted at rest
2. **Coin Selection**
- Use powers of 2 for efficient representation
- Minimize number of proofs sent (combines proofs)
- Consider fees in selection logic
3. **Always Swap on Receive**
- Sender knows secrets, could double-spend
- Creates new secrets only you know
- Critical security practice
4. **Multiple Mint Support**
- Allow users to trust multiple mints
- Separate balance per mint
- V4 tokens support multi-mint payments
5. **Backup and Recovery**
- Implement NUT-13 (deterministic secrets)
- Use NUT-09 for signature restoration
- Store seed securely (12/24 word mnemonic)
6. **Error Handling**
- Handle double-spend errors gracefully
- Retry failed melt operations
- Check token state before sending
7. **Privacy Considerations**
- Don't correlate amounts across sessions
- Use Tor/VPN for mint connections
- Regularly swap tokens for new secrets
### For Mints
1. **Signature Verification**
- Always verify proof signatures
- Check secrets not in spent database
- Validate keyset IDs
2. **Database Management**
- Index spent secrets for fast lookup
- Store pending operations atomically
- Archive old keysets (never delete)
3. **Lightning Integration**
- Robust Lightning node management
- Handle payment failures gracefully
- Return change for overpaid fees (NUT-08)
4. **Key Rotation**
- Rotate keysets periodically
- Keep old keysets active for swapping
- Announce deprecation before deactivation
5. **Rate Limiting**
- Prevent spam (checkstate, mint quote spam)
- Implement proof-of-work (optional)
- Monitor for abuse patterns
6. **DLEQ Proofs** (Recommended)
- Implement NUT-12 for transparency
- Proves signatures are valid
- Builds user trust
7. **Monitoring and Logging**
- Track Lightning balance vs issued proofs
- Alert on discrepancies
- Log all operations for auditing
### Security Considerations
1. **Mint Custody Risk**
- Mints are custodial (hold Bitcoin)
- Users must trust mint operator
- Diversify across multiple mints
2. **Double-Spend Prevention**
- Mint tracks spent secrets
- Atomic swap operations
- Network race conditions possible (accept only once)
3. **Key Compromise**
- If mint's private key leaks, tokens can be forged
- Key rotation limits damage
- Monitor for anomalies
4. **Secret Reuse**
- NEVER reuse secrets (breaks privacy)
- NEVER share secrets before receiving payment
- Always generate fresh secrets
5. **Token Lifetime**
- Tokens don't expire (unless mint goes offline)
- Old keysets can become invalid
- Swap to active keysets regularly
6. **Network Privacy**
- Use Tor for mint connections
- Don't reveal IP to mint
- Avoid timing correlation
## Common Patterns
### Coin Selection Algorithm
```typescript
function selectProofs(proofs: Proof[], targetAmount: number): Proof[] {
// Sort by amount descending
const sorted = proofs.sort((a, b) => b.amount - a.amount);
const selected: Proof[] = [];
let sum = 0;
for (const proof of sorted) {
if (sum >= targetAmount) break;
selected.push(proof);
sum += proof.amount;
}
if (sum < targetAmount) {
throw new Error("Insufficient balance");
}
return selected;
}
```
### Amount to Denominations
```typescript
function amountToDenominations(amount: number): number[] {
const denominations: number[] = [];
let remaining = amount;
let power = 0;
while (remaining > 0) {
if (remaining & 1) {
denominations.push(1 << power); // 2^power
}
remaining >>= 1;
power++;
}
return denominations;
}
// Example: 1000 = 512 + 256 + 128 + 64 + 32 + 8
console.log(amountToDenominations(1000));
// [8, 32, 64, 128, 256, 512]
```
### Deterministic Secret Generation
```typescript
import { sha256 } from '@noble/hashes/sha256';
import { bytesToHex } from '@noble/hashes/utils';
function generateSecret(seed: Uint8Array, counter: number): string {
const counterBytes = new Uint8Array(8);
new DataView(counterBytes.buffer).setBigUint64(0, BigInt(counter), false);
const combined = new Uint8Array(seed.length + counterBytes.length);
combined.set(seed);
combined.set(counterBytes, seed.length);
return bytesToHex(sha256(combined));
}
```
### Token Encoding Helper
```typescript
import { encodeBase64Url } from './utils';
import { encode as cborEncode } from 'cbor-x';
function encodeTokenV4(proofs: Proof[], mintUrl: string, memo?: string): string {
// Group proofs by keyset ID
const grouped = new Map<string, Proof[]>();
for (const proof of proofs) {
if (!grouped.has(proof.id)) {
grouped.set(proof.id, []);
}
grouped.get(proof.id)!.push(proof);
}
// Build token object
const token = {
t: [{
m: mintUrl,
u: "sat",
...(memo && { d: memo }),
t: Array.from(grouped.entries()).map(([id, proofs]) => ({
i: id.slice(0, 16), // Short form (8 bytes)
p: proofs.map(p => ({
a: p.amount,
s: p.secret,
c: p.C
}))
}))
}]
};
const cbor = cborEncode(token);
return 'cashuB' + encodeBase64Url(cbor);
}
```
## Troubleshooting
### Common Issues
**Token Already Spent:**
- Cause: Secret already in spent database
- Solution: Don't reuse tokens, always swap received tokens
- Check state before sending: `POST /v1/checkstate`
**Signature Verification Failed:**
- Cause: Invalid proof, wrong keyset, or tampered data
- Solution: Verify proof structure, check keyset ID, re-request from sender
**Lightning Payment Failed:**
- Cause: Invoice expired, insufficient liquidity, routing failure
- Solution: Retry with new quote, try different route, check balance
**Mint Not Responding:**
- Cause: Mint offline, network issues, rate limiting
- Solution: Use backup mint, check connection, wait and retry
**Amount Mismatch:**
- Cause: Fee estimation wrong, coin selection error
- Solution: Request melt quote first (shows fee), add buffer for fees
**Cannot Decode Token:**
- Cause: Invalid encoding, wrong version, corrupted data
- Solution: Check token prefix (cashuA/cashuB), validate base64, try different parser
## Development Resources
### Essential NUTs for Beginners
Start with these specifications in order:
1. **NUT-00** - Cryptography and models (MUST read)
2. **NUT-01** - Mint public keys
3. **NUT-04** - Minting tokens
4. **NUT-05** - Melting tokens
5. **NUT-03** - Swapping tokens
6. **NUT-07** - Token state check
### Testing and Development
- **Reference Mint**: nutshell (Python implementation)
- **Test Mint**: Use local nutshell instance for development
- **Libraries**: cashu-ts (TypeScript), cashu-crab (Rust), cashu-feni (Dart)
- **Wallets**: Nutstash (web), eNuts (mobile), Cashu.me (web)
- **Tools**: Cashu Explorer, token decoder utilities
### Key Repositories
- **NUTs Repository**: https://github.com/cashubtc/nuts
- **Nutshell (Python mint)**: https://github.com/cashubtc/nutshell
- **cashu-ts (TypeScript)**: https://github.com/cashubtc/cashu-ts
- **Cashu Website**: https://cashu.space
- **Documentation**: https://docs.cashu.space
## Reference Files
For comprehensive technical details, see:
- **references/nuts-overview.md** - Detailed descriptions of all NUT specifications
- **references/common-patterns.md** - Code patterns and best practices
## Quick Checklist
When implementing Cashu:
- [ ] Proofs have all required fields (amount, secret, C, id)
- [ ] Secrets are cryptographically random (32 bytes)
- [ ] Never reuse secrets across operations
- [ ] Always swap tokens on receive (critical for security)
- [ ] Verify mint signatures using public keys from NUT-01
- [ ] Use powers of 2 denominations for efficiency
- [ ] Handle keyset rotation gracefully
- [ ] Implement backup/recovery (NUT-09, NUT-13)
- [ ] Check token state before sending (NUT-07)
- [ ] Connected to multiple mints for redundancy
- [ ] Following relevant NUTs for features implemented
## Official Resources
- **Cashu Website**: https://cashu.space
- **Cashu Documentation**: https://docs.cashu.space
- **NUTs Repository**: https://github.com/cashubtc/nuts
- **Cashu Organization**: https://github.com/cashubtc
- **Cashu Community**: Telegram, Discord (links at cashu.space)

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,871 @@
# Cashu NUTs (Notation, Usage, and Terminology) - Complete Reference
This document provides detailed descriptions of all Cashu NUT specifications. NUTs define the Cashu protocol and enable interoperability between different implementations.
## NUT Status
- **Mandatory**: All wallets and mints MUST implement
- **Optional**: Implementations CAN implement for enhanced features
- **Draft**: Under development, subject to change
## Mandatory NUTs
### NUT-00: Cryptography and Models
**Status**: Mandatory
**Purpose**: Foundational cryptographic protocol and data structures
#### Overview
Defines the Blind Diffie-Hellman Key Exchange (BDHKE) scheme used for blind signatures, core data models, token serialization formats, and error handling.
#### Key Concepts
**BDHKE Scheme:**
```
1. Alice generates secret x, computes Y = hash_to_curve(x)
2. Alice blinds: B_ = Y + r·G
3. Bob signs: C_ = k·B_
4. Alice unblinds: C = C_ - r·K
5. Verification: k·hash_to_curve(x) == C
```
**Hash-to-Curve:**
```
DOMAIN_SEPARATOR = b"Secp256k1_HashToCurve_Cashu_"
msg_hash = SHA256(DOMAIN_SEPARATOR || x)
counter = 0
loop:
candidate = SHA256(msg_hash || counter)
try parse as secp256k1 point
if valid: return point
counter += 1
```
#### Data Structures
**BlindedMessage** (wallet → mint):
```json
{
"amount": 64,
"id": "00ffd48b78a7b2f4",
"B_": "02ab3c4d5e..."
}
```
**BlindSignature** (mint → wallet):
```json
{
"amount": 64,
"id": "00ffd48b78a7b2f4",
"C_": "03bc5d6e7f..."
}
```
**Proof** (unblinded token):
```json
{
"amount": 64,
"secret": "9a3b2c1d4e5f6a7b8c9d0e1f2a3b4c5d",
"C": "02cd7e8f9a...",
"id": "00ffd48b78a7b2f4",
"witness": "..." // Optional (P2PK, HTLC)
}
```
#### Token Serialization
**V4 Format (Current)**: `cashuB[base64_urlsafe_cbor]`
- CBOR encoding for efficiency
- Abbreviated keys (t, m, u, d, i, p, a, s, c)
- Short keyset IDs (8 bytes)
- Multi-mint support
**V3 Format (Deprecated)**: `cashuA[base64_urlsafe_json]`
- JSON encoding
- Full key names
- Legacy support only
#### Error Codes
Standard HTTP 400 response:
```json
{
"detail": "human-readable message",
"code": 1000X
}
```
Common codes:
- `10001`: Token already spent
- `10002`: Invalid proof
- `10003`: Quote not paid
- `10004`: Insufficient funds
---
### NUT-01: Mint Public Keys
**Status**: Mandatory
**Endpoint**: `GET /v1/keys` or `GET /v1/keys/{keyset_id}`
#### Purpose
Exchange mint's public keys with wallets. Keys are needed to unblind signatures and verify proofs.
#### Response Format
```json
{
"keysets": [
{
"id": "00ffd48b78a7b2f4",
"unit": "sat",
"keys": {
"1": "02194603ffa36356f4a56b7df9371fc3192472351453ec7398b8da8117e7c3e104",
"2": "03b0f36d6d47ce14df8a7be9137712c42bcdd960b19dd02f1d4a9703b1f31d7513",
"4": "0366be6e026e42852498efb82014ca91e89da2e7a5bd3761bdad699fa2aec9f96c",
"8": "0253de5237f189606f29d8a690ea719f74d65f617bb1cb6fbea34f2bc4f930016d"
}
}
]
}
```
#### Key Fields
- `id`: Keyset identifier (16-byte hex, SHA256 of concatenated pubkeys)
- `unit`: Currency unit (sat, msat, usd, eur, etc.)
- `keys`: Map of amount → public key (hex-encoded compressed secp256k1 points)
#### Key Rotation
Mints can rotate keys by creating new keysets. Old keysets should remain available for swapping until all proofs are migrated.
---
### NUT-02: Keysets and Fees
**Status**: Mandatory
**Endpoint**: `GET /v1/keysets`
#### Purpose
List all keysets (active and inactive) with fee information.
#### Response Format
```json
{
"keysets": [
{
"id": "00ffd48b78a7b2f4",
"unit": "sat",
"active": true,
"input_fee_ppk": 0,
"output_fee_ppk": 0
},
{
"id": "00ab12cd34ef5678",
"unit": "sat",
"active": false,
"input_fee_ppk": 100,
"output_fee_ppk": 100
}
]
}
```
#### Fee Structure
- `input_fee_ppk`: Fee per 1000 input proofs (parts per thousand)
- `output_fee_ppk`: Fee per 1000 output proofs
**Example**: 100 ppk = 0.1 sat per proof = 100 sats per 1000 proofs
#### Keyset Status
- `active: true`: Mint will sign new proofs with this keyset
- `active: false`: Keyset deprecated, can still swap but not mint
---
### NUT-03: Swapping Tokens
**Status**: Mandatory
**Endpoint**: `POST /v1/swap`
#### Purpose
Exchange proofs for new proofs of the same total value. Used for coin selection, sending exact amounts, and key rotation.
#### Request Format
```json
{
"inputs": [
{
"amount": 128,
"secret": "secret1",
"C": "02ab3c...",
"id": "00ffd48b"
}
],
"outputs": [
{
"amount": 64,
"id": "00ffd48b",
"B_": "03cd7e..."
},
{
"amount": 64,
"id": "00ffd48b",
"B_": "02ef9a..."
}
]
}
```
#### Response Format
```json
{
"signatures": [
{
"amount": 64,
"id": "00ffd48b",
"C_": "02ab3c..."
},
{
"amount": 64,
"id": "00ffd48b",
"C_": "03de9f..."
}
]
}
```
#### Validation
- Sum of inputs MUST equal sum of outputs (minus fees)
- All input proofs MUST be valid and unspent
- Atomic operation: all or nothing
- Mint marks input secrets as spent
---
### NUT-04: Minting Tokens
**Status**: Mandatory
**Endpoints**:
- `POST /v1/mint/quote/bolt11` - Create quote
- `GET /v1/mint/quote/bolt11/{quote_id}` - Check quote
- `POST /v1/mint/bolt11` - Mint tokens
#### Purpose
Deposit Bitcoin via Lightning and receive ecash.
#### Flow
**1. Create Quote**
Request:
```json
{
"amount": 1000,
"unit": "sat"
}
```
Response:
```json
{
"quote": "quote_12345",
"request": "lnbc1000n...",
"paid": false,
"expiry": 1704153600
}
```
**2. Check Quote Status**
Request: `GET /v1/mint/quote/bolt11/quote_12345`
Response:
```json
{
"quote": "quote_12345",
"request": "lnbc1000n...",
"paid": true,
"expiry": 1704153600
}
```
**3. Mint Tokens**
Request:
```json
{
"quote": "quote_12345",
"outputs": [
{"amount": 512, "id": "00ffd48b", "B_": "02ab..."},
{"amount": 256, "id": "00ffd48b", "B_": "03cd..."},
{"amount": 128, "id": "00ffd48b", "B_": "02ef..."},
{"amount": 64, "id": "00ffd48b", "B_": "03gh..."},
{"amount": 32, "id": "00ffd48b", "B_": "02ij..."},
{"amount": 8, "id": "00ffd48b", "B_": "03kl..."}
]
}
```
Response:
```json
{
"signatures": [
{"amount": 512, "id": "00ffd48b", "C_": "02mn..."},
{"amount": 256, "id": "00ffd48b", "C_": "03op..."},
{"amount": 128, "id": "00ffd48b", "C_": "02qr..."},
{"amount": 64, "id": "00ffd48b", "C_": "03st..."},
{"amount": 32, "id": "00ffd48b", "C_": "02uv..."},
{"amount": 8, "id": "00ffd48b", "C_": "03wx..."}
]
}
```
#### Error Codes
- `20001`: Quote not paid
- `20002`: Quote expired
- `20003`: Quote already issued
---
### NUT-05: Melting Tokens
**Status**: Mandatory
**Endpoints**:
- `POST /v1/melt/quote/bolt11` - Create quote
- `GET /v1/melt/quote/bolt11/{quote_id}` - Check quote
- `POST /v1/melt/bolt11` - Melt tokens
#### Purpose
Withdraw Bitcoin via Lightning by melting ecash.
#### Flow
**1. Create Quote**
Request:
```json
{
"request": "lnbc1000n...",
"unit": "sat"
}
```
Response:
```json
{
"quote": "melt_12345",
"amount": 1000,
"fee_reserve": 10,
"paid": false,
"expiry": 1704153600
}
```
**2. Melt Tokens**
Request:
```json
{
"quote": "melt_12345",
"inputs": [
{"amount": 512, "secret": "...", "C": "...", "id": "..."},
{"amount": 256, "secret": "...", "C": "...", "id": "..."},
{"amount": 128, "secret": "...", "C": "...", "id": "..."},
{"amount": 64, "secret": "...", "C": "...", "id": "..."},
{"amount": 32, "secret": "...", "C": "...", "id": "..."},
{"amount": 16, "secret": "...", "C": "...", "id": "..."},
{"amount": 2, "secret": "...", "C": "...", "id": "..."}
],
"outputs": [
{"amount": 8, "id": "00ffd48b", "B_": "02ab..."},
{"amount": 2, "id": "00ffd48b", "B_": "03cd..."}
]
}
```
Response:
```json
{
"paid": true,
"payment_preimage": "0e5b2f1a...",
"change": [
{"amount": 8, "id": "00ffd48b", "C_": "02ef..."},
{"amount": 2, "id": "00ffd48b", "C_": "03gh..."}
]
}
```
#### Fee Handling
- `fee_reserve`: Estimated maximum fee
- Inputs MUST cover: amount + fee_reserve
- Actual fee may be less → change returned
- See NUT-08 for overpaid fee handling
---
### NUT-06: Mint Information
**Status**: Mandatory
**Endpoint**: `GET /v1/info`
#### Purpose
Provide mint metadata and capabilities.
#### Response Format
```json
{
"name": "Example Mint",
"pubkey": "02ab3c4d...",
"version": "nutshell/0.15.0",
"description": "Community ecash mint",
"description_long": "A Cashu mint operated for the Bitcoin community...",
"contact": [
["email", "admin@example.com"],
["nostr", "npub1..."],
["twitter", "@example"]
],
"motd": "Welcome! Please backup your tokens.",
"nuts": {
"4": {
"methods": [
{"method": "bolt11", "unit": "sat", "min_amount": 1, "max_amount": 1000000}
],
"disabled": false
},
"5": {
"methods": [
{"method": "bolt11", "unit": "sat", "min_amount": 1, "max_amount": 1000000}
],
"disabled": false
},
"7": {"supported": true},
"8": {"supported": true},
"9": {"supported": true},
"10": {"supported": true},
"11": {"supported": true},
"12": {"supported": true}
}
}
```
#### Key Fields
- `name`: Human-readable mint name
- `version`: Mint software version
- `nuts`: Supported NUT specifications with parameters
- `contact`: Contact methods (array of [type, value])
- `motd`: Message of the day (displayed to users)
---
## Optional NUTs
### NUT-07: Token State Check
**Status**: Optional (Highly Recommended)
**Endpoint**: `POST /v1/checkstate`
#### Purpose
Check if secrets are spent, unspent, or pending without revealing the secret itself.
#### Request Format
```json
{
"Ys": [
"02ab3c4d5e...", // Y = hash_to_curve(secret)
"03bc5d6e7f...",
"02cd7e8f9a..."
]
}
```
#### Response Format
```json
{
"states": [
{
"Y": "02ab3c4d5e...",
"state": "UNSPENT",
"witness": null
},
{
"Y": "03bc5d6e7f...",
"state": "SPENT",
"witness": null
},
{
"Y": "02cd7e8f9a...",
"state": "PENDING",
"witness": null
}
]
}
```
#### States
- `UNSPENT`: Secret has not been used
- `SPENT`: Secret has been redeemed
- `PENDING`: Secret is in pending transaction
#### Use Cases
- Wallet recovery (check which proofs are still valid)
- Verify token validity before accepting
- Detect double-spend attempts
---
### NUT-08: Overpaid Lightning Fees
**Status**: Optional (Recommended)
**Integrated**: NUT-05 melt response
#### Purpose
Return change when actual Lightning fee is less than fee_reserve.
#### Implementation
When melting (NUT-05):
1. Wallet provides inputs for amount + fee_reserve
2. Mint pays invoice (actual_fee ≤ fee_reserve)
3. If actual_fee < fee_reserve, mint returns change
4. Change = fee_reserve - actual_fee
#### Example
```
Invoice amount: 1000 sats
Fee reserve: 10 sats
Inputs provided: 1010 sats
Actual fee: 3 sats
Change returned: 7 sats
```
---
### NUT-09: Restore Signatures
**Status**: Optional (Recommended for backup)
**Endpoint**: `POST /v1/restore`
#### Purpose
Recover lost proofs using deterministic secrets (NUT-13).
#### Request Format
```json
{
"outputs": [
{"amount": 1, "id": "00ffd48b", "B_": "02ab..."},
{"amount": 2, "id": "00ffd48b", "B_": "03cd..."},
{"amount": 4, "id": "00ffd48b", "B_": "02ef..."}
]
}
```
#### Response Format
```json
{
"outputs": [
{"amount": 1, "id": "00ffd48b", "C_": "02gh..."},
null, // Not issued
{"amount": 4, "id": "00ffd48b", "C_": "02ij..."}
],
"signatures": [
{"amount": 1, "id": "00ffd48b", "C_": "02gh..."},
{"amount": 4, "id": "00ffd48b", "C_": "02ij..."}
]
}
```
#### Usage Pattern
1. Wallet generates deterministic secrets (counter-based)
2. After mint loss, wallet regenerates secrets with same counters
3. Wallet creates blinded messages from regenerated secrets
4. Mint returns signatures for secrets that were previously issued
5. Wallet unblinds to recover proofs
---
### NUT-10: Spending Conditions
**Status**: Optional
**Purpose**: Programmable spending conditions on proofs
#### Supported Conditions
- P2PK (NUT-11): Pay-to-Public-Key
- HTLC (NUT-14): Hash Time Locked Contracts
- Custom: Extensible format
#### Secret Format
Spending condition secrets are JSON arrays:
```json
[
"condition_type",
{
"nonce": "random_hex",
"data": "condition_data",
"tags": [["key", "value"]]
}
]
```
#### Witness Format
When spending condition-locked proofs, include witness:
```json
{
"amount": 64,
"secret": "[\"P2PK\",{\"nonce\":\"abc\",\"data\":\"pubkey\"}]",
"C": "02ab3c...",
"id": "00ffd48b",
"witness": "{\"signatures\":[\"sig1\"]}"
}
```
---
### NUT-11: Pay-to-Public-Key (P2PK)
**Status**: Optional
**Purpose**: Lock proofs to specific public key (requires signature to spend)
#### Secret Format
```json
[
"P2PK",
{
"nonce": "da62796403af76c80cd6ce9153ed3746",
"data": "033281c37677ea273eb7183b783067f5244933ef78d8c3f15b1a77cb246099c26e",
"tags": [
["sigflag", "SIG_INPUTS"], // Optional: what to sign
["n_sigs", "2"], // Optional: multisig (N-of-M)
["pubkeys", "pk1,pk2,pk3"] // Optional: additional pubkeys
]
}
]
```
#### Witness Format
```json
{
"signatures": [
"fd5e0e3e6e5c6fa14059c56a66e36c44e1e06d820b0e164f56f14051a85c1cda6a9d1d7ddbb15e98e3b4eb5a34f97e49141c64bb3cbc70b1bde85bc5b53e16bb"
]
}
```
#### Signature Flags
- `SIG_INPUTS`: Sign all input proofs
- `SIG_OUTPUTS`: Sign all outputs (prevents mint alteration)
#### Use Cases
- Secure transfers (recipient must have private key)
- Non-custodial storage (wallet can't spend without key)
- Escrow services
---
### NUT-12: DLEQ Proofs
**Status**: Optional (Recommended for trust)
**Purpose**: Discrete Log Equality proofs to verify mint signatures
#### Concept
Proves that `C = k·Y` without revealing `k` (mint's private key).
#### DLEQ Structure
```json
{
"e": "9818e061ee51d5c8edc3342369a554998ff7b4381c8652d724cdf46429be73d9",
"s": "9818e061ee51d5c8edc3342369a554998ff7b4381c8652d724cdf46429be73d9"
}
```
#### Verification
```
C = s·G + e·K
Y' = s·B_ + e·C_
Verify: e == SHA256(K || C || Y')
```
#### Benefits
- Proves mint signed correctly
- Detects mint misbehavior (creating unbacked tokens)
- Builds user trust in mint
---
### NUT-13: Deterministic Secrets
**Status**: Optional (Recommended for backup)
**Purpose**: Generate secrets deterministically for wallet recovery
#### Secret Generation
```
secret = HMAC-SHA256(
key = seed,
msg = counter || keyset_id || amount
)
```
#### Counter Format
```
counter = 8-byte big-endian integer
```
#### Usage Pattern
1. Wallet generates seed (BIP39 mnemonic)
2. For each proof, increment counter
3. Generate secret from: seed + counter + keyset_id + amount
4. Store only seed and counter (not individual secrets)
5. For recovery: regenerate secrets and use NUT-09 restore
#### Benefits
- Backup entire wallet with 12/24 words
- Restore all proofs from seed
- No need to backup individual proofs
---
### NUT-14: Hashed Timelock Contracts (HTLC)
**Status**: Optional
**Purpose**: Time-locked proofs with hash preimage reveal
#### Secret Format
```json
[
"HTLC",
{
"nonce": "da62796403af76c80cd6ce9153ed3746",
"data": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
"tags": [
["locktime", "1704153600"], // Unix timestamp
["refund", "pubkey"] // Refund pubkey after locktime
]
}
]
```
#### Witness Format
**Before locktime (with preimage):**
```json
{
"preimage": "preimage_hex"
}
```
**After locktime (refund):**
```json
{
"signatures": ["refund_signature"]
}
```
#### Use Cases
- Atomic swaps
- Escrow with time limits
- Payment channels
---
### Extended NUTs (NUT-15 to NUT-27)
Brief descriptions of additional optional specifications:
- **NUT-15**: MPP (Multi-Path Payments) - Split Lightning payments across routes
- **NUT-16**: Animated QR codes - Encode large tokens across multiple QR frames
- **NUT-17**: WebSocket subscriptions - Real-time updates for quotes and proofs
- **NUT-18**: Payment requests - Invoice-like payment requests
- **NUT-19**: Cached responses - Performance optimization via caching
- **NUT-20**: Multiple signature methods - Support various signature schemes
- **NUT-21**: BOLT11 - Lightning invoice support (standard for minting/melting)
- **NUT-22**: BOLT12 - Lightning offers support (reusable payment requests)
- **NUT-23**: HTTP 402 - Payment Required status code integration
- **NUT-24**: Bech32m - Alternative token encoding format
- **NUT-25**: Nostr backup - Backup wallet to Nostr relays (encrypted kind 10000+ events)
- **NUT-26**: Subscription payments - Recurring payments
- **NUT-27**: Multi-mint atomic swaps - Atomic swaps across different mints
---
## Implementation Priority
### For Basic Wallet
1. NUT-00 (Cryptography)
2. NUT-01 (Mint Keys)
3. NUT-04 (Minting)
4. NUT-05 (Melting)
5. NUT-03 (Swapping)
6. NUT-07 (State Check)
### For Production Wallet
Add these to basic wallet:
7. NUT-08 (Overpaid Fees)
8. NUT-13 (Deterministic Secrets)
9. NUT-09 (Restore)
10. NUT-11 (P2PK)
### For Advanced Features
Add based on use case:
- NUT-12 (DLEQ) - Verify mint honesty
- NUT-14 (HTLC) - Atomic swaps, escrow
- NUT-17 (WebSocket) - Real-time updates
- NUT-25 (Nostr Backup) - Cloud backup
---
## Resources
- **Official NUTs**: https://github.com/cashubtc/nuts
- **NUT Status**: https://cashubtc.github.io/nuts/
- **Cashu Docs**: https://docs.cashu.space