diff options
| author | Adam Soltys <[email protected]> | 2026-10-23 07:39:05 -0700 |
|---|---|---|
| committer | Adam Soltys <[email protected]> | 2026-10-23 07:39:05 -0700 |
| commit | b3cee21d7f6614c4ec0cf462ba4cfe3a3d4e308c (patch) | |
| tree | 6a509af445ba45412e4bcf06c5c06ecbb45c6ccc /src/sw-nwc.js | |
| parent | c143b7dbe900df9a644bb67b87a92fd208e1ee74 (diff) | |
| download | coinosv3-b3cee21d7f6614c4ec0cf462ba4cfe3a3d4e308c.tar.gz coinosv3-b3cee21d7f6614c4ec0cf462ba4cfe3a3d4e308c.zip | |
iPhone: a push shows its line first and the outcome replaces it; a crash loop on open lands in safe mode; a closed-app payment is one history row
PullCap's night of 2026-10-22 on an iPhone: four hourly payments made while
closed, no notification for the fourth, then no more wake-ups until the app
was opened — WebKit's silent-push quota. APNs accepted every push (no 410);
the device had stopped listening. The stand-in line went up at the END of
the push handler, after a payment that can take most of the budget, and a
worker stopped before its last line showed nothing. On an Apple endpoint the
line now goes up first and the outcome ("Payment sent") replaces it.
The same phone then crashed on every open ("A problem repeatedly occurred").
An inline guard counts page starts before the app runs; the app clears the
count after eight seconds alive or a clean leave, and notes the boot phase
it reaches. A third start in a row opens in safe mode: no automatic Ark
connection, a notice naming the last phase, "Open normally" and "Copy
report".
Every payment the worker made showed twice once the app opened: the worker's
own ln-send row (merged from the mirror) and the "while closed" note the app
adds from its spend log. The note now stamps the existing row, and
lnFoldedIds hides a twin that still forms. The balance was never counted
twice — it comes from the coins.
Co-Authored-By: Claude Fable 5.1 <[email protected]>
Diffstat (limited to 'src/sw-nwc.js')
| -rw-r--r-- | src/sw-nwc.js | 15 |
1 files changed, 14 insertions, 1 deletions
diff --git a/src/sw-nwc.js b/src/sw-nwc.js index 0b65268..dbd2d98 100644 --- a/src/sw-nwc.js +++ b/src/sw-nwc.js @@ -155,14 +155,25 @@ self.addEventListener('push', (e) => { if (data.type !== 'nwc') { settle(async () => {}); return; } const startedAt = Date.now(); settle(async () => { + // WebKit's silent-push quota counts a push whose notification comes + // late: a payment can take most of the push budget, and a worker stopped + // before its last line never shows one (PullCap's night of 2026-10-22: + // four payments, no line for the fourth, then no more wakes). On an + // Apple endpoint the stand-in goes up FIRST; the outcome replaces it. + const apple = await applePush(); + const dropStandIn = async () => { + const open = await self.registration.getNotifications({ tag: 'coinos-bg' }).catch(() => []); + for (const n of open) n.close(); + }; + if (apple) { showed = true; await standIn(false).catch(() => {}); } // An open window handles requests itself with full wallet state — nudge // it and stay out of the way. On iOS only one on screen counts: a // backgrounded app is suspended, so a nudge to it went unanswered. const all = await self.clients.matchAll({ type: 'window', includeUncontrolled: true }); - const apple = await applePush(); const clients = all.filter((c) => !apple || c.visibilityState === 'visible'); if (clients.length) { for (const c of clients) c.postMessage({ type: 'nwc-wake', servicePubkey: data.servicePubkey }); + if (apple) await dropStandIn(); // the window on screen shows it live return; } // A wake is the only moment a closed wallet gets to look after its coins: @@ -189,6 +200,7 @@ self.addEventListener('push', (e) => { tag: handled.notify.tag || 'nwc-incoming', renotify: true, data: { url: './' }, }); + if (apple) await dropStandIn(); await tend(); return; } @@ -204,6 +216,7 @@ self.addEventListener('push', (e) => { tag: 'nwc-' + (data.servicePubkey || 'req'), renotify: false, data: { url: './' }, }); + if (apple) await dropStandIn(); }); }); |
