diff options
Diffstat (limited to 'src/verify-worker.js')
| -rw-r--r-- | src/verify-worker.js | 66 |
1 files changed, 51 insertions, 15 deletions
diff --git a/src/verify-worker.js b/src/verify-worker.js index 679c1a8..1f5203f 100644 --- a/src/verify-worker.js +++ b/src/verify-worker.js @@ -1,19 +1,55 @@ -// Off-main-thread nostr event verification. Schnorr signature checks (real -// secp256k1) on a relay backlog blocked the UI on boot / when a community -// opens — the carousel-stutter cause a CPU profile pinned to verifyEvent. This -// worker does that work on another thread; the main thread posts events and -// gets back a boolean per event, so the page never freezes on a burst. +// Off-main-thread nostr crypto. Schnorr signature checks (real secp256k1) on +// a relay backlog blocked the UI on boot / when a community opens — the +// carousel-stutter cause a CPU profile pinned to verifyEvent. This worker +// does that work on another thread; the main thread posts events and gets +// back a boolean per event, so the page never freezes on a burst. // -// Bundled to dist/verify-worker.js (see build.js) and loaded as a classic -// Worker. Same verifyEvent nostr-tools uses on the main thread, so semantics -// are identical — this only moves WHERE it runs. +// It also carries the other boot secp256k1 the profiler kept pinning: +// - 'openWraps': community (Concord) wraps — nip44 decrypt under the +// symmetric stream key + the seal's schnorr verify + hash checks. No +// secret crosses the thread boundary: the stream conversation key is +// group material every member derives. +// - 'unwrapDMs': NIP-17 gift wraps when the wallet holds the raw identity +// key (seed-derived / pasted nsec) — two ECDH ops + a seal verify each. +// Remote signers (bunker/extension) can't export their key, so their +// wraps never come here; the main thread keeps that path. +// +// Bundled to dist/verify-worker.js (see build.js). Same openWrap/unwrapDM/ +// verifyEvent the main thread uses, so semantics are identical — this only +// moves WHERE they run. import { verifyEvent } from 'nostr-tools/pure'; +import { hexToBytes } from '@noble/hashes/utils'; +import { openWrap } from './concord.js'; +import { unwrapDM } from './dm.js'; -self.onmessage = (e) => { - const { reqId, events } = e.data || {}; - if (reqId == null || !Array.isArray(events)) return; - const results = events.map((ev) => { - try { return verifyEvent(ev); } catch { return false; } - }); - self.postMessage({ reqId, results }); +self.onmessage = async (e) => { + const { reqId, events, op, wraps, convKey, sk } = e.data || {}; + if (reqId == null) return; + if (Array.isArray(events)) { + const results = events.map((ev) => { + try { return verifyEvent(ev); } catch { return false; } + }); + self.postMessage({ reqId, results }); + return; + } + if (op === 'openWraps' && Array.isArray(wraps)) { + let stream = null; + try { stream = { convKey: hexToBytes(convKey) }; } catch {} + const results = wraps.map((w) => { + try { return stream ? openWrap(w, stream) : null; } catch { return null; } + }); + self.postMessage({ reqId, results }); + return; + } + if (op === 'unwrapDMs' && Array.isArray(wraps)) { + let key = null; + try { key = hexToBytes(sk); } catch {} + const results = []; + for (const w of wraps) { + results.push(key ? await unwrapDM(w, key).catch(() => null) : null); + } + self.postMessage({ reqId, results }); + return; + } + self.postMessage({ reqId, results: null }); }; |
