import { sha256, md5 } from "node-forge"; import * as secp256k1 from '@noble/secp256k1'; const worker = new Worker(new URL('./crypto.worker.ts', import.meta.url), { type: 'module' }); type WorkerReq = | { id: number; type: 'encodeWithPassword'; payload: { password: string; data: any } } | { id: number; type: 'decodeWithPassword'; payload: { password: string; data: any } } | { id: number; type: 'encrypt'; payload: { publicKey: string; data: string } } | { id: number; type: 'decrypt'; payload: { privateKey: string; data: string } } | { id: number; type: 'chacha20Encrypt'; payload: { data: string } } | { id: number; type: 'chacha20Decrypt'; payload: { ciphertext: string; nonce: string; key: string } }; type WorkerRes = | { id: number; ok: true; data: any } | { id: number; ok: false; error: string }; let seq = 0; const pending = new Map void>(); worker.onmessage = (e: MessageEvent) => { const res = e.data; const cb = pending.get(res.id); if (cb) { pending.delete(res.id); cb(res); } }; function callWorker(req: Omit): Promise { return new Promise((resolve, reject) => { const id = ++seq; pending.set(id, (res) => (res.ok ? resolve(res.data) : reject(res.error))); worker.postMessage({ ...req, id }); }); } export const encodeWithPassword = (password: string, data: any): Promise => { return callWorker({ type: 'encodeWithPassword', payload: { password, data } }); }; export const decodeWithPassword = (password: string, data: any): Promise => { return callWorker({ type: 'decodeWithPassword', payload: { password, data } }); }; export const encrypt = (data: string, publicKey: string): Promise => { return callWorker({ type: 'encrypt', payload: { publicKey, data } }); }; export const decrypt = (data: string, privateKey: string): Promise => { return callWorker({ type: 'decrypt', payload: { privateKey, data } }); }; export const chacha20Encrypt = (data: string): Promise => { return callWorker({ type: 'chacha20Encrypt', payload: { data } }); }; export const chacha20Decrypt = (ciphertext: string, nonce: string, key: string): Promise => { return callWorker({ type: 'chacha20Decrypt', payload: { ciphertext, nonce, key } }); }; export const generateKeyPairFromSeed = async (seed: string) => { const privateKey = sha256.create().update(seed).digest().toHex().toString(); const publicKey = secp256k1.getPublicKey(Buffer.from(privateKey, "hex"), true); return { privateKey: privateKey, publicKey: Buffer.from(publicKey).toString('hex'), }; }; export const generateMd5 = async (data: string) => { const hash = md5.create(); hash.update(data); return hash.digest().toHex(); }; export const generateHashFromPrivateKey = async (privateKey: string) => { return sha256.create().update(privateKey + "rosetta").digest().toHex().toString(); }; export const isEncodedWithPassword = (data: string) => { try { atob(data).split(":"); return true; } catch (e) { return false; } };