Files
wikideck/src/miner.worker.ts
T
2026-10-19 12:16:49 -04:00

28 lines
1.3 KiB
TypeScript

/// <reference lib="webworker" />
import { argon2id } from 'hash-wasm';
import { POW, proofMessage, type Challenge } from '../shared/protocol.ts';
self.onmessage = async (event: MessageEvent<{ challenge: Challenge; owner: string; duty: number }>) => {
const { challenge, owner, duty } = event.data;
try {
const salt = new Uint8Array(challenge.seed.match(/.{2}/g)!.map(x => parseInt(x, 16)));
let nonce = crypto.getRandomValues(new Uint32Array(1))[0];
let attempts = 0;
const start = performance.now();
for (;;) {
const tick = performance.now();
const hash = await argon2id({ ...POW, password: proofMessage(challenge, owner, nonce), salt, outputType: 'hex' });
attempts++;
self.postMessage({ type: 'progress', attempts, hash, rate: attempts / ((performance.now() - start) / 1000) });
if (hash.startsWith('0'.repeat(challenge.difficulty))) {
self.postMessage({ type: 'found', hash, nonce });
return;
}
nonce++;
await new Promise(resolve => setTimeout(resolve, Math.max(20, (performance.now() - tick) * (1 / duty - 1))));
}
} catch (error) {
self.postMessage({ type: 'error', message: error instanceof Error ? error.message : 'Mining worker failed' });
}
};