# nt — Nostr Terminal (C99) A fast, no-nonsense terminal client for [Nostr](https://nostr.com), written in C99. This is a from-scratch port of the original Node.js [`nt`](resources/NostrTerminal_5/nt.mjs) (NostrTerminal_5), built on top of [`nostr_core_lib`](resources/nostr_core_lib/) for protocol, crypto, and NIP support. --- ## Philosophy **Fast in, fast out.** `nt` is designed to feel like a CLI utility, not a chat app. There is **no persistent relay pool**. Every action follows the same pattern: 1. **Connect** to the relays needed for the operation 2. **Do the thing** (publish an event, fetch a profile, query notes…) 3. **Disconnect** This keeps the program lightweight, predictable, and easy to reason about: - No background threads babysitting sockets - No reconnection storms - No hidden state between commands - Memory and FDs return to zero between operations - Trivial to script, embed in pipelines, or run on constrained hardware When you want streaming behavior (e.g. a live feed), you explicitly enter that mode and explicitly leave it — at which point the sockets close. --- ## Goals - **Fast startup, fast shutdown.** Sub-second from launch to first prompt. - **Tiny footprint.** Single static binary, minimal dependencies. - **Predictable.** One screen, one job. Connect → act → disconnect. - **Hackable.** C99, well-organized source, easy to fork. - **Self-contained.** Local SQLite cache; no daemon, no server. ## Non-Goals - Maintaining long-lived relay connections in the background - Acting as a relay yourself (the original Node version had a stub WSS — dropped here) - Being a full-featured GUI client - Push notifications --- ## Features (planned) See [`planning.md`](planning.md) for the full breakdown by priority. ### Core (P0) - Login via seed phrase, nsec, npub, or NIP-46 bunker - Profile view/edit (KIND 0) - Relay management (KIND 10002) - Quick tweet (KIND 1) - Follows list (KIND 3) ### Reading & Writing (P1) - Live feeds (follows, mentions, notifications, firehose) — explicit subscribe mode - Long-form posts (KIND 30023 / 30024) with `vipe` editor integration - Encrypted DMs (NIP-17 sealed, NIP-04 legacy) - Notifications digest ### Extras (P2) - Encrypted todo list - Daily diary - Cashu eCash wallet (NIP-60 / NIP-61) - AI prompts (Venice.ai / local Ollama) ### Experimental (P3) - Circus mode (AI persona swarm) - Blossom media server management - Bulk database maintenance --- ## Architecture ``` ┌─────────────────────────────────────────────┐ │ nt (this project) │ │ ┌──────────┐ ┌─────────┐ ┌──────────────┐ │ │ │ TUI │ │ Menus │ │ SQLite Cache│ │ │ │ (ncurses)│ │ (C99) │ │ (~/.nostr) │ │ │ └──────────┘ └─────────┘ └──────────────┘ │ │ │ │ │ │ │ └───────────┼────────────┘ │ │ ▼ │ │ ┌────────────────────────┐ │ │ │ Connect → Act → Close │ │ │ └────────────────────────┘ │ │ │ │ └─────────────────────┼────────────────────────┘ ▼ ┌─────────────────────────┐ │ nostr_core_lib │ │ (NIPs, crypto, pool, │ │ websocket, cashu, │ │ blossom, http) │ └─────────────────────────┘ │ ▼ ┌──────────────┐ │ Nostr Relays│ │ (transient) │ └──────────────┘ ``` Local SQLite at `~/.nostr/nostr.db` is the only persistent state between invocations. It caches: - Events (regular / replaceable / addressable / ephemeral) - Relay metadata (NIP-11 info, RTT, kind-1 acceptance tests) - People (cached pubkeys, names) - Publish history (`relay_posts`) - Local key/value state --- ## Dependencies **Build host:** - Docker (required) ### Runtime Dependencies `nt` is built as a fully static binary. Host runtime package dependencies are not required. TUI runtime note: `nt` uses the ncurses alternate screen buffer with a footer-log status line for latest action results; use the **View log** main menu entry to open the full scrollable action history. ### TUI Features - Arrow-key navigation + shortcut keys in all menus - Scrollable tables with PgUp/PgDn - Footer status bar showing latest action result - **View log** menu entry to scroll through full action history - Full-screen pager for long content (event JSON, blog posts, relay info) - Modal dialogs for errors and confirmations **Libraries (vendored in `resources/nostr_core_lib`):** - `nostr_core_lib` — Nostr protocol, NIPs, crypto, relay pool, websocket - `cJSON` — JSON parsing **External tools (optional, runtime):** - `vipe` (from `moreutils`) — for editor-based note composition - `brave-browser` — for the optional web UI launcher --- ## Building ```bash git clone cd nostr_terminal ./build.sh ./nt ``` This project is **static-only**. The only supported build path is [`build.sh`](build.sh), which builds inside Docker (Alpine/musl), verifies static linkage, and emits a single binary at [`./nt`](nt). --- ## Project Layout ``` nostr_terminal/ ├── README.md ← you are here ├── planning.md ← detailed feature/menu breakdown ├── build.sh ← only supported build entrypoint (static-only) ├── src/ ← nt source code (C99) ├── include/ ← nt public headers ├── tests/ ← unit & integration tests └── resources/ ├── nostr_core_lib/ ← vendored protocol library └── NostrTerminal_5/ ← reference Node.js implementation ``` --- ## Status 🚧 **Early planning / scaffolding.** See [`planning.md`](planning.md) for the implementation roadmap and per-menu status. --- ## License TBD