Add Nostr Feed Manager: Rust backend with Electron + React GUI
- Rust library (nostr-manager-backend) with CLI and JSON-lines IPC serve mode: profiles, publishing with per-relay reports, relays, settings, vault storage and legacy-vault migration - Electron + React + TypeScript desktop GUI using the same backend over stdio IPC - Vitest suite with a fake backend speaking the real protocol - electron-builder linux packaging; README with build and usage instructions
This commit is contained in:
commit
7e3bac345c
68 changed files with 18262 additions and 0 deletions
139
README.md
Normal file
139
README.md
Normal file
|
|
@ -0,0 +1,139 @@
|
|||
# Nostr Feed Manager
|
||||
|
||||
A friendly Linux desktop application for managing Nostr profiles and publishing text notes.
|
||||
|
||||
It pairs a Rust core (the same library behind the original command-line tool) with a polished
|
||||
Electron + React interface. All Nostr logic — key generation, signing, relay communication —
|
||||
runs in the Rust backend, which the GUI talks to over a JSON-lines IPC channel.
|
||||
|
||||
## Features
|
||||
|
||||
- Create and switch between Nostr profiles (`npub` addresses)
|
||||
- Publish short text notes to the Nostr network
|
||||
- Per-relay publish reports: you always know where a note was accepted
|
||||
- Add, remove, enable/disable, and test relays
|
||||
- Light / dark / system theme, configurable publish confirmation and key shortening
|
||||
- Back up your vault from the UI
|
||||
- Honest about security: the vault is stored in plaintext (as in the original CLI), readable
|
||||
only by your user account; this is clearly disclosed in the app
|
||||
|
||||
## Architecture
|
||||
|
||||
```
|
||||
┌──────────────────────────┐ JSON-lines over stdio ┌──────────────────────────┐
|
||||
│ Electron (React) GUI │ ────────────────────────────────▶ │ Rust backend │
|
||||
│ - React + TypeScript │ {"id":1,"method":"publish_note",│ - nostr-sdk 0.40 │
|
||||
│ - renders in app:// │ "params":{"content":"..."}} │ - vault / keys / signing │
|
||||
│ - never sees secret keys │ ◀──────────────────────────────── │ - relay communication │
|
||||
└──────────────────────────┘ {"id":1,"status":"ok","data":…} └──────────────────────────┘
|
||||
```
|
||||
|
||||
- `src/` — the Rust library (`nostr-manager-backend`). Exposes the same functionality as a
|
||||
command-line binary and as a long-running `serve` process.
|
||||
- `frontend/electron/` — the Electron main and preload scripts. The main process spawns the
|
||||
Rust backend and correlates requests by `id`.
|
||||
- `frontend/src/` — the React renderer. It talks only to a thin `window.backend` bridge;
|
||||
profile summaries and publish reports contain no secret material.
|
||||
|
||||
## Requirements
|
||||
|
||||
- Rust (stable) and Cargo
|
||||
- Node.js 20+ and npm
|
||||
- Linux with a display server (X11 or Wayland)
|
||||
|
||||
The Rust backend also exists as a standalone CLI if you prefer the terminal.
|
||||
|
||||
## Building and running the GUI
|
||||
|
||||
```sh
|
||||
# 1. Build the Rust backend (release)
|
||||
cargo build --release
|
||||
|
||||
# 2. Install frontend dependencies
|
||||
cd frontend
|
||||
npm install
|
||||
|
||||
# 3. Run the app (production-style, served from the built bundle via app://)
|
||||
npm start
|
||||
```
|
||||
|
||||
During development you can use Vite's live-reloading renderer instead:
|
||||
|
||||
```sh
|
||||
# terminal 1
|
||||
npm run dev # starts Vite on http://localhost:5173
|
||||
|
||||
# terminal 2
|
||||
NOSTR_GUI_DEV_URL=http://localhost:5173 npm start
|
||||
```
|
||||
|
||||
### Packaging
|
||||
|
||||
```sh
|
||||
cd frontend
|
||||
npm run dist # builds the renderer + backend and runs electron-builder
|
||||
```
|
||||
|
||||
The unpacked application lands in `frontend/release/linux-unpacked/`; launch it with
|
||||
`./nost-feed-manager`.
|
||||
|
||||
## Command-line usage
|
||||
|
||||
The Rust crate builds a single binary with both a CLI and the GUI IPC server:
|
||||
|
||||
```sh
|
||||
cargo run --release -- create "Alice" # create a profile
|
||||
cargo run --release -- list # list profiles (no secret keys)
|
||||
cargo run --release -- switch <npub> # select the active profile
|
||||
cargo run --release -- publish <npub> "Hello" # publish a text note
|
||||
cargo run --release -- relays list|add|remove|enable|disable|test
|
||||
cargo run --release -- settings get|set theme|confirm|shorten
|
||||
cargo run --release -- info # show storage locations
|
||||
cargo run --release -- serve # JSON-lines IPC server (used by the GUI)
|
||||
```
|
||||
|
||||
## Storage and migration
|
||||
|
||||
- The vault (`profiles_vault.json`) and settings live in
|
||||
`$XDG_DATA_HOME/nost-feed-manager/` (defaulting to `~/.local/share/nost-feed-manager/`),
|
||||
created with permissions `0700` for the directory and `0600` for the files.
|
||||
- The original CLI saved `profiles_vault.json` in its working directory. On first launch this
|
||||
app finds that file, copies it to a timestamped `*.backup-<ts>` next to it, and imports your
|
||||
profiles into the new location. The original file is left untouched.
|
||||
- Private keys are stored in the vault in plaintext. Anyone with access to your user account
|
||||
can read them; a password-encrypted vault is planned for a future version.
|
||||
|
||||
## Development
|
||||
|
||||
```sh
|
||||
cd frontend
|
||||
npm run typecheck # TypeScript (renderer + electron)
|
||||
npm run lint # ESLint
|
||||
npm run format:check # Prettier
|
||||
npm test # Vitest (jsdom), including IPC-level fake backend tests
|
||||
|
||||
cd ..
|
||||
cargo test # Rust unit tests
|
||||
cargo fmt --check # formatting
|
||||
cargo clippy --all-targets
|
||||
```
|
||||
|
||||
## Project layout
|
||||
|
||||
```
|
||||
src/ Rust library + CLI + IPC server
|
||||
app.rs application state loading/persistence
|
||||
errors.rs structured AppError
|
||||
ipc.rs JSON-lines serve() loop and request/reply envelope
|
||||
main.rs CLI entry point
|
||||
profiles.rs profile create/list/select
|
||||
publish.rs note publishing with per-relay reports
|
||||
relays.rs default relays, validation, connection tests
|
||||
settings.rs theme and user preferences
|
||||
vault.rs encrypted-vault-ready storage (currently plaintext)
|
||||
frontend/
|
||||
electron/ Electron main + preload (backend spawn, IPC, clipboard)
|
||||
src/ React app (components, screens, state, styles)
|
||||
src/test/ Vitest suite with a fake backend speaking the real protocol
|
||||
package.json scripts and electron-builder config
|
||||
```
|
||||
Loading…
Add table
Add a link
Reference in a new issue