From 4975951f2b2c1f2a56a2660761c7cfca999a1722 Mon Sep 17 00:00:00 2001 From: Chris Duncan Date: Tue, 3 Dec 2024 23:12:38 -0800 Subject: [PATCH] Worker imports using strings does not work with an async function, so revert that addition and use thenable instead. Also improve environment checking to detect Node.js vs browser. --- src/lib/bip44-ckd.ts | 33 +++++++++++++++++++++------------ src/lib/nano-nacl.ts | 23 ++++++++++++++--------- src/lib/pool.ts | 2 +- src/lib/pow.ts | 19 ++++++++++++------- 4 files changed, 48 insertions(+), 29 deletions(-) diff --git a/src/lib/bip44-ckd.ts b/src/lib/bip44-ckd.ts index 3aa91ef..b6ed3a5 100644 --- a/src/lib/bip44-ckd.ts +++ b/src/lib/bip44-ckd.ts @@ -6,16 +6,20 @@ type ExtendedKey = { chainCode: DataView } -const b = async () => { +const b = () => { /** * Polyfill for window methods which do not exist when executing Node.js tests. */ - if (typeof Window === 'undefined') { - const { isMainThread, parentPort } = await import('node:worker_threads') - if (!isMainThread && parentPort) { - var addEventListener = Object.getPrototypeOf(parentPort).addListener.bind(parentPort) - var postMessage = Object.getPrototypeOf(parentPort).postMessage.bind(parentPort) - } + if (typeof window === 'undefined' && typeof self === 'undefined') { + try { + import('node:worker_threads').then(worker_threads => { + const { isMainThread, parentPort } = worker_threads + if (!isMainThread && parentPort) { + var addEventListener = Object.getPrototypeOf(parentPort).addListener.bind(parentPort) + var postMessage = Object.getPrototypeOf(parentPort).postMessage.bind(parentPort) + } + }) + } catch { } } const BIP44_COIN_NANO = 165 @@ -26,17 +30,18 @@ const b = async () => { /** * Listens for messages from a calling function. */ - if (addEventListener != null) { + if (typeof addEventListener === 'function') { addEventListener('message', (message: any): void => { const data = JSON.parse(new TextDecoder().decode(message.data ?? message)) - process(data).then(results => { + calculate(data).then(results => { const buf = new TextEncoder().encode(JSON.stringify(results)).buffer + //@ts-expect-error postMessage(buf, [buf]) }) }) } - async function process (data: any[]): Promise { + async function calculate (data: any[]): Promise { return new Promise(async (resolve) => { for (const d of data) { d.privateKey = await nanoCKD(d.seed, d.index) @@ -65,7 +70,11 @@ const b = async () => { const coinKey = await CKDpriv(purposeKey, BIP44_COIN_NANO + HARDENED_OFFSET) const accountKey = await CKDpriv(coinKey, index + HARDENED_OFFSET) const privateKey = new Uint8Array(accountKey.privateKey.buffer) - return privateKey.reduce((key, byte) => key.concat(byte.toString(16).padStart(2, '0')), '') + let hex = '' + for (let i = 0; i < privateKey.length; i++) { + hex += privateKey[i].toString(16).padStart(2, '0') + } + return hex } async function slip10 (curve: string, S: string): Promise { @@ -122,7 +131,7 @@ const b = async () => { return { nanoCKD } } -export const Bip44Ckd = await b() +export const Bip44Ckd = b() const start = b.toString().indexOf('{') + 1 const end = b.toString().lastIndexOf('return') diff --git a/src/lib/nano-nacl.ts b/src/lib/nano-nacl.ts index e57e836..d6f9fad 100644 --- a/src/lib/nano-nacl.ts +++ b/src/lib/nano-nacl.ts @@ -17,28 +17,33 @@ import { Blake2b } from './blake2b.js' // See for details: https://docs.nano.org/integration-guides/the-basics/ // Original source commit: https://github.com/dchest/tweetnacl-js/blob/71df1d6a1d78236ca3e9f6c788786e21f5a651a6/nacl-fast.js -const n = async () => { +const n = () => { /** * Polyfill for window methods which do not exist when executing Node.js tests. */ - if (typeof Window === 'undefined') { - const { isMainThread, parentPort } = await import('node:worker_threads') - if (!isMainThread && parentPort) { - var addEventListener = Object.getPrototypeOf(parentPort).addListener.bind(parentPort) - var postMessage = Object.getPrototypeOf(parentPort).postMessage.bind(parentPort) - } + if (typeof window === 'undefined' && typeof self === 'undefined') { + try { + import('node:worker_threads').then(worker_threads => { + const { isMainThread, parentPort } = worker_threads + if (!isMainThread && parentPort) { + var addEventListener = Object.getPrototypeOf(parentPort).addListener.bind(parentPort) + var postMessage = Object.getPrototypeOf(parentPort).postMessage.bind(parentPort) + } + }) + } catch { } } /** * Listens for messages from a calling function. */ - if (addEventListener != null) { + if (typeof addEventListener === 'function') { addEventListener('message', (message: any): void => { const data = JSON.parse(new TextDecoder().decode(message.data ?? message)) for (const d of data) { d.publicKey = convert(d.privateKey) } const buf = new TextEncoder().encode(JSON.stringify(data)).buffer + //@ts-expect-error postMessage(buf, [buf]) }) } @@ -862,7 +867,7 @@ const n = async () => { return { sign, open, detached, verify, convert } } -export const NanoNaCl = await n() +export const NanoNaCl = n() const start = n.toString().indexOf('{') + 1 const end = n.toString().lastIndexOf('return') diff --git a/src/lib/pool.ts b/src/lib/pool.ts index 245b6ee..6360bee 100644 --- a/src/lib/pool.ts +++ b/src/lib/pool.ts @@ -36,7 +36,7 @@ export class Pool { } constructor (fn: string) { - if (typeof Window === 'undefined') { + if (typeof window === 'undefined' && typeof self === 'undefined') { this.#url = fn } else { this.#url = URL.createObjectURL(new Blob([fn], { type: 'text/javascript' })) diff --git a/src/lib/pow.ts b/src/lib/pow.ts index 9065386..eb55711 100644 --- a/src/lib/pow.ts +++ b/src/lib/pow.ts @@ -5,19 +5,23 @@ const p = async () => { /** * Polyfill for window methods which do not exist when executing Node.js tests. */ - if (typeof Window === 'undefined') { - const { isMainThread, parentPort } = await import('node:worker_threads') - if (!isMainThread && parentPort) { - var addEventListener = Object.getPrototypeOf(parentPort).addListener.bind(parentPort) - var postMessage = Object.getPrototypeOf(parentPort).postMessage.bind(parentPort) - } + if (typeof window === 'undefined' && typeof self === 'undefined') { + try { + import('node:worker_threads').then(worker_threads => { + const { isMainThread, parentPort } = worker_threads + if (!isMainThread && parentPort) { + var addEventListener = Object.getPrototypeOf(parentPort).addListener.bind(parentPort) + var postMessage = Object.getPrototypeOf(parentPort).postMessage.bind(parentPort) + } + }) + } catch (err) { } } const SEND_THRESHOLD = '0xfffffff8' /** * Listens for messages from a calling function. */ - if (addEventListener != null) { + if (typeof addEventListener === 'function') { addEventListener('message', (message: any): void => { const data = JSON.parse(new TextDecoder().decode(message.data ?? message)) for (const d of data) { @@ -28,6 +32,7 @@ const p = async () => { find(d.hash, d.threshold ?? SEND_THRESHOLD).then(nonce => { d.work = nonce const buf = new TextEncoder().encode(JSON.stringify(data)).buffer + //@ts-expect-error postMessage(buf, [buf]) }) } -- 2.34.1