aboutsummaryrefslogtreecommitdiffstats
path: root/build.js
diff options
context:
space:
mode:
authorAdam Soltys <[email protected]>2026-09-03 22:55:03 -0700
committerAdam Soltys <[email protected]>2026-09-03 22:55:03 -0700
commit618a84ab96f1865f6112d696077390ba184dd9b3 (patch)
tree37d81fa5945dcc1395ac70479193207143140ac1 /build.js
parentc0c6f017324a07fc7850cc2a6b705415b8a9e85c (diff)
downloadcoinosv3-618a84ab96f1865f6112d696077390ba184dd9b3.tar.gz
coinosv3-618a84ab96f1865f6112d696077390ba184dd9b3.zip
Nostr signature verification moves off the main thread: the pool's synchronous verifyEvent (a schnorr check per event, ~560ms on a relay backlog — the profiled carousel-stutter cause) is switched off, and every event is now gated through a Web Worker before any caller sees it. Nothing unverified is ever trusted — the worker runs the same nostr-tools verifyEvent, just on another thread, with a synchronous fallback if the worker is unavailable (standalone file://) or stalls. Bundled to dist/verify-worker.js, precached in the SW
Co-Authored-By: Claude Fable 5 <[email protected]> Claude-Session: https://claude.ai/code/session_01MrkLsNScXe9b6BviUSdmMr
Diffstat (limited to 'build.js')
-rw-r--r--build.js19
1 files changed, 18 insertions, 1 deletions
diff --git a/build.js b/build.js
index e2c0217..e48c4f7 100644
--- a/build.js
+++ b/build.js
@@ -42,7 +42,7 @@ const SW = `const CACHE = 'cold-{{VERSION}}';
// module are available offline too. app-{{VERSION}}.js is the main bundle —
// content-addressed, so a new deploy precaches a new name and the old cache
// is dropped wholesale.
-const SHELL = ['./', 'manifest.webmanifest', 'icon-192.png', 'icon-512.png', 'jsqr.js', 'nip46.js', 'app-{{VERSION}}.js'{{EXTRA_SHELL}}];
+const SHELL = ['./', 'manifest.webmanifest', 'icon-192.png', 'icon-512.png', 'jsqr.js', 'nip46.js', 'verify-worker.js', 'app-{{VERSION}}.js'{{EXTRA_SHELL}}];
self.addEventListener('install', (e) => {
self.skipWaiting();
@@ -181,6 +181,22 @@ export async function buildNip46({ minify = true } = {}) {
return iife(await result.outputs[0].text());
}
+// Off-main-thread nostr event verification worker (classic Worker, its own
+// bundle of nostr-tools verify + noble crypto). NOT wrapped in an IIFE —
+// worker code runs at top level and needs its self.onmessage handler live.
+export async function buildVerifyWorker({ minify = true } = {}) {
+ const result = await Bun.build({
+ entrypoints: ['./src/verify-worker.js'],
+ target: 'browser',
+ minify,
+ });
+ if (!result.success) {
+ for (const log of result.logs) console.error(log);
+ throw new Error('verify-worker bundle failed');
+ }
+ return await result.outputs[0].text();
+}
+
// The notify-only push handler for builds without the ark+nwc features (the
// full builds get the bundled auto-answering handler from src/sw-nwc.js).
const SW_WAKE_ONLY = `self.addEventListener('push', (e) => {
@@ -421,6 +437,7 @@ if (import.meta.main) {
// Lazy-loaded QR decoder — kept out of index.html, fetched only when a
// browser without BarcodeDetector opens the scanner.
+ await Bun.write('dist/verify-worker.js', await buildVerifyWorker());
await Bun.write('dist/jsqr.js', await buildJsQr());
// Lazy-loaded NIP-46 remote-signer client — fetched on first bunker login.
await Bun.write('dist/nip46.js', await buildNip46());