What to Back Up · Quick Backup · Automated · Recovery · Seed Recovery · Failure Scenarios · Rules
Your NUTbits state contains ecash proofs (real money) and NWC private keys. Losing this data means losing funds and wallet access.
| Backend | Files to back up | Notes |
|---|---|---|
file |
nutbits_state.enc |
The entire wallet in one file |
sqlite |
nutbits_state.db |
Single database file |
mysql |
Database dump | Use mysqldump |
Always back up your .env file too - it contains NUTBITS_STATE_PASSPHRASE (required to decrypt everything), your seed, and service fee configuration.
Store the passphrase and the data separately. One without the other is useless.
nutbits backup # auto-named with timestamp
nutbits backup --out ./my-backup.enc # custom path
nutbits verify ./my-backup.enc # check a backupcp nutbits_state.enc "backups/nutbits_$(date +%Y%m%d_%H%M%S).enc"cp nutbits_state.db "backups/nutbits_$(date +%Y%m%d_%H%M%S).db"mysqldump -u nutbits -p nutbits > "backups/nutbits_$(date +%Y%m%d_%H%M%S).sql"Add to crontab (crontab -e):
# Daily backup at 2 AM
0 2 * * * cp /path/to/nutbits_state.enc /path/to/backups/nutbits_$(date +\%Y\%m\%d).enc- Stop NUTbits
- Copy your backup file to the configured path
- Ensure
.envhas the correctNUTBITS_STATE_PASSPHRASE - Start NUTbits
# Example: restore file backend
cp backups/nutbits_20260318.enc nutbits_state.enc
npm startEcash proofs are single-use. If you restore an old backup, proofs that were spent since the backup will be rejected by the mint. Unspent proofs still work. You won't lose more than what was spent between the backup and now.
This is your last resort when you have no backup but still have your seed. It recovers ecash proofs directly from the mint.
nutbits restore # recover from all configured mints
nutbits restore --mint <url> # recover from a specific mintNUTbits generates ecash proofs using your seed and a counter (NUT-13). The mint remembers every proof it ever signed. NUT-09 lets you ask the mint: "did you sign any of these?" and rebuild your proofs from the answers.
seed + counter 0 → ask mint → "yes, I signed that" → proof recovered
seed + counter 1 → ask mint → "yes, I signed that" → proof recovered
seed + counter 2 → ask mint → "never seen this" → done
Automatically on startup - if NUTbits has a seed configured but no proofs stored for a mint, it attempts recovery. You don't need to do anything.
- You lost your state file / database
- You still have your seed (
NUTBITS_SEEDfrom.envor your password manager)
# Make sure your .env has the seed
NUTBITS_SEED=your-seed-here
# Delete the old state (if corrupted) and start fresh
rm nutbits_state.enc
npm startNUTbits will:
- Start with an empty state
- Detect that the seed is configured but no proofs exist
- Contact each mint and recover all proofs it ever signed for your seed
- Log:
NUT-09: restored proofs from seed
| Recoverable | Not recoverable | |
|---|---|---|
| Ecash proofs (your sats) | With seed | Without seed |
| NWC connection string | No - a new one is generated | Save it separately |
| Transaction history | No - stored locally only | Gone |
| NWC private keys | No - regenerated | Clients need to reconnect |
- Your mint must support NUT-09 (most modern mints do; NUTbits checks this at startup)
- You must have used a seed (
NUTBITS_SEED) before the proofs were created - Proofs created with random secrets (no seed) cannot be recovered this way
NUTbits generates a seed on first run and auto-saves it to your
.envfile. Back up your.envor copy the seed to a password manager.
| Scenario | Impact | Recovery |
|---|---|---|
| Deleted state file | Wallet gone, NWC string invalid | Restore from backup, or seed recovery |
| Lost passphrase | Data permanently locked | Seed recovery (proofs only) |
| Corrupted file | State load fails, starts fresh | Seed recovery runs automatically |
| Restored old backup | Spent proofs rejected, unspent proofs work | Acceptable partial recovery |
| Copied to new machine | Works - same file + passphrase = same wallet | Don't run two copies at once |
| Lost state + have seed | Proofs recovered, NWC string regenerated | Clients need new NWC string |
| Lost state + no seed | Funds permanently lost | None |
To view decrypted state without starting NUTbits:
// decrypt_state.js
import crypto from 'crypto';
import fs from 'fs';
var passphrase = process.argv[2];
if (!passphrase) { console.error('Usage: node decrypt_state.js <passphrase>'); process.exit(1); }
var blob = fs.readFileSync('./nutbits_state.enc');
var salt = blob.subarray(0, 16);
var iv = blob.subarray(16, 28);
var tag = blob.subarray(28, 44);
var enc = blob.subarray(44);
var key = crypto.scryptSync(passphrase, salt, 32);
var d = crypto.createDecipheriv('aes-256-gcm', key, iv);
d.setAuthTag(tag);
console.log(JSON.stringify(JSON.parse(d.update(enc, null, 'utf8') + d.final('utf8')), null, 2));node decrypt_state.js "your-passphrase"- Never run two NUTbits instances with the same state; double-spend attempts will burn proofs
- Back up after funding - the state changes on every payment
- The
.tmpfile is a write-in-progress artifact; the main file is always the valid one - File permissions are set to
0600(owner-only) automatically
- STATE.md — encrypted state file format and manual decryption
- DATABASE.md — storage backends (file, SQLite, MySQL)
- INSTALL.md — getting NUTbits up and running