Skip to content
Clone
327df0c
30 lines 1.2 KB
import type { ChallengeResponse, PowProofRequest } from '@/shared/api'
import { t } from '@/shared/i18n'
import { AuthError } from './error'
export function solve(challenge: ChallengeResponse, payload: string, signal: AbortSignal): Promise<PowProofRequest> {
signal.throwIfAborted()
return new Promise((resolve, reject) => {
const worker = new Worker(new URL('./pow.worker.ts', import.meta.url), { type: 'module' })
const finish = () => {
worker.terminate()
signal.removeEventListener('abort', cancel)
}
const cancel = () => {
finish()
reject(signal.reason)
}
signal.addEventListener('abort', cancel, { once: true })
worker.onmessage = (event: MessageEvent<{ nonce?: number; error?: string }>) => {
finish()
if (event.data.error || event.data.nonce === undefined)
reject(new AuthError('expired', event.data.error || t('error.expired')))
else resolve({ nonce: event.data.nonce, payload: Array.from(new TextEncoder().encode(payload)) })
}
worker.onerror = () => {
finish()
reject(new AuthError('proof', t('pow.unavailable')))
}
worker.postMessage({ challenge, payload })
})
}