aboutsummaryrefslogtreecommitdiffstats
path: root/src/sw-nwc.js
diff options
context:
space:
mode:
authorAdam Soltys <[email protected]>2026-08-02 22:41:39 -0700
committerAdam Soltys <[email protected]>2026-08-02 22:41:39 -0700
commitd60697c8d1cc0b862d7488be4cf8ee21cafdfd1d (patch)
tree06919a327951f9979cb4ff7cf695bb03483757fd /src/sw-nwc.js
parent817b592bf3e6dbf3f6ef0d88a981efc6c2cc6dca (diff)
downloadcoinosv3-d60697c8d1cc0b862d7488be4cf8ee21cafdfd1d.tar.gz
coinosv3-d60697c8d1cc0b862d7488be4cf8ee21cafdfd1d.zip
Push notifications for payments and messages; offline Spending notice
The nwcpush notifier grows a second registration kind alongside NWC: a notify watch of what it can see without keys — kind-1059 wraps p-tagged at the user (DMs, direct invites), zap receipts (9735/9737), and wraps authored by the user's community channel keys (chat). It pushes a typed nudge, throttled per device (chat bursts collapse); the service worker shows a generic notification unless a window is visible, and tapping opens the app. The names registrar reports settled lightning-address receives server-to-server (token-gated /notify), so the common payment path notifies even with no nostr event in sight. The app registers silently whenever permission is already granted and keeps the watch current as communities change; a dismissible card on the chat home offers to enable it otherwise. Ark zap receipts (9737) join the relay whitelist so the payment watch can see them. Also: the offline Spending receive pane now says you're offline and offers a one-tap switch to Savings instead of spinning forever. Co-Authored-By: Claude Fable 5 <[email protected]> Claude-Session: https://claude.ai/code/session_01Wvj4aoeMZwA7VUGdJP9Swi
Diffstat (limited to 'src/sw-nwc.js')
-rw-r--r--src/sw-nwc.js21
1 files changed, 21 insertions, 0 deletions
diff --git a/src/sw-nwc.js b/src/sw-nwc.js
index b6cfc01..0fdc4d7 100644
--- a/src/sw-nwc.js
+++ b/src/sw-nwc.js
@@ -11,6 +11,27 @@ const NOTIFIER = 'https://nwcpush.coinos.io';
self.addEventListener('push', (e) => {
let data = {};
try { data = e.data ? e.data.json() : {}; } catch (_) {}
+ // User-facing notifications (payments, DMs, community chat). An open
+ // window already shows everything live — stay quiet then.
+ if (data.type === 'notify') {
+ e.waitUntil((async () => {
+ const clients = await self.clients.matchAll({ type: 'window', includeUncontrolled: true });
+ if (clients.some((c) => c.visibilityState === 'visible')) return;
+ const T = {
+ payment: ['Payment received', data.amountSat ? `+${Number(data.amountSat).toLocaleString()} sats — open coinos to see it.` : 'Open coinos to see it.'],
+ dm: ['New message', 'You have a new private message.'],
+ chat: ['New chat activity', 'There are new messages in your communities.'],
+ };
+ const [title, body] = T[data.reason] || T.chat;
+ await self.registration.showNotification(title, {
+ body,
+ icon: 'icon-192.png', badge: 'icon-192.png',
+ tag: 'notify-' + (data.reason || 'chat'), renotify: data.reason === 'payment',
+ data: { url: './' },
+ });
+ })());
+ return;
+ }
if (data.type !== 'nwc') return;
e.waitUntil((async () => {
// An open window handles requests itself with full wallet state — nudge