verify-wasm-host.mjs raw
1 // verify-wasm-host.mjs — Worker bootstrap for verify.wasm.
2 //
3 // Pure compute worker: receives ["V_CHECK", reqID, evJSON], runs BIP-340
4 // Schnorr verification natively in WASM, returns ["V_RESULT", reqID, 1|0].
5 //
6 // No IDB, no WebSocket, no storage access. Bridge surface: verify_worker_* only.
7
8 import {
9 makeCoreHelpers, makeWasi, makeCommonBridge,
10 computeBuildHash,
11 } from './bridge-common.mjs';
12
13 let mem, xp;
14 const _sabTable = new Map();
15 const _sabSeqRef = { value: 0 };
16 const _spawnedWorkerChans = new Map();
17 const _wasmUrlRef = { value: null };
18 const _buildHashRef = { value: null };
19
20 const h = makeCoreHelpers(() => mem, () => xp);
21 const { readStr, readBytes, writeStr, writeI32, writeBytes, cb0, cbs, cbb, cbdata } = h;
22
23 let _workerMsgCBID = 0;
24
25 function jsonEsc(s) {
26 return String(s).replace(/\\/g, '\\\\').replace(/"/g, '\\"')
27 .replace(/\n/g, '\\n').replace(/\r/g, '\\r').replace(/\t/g, '\\t');
28 }
29
30 const bridge = {
31 verify_worker_on_message(cbID) { _workerMsgCBID = cbID; },
32 verify_worker_post(ptr, len) { self.postMessage(readStr(ptr, len)); },
33 verify_worker_set_timeout(ms, cbID) { return setTimeout(() => cb0(cbID), ms); },
34 verify_worker_clear_timeout(handle) { clearTimeout(handle); },
35
36 ...makeCommonBridge(h, _sabTable, _sabSeqRef, _wasmUrlRef, _buildHashRef, _spawnedWorkerChans),
37 };
38
39 const wasi = makeWasi(() => mem);
40
41 self.addEventListener('unhandledrejection', function(ev) {
42 self.postMessage('["__ERROR","unhandledrejection: ' + jsonEsc(String(ev.reason)) + '"]');
43 });
44
45 self.onmessage = async function(e) {
46 const d = e.data;
47
48 if (d && d.type === 'init' && d.mode === 'root') {
49 try {
50 const wasmBytes = await fetch(d.wasmUrl, { cache: 'no-store' }).then(r => r.arrayBuffer());
51 const buildHash = await computeBuildHash(wasmBytes);
52 _wasmUrlRef.value = d.wasmUrl;
53 _buildHashRef.value = buildHash;
54
55 const { instance } = await WebAssembly.instantiate(wasmBytes,
56 { bridge, wasi_snapshot_preview1: wasi });
57 mem = instance.exports.memory;
58 xp = instance.exports;
59 xp._start();
60 } catch (err) {
61 self.postMessage('["__ERROR","boot: ' + jsonEsc(String(err)) + '"]');
62 }
63 return;
64 }
65
66 if (typeof d === 'string' && _workerMsgCBID) {
67 cbs(_workerMsgCBID, d);
68 }
69 };
70