Replace the browser Notification constructor (tab-must-be-open) with nostr-push
Web Push notifications that work even when the browser is closed.
- Add service worker (public/sw.js) for receiving and displaying push events
- Add nostr-push RPC client (src/lib/nostrPush.ts) using an ephemeral device
keypair for signing — the user's Nostr signer is never prompted
- Add usePushNotifications hook managing the full lifecycle: SW registration,
VAPID key fetch, pushManager.subscribe, and nostr-push registration
- Replace the web path in useNativeNotifications with push registration that
auto-enables/disables based on the notificationsEnabled encrypted setting
- Android native Capacitor path is unchanged
- Requires VITE_NOSTR_PUSH_PUBKEY env var (hex pubkey of the nostr-push server)
Sentry SDK is loaded via dynamic import() only when a DSN is configured
and error reporting is enabled, keeping it out of the initial bundle.
Users can control error reporting via a toggle and DSN field in
Advanced Settings, with the DSN synced across devices via encrypted
NIP-78 settings. The ErrorBoundary now reports fatal crashes to Sentry
with component stack context, and a beforeSend hook censors nsec
private keys before any data leaves the browser.