mirror of
https://github.com/hoornet/vega.git
synced 2026-04-23 22:30:00 -07:00
Clean up repo: private_docs dir, update AGENTS.md, harden gitignore
Move all private documents (grant app, specs, research, drafts) into gitignored private_docs/ directory. Update AGENTS.md to reflect current Vega state (was still referencing Wrystr). Simplify gitignore rules.
This commit is contained in:
11
.gitignore
vendored
11
.gitignore
vendored
@@ -18,18 +18,11 @@ dist-ssr
|
||||
# Build artifacts / test screenshots
|
||||
squashfs-root/
|
||||
phase-4-tests/
|
||||
phase-4.md
|
||||
*.png
|
||||
!src-tauri/icons/*.png
|
||||
|
||||
# Private / not for public repo
|
||||
OPENSATS_APPLICATION.md
|
||||
PHASE6.md
|
||||
RENAME_ARTICLE_DRAFT.md
|
||||
TODO.md
|
||||
NOSTR_POST_*.md
|
||||
SHELLEY_SPEC.md
|
||||
docs/
|
||||
# Private docs (drafts, specs, research, grant applications)
|
||||
private_docs/
|
||||
test/accounts.json
|
||||
|
||||
# AI agent / editor state
|
||||
|
||||
241
AGENTS.md
241
AGENTS.md
@@ -1,17 +1,16 @@
|
||||
# AGENTS.md — Vega
|
||||
|
||||
This file guides AI coding agents (Claude Code, Copilot, etc.) working on this codebase.
|
||||
Read it fully before making changes. Follow the conventions here strictly.
|
||||
This file guides AI coding agents working on this codebase.
|
||||
**See `CLAUDE.md` for the authoritative, up-to-date architecture and conventions.**
|
||||
|
||||
---
|
||||
|
||||
## What is Wrystr?
|
||||
## What is Vega?
|
||||
|
||||
Wrystr is a cross-platform desktop Nostr client built for Mac, Windows, and Linux.
|
||||
The goal is to be the best Nostr desktop experience — polished UI, deep Lightning
|
||||
integration, full NIP coverage, and performance that feels native, not webby.
|
||||
|
||||
Named as a nod to Nostr with a wry twist. The `-str` suffix is intentional.
|
||||
Vega is a cross-platform desktop Nostr client built for Mac, Windows, and Linux.
|
||||
Named after Jurij Vega (1754–1802), Slovenian mathematician.
|
||||
The goal: best Nostr desktop experience — polished UI, deep Lightning integration,
|
||||
full NIP coverage, performance that feels native.
|
||||
|
||||
---
|
||||
|
||||
@@ -20,133 +19,13 @@ Named as a nod to Nostr with a wry twist. The `-str` suffix is intentional.
|
||||
| Layer | Technology |
|
||||
|---|---|
|
||||
| Desktop shell | Tauri 2.0 (Rust backend) |
|
||||
| Frontend | React + TypeScript (Vite) |
|
||||
| Nostr protocol | NDK (Nostr Dev Kit for JS) |
|
||||
| Lightning | Nostr Wallet Connect (NIP-47) primary; LND/CLN gRPC optional |
|
||||
| Styling | Tailwind CSS |
|
||||
| Frontend | React 19 + TypeScript (Vite 7) |
|
||||
| Nostr protocol | NDK (Nostr Dev Kit) |
|
||||
| Lightning | Nostr Wallet Connect (NIP-47) |
|
||||
| Styling | Tailwind CSS 4 |
|
||||
| State management | Zustand |
|
||||
| Local storage | SQLite via Tauri plugin (tauri-plugin-sql) |
|
||||
| Key storage | OS keychain via Tauri plugin (tauri-plugin-keychain) |
|
||||
|
||||
Rust is used for: key management, secure storage, native node connections, system tray,
|
||||
OS notifications. TypeScript/React handles all UI and Nostr logic via NDK.
|
||||
|
||||
---
|
||||
|
||||
## Project Structure
|
||||
|
||||
```
|
||||
wrystr/
|
||||
├── src-tauri/ # Rust backend (Tauri)
|
||||
│ ├── src/
|
||||
│ │ ├── main.rs
|
||||
│ │ ├── commands/ # Tauri commands exposed to frontend
|
||||
│ │ ├── keys/ # Key management, signing
|
||||
│ │ ├── lightning/ # LND/CLN direct node connections
|
||||
│ │ └── storage/ # SQLite, keychain wrappers
|
||||
│ └── Cargo.toml
|
||||
├── src/ # React frontend
|
||||
│ ├── main.tsx
|
||||
│ ├── App.tsx
|
||||
│ ├── components/ # Reusable UI components
|
||||
│ │ ├── feed/
|
||||
│ │ ├── notes/
|
||||
│ │ ├── profile/
|
||||
│ │ ├── lightning/
|
||||
│ │ └── shared/
|
||||
│ ├── views/ # Full page/screen views
|
||||
│ ├── stores/ # Zustand state stores
|
||||
│ ├── hooks/ # Custom React hooks
|
||||
│ ├── lib/
|
||||
│ │ ├── nostr/ # NDK setup, relay management, NIP helpers
|
||||
│ │ └── lightning/ # NWC client, zap flows, LNURL
|
||||
│ └── types/ # Shared TypeScript types
|
||||
├── AGENTS.md
|
||||
├── README.md
|
||||
└── package.json
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Nostr Protocol Coverage
|
||||
|
||||
### Priority 1 — Core (must be solid before anything else)
|
||||
- NIP-01 Basic protocol (events, subscriptions, relay communication)
|
||||
- NIP-02 Follow lists
|
||||
- NIP-03 OpenTimestamps (optional but nice)
|
||||
- NIP-10 Reply threading
|
||||
- NIP-11 Relay metadata (used for relay health display)
|
||||
- NIP-19 bech32 encoding (npub, nsec, note, nprofile, nevent)
|
||||
- NIP-21 `nostr:` URI scheme
|
||||
- NIP-25 Reactions
|
||||
- NIP-27 Text note references
|
||||
- NIP-50 Full-text search
|
||||
|
||||
### Priority 2 — Lightning & Social
|
||||
- NIP-47 Nostr Wallet Connect (primary Lightning integration)
|
||||
- NIP-57 Lightning Zaps
|
||||
- NIP-65 Relay list metadata (outbox model)
|
||||
|
||||
### Priority 3 — Rich features
|
||||
- NIP-04 Legacy encrypted DMs (keep for compatibility)
|
||||
- NIP-44 Encrypted payloads (new DM standard)
|
||||
- NIP-17 Private Direct Messages
|
||||
- NIP-23 Long-form content (articles)
|
||||
- NIP-36 Sensitive content warnings
|
||||
- NIP-51 Lists (mute lists, bookmarks, etc.)
|
||||
- NIP-72 Moderated communities
|
||||
- NIP-94 File metadata
|
||||
- NIP-96 File storage (media uploads)
|
||||
- NIP-98 HTTP Auth
|
||||
|
||||
---
|
||||
|
||||
## Lightning Integration
|
||||
|
||||
**Primary path: NWC (NIP-47)**
|
||||
- Widest wallet compatibility (Alby, Mutiny-compatible, etc.)
|
||||
- Handles: pay invoice, make invoice, get balance, list transactions
|
||||
- UI: inline zap buttons that feel instant, not modal-heavy
|
||||
|
||||
**Secondary path: Direct node connection**
|
||||
- LND via gRPC (Rust backend)
|
||||
- Core Lightning via REST
|
||||
- Handled entirely in `src-tauri/src/lightning/`
|
||||
- Never expose node credentials to the frontend layer
|
||||
|
||||
**LNURL support**
|
||||
- lnurl-pay, lnurl-auth, lightning address resolution
|
||||
- Lightning address shown on profiles when available
|
||||
|
||||
**Zap flow UX goal:**
|
||||
Zapping should feel as fast and frictionless as a like button.
|
||||
No unnecessary confirmation dialogs for small amounts.
|
||||
Custom amounts and messages available but not forced.
|
||||
|
||||
---
|
||||
|
||||
## Key Management
|
||||
|
||||
- **nsec** stored encrypted in OS keychain (never in localStorage or SQLite)
|
||||
- Support multiple accounts
|
||||
- NIP-07 browser extension passthrough for users who prefer that flow
|
||||
- Hardware signer support (NIP-07-compatible) — future
|
||||
- Key generation uses Rust (cryptographically secure)
|
||||
- Signing can be delegated to Rust backend via Tauri commands to avoid
|
||||
exposing private keys to the JS layer
|
||||
|
||||
---
|
||||
|
||||
## UI / UX Principles
|
||||
|
||||
- Target quality bar: **Telegram Desktop**. Fast, keyboard-navigable, no loading spinners
|
||||
where possible, snappy transitions.
|
||||
- Feels like a native app, not a web page in a frame.
|
||||
- NOT a "crypto app" — no unnecessary blockchain/wallet jargon in the UI.
|
||||
Use plain language: "Send tip" not "Broadcast zap transaction".
|
||||
- Dark mode by default. Light mode supported.
|
||||
- Responsive within desktop constraints (min window ~900px wide).
|
||||
- Keyboard shortcuts for all primary actions.
|
||||
| Local storage | SQLite via `rusqlite` (bundled) |
|
||||
| Key storage | OS keychain via `keyring` crate |
|
||||
|
||||
---
|
||||
|
||||
@@ -154,93 +33,35 @@ Custom amounts and messages available but not forced.
|
||||
|
||||
### TypeScript / React
|
||||
- Functional components only, no class components
|
||||
- Hooks for all logic — no business logic directly in components
|
||||
- Zustand stores per domain (feed, profile, relays, lightning, ui)
|
||||
- Types defined in `src/types/` — never use `any`
|
||||
- NDK interactions go through `src/lib/nostr/` — not called directly in components
|
||||
- Use `async/await` over `.then()` chains
|
||||
- Error boundaries around major UI sections
|
||||
- Zustand stores per domain (`src/stores/`)
|
||||
- Types in `src/types/` — never use `any`
|
||||
- NDK interactions only through `src/lib/nostr/` wrapper
|
||||
- Lightning/NWC only through `src/lib/lightning/` wrapper
|
||||
- Tailwind classes only — no inline styles (except unavoidable WebkitUserSelect)
|
||||
|
||||
### Rust
|
||||
- All Tauri commands in `src-tauri/src/commands/`
|
||||
- Return `Result<T, String>` from Tauri commands for consistent error handling on the JS side
|
||||
- Sensitive operations (key access, node credentials) must never log to console in production
|
||||
- Use `serde` for all JSON serialization
|
||||
- Commands return `Result<T, String>`
|
||||
- Private keys only in OS keychain via `keyring` crate
|
||||
- No secrets logged in production
|
||||
|
||||
### General
|
||||
- No secrets, keys, or credentials ever committed to git
|
||||
- `.env` for dev config, `.env.example` committed as template
|
||||
- Prefer explicit over clever — this codebase should be readable by someone new
|
||||
|
||||
---
|
||||
|
||||
## Relay Management
|
||||
|
||||
- Connect to multiple relays simultaneously
|
||||
- Display relay health (latency, NIP support from NIP-11)
|
||||
- Outbox model (NIP-65): write to user's own relays, read from followed users' relays
|
||||
- Default relay list for new users
|
||||
- Relay list persisted locally and synced to Nostr (NIP-65 events)
|
||||
|
||||
---
|
||||
|
||||
## Development Setup
|
||||
|
||||
```bash
|
||||
# Prerequisites: Node.js 20+, Rust stable, Tauri CLI
|
||||
npm install
|
||||
npm run tauri dev # starts dev build with hot reload
|
||||
npm run tauri build # production build
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Thread View (next major feature after reactions/replies)
|
||||
|
||||
Clicking a note should open a thread view showing:
|
||||
- The root note
|
||||
- All replies in chronological order (or threaded if nested)
|
||||
- An inline reply composer at the bottom
|
||||
|
||||
This is essential for replies to feel complete — right now replies are posted to the network but there's no way to read them in context within the app.
|
||||
|
||||
Implementation notes:
|
||||
- Fetch replies via `kinds: [1], #e: [noteId]` NDK filter
|
||||
- Thread view can be a new `currentView` in the UI store, with a `selectedNote` state
|
||||
- Back navigation returns to the feed
|
||||
|
||||
---
|
||||
|
||||
## Onboarding
|
||||
|
||||
Nostr onboarding is notoriously bad across most clients. Wrystr should be the exception.
|
||||
Goals:
|
||||
- Key generation built-in (no "go get a browser extension first")
|
||||
- Human-readable explanation of what a key is, without crypto jargon
|
||||
- One-click backup flow (show nsec, prompt to save it somewhere)
|
||||
- Optional: sign up with email/password via a custodial key service for non-technical users, with a clear path to self-custody later
|
||||
- New users should see interesting content immediately, not a blank feed
|
||||
|
||||
This is a first-class feature, not an afterthought.
|
||||
- No secrets, keys, or credentials committed to git
|
||||
- Private docs (drafts, specs, research) go in `private_docs/` (gitignored)
|
||||
- Prefer explicit over clever
|
||||
|
||||
---
|
||||
|
||||
## What to Avoid
|
||||
|
||||
- Do NOT add new dependencies without checking if something in the existing stack covers it
|
||||
- Do NOT store private keys anywhere except the OS keychain via Tauri plugin
|
||||
- Do NOT add paywalls or restrictions to core social/protocol features
|
||||
- Do NOT expose Lightning node credentials to the frontend/JS layer
|
||||
- Do NOT break the single-shot zap flow with unnecessary confirmation modals
|
||||
- Do NOT add dependencies without checking if the existing stack covers it
|
||||
- Do NOT store private keys anywhere except the OS keychain
|
||||
- Do NOT expose Lightning credentials to the frontend/JS layer
|
||||
- Do NOT use inline styles — use Tailwind classes
|
||||
- Do NOT add paywalls to core social/protocol features
|
||||
|
||||
---
|
||||
|
||||
## Monetization Context
|
||||
## Monetization
|
||||
|
||||
Wrystr will support monetization through:
|
||||
- Built-in developer Lightning address (tip jar, visible in About)
|
||||
- Optional paid relay tier (run separately)
|
||||
- One-time purchase / sponsorship tier for power features
|
||||
|
||||
Keep core social features fully free and open. Monetization lives at the edges.
|
||||
Open source client (MIT) + closed source server-side premium services.
|
||||
Core social features stay fully free. Revenue at the edges (PRO relay, NIP-05, analytics).
|
||||
|
||||
Reference in New Issue
Block a user