Browser push notification#50
Closed
Opeyemi01-del wants to merge 2 commits into
Closed
Conversation
|
@Rocket1960 is attempting to deploy a commit to the truthixify's projects Team on Vercel. A member of the Team first needs to authorize it. |
Contributor
|
Closing this one because it overlaps fully with your other open PR #49: every Let's split cleanly:
That keeps each PR focused on one issue and avoids the conflict. Thanks @Opeyemi01-del. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
feat(stellar): browser push notifications for incoming payments
Closes #21
Add a service-worker-driven, opt-in notification system that alerts
users when a Stellar stealth payment arrives — even when the Receive
tab is closed. Default OFF; the user must affirmatively enable.
New files
src/lib/notification-storage.ts
IndexedDB wrapper and AES-256-GCM crypto helpers. Persists the
encrypted viewing key, cursor, and rate-limit timestamp. The viewing
key is encrypted with a key derived via PBKDF2 (100 000 iterations)
from the wallet signing output — it never leaves the device in
plaintext. Disabling notifications calls clearState(), which
immediately deletes the key from storage.
src/hooks/useStellarNotifications.ts
React hook managing the full opt-in lifecycle:
(Chrome/Edge 80+), or fall back to a 5-minute setInterval ping
loop when PBS is unavailable (Firefox, iOS Safari)
Disable() unregisters PBS, clears IndexedDB state, and stops the
ping loop.
src/components/StellarNotificationToggle.tsx
Self-contained opt-in widget for the Receive page:
the viewing key storage trade-off and spending key guarantee
Notification.permission === 'denied'
iOS Safari support is limited."
src/sw/stellar-notification-sw.ts → public/stellar-notification-sw.js
Service worker handling three events:
Core scan flow:
1. Read NotificationState from IndexedDB
2. Decrypt viewing key in memory via PBKDF2 + AES-GCM
3. Fetch Horizon announcements since lastSeenCursor
4. Spawn Web Worker (/stellar-scan-worker.js) for EC math
5. showNotification() if matches found and not rate-limited
6. Persist nextCursor and lastNotifiedAt
Notification design:
- Title: "Wraith Payment received" (single) or
"Wraith N new payments" (batch)
- Body: "Stellar payment of X XLM to your stealth address GABCD…EF12"
- Icon: /wraith-192.png, badge: /wraith-badge-96.png
- data.chain: 'stellar' (prevents cross-chain confusion)
- Rate limit: one notification per 5 min per chain; multiple
arrivals batched into a single summary notification
Includes inline IndexedDB and PBKDF2/AES-GCM helpers duplicated
from notification-storage.ts — SWs cannot import main-thread
modules so the crypto is self-contained.
src/workers/stellar-scan-worker.ts → public/stellar-scan-worker.js
Standalone Web Worker spawned by the SW. Calls
scanAnnouncements() from @wraith-protocol/sdk/chains/stellar, posts
{ matches } or { error } back to the SW. Offloads EC math to avoid
blocking the SW event loop, which would delay the notification.
scripts/build-sw.sh
esbuild script compiling the SW and scan worker to public/ without
requiring vite-plugin-pwa. Run before pnpm dev for the first time.
Modified files
vite.config.ts
Adds the scan worker as a named Rollup entry (stellar-scan-worker)
so it lands at /stellar-scan-worker.js where the SW can new Worker()
it. Adds optional vite-plugin-pwa integration in injectManifest mode
for teams that want the full PWA pipeline.
Integration (StellarReceive.tsx three-line patch)
See src/components/StellarReceive.integration.ts. Summary:
Privacy model
with IndexedDB access cannot decrypt without the wallet signature.
Browser compatibility
Chrome/Edge 80+ Full PBS, background scans when tab is closed
Firefox Ping-loop fallback, works while tab is open
iOS Safari 16.4+ Limited; PBS fires infrequently, PWA only
Other Ping-loop only (tab must stay open)
Acceptance criteria
[x] Opt-in flow + permission handling (granted / denied / unsupported)
[x] Service worker periodic scan (PBS tag wraith-stellar-scan)
[x] Notifications fire with correct title / body / icon / chain tag
[x] Privacy disclosure visible at opt-in
[x] Killswitch: disable() unregisters PBS + clears IndexedDB state
[x] Rate limiting: max 1 notification per 5 min, batching for N > 1
[x] Notification click focuses/opens /receive
[x] iOS / Firefox fallback documented and implemented