Skip to content

DoktorShift/NUTbits

NUTbits - Cashu ecash to NWC bridge

What is NUTbits?

NUTbits is an NWC wallet service that translates between Cashu Mint (NUTs) and Nostr Wallet Connect (NIP-47). It connects to a Cashu mint, manages ecash tokens automatically, and exposes a full NWC server, so any NWC-compatible app can send and receive Lightning payments through the mint.

Use case: plug the NWC string into LNbits as a funding source, and your ecash mint powers the entire LNbits instance with 60+ Extensions.

Inspired by supertestnet/bankify. Built on @cashu/cashu-ts and nostr-core.

Quick Start

See INSTALL.md for full setup instructions (bare metal, Docker, LNbits integration).

git clone https://github.com/DoktorShift/nutbits.git && cd nutbits
npm install && cp .env.example .env
# Edit .env - set NUTBITS_MINT_URL and NUTBITS_STATE_PASSPHRASE
npm start

NUTbits has three main parts:

  • the service (npm start) that handles NWC traffic
  • the management console (nutbits) with CLI and TUI modes
  • the web GUI in gui/, served by npm run gui

The service usually runs in one terminal or in the background. The console and GUI connect to the same local API, so you can manage the same NUTbits instance from terminal or browser.

The default NWC string printed on startup works, but you'll want to use the console to create dedicated connections with scoped permissions and spending limits - one for LNbits, another for a POS, each with its own rules. See Management Console below.

Running Modes

Run these commands from the repository root, where package.json lives.

Pick One

npm start                        # backend only, in your terminal
npm run nutbits                  # backend + GUI, in the background
npm run service:mac              # macOS 24/7 backend service
npm run service:linux            # Linux 24/7 backend service

That is the simplest mental model:

  • use npm start when you want the normal terminal experience
  • use npm run nutbits when you want the web GUI too
  • use npm run service:mac or npm run service:linux when you want the backend to keep running 24/7

If you want the backend to run 24/7 under your operating system's service manager, see SERVICE.md.

Local NUTbits Commands

npm run nutbits                  # backend + GUI in the background
npm run nutbits:interactive      # GUI in background, backend in your terminal
npm run nutbits:stop             # stop backend + GUI
npm run nutbits:restart          # restart NUTbits mode
npm run nutbits:update           # update, rebuild GUI, restart background NUTbits

These helper scripts live in scripts/. In background mode, logs go to logs/nutbits.log and logs/gui.log.

Configuration

All settings in .env (see .env.example):

Required

Variable Default Description
NUTBITS_MINT_URL https://mint.minibits.cash/Bitcoin Cashu mint URL (find mints)
NUTBITS_STATE_PASSPHRASE (required) Passphrase to encrypt state at rest

Wallet & Recovery

Variable Default Description
NUTBITS_SEED (auto-generated) Deterministic wallet seed for proof recovery. Back this up.
NUTBITS_MINT_URLS (optional) Comma-separated mint URLs for multi-mint failover (first = primary). When set, overrides NUTBITS_MINT_URL.
NUTBITS_RELAYS wss://nostrue.com Comma-separated Nostr relays for NWC
NUTBITS_STATE_BACKEND file Storage backend: file, sqlite, or mysql
NUTBITS_STATE_FILE ./nutbits_state.enc Path to encrypted state file (file backend)
NUTBITS_SQLITE_PATH ./nutbits_state.db SQLite database path (sqlite backend)
NUTBITS_MYSQL_URL (optional) MySQL connection URL (mysql backend)

Spending Limits

Variable Default Description
NUTBITS_MAX_PAYMENT_SATS 0 Max sats per payment (0 = no limit)
NUTBITS_DAILY_LIMIT_SATS 0 Max sats per day (0 = no limit)
NUTBITS_FEE_RESERVE_PCT 1 Percentage reserved for Lightning routing fees

Service Fees

Variable Default Description
NUTBITS_SERVICE_FEE_PPM 0 Fee in parts per million on outgoing payments (0 = disabled)
NUTBITS_SERVICE_FEE_BASE 0 Flat base fee in sats per outgoing payment (0 = disabled)

Network & Timing

Variable Default Description
NUTBITS_HEALTH_CHECK_INTERVAL_MS 60000 Mint health check interval
NUTBITS_FAILOVER_COOLDOWN_MS 10000 Cooldown before retrying a failed mint
NUTBITS_INVOICE_CHECK_MAX_RETRIES 60 Max retries for pending invoice checks
NUTBITS_INVOICE_CHECK_INTERVAL_SECS 20 Seconds between pending invoice checks
NUTBITS_FETCH_TIMEOUT_MS 15000 Timeout for mint API requests

Management API

Variable Default Description
NUTBITS_API_ENABLED true Set to false to disable the management API, CLI, and GUI
NUTBITS_API_PORT (optional) HTTP port for the API (leave empty for Unix socket only)
NUTBITS_API_SOCKET (auto) Unix socket path (default: ~/.nutbits/nutbits.sock)
NUTBITS_API_TOKEN (auto) Bearer token for API access (auto-generated on start)
NUTBITS_LOG_LEVEL info error, warn, info, or debug

Storage: See DATABASE.md for backend comparison, setup, and migration. Backups: See BACKUP.md for backup and recovery procedures. Service fees: See CLI.md for fee configuration, per-connection overrides, and revenue tracking.

Encryption: NIP-44 (preferred) with NIP-04 fallback, auto-detected per client.

Supported Cashu NUTs

NUT-00 NUT-01 NUT-02 NUT-03 NUT-04 NUT-05 NUT-06 NUT-07 NUT-08 NUT-09 NUT-12 NUT-13 NUT-17

NUT Name Status Used For
NUT-00 Cryptography & Models supported Proof structure, keyset IDs
NUT-01 Mint Public Keys supported Key fetching via loadMint()
NUT-02 Keysets supported Keyset management, fee calculation
NUT-03 Swap supported Proof selection via wallet.send()
NUT-04 Mint (BOLT11) supported Receiving: make_invoice
NUT-05 Melt (BOLT11) supported Sending: pay_invoice
NUT-06 Mint Info supported Feature detection, capability gating
NUT-07 Proof State Check supported Verify proofs on mint recovery
NUT-08 Lightning Fee Return supported Change proofs from overpaid fees
NUT-09 Signature Restore supported Recover proofs from seed after data loss
NUT-12 DLEQ Proofs supported Verify mint signatures, anti-counterfeit
NUT-13 Deterministic Secrets supported Seed-based proof generation for recovery
NUT-17 WebSocket Subscriptions supported Instant invoice settlement (replaces polling)

Supported Nostr NIPs

NIP-04 NIP-44 NIP-47 NIP-40

NIP Name Used For
NIP-04 Encrypted DMs Legacy encryption fallback
NIP-40 Expiration Tag Ignoring expired NWC requests
NIP-44 Versioned Encryption Preferred encryption (auto-detected)
NIP-47 Nostr Wallet Connect Core protocol for all wallet operations

Supported NWC Methods (NIP-47)

Wallet operations:

  • get_info - wallet metadata, capabilities, encryption support
  • get_balance - current balance in millisats
  • make_invoice - create a Lightning invoice (NUT-4 mint)
  • pay_invoice - pay a Lightning invoice (NUT-5 melt)
  • lookup_invoice - check invoice status by payment hash
  • list_transactions - transaction history with filtering

Notifications (push):

  • payment_received - sent when an incoming invoice settles
  • payment_sent - sent when an outgoing payment completes

Lightning Address support: Each NWC connection can optionally carry a Lightning Address (lud16). Apps that understand this parameter can use it for receiving payments. The address is included in the NWC connection string as &lud16=user@domain.com and is validated via LUD-16 resolution on create and edit.

Optional NIP-47 extensions (non-breaking, clients can ignore or honor):

  • get_info response includes service_fee object when fees are enabled (ppm, base, applies_to)
  • pay_invoice response includes service_fee field (msats) separate from fees_paid (routing)

How It Works

LNbits -> NWC -> NUTbits -> Cashu NUTs -> Mint -> Lightning -> Network

  1. NUTbits generates a keypair and creates an NWC connection string
  2. It subscribes to NWC request events (kind 23194) on configured Nostr relays
  3. When a command arrives, it translates to Cashu operations via @cashu/cashu-ts:
    • pay_invoice -> wallet melts ecash to pay the Lightning invoice (NUT-5). Optional service fee deducted if configured.
    • make_invoice -> wallet requests a mint quote; upon payment, mints new ecash (NUT-4). No fees on incoming.
  4. Responses are sent back as NWC events (kind 23195)

State (keys, ecash proofs, transaction history) is encrypted with AES-256-GCM and persisted to disk.

For a plain-language deep dive, see HOW-IT-WORKS.md.

Management Console

NUTbits includes a CLI and interactive TUI to manage the daemon while it's running. Open a second terminal and use nutbits to control connections, check balances, pay invoices, and monitor activity, all without restarting the service.

nutbits                    # interactive TUI dashboard
nutbits balance            # check balance across mints
nutbits connections        # list NWC connections
nutbits connect            # create new connection (guided wizard)
nutbits connect --lud16 user@example.com   # attach a Lightning Address
nutbits revoke <label>     # revoke a connection
nutbits pay <invoice>      # pay a Lightning invoice
nutbits receive <amount>   # create an invoice
nutbits history            # transaction history
nutbits fees               # view/manage service fees
nutbits mints              # mint status and health
nutbits relays             # relay connection status
nutbits logs               # recent log output
nutbits watch              # live activity monitor
nutbits config             # view runtime configuration

Create multiple NWC connections with scoped permissions and spending limits; one for LNbits with full access, another for a POS with pay-only and a daily cap. Revoke any connection without affecting the others.

See CLI.md for the full command reference and CONSOLE.md for TUI usage.

Set NUTBITS_API_ENABLED=false in .env to disable the management API entirely.

Web GUI

NUTbits ships with a browser-based GUI in gui/. It talks to the same local management API as the CLI and TUI, so all three interfaces stay in sync.

  • Default local URL: http://127.0.0.1:8080
  • Backend API default: http://127.0.0.1:3338
  • The GUI can bootstrap the local API token automatically when the backend is running on loopback

GUI Pages

Page What it does
Dashboard Live overview: balance, connections, relays, uptime, mint health, recent transactions
Connections Create, view, export, and revoke NWC connections. Card and list views. QR codes for NWC strings.
History Transaction history with volume chart, type/connection filters, and CSV/JSON export
Pay Pay a Lightning invoice or LNURL/Lightning Address from the GUI
Receive Create a Lightning invoice with QR code
Mints Active mint details, multi-mint management, failover priority, NUT capability matrix
Relays Nostr relay status, add/remove relays
NUTs Detailed NUT protocol support for each mint
Fees Service fee earnings dashboard with 7-day chart and per-connection breakdown
Settings All configuration in one place: wallet, network, limits, fees, API, advanced
Logs Live log viewer with level filtering, search, and auto-refresh

Security

  • Encrypted state persistence (AES-256-GCM + scrypt, N=65536)
  • Event deduplication across relays (prevents double-payments)
  • Per-payment and daily spend limits (global + per-connection)
  • Per-connection service fee scoping
  • NWC string masked in logs
  • State file permissions restricted to owner (0600)
  • Atomic state writes (crash-safe)
  • Graceful shutdown with state save
  • Seed-based proof recovery (NUT-09, NUT-13)
  • DLEQ proof verification (NUT-12)

All wallet data (ecash proofs, NWC keys, transaction history) is stored in an encrypted state file. Read BACKUP.md for backup, recovery, and encryption details - this is critical if you're running NUTbits with real funds.

Multi-Mint Failover

NUTbits supports optional multi-mint failover for higher reliability. Configure multiple mints and NUTbits will automatically switch to the next one if the active mint goes down. Your NWC connection string stays the same.

# In .env - first mint is primary, rest are fallbacks
NUTBITS_MINT_URLS=https://your-primary-mint.com,https://your-backup-mint.com

Multi-Mint Failover: Normal -> Failover -> Recovery

  • On startup, NUTbits tries mints in order until one responds
  • If the active mint goes down, it automatically fails over to the next healthy mint
  • A background health check runs every 60s. When the primary mint recovers, NUTbits switches back
  • In-flight invoices are checked against the mint that created them, even during failover
  • Your NWC connection string stays the same throughout

Trade-offs

Ecash proofs are cryptographically bound to the mint that issued them. Proofs from Mint A cannot be spent through Mint B. This means:

  • On failover, your spendable balance is whatever was pre-funded on the new active mint. Proofs on the old mint are not lost; they become spendable again when that mint recovers.
  • In-flight invoices (created but not yet paid) are tied to their originating mint. They will still resolve when that mint comes back online.
  • When a mint recovers, NUTbits automatically switches back and the full balance on that mint is available again.

For self-hosted / personal use

These trade-offs are minimal if you run your own mints. Pre-fund both mints, and failover is seamless. Recovery is automatic.

For multi-user servers

Be aware that switching mints can temporarily affect users trying to pay out, since the spendable balance depends on which mint is active. If you run NUTbits as a funding source for others, consider whether the failover behavior fits your use case before enabling it in production.

Documentation

Document Description
HOW-IT-WORKS.md Plain-language guide; what NUTbits does and why
CONSOLE.md How to use the TUI, CLI, and GUI day-to-day
CLI.md Full command reference - flags, scripting, connections
INSTALL.md Setup guide - bare metal, Docker, LNbits
SERVICE.md 24/7 backend service setup with launchd and systemd
DATABASE.md Storage backends - file, SQLite, MySQL
BACKUP.md Backup, recovery, and encryption details
STATE.md Deep dive into the encrypted state file
AGENTS.md Agent/developer reference for building on NUTbits

Trust Model

Ecash is custodial. The mint holds the funds. Standard risks apply: the mint can steal, get shut down, or get hacked. Only use mints you trust, and only with amounts you can afford to lose.

NUTbits operators can optionally enable a service fee on outgoing payments. This fee is transparent - advertised in the NWC get_info response and reported separately in every pay_invoice response. Receiving payments is always free. By default, no fees are charged.

Related Projects

License

AGPL-3.0 - Free to use, modify, and distribute. If you run a modified version as a network service, you must share your source code.

About

NUTbits is an NWC wallet service that translates between Cashu Mint (NUTs) and Nostr Wallet Connect (NIP-47). It connects to a Cashu mint, manages ecash tokens automatically, and exposes a full NWC server, so any NWC-compatible app (or a nwc LNbits funding source) can send and receive Lightning payments through the mint

Resources

License

Contributing

Security policy

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors