Nostr-native todo manager with encrypted storage and zap bounties.
A demo app showcasing Nostr's potential beyond social media:
- Self-sovereign identity - Your npub is your account
- Encrypted relay storage - Your data, your keys
- Collaborative lists - Share via npub or NIP-05 address
- Public projects - Discoverable task lists anyone can contribute to
- Bounty tasks - Zap payments for completed work
- Reputation - Public event trail of commitments and completions
npm install
npm run dev- A Nostr signer extension — nos2x-fox for Firefox, nos2x or Alby for Chrome
- For bounties: NWC-compatible wallet (Alby, Mutiny, etc.)
- Connect your Nostr identity via browser extension
- Create lists - private (encrypted) or public projects
- Add tasks - with optional due dates, priorities, and bounties
- Share - invite collaborators by npub or NIP-05 address
- Claim & complete - take on bounty tasks, get zapped on verification
All data is stored as encrypted events on Nostr relays. No account creation, no central server, no vendor lock-in.
- docs/NOSTR-PROTOCOL.md - Nostr protocol spec — event schemas, tag conventions, encryption strategy, NIP proposal draft
- docs/PRD.md - Product requirements and roadmap
- docs/PHASE1.md - Implementation checklist
- AGENTS.md - Instructions for AI coding agents
- React 18 + TypeScript + Vite
- Tailwind CSS
- Zustand (state management)
- nostr-tools (Nostr protocol)
Zaptask uses standard NIPs wherever possible. Private data uses NIP-78 (kind 30078). Public projects and bounties enrich events with NIP-31 (alt), NIP-32 (labels), and standard title/t tags for cross-client discoverability.
Full protocol spec, prior art analysis, and a draft NIP proposal for task/bounty events: docs/NOSTR-PROTOCOL.md
| NIP | Purpose |
|---|---|
| NIP-07 | Browser extension signing |
| NIP-31 | Fallback text for unknown event kinds |
| NIP-32 | Labels for status and priority |
| NIP-44 | Encrypted payloads |
| NIP-47 | Nostr Wallet Connect |
| NIP-57 | Zaps |
| NIP-78 | Application-specific data |
Zaptask takes encryption and input validation seriously, even as a demo:
- Event signature verification — All events from relays are verified with
verifyEvent()before processing. Fabricated events are rejected. - NIP-44 preferred — Encryption uses NIP-44 (ChaCha20 + HMAC-SHA256) over the deprecated NIP-04, with automatic fallback for older extensions.
- Content Security Policy — CSP meta tag restricts script/style/connect sources.
- Input validation — Runtime schema validation on all parsed event JSON. Length limits on list names (256 chars) and task titles (1024 chars). Pubkey format validation, relay URL scheme validation, profile image URL validation.
- No secrets in storage — Symmetric
list_keyvalues are stripped from localStorage caches. - Production hardening — Console output stripped in production builds. Error messages sanitized before display.
Known limitations (documented in NOSTR-PROTOCOL.md):
- Share revocation is advisory-only (revoked users still possess the
list_key) - Plaintext tags leak metadata (task-list relationships, sharing social graph, timing)
MIT