zeldhash-miner 0.1.0 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +11 -11
- package/dist/index.js.map +1 -1
- package/dist/worker.js +1 -1
- package/dist/worker.js.map +1 -1
- package/package.json +1 -1
- package/wasm/package.json +1 -1
- package/wasm/zeldhash_miner_wasm.js +4 -12
- package/wasm/zeldhash_miner_wasm_bg.wasm +0 -0
package/dist/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
var o = /* @__PURE__ */ ((s) => (s.INVALID_ADDRESS = "INVALID_ADDRESS", s.UNSUPPORTED_ADDRESS_TYPE = "UNSUPPORTED_ADDRESS_TYPE", s.INSUFFICIENT_FUNDS = "INSUFFICIENT_FUNDS", s.NO_CHANGE_OUTPUT = "NO_CHANGE_OUTPUT", s.MULTIPLE_CHANGE_OUTPUTS = "MULTIPLE_CHANGE_OUTPUTS", s.INVALID_INPUT = "INVALID_INPUT", s.WEBGPU_NOT_AVAILABLE = "WEBGPU_NOT_AVAILABLE", s.WORKER_ERROR = "WORKER_ERROR", s.MINING_ABORTED = "MINING_ABORTED", s.DUST_OUTPUT = "DUST_OUTPUT", s))(o || {});
|
|
2
2
|
const $ = (s) => s instanceof Error ? s.message : String(s);
|
|
3
|
-
class
|
|
3
|
+
class A extends Error {
|
|
4
4
|
code;
|
|
5
5
|
details;
|
|
6
6
|
constructor(t, e, r) {
|
|
@@ -8,11 +8,11 @@ class _ extends Error {
|
|
|
8
8
|
}
|
|
9
9
|
}
|
|
10
10
|
const M = (s, t = o.WORKER_ERROR, e) => {
|
|
11
|
-
if (s instanceof
|
|
11
|
+
if (s instanceof A)
|
|
12
12
|
return s;
|
|
13
13
|
const r = $(s);
|
|
14
|
-
return new
|
|
15
|
-
}, u = (s, t, e) => new
|
|
14
|
+
return new A(t, r, e);
|
|
15
|
+
}, u = (s, t, e) => new A(s, t, e), k = (s) => {
|
|
16
16
|
const t = BigInt(Number.MAX_SAFE_INTEGER);
|
|
17
17
|
return s > t ? Number.MAX_SAFE_INTEGER : s < -t ? -Number.MAX_SAFE_INTEGER : Number(s);
|
|
18
18
|
};
|
|
@@ -119,7 +119,7 @@ class C {
|
|
|
119
119
|
case "error":
|
|
120
120
|
this.running = !1, this.paused = !1, this.terminateWorkers(), this.cleanupExternalAbort(), this.emit(
|
|
121
121
|
"error",
|
|
122
|
-
new
|
|
122
|
+
new A(
|
|
123
123
|
e.code ?? o.WORKER_ERROR,
|
|
124
124
|
e.message,
|
|
125
125
|
{
|
|
@@ -228,18 +228,18 @@ const Z = () => {
|
|
|
228
228
|
}
|
|
229
229
|
return t.call(this, r);
|
|
230
230
|
});
|
|
231
|
-
}, S = (s) => s.endsWith("/") ? s : `${s}/`,
|
|
231
|
+
}, S = (s) => s.endsWith("/") ? s : `${s}/`, _ = (s) => {
|
|
232
232
|
const t = s.trim();
|
|
233
233
|
return t && (typeof window < "u" && typeof window.location?.origin == "string" ? S(new URL(t, window.location.origin).href) : S(new URL(t, import.meta.url).href));
|
|
234
234
|
}, H = () => {
|
|
235
235
|
const s = globalThis.__ZELDMINER_WASM_BASE__;
|
|
236
236
|
if (typeof s == "string" && s.trim())
|
|
237
|
-
return
|
|
237
|
+
return _(s);
|
|
238
238
|
const t = q?.VITE_ZELDMINER_WASM_BASE;
|
|
239
239
|
if (typeof t == "string" && t.trim())
|
|
240
|
-
return
|
|
240
|
+
return _(t);
|
|
241
241
|
const e = "/";
|
|
242
|
-
return e.trim() ?
|
|
242
|
+
return e.trim() ? _(`${S(e.trim())}wasm/`) : _("/wasm/");
|
|
243
243
|
}, W = H(), L = `${W}zeldhash_miner_wasm.js`, X = `${W}zeldhash_miner_wasm_bg.wasm`, v = (s) => s instanceof Error ? s.message : String(s), K = async () => {
|
|
244
244
|
Z();
|
|
245
245
|
let s;
|
|
@@ -258,7 +258,7 @@ const Z = () => {
|
|
|
258
258
|
throw new Error("WASM init function is missing from the bundle.");
|
|
259
259
|
try {
|
|
260
260
|
const r = new URL(X, import.meta.url);
|
|
261
|
-
await t(r);
|
|
261
|
+
await t({ module_or_path: r });
|
|
262
262
|
} catch (r) {
|
|
263
263
|
throw new Error(
|
|
264
264
|
`Failed to initialize WASM bundle: ${v(r)}`
|
|
@@ -767,7 +767,7 @@ export {
|
|
|
767
767
|
C as MiningCoordinator,
|
|
768
768
|
ot as TransactionBuilder,
|
|
769
769
|
at as ZeldMiner,
|
|
770
|
-
|
|
770
|
+
A as ZeldMinerError,
|
|
771
771
|
o as ZeldMinerErrorCode,
|
|
772
772
|
u as createMinerError,
|
|
773
773
|
M as toZeldMinerError
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sources":["../src/types.ts","../src/errors.ts","../src/coordinator.ts","../src/wasm.ts","../src/nonce.ts","../src/builder.ts","../src/index.ts"],"sourcesContent":["export enum ZeldMinerErrorCode {\n INVALID_ADDRESS = \"INVALID_ADDRESS\",\n UNSUPPORTED_ADDRESS_TYPE = \"UNSUPPORTED_ADDRESS_TYPE\",\n INSUFFICIENT_FUNDS = \"INSUFFICIENT_FUNDS\",\n NO_CHANGE_OUTPUT = \"NO_CHANGE_OUTPUT\",\n MULTIPLE_CHANGE_OUTPUTS = \"MULTIPLE_CHANGE_OUTPUTS\",\n INVALID_INPUT = \"INVALID_INPUT\",\n WEBGPU_NOT_AVAILABLE = \"WEBGPU_NOT_AVAILABLE\",\n WORKER_ERROR = \"WORKER_ERROR\",\n MINING_ABORTED = \"MINING_ABORTED\",\n DUST_OUTPUT = \"DUST_OUTPUT\",\n}\n\nexport type ZeldMinerErrorDetails = Record<string, unknown>;\n\nexport type Network = \"mainnet\" | \"testnet\" | \"signet\" | \"regtest\";\n\nexport interface ZeldMinerOptions {\n network: Network;\n batchSize: number;\n useWebGPU: boolean;\n workerThreads: number;\n satsPerVbyte: number;\n}\n\nexport interface MiningCoordinatorOptions {\n mode: WorkerMode;\n batchSize: number;\n workerThreads: number;\n}\n\nexport interface TxInput {\n txid: string;\n vout: number;\n scriptPubKey: string;\n amount: number;\n}\n\nexport interface TxOutput {\n address: string;\n amount?: number;\n change: boolean;\n}\n\nexport interface MineResult {\n psbt: string;\n txid: string;\n nonce: bigint;\n attempts: bigint;\n duration: number;\n hashRate: number;\n}\n\nexport interface ProgressEvent {\n hashesProcessed: bigint;\n hashRate: number;\n elapsedMs?: number;\n lastNonce?: bigint;\n workerId?: string;\n}\n\nexport type WorkerMode = \"cpu\" | \"gpu\";\n\nexport type WorkerMessage =\n | { type: \"init\"; mode: WorkerMode }\n | {\n type: \"mine\";\n inputs: TxInput[];\n outputs: TxOutput[];\n network: Network;\n satsPerVbyte: number;\n template: WorkerTemplate;\n startNonce: bigint;\n batchSize: number;\n targetZeros: number;\n nonceStep?: bigint;\n distribution?: bigint[];\n }\n | { type: \"stop\" };\n\nexport type WorkerResponse =\n | { type: \"ready\"; workerId?: string }\n | {\n type: \"progress\";\n hashesProcessed: bigint;\n hashRate: number;\n lastNonce?: bigint;\n workerId?: string;\n }\n | {\n type: \"found\";\n result: MineResult;\n hashesProcessed?: bigint;\n hashRate?: number;\n lastNonce?: bigint;\n workerId?: string;\n }\n | { type: \"batch_complete\"; lastNonce: bigint; workerId?: string }\n | {\n type: \"error\";\n message: string;\n code?: ZeldMinerErrorCode;\n details?: ZeldMinerErrorDetails;\n workerId?: string;\n };\n\nexport interface MiningState {\n mode: WorkerMode;\n running: boolean;\n startNonce: bigint;\n nextNonce: bigint;\n batchSize: number;\n targetZeros: number;\n hashesProcessed: bigint;\n lastHashRate?: number;\n}\n\nexport interface MiningTemplate {\n prefix: Uint8Array;\n suffix: Uint8Array;\n useCborNonce?: boolean;\n}\n\nexport interface WorkerTemplate extends MiningTemplate {\n nonceLength: number;\n useCborNonce?: boolean;\n}\n\nexport interface ValidationResult {\n ok: boolean;\n error?: string;\n addressType?: \"p2wpkh\" | \"p2tr\";\n network?: Network;\n}\n\nexport interface WasmExports {\n init_panic_hook: () => void;\n mine_batch_wasm: (\n txPrefix: Uint8Array,\n txSuffix: Uint8Array,\n startNonce: bigint,\n batchSize: number,\n targetZeros: number,\n useCborNonce?: boolean\n ) => ValidationResult | MineResult | null;\n mine_batch_gpu?: (\n txPrefix: Uint8Array,\n txSuffix: Uint8Array,\n startNonce: bigint,\n batchSize: number,\n targetZeros: number,\n useCborNonce?: boolean\n ) => Promise<ValidationResult | MineResult | null>;\n mine_range_wasm: (\n inputs: TxInput[],\n outputs: TxOutput[],\n network: Network,\n satsPerVbyte: bigint,\n startNonce: bigint,\n batchSize: number,\n targetZeros: number,\n distribution?: bigint[] | null\n ) => ValidationResult | MineResult | null;\n mine_range_gpu?: (\n inputs: TxInput[],\n outputs: TxOutput[],\n network: Network,\n satsPerVbyte: bigint,\n startNonce: bigint,\n batchSize: number,\n targetZeros: number,\n distribution?: bigint[] | null\n ) => Promise<ValidationResult | MineResult | null>;\n validate_address: (addr: string, network: Network) => ValidationResult;\n build_psbt: (\n inputs: TxInput[],\n outputs: TxOutput[],\n network: Network,\n satsPerVbyte: bigint,\n nonce: bigint,\n distribution?: bigint[] | null\n ) => string;\n build_mining_template: (\n inputs: TxInput[],\n outputs: TxOutput[],\n network: Network,\n satsPerVbyte: bigint,\n startNonce: bigint,\n batchSize: number,\n distribution?: bigint[] | null\n ) => MiningTemplate;\n compute_txid: (txBytes: Uint8Array) => string;\n init_gpu?: () => Promise<unknown>;\n calibrate_batch_size?: () => Promise<number>;\n}\n\nexport type ProgressStats = ProgressEvent;\n\nexport interface MineParams {\n inputs: TxInput[];\n outputs: TxOutput[];\n targetZeros: number;\n startNonce?: bigint;\n batchSize?: number;\n signal?: AbortSignal;\n distribution?: bigint[];\n}\n\n","import { ZeldMinerErrorCode, type ZeldMinerErrorDetails } from \"./types\";\n\nconst formatUnknownError = (err: unknown): string =>\n err instanceof Error ? err.message : String(err);\n\nexport class ZeldMinerError extends Error {\n readonly code: ZeldMinerErrorCode;\n readonly details?: ZeldMinerErrorDetails;\n\n constructor(\n code: ZeldMinerErrorCode,\n message: string,\n details?: ZeldMinerErrorDetails\n ) {\n super(message);\n this.name = \"ZeldMinerError\";\n this.code = code;\n this.details = details;\n }\n}\n\nexport const toZeldMinerError = (\n err: unknown,\n fallbackCode: ZeldMinerErrorCode = ZeldMinerErrorCode.WORKER_ERROR,\n details?: ZeldMinerErrorDetails\n): ZeldMinerError => {\n if (err instanceof ZeldMinerError) {\n return err;\n }\n\n const message = formatUnknownError(err);\n return new ZeldMinerError(fallbackCode, message, details);\n};\n\nexport const createMinerError = (\n code: ZeldMinerErrorCode,\n message: string,\n details?: ZeldMinerErrorDetails\n): ZeldMinerError => new ZeldMinerError(code, message, details);\n\n","import type {\n MineResult,\n MiningCoordinatorOptions,\n ProgressEvent as MiningProgressEvent,\n Network,\n TxInput,\n TxOutput,\n WorkerMessage,\n WorkerMode,\n WorkerResponse,\n WorkerTemplate,\n} from \"./types\";\nimport { ZeldMinerErrorCode } from \"./types\";\nimport { ZeldMinerError } from \"./errors\";\n\ntype CoordinatorEvent = \"ready\" | \"progress\" | \"found\" | \"error\" | \"stopped\";\n\ntype CoordinatorEventMap = {\n ready: void;\n progress: MiningProgressEvent;\n found: MineResult;\n error: ZeldMinerError;\n stopped: void;\n};\n\ntype CoordinatorListener<K extends CoordinatorEvent> = (\n payload: CoordinatorEventMap[K]\n) => void;\n\ninterface WorkerState {\n worker: Worker;\n hashesProcessed: bigint;\n hashRate: number;\n lastNonce?: bigint;\n nextNonce: bigint;\n processedBase: bigint;\n terminated?: boolean;\n}\n\ninterface StartParams {\n inputs: TxInput[];\n outputs: TxOutput[];\n network: Network;\n satsPerVbyte: number;\n template: WorkerTemplate;\n targetZeros: number;\n startNonce?: bigint;\n signal?: AbortSignal;\n distribution?: bigint[];\n}\n\nconst safeBigIntToNumber = (value: bigint): number => {\n const max = BigInt(Number.MAX_SAFE_INTEGER);\n if (value > max) return Number.MAX_SAFE_INTEGER;\n if (value < -max) return -Number.MAX_SAFE_INTEGER;\n return Number(value);\n};\n\nexport class MiningCoordinator {\n private readonly mode: WorkerMode;\n private readonly batchSize: number;\n private readonly workerCount: number;\n private readonly listeners: {\n [K in CoordinatorEvent]: Set<CoordinatorListener<K>>;\n };\n private readonly workers: WorkerState[] = [];\n private readonly readyPromise: Promise<void>;\n private readonly abortHandler: () => void;\n\n private stride: bigint;\n private cleanupExternalAbort = (): void => {\n if (this.externalAbort) {\n this.externalAbort.removeEventListener(\"abort\", this.abortHandler);\n this.externalAbort = undefined;\n }\n };\n private running = false;\n private paused = false;\n private startedAt: number | null = null;\n private txInputs?: TxInput[];\n private txOutputs?: TxOutput[];\n private txNetwork?: Network;\n private satsPerVbyte?: number;\n private template?: WorkerTemplate;\n private targetZeros?: number;\n private startNonce: bigint = 0n;\n private txDistribution?: bigint[];\n private externalAbort?: AbortSignal;\n private terminated = false;\n\n constructor(options: MiningCoordinatorOptions) {\n this.mode = options.mode;\n this.batchSize = options.batchSize;\n this.workerCount =\n this.mode === \"gpu\" ? 1 : Math.max(1, options.workerThreads);\n this.stride =\n this.mode === \"gpu\"\n ? BigInt(this.batchSize)\n : BigInt(this.batchSize) * BigInt(this.workerCount);\n\n this.listeners = {\n ready: new Set(),\n progress: new Set(),\n found: new Set(),\n error: new Set(),\n stopped: new Set(),\n };\n\n this.abortHandler = () => this.stop();\n this.readyPromise = this.spawnWorkers();\n }\n\n on<K extends CoordinatorEvent>(\n event: K,\n handler: CoordinatorListener<K>\n ): void {\n this.listeners[event].add(handler);\n }\n\n off<K extends CoordinatorEvent>(\n event: K,\n handler: CoordinatorListener<K>\n ): void {\n this.listeners[event].delete(handler);\n }\n\n private emit<K extends CoordinatorEvent>(\n event: K,\n payload: CoordinatorEventMap[K]\n ): void {\n this.listeners[event].forEach((handler) => handler(payload));\n }\n\n private async spawnWorkers(): Promise<void> {\n const readySignals: Promise<void>[] = [];\n\n for (let i = 0; i < this.workerCount; i += 1) {\n const worker = new Worker(new URL(\"./worker.ts\", import.meta.url), {\n type: \"module\",\n /* @vite-ignore */ name: `zeldminer-worker-${i}`,\n });\n\n const state: WorkerState = {\n worker,\n hashesProcessed: 0n,\n hashRate: 0,\n nextNonce: 0n,\n processedBase: 0n,\n };\n\n this.workers.push(state);\n\n readySignals.push(\n new Promise<void>((resolve) => {\n const handleReady = (event: MessageEvent<WorkerResponse>): void => {\n if (event.data.type === \"ready\") {\n worker.removeEventListener(\"message\", handleReady);\n resolve();\n }\n };\n\n worker.addEventListener(\"message\", handleReady);\n })\n );\n\n worker.addEventListener(\"message\", (event: MessageEvent<WorkerResponse>) =>\n this.handleWorkerMessage(state, event.data)\n );\n\n const initMessage: WorkerMessage = { type: \"init\", mode: this.mode };\n worker.postMessage(initMessage);\n }\n\n await Promise.all(readySignals);\n this.emit(\"ready\", undefined as unknown as void);\n }\n\n private handleWorkerMessage(\n state: WorkerState,\n message: WorkerResponse\n ): void {\n switch (message.type) {\n case \"ready\":\n break;\n case \"progress\":\n state.hashesProcessed = state.processedBase + message.hashesProcessed;\n state.hashRate = message.hashRate;\n state.lastNonce = message.lastNonce ?? state.lastNonce;\n this.emitProgress();\n break;\n case \"batch_complete\":\n state.lastNonce = message.lastNonce;\n state.nextNonce = this.computeNextNonce(message.lastNonce);\n break;\n case \"found\":\n state.hashesProcessed =\n state.processedBase + (message.hashesProcessed ?? state.hashesProcessed);\n state.hashRate = message.hashRate ?? state.hashRate;\n state.lastNonce = message.lastNonce ?? state.lastNonce;\n\n const attempts = this.workers.reduce(\n (total, worker) => total + worker.hashesProcessed,\n 0n\n );\n const duration = this.startedAt ? performance.now() - this.startedAt : 0;\n const hashRate =\n duration > 0\n ? safeBigIntToNumber(attempts) / (duration / 1000)\n : 0;\n\n const adjustedResult: MineResult = {\n ...message.result,\n attempts,\n duration,\n hashRate,\n };\n\n this.running = false;\n this.paused = false;\n this.terminateWorkers();\n this.cleanupExternalAbort();\n this.emit(\"found\", adjustedResult);\n break;\n case \"error\":\n this.running = false;\n this.paused = false;\n this.terminateWorkers();\n this.cleanupExternalAbort();\n this.emit(\n \"error\",\n new ZeldMinerError(\n message.code ?? ZeldMinerErrorCode.WORKER_ERROR,\n message.message,\n {\n workerId: message.workerId,\n ...(message.details ?? {}),\n }\n )\n );\n break;\n }\n }\n\n private emitProgress(): void {\n if (!this.running) return;\n\n const hashesProcessed = this.workers.reduce(\n (total, worker) => total + worker.hashesProcessed,\n 0n\n );\n const elapsedMs = this.startedAt ? performance.now() - this.startedAt : 0;\n // Derive rate from total attempts over wall-clock time to avoid overstating\n // throughput on multi-worker CPU runs.\n const hashRate =\n elapsedMs > 0\n ? safeBigIntToNumber(hashesProcessed) / (elapsedMs / 1000)\n : 0;\n\n const progress: MiningProgressEvent = {\n hashesProcessed,\n hashRate,\n elapsedMs,\n };\n\n this.emit(\"progress\", progress);\n }\n\n private computeNextNonce(lastNonce: bigint): bigint {\n const batchAdvance = this.stride - BigInt(this.batchSize);\n return lastNonce + 1n + batchAdvance;\n }\n\n private stopWorkers(): void {\n if (this.terminated) return;\n this.workers.forEach((state) =>\n state.worker.postMessage({ type: \"stop\" } satisfies WorkerMessage)\n );\n }\n\n private terminateWorkers(): void {\n if (this.terminated) return;\n this.stopWorkers();\n this.workers.forEach((state) => {\n try {\n state.worker.terminate();\n state.terminated = true;\n } catch {\n /* ignore termination errors */\n }\n });\n this.terminated = true;\n }\n\n async start(params: StartParams): Promise<void> {\n await this.readyPromise;\n this.stopWorkers();\n\n this.running = true;\n this.paused = false;\n this.startedAt = performance.now();\n this.txInputs = params.inputs;\n this.txOutputs = params.outputs;\n this.txNetwork = params.network === \"signet\" ? \"testnet\" : params.network;\n this.satsPerVbyte = params.satsPerVbyte;\n this.template = params.template;\n this.targetZeros = params.targetZeros;\n this.startNonce = params.startNonce ?? 0n;\n this.txDistribution = params.distribution;\n\n if (this.externalAbort && this.externalAbort !== params.signal) {\n this.cleanupExternalAbort();\n }\n\n if (params.signal) {\n this.externalAbort = params.signal;\n params.signal.addEventListener(\"abort\", this.abortHandler, { once: true });\n }\n\n if (\n !this.template ||\n !this.txInputs ||\n !this.txOutputs ||\n this.targetZeros === undefined ||\n this.satsPerVbyte === undefined ||\n !this.txNetwork\n ) {\n throw new Error(\"Mining parameters are missing\");\n }\n\n const inputs = this.txInputs;\n const outputs = this.txOutputs;\n const network = this.txNetwork;\n const satsPerVbyte = this.satsPerVbyte;\n const template = this.template;\n const targetZeros = this.targetZeros;\n const distribution = this.txDistribution;\n const stride = this.stride;\n\n this.workers.forEach((state, idx) => {\n state.processedBase = 0n;\n state.hashesProcessed = 0n;\n state.hashRate = 0;\n state.lastNonce = undefined;\n const workerStart =\n this.startNonce + BigInt(idx) * BigInt(this.batchSize);\n state.nextNonce = workerStart;\n\n const message: WorkerMessage = {\n type: \"mine\",\n inputs,\n outputs,\n network,\n satsPerVbyte,\n template,\n startNonce: workerStart,\n batchSize: this.batchSize,\n targetZeros,\n nonceStep: stride,\n distribution,\n };\n\n state.worker.postMessage(message);\n });\n }\n\n pause(): void {\n if (!this.running) return;\n this.running = false;\n this.paused = true;\n this.stopWorkers();\n }\n\n async resume(): Promise<void> {\n if (\n !this.paused ||\n !this.template ||\n !this.txInputs ||\n !this.txOutputs ||\n this.targetZeros === undefined ||\n this.satsPerVbyte === undefined ||\n !this.txNetwork\n )\n return;\n await this.readyPromise;\n\n this.running = true;\n this.paused = false;\n if (!this.startedAt) {\n this.startedAt = performance.now();\n }\n\n const inputs = this.txInputs;\n const outputs = this.txOutputs;\n const network = this.txNetwork;\n const satsPerVbyte = this.satsPerVbyte;\n const template = this.template;\n const targetZeros = this.targetZeros as number;\n const distribution = this.txDistribution;\n const stride = this.stride;\n\n this.workers.forEach((state, idx) => {\n state.processedBase = state.hashesProcessed;\n state.hashRate = 0;\n const workerStart =\n state.nextNonce ||\n this.startNonce + BigInt(idx) * BigInt(this.batchSize);\n\n const message: WorkerMessage = {\n type: \"mine\",\n inputs,\n outputs,\n network,\n satsPerVbyte,\n template,\n startNonce: workerStart,\n batchSize: this.batchSize,\n targetZeros,\n nonceStep: stride,\n distribution,\n };\n\n state.worker.postMessage(message);\n });\n }\n\n stop(): void {\n if (!this.running && !this.paused) return;\n this.running = false;\n this.paused = false;\n this.terminateWorkers();\n this.cleanupExternalAbort();\n this.emit(\"stopped\", undefined as unknown as void);\n }\n}\n\n","import type { WasmExports } from \"./types\";\n\nlet wasmModule: WasmExports | null = null;\nlet wasmInitPromise: Promise<WasmExports> | null = null;\n\n// Chrome/Dawn can reject requestDevice when optional limits (e.g.\n// maxInterStageShaderComponents) are present but unsupported. Strip any\n// limit keys the adapter doesn't expose to keep WebGPU initialization\n// portable across browser versions.\nlet webGpuLimitShimInstalled = false;\nconst installWebGpuLimitShim = (): void => {\n if (webGpuLimitShimInstalled) return;\n webGpuLimitShimInstalled = true;\n\n const adapterProto = (globalThis as typeof globalThis & { GPUAdapter?: { prototype?: unknown } })\n .GPUAdapter?.prototype as GPUAdapter | undefined;\n const requestDevice = adapterProto?.requestDevice;\n if (!adapterProto || typeof requestDevice !== \"function\") return;\n\n adapterProto.requestDevice = function patchedRequestDevice(\n this: GPUAdapter,\n descriptor?: GPUDeviceDescriptor\n ): Promise<GPUDevice> {\n if (descriptor?.requiredLimits && typeof this.limits === \"object\") {\n const limits = descriptor.requiredLimits as Record<string, unknown>;\n const supported = this.limits as unknown as Record<string, unknown>;\n for (const key of Object.keys(limits)) {\n if (!(key in supported) || supported[key] === undefined) {\n delete limits[key];\n }\n }\n }\n return requestDevice.call(this, descriptor);\n };\n};\n\nconst ensureTrailingSlash = (value: string): string =>\n value.endsWith(\"/\") ? value : `${value}/`;\n\nconst toAbsoluteBase = (base: string): string => {\n const trimmed = base.trim();\n if (!trimmed) return trimmed;\n // Use window origin when available so Vite treats it as an external URL and does not try to transform public assets.\n if (typeof window !== \"undefined\" && typeof window.location?.origin === \"string\") {\n return ensureTrailingSlash(new URL(trimmed, window.location.origin).href);\n }\n return ensureTrailingSlash(new URL(trimmed, import.meta.url).href);\n};\n\nconst resolveWasmBase = (): string => {\n const globalBase = (globalThis as { __ZELDMINER_WASM_BASE__?: unknown })\n .__ZELDMINER_WASM_BASE__;\n if (typeof globalBase === \"string\" && globalBase.trim()) {\n return toAbsoluteBase(globalBase);\n }\n\n const envBase = (import.meta as ImportMeta & { env?: Record<string, unknown> })\n .env?.VITE_ZELDMINER_WASM_BASE;\n if (typeof envBase === \"string\" && envBase.trim()) {\n return toAbsoluteBase(envBase);\n }\n\n const viteBase = (import.meta as ImportMeta & { env?: Record<string, unknown> }).env?.BASE_URL;\n if (typeof viteBase === \"string\" && viteBase.trim()) {\n return toAbsoluteBase(`${ensureTrailingSlash(viteBase.trim())}wasm/`);\n }\n\n return toAbsoluteBase(\"/wasm/\");\n};\n\nconst WASM_BASE_URL = resolveWasmBase();\nconst WASM_JS_PATH = `${WASM_BASE_URL}zeldhash_miner_wasm.js`;\nconst WASM_BINARY_PATH = `${WASM_BASE_URL}zeldhash_miner_wasm_bg.wasm`;\n\nconst formatError = (err: unknown): string =>\n err instanceof Error ? err.message : String(err);\n\nconst loadModule = async (): Promise<WasmExports> => {\n installWebGpuLimitShim();\n\n let bindings: unknown;\n try {\n bindings = await import(/* @vite-ignore */ WASM_JS_PATH);\n } catch (err) {\n throw new Error(\n `Failed to import WASM bundle (${WASM_JS_PATH}). ` +\n `Did you run ./scripts/build-wasm.sh? (${formatError(err)})`\n );\n }\n\n const init = (bindings as { default?: unknown }).default;\n if (typeof init !== \"function\") {\n throw new Error(\"WASM init function is missing from the bundle.\");\n }\n\n try {\n const wasmUrl = new URL(WASM_BINARY_PATH, import.meta.url);\n await init(wasmUrl);\n } catch (err) {\n throw new Error(\n `Failed to initialize WASM bundle: ${formatError(err)}`\n );\n }\n\n const typedBindings = bindings as WasmExports;\n try {\n typedBindings.init_panic_hook?.();\n } catch {\n /* ignore optional panic hook failures */\n }\n\n return typedBindings;\n};\n\nexport const loadWasm = async (): Promise<WasmExports> => {\n if (wasmModule) return wasmModule;\n if (!wasmInitPromise) {\n wasmInitPromise = loadModule()\n .then((mod) => {\n wasmModule = mod;\n return mod;\n })\n .catch((err) => {\n wasmInitPromise = null;\n throw err;\n });\n }\n return wasmInitPromise;\n};\n\nexport const getWasm = (): WasmExports | null => wasmModule;\n\nexport const resetWasm = (): void => {\n wasmModule = null;\n wasmInitPromise = null;\n};\n\n","const MAX_U64 = (1n << 64n) - 1n;\n\nexport interface NonceSegment {\n start: bigint;\n size: number;\n nonceLength: number;\n}\n\nexport const nonceLength = (nonce: bigint): number => {\n if (nonce < 0n) {\n throw new Error(\"nonce must be non-negative\");\n }\n\n if (nonce === 0n) return 1;\n\n let len = 0;\n let value = nonce;\n while (value > 0n) {\n len += 1;\n value >>= 8n;\n }\n return len;\n};\n\nexport const cborNonceLength = (nonce: bigint): number => {\n if (nonce < 0n) {\n throw new Error(\"nonce must be non-negative\");\n }\n\n if (nonce <= 23n) return 1;\n if (nonce <= 0xffn) return 2;\n if (nonce <= 0xffffn) return 3;\n if (nonce <= 0xffff_ffffn) return 5;\n if (nonce <= MAX_U64) return 9;\n\n throw new Error(\"nonce range exceeds u64\");\n};\n\nconst maxValueForLength = (len: number): bigint => {\n if (!Number.isInteger(len) || len <= 0 || len > 8) {\n throw new Error(\"nonceLength must be between 1 and 8\");\n }\n return (1n << BigInt(len * 8)) - 1n;\n};\n\nconst maxValueForCborLength = (len: number): bigint => {\n switch (len) {\n case 1:\n return 23n;\n case 2:\n return 0xffn;\n case 3:\n return 0xffffn;\n case 5:\n return 0xffff_ffffn;\n case 9:\n return MAX_U64;\n default:\n throw new Error(\"cbor nonceLength must be one of 1, 2, 3, 5, 9\");\n }\n};\n\nexport const splitNonceSegments = (startNonce: bigint, span: number): NonceSegment[] => {\n if (startNonce < 0n) {\n throw new Error(\"startNonce must be non-negative\");\n }\n if (!Number.isInteger(span) || span <= 0) {\n throw new Error(\"batchSize must be a positive integer\");\n }\n\n const end = startNonce + BigInt(span - 1);\n if (end > MAX_U64) {\n throw new Error(\"nonce range exceeds u64\");\n }\n\n const segments: NonceSegment[] = [];\n let current = startNonce;\n\n while (current <= end) {\n const len = nonceLength(current);\n const maxForLen = maxValueForLength(len);\n const segmentEnd = end < maxForLen ? end : maxForLen;\n const segmentSize = segmentEnd - current + 1n;\n\n if (segmentSize > BigInt(Number.MAX_SAFE_INTEGER)) {\n throw new Error(\"segment size exceeds safe integer range\");\n }\n\n segments.push({\n start: current,\n size: Number(segmentSize),\n nonceLength: len,\n });\n\n if (segmentEnd === end) {\n break;\n }\n\n current = segmentEnd + 1n;\n }\n\n return segments;\n};\n\nexport const maxNonceForLength = (len: number): bigint => maxValueForLength(len);\n\nexport const splitNonceSegmentsCbor = (startNonce: bigint, span: number): NonceSegment[] => {\n if (startNonce < 0n) {\n throw new Error(\"startNonce must be non-negative\");\n }\n if (!Number.isInteger(span) || span <= 0) {\n throw new Error(\"batchSize must be a positive integer\");\n }\n\n const end = startNonce + BigInt(span - 1);\n if (end > MAX_U64) {\n throw new Error(\"nonce range exceeds u64\");\n }\n\n const segments: NonceSegment[] = [];\n let current = startNonce;\n\n while (current <= end) {\n const len = cborNonceLength(current);\n const maxForLen = maxValueForCborLength(len);\n const segmentEnd = end < maxForLen ? end : maxForLen;\n const segmentSize = segmentEnd - current + 1n;\n\n if (segmentSize > BigInt(Number.MAX_SAFE_INTEGER)) {\n throw new Error(\"segment size exceeds safe integer range\");\n }\n\n segments.push({\n start: current,\n size: Number(segmentSize),\n nonceLength: len,\n });\n\n if (segmentEnd === end) {\n break;\n }\n\n current = segmentEnd + 1n;\n }\n\n return segments;\n};\n\n\n","import type {\n MiningTemplate,\n Network,\n TxInput,\n TxOutput,\n ValidationResult,\n WasmExports,\n} from \"./types\";\nimport { ZeldMinerErrorCode } from \"./types\";\nimport { createMinerError, toZeldMinerError } from \"./errors\";\nimport { loadWasm } from \"./wasm\";\nimport { cborNonceLength, nonceLength } from \"./nonce\";\n\nconst TXID_REGEX = /^[0-9a-fA-F]{64}$/;\nconst HEX_REGEX = /^[0-9a-fA-F]+$/;\nconst MAX_U64 = (1n << 64n) - 1n;\nconst MAX_U32 = 0xffff_ffff;\n\nconst dustLimitForAddress = (addressType?: \"p2wpkh\" | \"p2tr\"): number => {\n if (addressType === \"p2tr\") return 330;\n if (addressType === \"p2wpkh\") return 310;\n return 546; // conservative fallback for unexpected types\n};\n\nconst formatError = (err: unknown): string =>\n err instanceof Error ? err.message : String(err);\n\nconst includesAny = (haystack: string, needles: string[]): boolean =>\n needles.some((needle) => haystack.includes(needle));\n\nconst mapWasmError = (\n err: unknown,\n context: string,\n details?: Record<string, unknown>\n): never => {\n const message = formatError(err);\n const normalized = message.toLowerCase();\n\n if (includesAny(normalized, [\"insufficient funds\", \"insufficient_funds\"])) {\n throw createMinerError(\n ZeldMinerErrorCode.INSUFFICIENT_FUNDS,\n \"Insufficient funds for outputs and fee\",\n { ...details, cause: message }\n );\n }\n\n if (includesAny(normalized, [\"change would be dust\", \"output amount below dust limit\", \"dust\"])) {\n throw createMinerError(\n ZeldMinerErrorCode.DUST_OUTPUT,\n \"Change would be dust\",\n { ...details, cause: message }\n );\n }\n\n throw toZeldMinerError(err, ZeldMinerErrorCode.WORKER_ERROR, {\n ...details,\n context,\n });\n};\n\nconst normalizeNetwork = (network: Network): Network =>\n network === \"signet\" ? \"testnet\" : network;\n\nexport class TransactionBuilder {\n private readonly network: Network;\n private readonly satsPerVbyte: number;\n\n constructor(network: Network, satsPerVbyte: number) {\n if (!Number.isFinite(satsPerVbyte) || satsPerVbyte <= 0) {\n throw createMinerError(\n ZeldMinerErrorCode.INVALID_INPUT,\n \"satsPerVbyte must be a positive number\",\n { field: \"satsPerVbyte\" }\n );\n }\n this.network = network;\n this.satsPerVbyte = satsPerVbyte;\n }\n\n private async getWasm(): Promise<WasmExports> {\n return loadWasm();\n }\n\n private assertNonceRange(startNonce: bigint, batchSize: number, useCborNonce: boolean): number {\n if (startNonce < 0n || startNonce > MAX_U64) {\n throw createMinerError(\n ZeldMinerErrorCode.INVALID_INPUT,\n \"startNonce must be between 0 and 2^64 - 1\",\n { startNonce }\n );\n }\n if (!Number.isInteger(batchSize) || batchSize <= 0 || batchSize > MAX_U32) {\n throw createMinerError(\n ZeldMinerErrorCode.INVALID_INPUT,\n \"batchSize must be a positive 32-bit integer\",\n { batchSize }\n );\n }\n\n const lastNonce = startNonce + BigInt(batchSize - 1);\n if (lastNonce > MAX_U64) {\n throw createMinerError(\n ZeldMinerErrorCode.INVALID_INPUT,\n \"nonce range exceeds u64\",\n { startNonce, batchSize }\n );\n }\n\n const lengthFn = useCborNonce ? cborNonceLength : nonceLength;\n const startLen = lengthFn(startNonce);\n const lastLen = lengthFn(lastNonce);\n if (startLen !== lastLen) {\n const boundaryLabel = useCborNonce ? \"CBOR length\" : \"byte-length\";\n throw createMinerError(\n ZeldMinerErrorCode.INVALID_INPUT,\n `nonce range crosses ${boundaryLabel} boundary; reduce batch size`,\n { startNonce, batchSize }\n );\n }\n\n return startLen;\n }\n\n private cloneInputs(inputs: TxInput[]): TxInput[] {\n return inputs.map((input) => ({ ...input }));\n }\n\n private cloneOutputs(outputs: TxOutput[]): TxOutput[] {\n return outputs.map((output) => ({ ...output }));\n }\n\n private validateInputs(inputs: TxInput[]): void {\n if (!Array.isArray(inputs) || inputs.length === 0) {\n throw createMinerError(\n ZeldMinerErrorCode.INVALID_INPUT,\n \"At least one input is required\"\n );\n }\n\n inputs.forEach((input, idx) => {\n if (!TXID_REGEX.test(input.txid)) {\n throw createMinerError(\n ZeldMinerErrorCode.INVALID_INPUT,\n `inputs[${idx}].txid must be a 64-character hex`,\n { index: idx }\n );\n }\n if (!Number.isInteger(input.vout) || input.vout < 0) {\n throw createMinerError(\n ZeldMinerErrorCode.INVALID_INPUT,\n `inputs[${idx}].vout must be a non-negative integer`,\n { index: idx }\n );\n }\n if (!Number.isInteger(input.amount) || input.amount <= 0) {\n throw createMinerError(\n ZeldMinerErrorCode.INVALID_INPUT,\n `inputs[${idx}].amount must be a positive integer`,\n { index: idx }\n );\n }\n if (\n typeof input.scriptPubKey !== \"string\" ||\n input.scriptPubKey.length === 0 ||\n input.scriptPubKey.length % 2 !== 0 ||\n !HEX_REGEX.test(input.scriptPubKey)\n ) {\n throw createMinerError(\n ZeldMinerErrorCode.INVALID_INPUT,\n `inputs[${idx}].scriptPubKey must be valid hex`,\n { index: idx }\n );\n }\n });\n }\n\n private validateAddressResult(\n validation: ValidationResult,\n idx: number,\n network: Network\n ): void {\n if (!validation.ok) {\n const reason = validation.error ?? \"invalid address\";\n const normalized = reason.toLowerCase();\n const code = normalized.includes(\"unsupported\")\n ? ZeldMinerErrorCode.UNSUPPORTED_ADDRESS_TYPE\n : ZeldMinerErrorCode.INVALID_ADDRESS;\n\n throw createMinerError(\n code,\n `outputs[${idx}].address is invalid (${reason})`,\n { index: idx }\n );\n }\n\n if (\n validation.network &&\n validation.network !== network &&\n !(validation.network === \"testnet\" && network === \"signet\")\n ) {\n throw createMinerError(\n ZeldMinerErrorCode.INVALID_ADDRESS,\n `outputs[${idx}].address network mismatch`,\n { index: idx }\n );\n }\n\n if (\n validation.addressType &&\n validation.addressType !== \"p2tr\" &&\n validation.addressType !== \"p2wpkh\"\n ) {\n throw createMinerError(\n ZeldMinerErrorCode.UNSUPPORTED_ADDRESS_TYPE,\n `outputs[${idx}].address uses an unsupported type`,\n { index: idx, addressType: validation.addressType }\n );\n }\n }\n\n private async validateOutputs(outputs: TxOutput[]): Promise<void> {\n if (!Array.isArray(outputs) || outputs.length === 0) {\n throw createMinerError(\n ZeldMinerErrorCode.INVALID_INPUT,\n \"At least one output is required\"\n );\n }\n\n const changeCount = outputs.filter((o) => o.change).length;\n if (changeCount !== 1) {\n const code =\n changeCount === 0\n ? ZeldMinerErrorCode.NO_CHANGE_OUTPUT\n : ZeldMinerErrorCode.MULTIPLE_CHANGE_OUTPUTS;\n throw createMinerError(\n code,\n \"Exactly one change output is required\",\n { changeCount }\n );\n }\n\n const wasm = await this.getWasm();\n const net = normalizeNetwork(this.network);\n\n outputs.forEach((output, idx) => {\n const validation = wasm.validate_address(output.address, net);\n this.validateAddressResult(validation, idx, net);\n const dustLimit = dustLimitForAddress(validation.addressType);\n\n if (output.change) {\n if (\n output.amount !== undefined &&\n (!Number.isInteger(output.amount) || output.amount < 0)\n ) {\n throw createMinerError(\n ZeldMinerErrorCode.INVALID_INPUT,\n `outputs[${idx}].amount must be a non-negative integer when provided`,\n { index: idx }\n );\n }\n } else {\n if (\n !Number.isInteger(output.amount) ||\n (output.amount as number) < dustLimit\n ) {\n throw createMinerError(\n ZeldMinerErrorCode.DUST_OUTPUT,\n `outputs[${idx}].amount must be at least ${dustLimit} sats`,\n { index: idx, addressType: validation.addressType }\n );\n }\n }\n });\n }\n\n private validateDistribution(\n outputs: TxOutput[],\n distribution?: bigint[]\n ): bigint[] | undefined {\n if (distribution === undefined) return undefined;\n if (!Array.isArray(distribution)) {\n throw createMinerError(\n ZeldMinerErrorCode.INVALID_INPUT,\n \"distribution must be an array of bigint values\"\n );\n }\n\n if (distribution.length !== outputs.length) {\n throw createMinerError(\n ZeldMinerErrorCode.INVALID_INPUT,\n \"distribution length must match number of outputs\",\n { expected: outputs.length, actual: distribution.length }\n );\n }\n\n return distribution.map((value, idx) => {\n if (typeof value !== \"bigint\") {\n throw createMinerError(\n ZeldMinerErrorCode.INVALID_INPUT,\n \"distribution values must be bigint\",\n { index: idx }\n );\n }\n if (value < 0n) {\n throw createMinerError(\n ZeldMinerErrorCode.INVALID_INPUT,\n \"distribution values must be non-negative\",\n { index: idx }\n );\n }\n return value;\n });\n }\n\n async buildMiningTemplate(params: {\n inputs: TxInput[];\n outputs: TxOutput[];\n startNonce: bigint;\n batchSize: number;\n distribution?: bigint[];\n }): Promise<MiningTemplate & { nonceLength: number }> {\n const { inputs, outputs, startNonce, batchSize, distribution } = params;\n this.validateInputs(inputs);\n await this.validateOutputs(outputs);\n const validatedDistribution = this.validateDistribution(outputs, distribution);\n const useCborNonce = Array.isArray(validatedDistribution);\n const nonceLength = this.assertNonceRange(startNonce, batchSize, useCborNonce);\n\n const wasm = await this.getWasm();\n try {\n const template = wasm.build_mining_template(\n this.cloneInputs(inputs),\n this.cloneOutputs(outputs),\n normalizeNetwork(this.network),\n BigInt(this.satsPerVbyte),\n startNonce,\n batchSize,\n validatedDistribution ?? null\n );\n\n if (\n !template ||\n !(template.prefix instanceof Uint8Array) ||\n !(template.suffix instanceof Uint8Array)\n ) {\n throw createMinerError(\n ZeldMinerErrorCode.WORKER_ERROR,\n \"WASM returned an invalid mining template\"\n );\n }\n\n const templateUsesCbor = template.useCborNonce ?? useCborNonce;\n return { ...template, nonceLength, useCborNonce: templateUsesCbor };\n } catch (err) {\n throw mapWasmError(err, \"build_mining_template\", {\n startNonce,\n batchSize,\n distribution: validatedDistribution,\n });\n }\n }\n\n async buildPsbt(params: {\n inputs: TxInput[];\n outputs: TxOutput[];\n nonce: bigint;\n distribution?: bigint[];\n }): Promise<string> {\n const { inputs, outputs, nonce, distribution } = params;\n this.validateInputs(inputs);\n await this.validateOutputs(outputs);\n const validatedDistribution = this.validateDistribution(outputs, distribution);\n\n if (nonce < 0n || nonce > MAX_U64) {\n throw createMinerError(\n ZeldMinerErrorCode.INVALID_INPUT,\n \"nonce must be between 0 and 2^64 - 1\",\n { nonce }\n );\n }\n\n const wasm = await this.getWasm();\n try {\n return wasm.build_psbt(\n this.cloneInputs(inputs),\n this.cloneOutputs(outputs),\n normalizeNetwork(this.network),\n BigInt(this.satsPerVbyte),\n nonce,\n validatedDistribution ?? null\n );\n } catch (err) {\n throw mapWasmError(err, \"build_psbt\", { nonce, distribution: validatedDistribution });\n }\n }\n}\n\n","import { MiningCoordinator } from \"./coordinator\";\nimport { TransactionBuilder } from \"./builder\";\nimport { splitNonceSegments, splitNonceSegmentsCbor } from \"./nonce\";\nimport type {\n MineParams,\n MineResult,\n ProgressStats,\n WorkerMode,\n ZeldMinerOptions,\n} from \"./types\";\nimport { ZeldMinerErrorCode } from \"./types\";\nimport { createMinerError, toZeldMinerError, ZeldMinerError } from \"./errors\";\n\ntype ZeldMinerEvent = \"progress\" | \"found\" | \"error\" | \"stopped\";\n\ntype ZeldMinerEventMap = {\n progress: ProgressStats;\n found: MineResult;\n error: ZeldMinerError;\n stopped: void;\n};\n\nconst MIN_TARGET_ZEROS = 1;\nconst MAX_TARGET_ZEROS = 32;\n\nexport class ZeldMiner {\n private readonly options: ZeldMinerOptions;\n private readonly builder: TransactionBuilder;\n private coordinator: MiningCoordinator | null = null;\n private readonly listeners: {\n [K in ZeldMinerEvent]: Set<(payload: ZeldMinerEventMap[K]) => void>;\n };\n private state: \"idle\" | \"running\" | \"paused\" = \"idle\";\n private stopRequested = false;\n\n constructor(options: ZeldMinerOptions) {\n this.options = this.validateOptions(options);\n this.builder = new TransactionBuilder(options.network, options.satsPerVbyte);\n this.listeners = {\n progress: new Set(),\n found: new Set(),\n error: new Set(),\n stopped: new Set(),\n };\n }\n\n on<K extends ZeldMinerEvent>(\n event: K,\n handler: (payload: ZeldMinerEventMap[K]) => void\n ): void {\n this.listeners[event].add(handler);\n }\n\n off<K extends ZeldMinerEvent>(\n event: K,\n handler: (payload: ZeldMinerEventMap[K]) => void\n ): void {\n this.listeners[event].delete(handler);\n }\n\n private emit<K extends ZeldMinerEvent>(\n event: K,\n payload: ZeldMinerEventMap[K]\n ): void {\n this.listeners[event].forEach((handler) => handler(payload));\n }\n\n private validateOptions(options: ZeldMinerOptions): ZeldMinerOptions {\n if (!Number.isInteger(options.batchSize) || options.batchSize <= 0) {\n throw createMinerError(\n ZeldMinerErrorCode.INVALID_INPUT,\n \"batchSize must be a positive integer\",\n { field: \"batchSize\" }\n );\n }\n if (!Number.isInteger(options.workerThreads) || options.workerThreads <= 0) {\n throw createMinerError(\n ZeldMinerErrorCode.INVALID_INPUT,\n \"workerThreads must be a positive integer\",\n { field: \"workerThreads\" }\n );\n }\n if (!Number.isFinite(options.satsPerVbyte) || options.satsPerVbyte <= 0) {\n throw createMinerError(\n ZeldMinerErrorCode.INVALID_INPUT,\n \"satsPerVbyte must be a positive number\",\n { field: \"satsPerVbyte\" }\n );\n }\n return options;\n }\n\n private async selectBackend(): Promise<WorkerMode> {\n if (!this.options.useWebGPU) return \"cpu\";\n if (typeof navigator === \"undefined\") return \"cpu\";\n\n const gpu = (navigator as Navigator & { gpu?: { requestAdapter?: () => Promise<unknown> } }).gpu;\n const adapter =\n typeof gpu?.requestAdapter === \"function\" ? await gpu.requestAdapter() : null;\n return adapter ? \"gpu\" : \"cpu\";\n }\n\n private clearCoordinatorHandlers(\n coordinator: MiningCoordinator,\n handlers: Partial<Record<ZeldMinerEvent, (...args: any[]) => void>>\n ): void {\n if (handlers.progress) {\n coordinator.off(\"progress\", handlers.progress as (payload: ProgressStats) => void);\n }\n if (handlers.found) {\n coordinator.off(\"found\", handlers.found as (payload: MineResult) => void);\n }\n if (handlers.error) {\n coordinator.off(\"error\", handlers.error as (payload: Error) => void);\n }\n if (handlers.stopped) {\n coordinator.off(\"stopped\", handlers.stopped as (payload: void) => void);\n }\n }\n\n async mineTransaction(params: MineParams): Promise<MineResult> {\n if (this.state === \"running\") {\n throw createMinerError(\n ZeldMinerErrorCode.INVALID_INPUT,\n \"Mining is already in progress\"\n );\n }\n\n if (\n !Number.isInteger(params.targetZeros) ||\n params.targetZeros < MIN_TARGET_ZEROS ||\n params.targetZeros > MAX_TARGET_ZEROS\n ) {\n throw createMinerError(\n ZeldMinerErrorCode.INVALID_INPUT,\n `targetZeros must be an integer between ${MIN_TARGET_ZEROS} and ${MAX_TARGET_ZEROS}`,\n { targetZeros: params.targetZeros }\n );\n }\n\n const startNonce = params.startNonce ?? 0n;\n const batchSize = params.batchSize ?? this.options.batchSize;\n\n if (!Number.isInteger(batchSize) || batchSize <= 0) {\n throw createMinerError(\n ZeldMinerErrorCode.INVALID_INPUT,\n \"batchSize must be a positive integer\",\n { batchSize }\n );\n }\n\n if (params.signal?.aborted) {\n throw createMinerError(\n ZeldMinerErrorCode.MINING_ABORTED,\n \"Abort signal already triggered\"\n );\n }\n\n const distribution = params.distribution;\n const useCborNonce = Boolean(distribution && distribution.length > 0);\n let firstSegmentSize = batchSize;\n try {\n const [firstSegment] = useCborNonce\n ? splitNonceSegmentsCbor(startNonce, batchSize)\n : splitNonceSegments(startNonce, batchSize);\n if (!firstSegment) {\n throw createMinerError(\n ZeldMinerErrorCode.INVALID_INPUT,\n \"Failed to compute nonce segments\",\n { startNonce, batchSize }\n );\n }\n firstSegmentSize = firstSegment.size;\n } catch (err) {\n throw createMinerError(\n ZeldMinerErrorCode.INVALID_INPUT,\n err instanceof Error ? err.message : String(err),\n { startNonce, batchSize }\n );\n }\n\n const mode = await this.selectBackend();\n const template = await this.builder.buildMiningTemplate({\n inputs: params.inputs,\n outputs: params.outputs,\n startNonce,\n batchSize: firstSegmentSize,\n distribution,\n });\n\n const network =\n this.options.network === \"signet\" ? \"testnet\" : this.options.network;\n const coordinator = new MiningCoordinator({\n mode,\n batchSize,\n workerThreads: this.options.workerThreads,\n });\n\n this.coordinator = coordinator;\n this.state = \"running\";\n this.stopRequested = false;\n\n return new Promise<MineResult>((resolve, reject) => {\n let settled = false;\n\n const cleanup = (): void => {\n this.clearCoordinatorHandlers(coordinator, handlers);\n if (this.coordinator === coordinator) {\n this.coordinator = null;\n }\n this.state = \"idle\";\n this.stopRequested = false;\n };\n\n const resolveOnce = (value: MineResult): void => {\n if (settled) return;\n settled = true;\n cleanup();\n resolve(value);\n };\n\n const rejectOnce = (err: unknown): void => {\n if (settled) return;\n settled = true;\n const error = toZeldMinerError(err);\n cleanup();\n this.emit(\"error\", error);\n reject(error);\n };\n\n const handlers: Partial<Record<ZeldMinerEvent, (...args: any[]) => void>> = {};\n\n handlers.progress = (stats: ProgressStats): void => {\n this.emit(\"progress\", stats);\n };\n\n handlers.found = async (result: MineResult): Promise<void> => {\n try {\n const psbt = await this.builder.buildPsbt({\n inputs: params.inputs,\n outputs: params.outputs,\n nonce: result.nonce,\n distribution,\n });\n\n const finalResult: MineResult = { ...result, psbt };\n this.emit(\"found\", finalResult);\n resolveOnce(finalResult);\n } catch (err) {\n rejectOnce(err);\n }\n };\n\n handlers.error = (err: Error): void => {\n rejectOnce(err);\n };\n\n handlers.stopped = (): void => {\n if (settled) return;\n const reason = this.stopRequested\n ? createMinerError(\n ZeldMinerErrorCode.MINING_ABORTED,\n \"Mining stopped by caller\"\n )\n : createMinerError(\n ZeldMinerErrorCode.MINING_ABORTED,\n \"Mining halted\"\n );\n this.emit(\"stopped\", undefined as unknown as void);\n rejectOnce(reason);\n };\n\n coordinator.on(\"progress\", handlers.progress);\n coordinator.on(\"found\", handlers.found);\n coordinator.on(\"error\", handlers.error);\n coordinator.on(\"stopped\", handlers.stopped);\n\n coordinator\n .start({\n inputs: params.inputs,\n outputs: params.outputs,\n network,\n satsPerVbyte: this.options.satsPerVbyte,\n template,\n targetZeros: params.targetZeros,\n startNonce,\n signal: params.signal,\n distribution,\n })\n .catch(rejectOnce);\n });\n }\n\n stop(): void {\n if (!this.coordinator) return;\n this.stopRequested = true;\n this.coordinator.stop();\n }\n\n pause(): void {\n if (this.state !== \"running\" || !this.coordinator) return;\n this.state = \"paused\";\n this.coordinator.pause();\n }\n\n async resume(): Promise<void> {\n if (this.state !== \"paused\" || !this.coordinator) return;\n this.state = \"running\";\n await this.coordinator.resume();\n }\n}\n\nexport type {\n ZeldMinerOptions,\n MineParams,\n MineResult,\n ProgressStats,\n Network,\n TxInput,\n TxOutput,\n} from \"./types\";\nexport { ZeldMinerErrorCode } from \"./types\";\nexport { TransactionBuilder } from \"./builder\";\nexport { MiningCoordinator } from \"./coordinator\";\nexport {\n ZeldMinerError,\n createMinerError,\n toZeldMinerError,\n} from \"./errors\";\n\n"],"names":["ZeldMinerErrorCode","formatUnknownError","err","ZeldMinerError","code","message","details","toZeldMinerError","fallbackCode","createMinerError","safeBigIntToNumber","value","max","MiningCoordinator","options","event","handler","payload","readySignals","i","worker","state","resolve","handleReady","initMessage","attempts","total","duration","hashRate","adjustedResult","hashesProcessed","elapsedMs","progress","lastNonce","batchAdvance","params","inputs","outputs","network","satsPerVbyte","template","targetZeros","distribution","stride","idx","workerStart","wasmModule","wasmInitPromise","webGpuLimitShimInstalled","installWebGpuLimitShim","adapterProto","requestDevice","descriptor","limits","supported","key","ensureTrailingSlash","toAbsoluteBase","base","trimmed","resolveWasmBase","globalBase","envBase","__vite_import_meta_env__","viteBase","WASM_BASE_URL","WASM_JS_PATH","WASM_BINARY_PATH","formatError","loadModule","bindings","init","wasmUrl","typedBindings","loadWasm","mod","MAX_U64","nonceLength","nonce","len","cborNonceLength","maxValueForLength","maxValueForCborLength","splitNonceSegments","startNonce","span","end","segments","current","maxForLen","segmentEnd","segmentSize","splitNonceSegmentsCbor","TXID_REGEX","HEX_REGEX","MAX_U32","dustLimitForAddress","addressType","includesAny","haystack","needles","needle","mapWasmError","context","normalized","normalizeNetwork","TransactionBuilder","batchSize","useCborNonce","lengthFn","startLen","lastLen","boundaryLabel","input","output","validation","reason","changeCount","o","wasm","net","dustLimit","validatedDistribution","templateUsesCbor","MIN_TARGET_ZEROS","MAX_TARGET_ZEROS","ZeldMiner","gpu","coordinator","handlers","firstSegmentSize","firstSegment","mode","reject","settled","cleanup","resolveOnce","rejectOnce","error","stats","result","psbt","finalResult"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","sources":["../src/types.ts","../src/errors.ts","../src/coordinator.ts","../src/wasm.ts","../src/nonce.ts","../src/builder.ts","../src/index.ts"],"sourcesContent":["export enum ZeldMinerErrorCode {\n INVALID_ADDRESS = \"INVALID_ADDRESS\",\n UNSUPPORTED_ADDRESS_TYPE = \"UNSUPPORTED_ADDRESS_TYPE\",\n INSUFFICIENT_FUNDS = \"INSUFFICIENT_FUNDS\",\n NO_CHANGE_OUTPUT = \"NO_CHANGE_OUTPUT\",\n MULTIPLE_CHANGE_OUTPUTS = \"MULTIPLE_CHANGE_OUTPUTS\",\n INVALID_INPUT = \"INVALID_INPUT\",\n WEBGPU_NOT_AVAILABLE = \"WEBGPU_NOT_AVAILABLE\",\n WORKER_ERROR = \"WORKER_ERROR\",\n MINING_ABORTED = \"MINING_ABORTED\",\n DUST_OUTPUT = \"DUST_OUTPUT\",\n}\n\nexport type ZeldMinerErrorDetails = Record<string, unknown>;\n\nexport type Network = \"mainnet\" | \"testnet\" | \"signet\" | \"regtest\";\n\nexport interface ZeldMinerOptions {\n network: Network;\n batchSize: number;\n useWebGPU: boolean;\n workerThreads: number;\n satsPerVbyte: number;\n}\n\nexport interface MiningCoordinatorOptions {\n mode: WorkerMode;\n batchSize: number;\n workerThreads: number;\n}\n\nexport interface TxInput {\n txid: string;\n vout: number;\n scriptPubKey: string;\n amount: number;\n}\n\nexport interface TxOutput {\n address: string;\n amount?: number;\n change: boolean;\n}\n\nexport interface MineResult {\n psbt: string;\n txid: string;\n nonce: bigint;\n attempts: bigint;\n duration: number;\n hashRate: number;\n}\n\nexport interface ProgressEvent {\n hashesProcessed: bigint;\n hashRate: number;\n elapsedMs?: number;\n lastNonce?: bigint;\n workerId?: string;\n}\n\nexport type WorkerMode = \"cpu\" | \"gpu\";\n\nexport type WorkerMessage =\n | { type: \"init\"; mode: WorkerMode }\n | {\n type: \"mine\";\n inputs: TxInput[];\n outputs: TxOutput[];\n network: Network;\n satsPerVbyte: number;\n template: WorkerTemplate;\n startNonce: bigint;\n batchSize: number;\n targetZeros: number;\n nonceStep?: bigint;\n distribution?: bigint[];\n }\n | { type: \"stop\" };\n\nexport type WorkerResponse =\n | { type: \"ready\"; workerId?: string }\n | {\n type: \"progress\";\n hashesProcessed: bigint;\n hashRate: number;\n lastNonce?: bigint;\n workerId?: string;\n }\n | {\n type: \"found\";\n result: MineResult;\n hashesProcessed?: bigint;\n hashRate?: number;\n lastNonce?: bigint;\n workerId?: string;\n }\n | { type: \"batch_complete\"; lastNonce: bigint; workerId?: string }\n | {\n type: \"error\";\n message: string;\n code?: ZeldMinerErrorCode;\n details?: ZeldMinerErrorDetails;\n workerId?: string;\n };\n\nexport interface MiningState {\n mode: WorkerMode;\n running: boolean;\n startNonce: bigint;\n nextNonce: bigint;\n batchSize: number;\n targetZeros: number;\n hashesProcessed: bigint;\n lastHashRate?: number;\n}\n\nexport interface MiningTemplate {\n prefix: Uint8Array;\n suffix: Uint8Array;\n useCborNonce?: boolean;\n}\n\nexport interface WorkerTemplate extends MiningTemplate {\n nonceLength: number;\n useCborNonce?: boolean;\n}\n\nexport interface ValidationResult {\n ok: boolean;\n error?: string;\n addressType?: \"p2wpkh\" | \"p2tr\";\n network?: Network;\n}\n\nexport interface WasmExports {\n init_panic_hook: () => void;\n mine_batch_wasm: (\n txPrefix: Uint8Array,\n txSuffix: Uint8Array,\n startNonce: bigint,\n batchSize: number,\n targetZeros: number,\n useCborNonce?: boolean\n ) => ValidationResult | MineResult | null;\n mine_batch_gpu?: (\n txPrefix: Uint8Array,\n txSuffix: Uint8Array,\n startNonce: bigint,\n batchSize: number,\n targetZeros: number,\n useCborNonce?: boolean\n ) => Promise<ValidationResult | MineResult | null>;\n mine_range_wasm: (\n inputs: TxInput[],\n outputs: TxOutput[],\n network: Network,\n satsPerVbyte: bigint,\n startNonce: bigint,\n batchSize: number,\n targetZeros: number,\n distribution?: bigint[] | null\n ) => ValidationResult | MineResult | null;\n mine_range_gpu?: (\n inputs: TxInput[],\n outputs: TxOutput[],\n network: Network,\n satsPerVbyte: bigint,\n startNonce: bigint,\n batchSize: number,\n targetZeros: number,\n distribution?: bigint[] | null\n ) => Promise<ValidationResult | MineResult | null>;\n validate_address: (addr: string, network: Network) => ValidationResult;\n build_psbt: (\n inputs: TxInput[],\n outputs: TxOutput[],\n network: Network,\n satsPerVbyte: bigint,\n nonce: bigint,\n distribution?: bigint[] | null\n ) => string;\n build_mining_template: (\n inputs: TxInput[],\n outputs: TxOutput[],\n network: Network,\n satsPerVbyte: bigint,\n startNonce: bigint,\n batchSize: number,\n distribution?: bigint[] | null\n ) => MiningTemplate;\n compute_txid: (txBytes: Uint8Array) => string;\n init_gpu?: () => Promise<unknown>;\n calibrate_batch_size?: () => Promise<number>;\n}\n\nexport type ProgressStats = ProgressEvent;\n\nexport interface MineParams {\n inputs: TxInput[];\n outputs: TxOutput[];\n targetZeros: number;\n startNonce?: bigint;\n batchSize?: number;\n signal?: AbortSignal;\n distribution?: bigint[];\n}\n\n","import { ZeldMinerErrorCode, type ZeldMinerErrorDetails } from \"./types\";\n\nconst formatUnknownError = (err: unknown): string =>\n err instanceof Error ? err.message : String(err);\n\nexport class ZeldMinerError extends Error {\n readonly code: ZeldMinerErrorCode;\n readonly details?: ZeldMinerErrorDetails;\n\n constructor(\n code: ZeldMinerErrorCode,\n message: string,\n details?: ZeldMinerErrorDetails\n ) {\n super(message);\n this.name = \"ZeldMinerError\";\n this.code = code;\n this.details = details;\n }\n}\n\nexport const toZeldMinerError = (\n err: unknown,\n fallbackCode: ZeldMinerErrorCode = ZeldMinerErrorCode.WORKER_ERROR,\n details?: ZeldMinerErrorDetails\n): ZeldMinerError => {\n if (err instanceof ZeldMinerError) {\n return err;\n }\n\n const message = formatUnknownError(err);\n return new ZeldMinerError(fallbackCode, message, details);\n};\n\nexport const createMinerError = (\n code: ZeldMinerErrorCode,\n message: string,\n details?: ZeldMinerErrorDetails\n): ZeldMinerError => new ZeldMinerError(code, message, details);\n\n","import type {\n MineResult,\n MiningCoordinatorOptions,\n ProgressEvent as MiningProgressEvent,\n Network,\n TxInput,\n TxOutput,\n WorkerMessage,\n WorkerMode,\n WorkerResponse,\n WorkerTemplate,\n} from \"./types\";\nimport { ZeldMinerErrorCode } from \"./types\";\nimport { ZeldMinerError } from \"./errors\";\n\ntype CoordinatorEvent = \"ready\" | \"progress\" | \"found\" | \"error\" | \"stopped\";\n\ntype CoordinatorEventMap = {\n ready: void;\n progress: MiningProgressEvent;\n found: MineResult;\n error: ZeldMinerError;\n stopped: void;\n};\n\ntype CoordinatorListener<K extends CoordinatorEvent> = (\n payload: CoordinatorEventMap[K]\n) => void;\n\ninterface WorkerState {\n worker: Worker;\n hashesProcessed: bigint;\n hashRate: number;\n lastNonce?: bigint;\n nextNonce: bigint;\n processedBase: bigint;\n terminated?: boolean;\n}\n\ninterface StartParams {\n inputs: TxInput[];\n outputs: TxOutput[];\n network: Network;\n satsPerVbyte: number;\n template: WorkerTemplate;\n targetZeros: number;\n startNonce?: bigint;\n signal?: AbortSignal;\n distribution?: bigint[];\n}\n\nconst safeBigIntToNumber = (value: bigint): number => {\n const max = BigInt(Number.MAX_SAFE_INTEGER);\n if (value > max) return Number.MAX_SAFE_INTEGER;\n if (value < -max) return -Number.MAX_SAFE_INTEGER;\n return Number(value);\n};\n\nexport class MiningCoordinator {\n private readonly mode: WorkerMode;\n private readonly batchSize: number;\n private readonly workerCount: number;\n private readonly listeners: {\n [K in CoordinatorEvent]: Set<CoordinatorListener<K>>;\n };\n private readonly workers: WorkerState[] = [];\n private readonly readyPromise: Promise<void>;\n private readonly abortHandler: () => void;\n\n private stride: bigint;\n private cleanupExternalAbort = (): void => {\n if (this.externalAbort) {\n this.externalAbort.removeEventListener(\"abort\", this.abortHandler);\n this.externalAbort = undefined;\n }\n };\n private running = false;\n private paused = false;\n private startedAt: number | null = null;\n private txInputs?: TxInput[];\n private txOutputs?: TxOutput[];\n private txNetwork?: Network;\n private satsPerVbyte?: number;\n private template?: WorkerTemplate;\n private targetZeros?: number;\n private startNonce: bigint = 0n;\n private txDistribution?: bigint[];\n private externalAbort?: AbortSignal;\n private terminated = false;\n\n constructor(options: MiningCoordinatorOptions) {\n this.mode = options.mode;\n this.batchSize = options.batchSize;\n this.workerCount =\n this.mode === \"gpu\" ? 1 : Math.max(1, options.workerThreads);\n this.stride =\n this.mode === \"gpu\"\n ? BigInt(this.batchSize)\n : BigInt(this.batchSize) * BigInt(this.workerCount);\n\n this.listeners = {\n ready: new Set(),\n progress: new Set(),\n found: new Set(),\n error: new Set(),\n stopped: new Set(),\n };\n\n this.abortHandler = () => this.stop();\n this.readyPromise = this.spawnWorkers();\n }\n\n on<K extends CoordinatorEvent>(\n event: K,\n handler: CoordinatorListener<K>\n ): void {\n this.listeners[event].add(handler);\n }\n\n off<K extends CoordinatorEvent>(\n event: K,\n handler: CoordinatorListener<K>\n ): void {\n this.listeners[event].delete(handler);\n }\n\n private emit<K extends CoordinatorEvent>(\n event: K,\n payload: CoordinatorEventMap[K]\n ): void {\n this.listeners[event].forEach((handler) => handler(payload));\n }\n\n private async spawnWorkers(): Promise<void> {\n const readySignals: Promise<void>[] = [];\n\n for (let i = 0; i < this.workerCount; i += 1) {\n const worker = new Worker(new URL(\"./worker.ts\", import.meta.url), {\n type: \"module\",\n /* @vite-ignore */ name: `zeldminer-worker-${i}`,\n });\n\n const state: WorkerState = {\n worker,\n hashesProcessed: 0n,\n hashRate: 0,\n nextNonce: 0n,\n processedBase: 0n,\n };\n\n this.workers.push(state);\n\n readySignals.push(\n new Promise<void>((resolve) => {\n const handleReady = (event: MessageEvent<WorkerResponse>): void => {\n if (event.data.type === \"ready\") {\n worker.removeEventListener(\"message\", handleReady);\n resolve();\n }\n };\n\n worker.addEventListener(\"message\", handleReady);\n })\n );\n\n worker.addEventListener(\"message\", (event: MessageEvent<WorkerResponse>) =>\n this.handleWorkerMessage(state, event.data)\n );\n\n const initMessage: WorkerMessage = { type: \"init\", mode: this.mode };\n worker.postMessage(initMessage);\n }\n\n await Promise.all(readySignals);\n this.emit(\"ready\", undefined as unknown as void);\n }\n\n private handleWorkerMessage(\n state: WorkerState,\n message: WorkerResponse\n ): void {\n switch (message.type) {\n case \"ready\":\n break;\n case \"progress\":\n state.hashesProcessed = state.processedBase + message.hashesProcessed;\n state.hashRate = message.hashRate;\n state.lastNonce = message.lastNonce ?? state.lastNonce;\n this.emitProgress();\n break;\n case \"batch_complete\":\n state.lastNonce = message.lastNonce;\n state.nextNonce = this.computeNextNonce(message.lastNonce);\n break;\n case \"found\":\n state.hashesProcessed =\n state.processedBase + (message.hashesProcessed ?? state.hashesProcessed);\n state.hashRate = message.hashRate ?? state.hashRate;\n state.lastNonce = message.lastNonce ?? state.lastNonce;\n\n const attempts = this.workers.reduce(\n (total, worker) => total + worker.hashesProcessed,\n 0n\n );\n const duration = this.startedAt ? performance.now() - this.startedAt : 0;\n const hashRate =\n duration > 0\n ? safeBigIntToNumber(attempts) / (duration / 1000)\n : 0;\n\n const adjustedResult: MineResult = {\n ...message.result,\n attempts,\n duration,\n hashRate,\n };\n\n this.running = false;\n this.paused = false;\n this.terminateWorkers();\n this.cleanupExternalAbort();\n this.emit(\"found\", adjustedResult);\n break;\n case \"error\":\n this.running = false;\n this.paused = false;\n this.terminateWorkers();\n this.cleanupExternalAbort();\n this.emit(\n \"error\",\n new ZeldMinerError(\n message.code ?? ZeldMinerErrorCode.WORKER_ERROR,\n message.message,\n {\n workerId: message.workerId,\n ...(message.details ?? {}),\n }\n )\n );\n break;\n }\n }\n\n private emitProgress(): void {\n if (!this.running) return;\n\n const hashesProcessed = this.workers.reduce(\n (total, worker) => total + worker.hashesProcessed,\n 0n\n );\n const elapsedMs = this.startedAt ? performance.now() - this.startedAt : 0;\n // Derive rate from total attempts over wall-clock time to avoid overstating\n // throughput on multi-worker CPU runs.\n const hashRate =\n elapsedMs > 0\n ? safeBigIntToNumber(hashesProcessed) / (elapsedMs / 1000)\n : 0;\n\n const progress: MiningProgressEvent = {\n hashesProcessed,\n hashRate,\n elapsedMs,\n };\n\n this.emit(\"progress\", progress);\n }\n\n private computeNextNonce(lastNonce: bigint): bigint {\n const batchAdvance = this.stride - BigInt(this.batchSize);\n return lastNonce + 1n + batchAdvance;\n }\n\n private stopWorkers(): void {\n if (this.terminated) return;\n this.workers.forEach((state) =>\n state.worker.postMessage({ type: \"stop\" } satisfies WorkerMessage)\n );\n }\n\n private terminateWorkers(): void {\n if (this.terminated) return;\n this.stopWorkers();\n this.workers.forEach((state) => {\n try {\n state.worker.terminate();\n state.terminated = true;\n } catch {\n /* ignore termination errors */\n }\n });\n this.terminated = true;\n }\n\n async start(params: StartParams): Promise<void> {\n await this.readyPromise;\n this.stopWorkers();\n\n this.running = true;\n this.paused = false;\n this.startedAt = performance.now();\n this.txInputs = params.inputs;\n this.txOutputs = params.outputs;\n this.txNetwork = params.network === \"signet\" ? \"testnet\" : params.network;\n this.satsPerVbyte = params.satsPerVbyte;\n this.template = params.template;\n this.targetZeros = params.targetZeros;\n this.startNonce = params.startNonce ?? 0n;\n this.txDistribution = params.distribution;\n\n if (this.externalAbort && this.externalAbort !== params.signal) {\n this.cleanupExternalAbort();\n }\n\n if (params.signal) {\n this.externalAbort = params.signal;\n params.signal.addEventListener(\"abort\", this.abortHandler, { once: true });\n }\n\n if (\n !this.template ||\n !this.txInputs ||\n !this.txOutputs ||\n this.targetZeros === undefined ||\n this.satsPerVbyte === undefined ||\n !this.txNetwork\n ) {\n throw new Error(\"Mining parameters are missing\");\n }\n\n const inputs = this.txInputs;\n const outputs = this.txOutputs;\n const network = this.txNetwork;\n const satsPerVbyte = this.satsPerVbyte;\n const template = this.template;\n const targetZeros = this.targetZeros;\n const distribution = this.txDistribution;\n const stride = this.stride;\n\n this.workers.forEach((state, idx) => {\n state.processedBase = 0n;\n state.hashesProcessed = 0n;\n state.hashRate = 0;\n state.lastNonce = undefined;\n const workerStart =\n this.startNonce + BigInt(idx) * BigInt(this.batchSize);\n state.nextNonce = workerStart;\n\n const message: WorkerMessage = {\n type: \"mine\",\n inputs,\n outputs,\n network,\n satsPerVbyte,\n template,\n startNonce: workerStart,\n batchSize: this.batchSize,\n targetZeros,\n nonceStep: stride,\n distribution,\n };\n\n state.worker.postMessage(message);\n });\n }\n\n pause(): void {\n if (!this.running) return;\n this.running = false;\n this.paused = true;\n this.stopWorkers();\n }\n\n async resume(): Promise<void> {\n if (\n !this.paused ||\n !this.template ||\n !this.txInputs ||\n !this.txOutputs ||\n this.targetZeros === undefined ||\n this.satsPerVbyte === undefined ||\n !this.txNetwork\n )\n return;\n await this.readyPromise;\n\n this.running = true;\n this.paused = false;\n if (!this.startedAt) {\n this.startedAt = performance.now();\n }\n\n const inputs = this.txInputs;\n const outputs = this.txOutputs;\n const network = this.txNetwork;\n const satsPerVbyte = this.satsPerVbyte;\n const template = this.template;\n const targetZeros = this.targetZeros as number;\n const distribution = this.txDistribution;\n const stride = this.stride;\n\n this.workers.forEach((state, idx) => {\n state.processedBase = state.hashesProcessed;\n state.hashRate = 0;\n const workerStart =\n state.nextNonce ||\n this.startNonce + BigInt(idx) * BigInt(this.batchSize);\n\n const message: WorkerMessage = {\n type: \"mine\",\n inputs,\n outputs,\n network,\n satsPerVbyte,\n template,\n startNonce: workerStart,\n batchSize: this.batchSize,\n targetZeros,\n nonceStep: stride,\n distribution,\n };\n\n state.worker.postMessage(message);\n });\n }\n\n stop(): void {\n if (!this.running && !this.paused) return;\n this.running = false;\n this.paused = false;\n this.terminateWorkers();\n this.cleanupExternalAbort();\n this.emit(\"stopped\", undefined as unknown as void);\n }\n}\n\n","import type { WasmExports } from \"./types\";\n\nlet wasmModule: WasmExports | null = null;\nlet wasmInitPromise: Promise<WasmExports> | null = null;\n\n// Chrome/Dawn can reject requestDevice when optional limits (e.g.\n// maxInterStageShaderComponents) are present but unsupported. Strip any\n// limit keys the adapter doesn't expose to keep WebGPU initialization\n// portable across browser versions.\nlet webGpuLimitShimInstalled = false;\nconst installWebGpuLimitShim = (): void => {\n if (webGpuLimitShimInstalled) return;\n webGpuLimitShimInstalled = true;\n\n const adapterProto = (globalThis as typeof globalThis & { GPUAdapter?: { prototype?: unknown } })\n .GPUAdapter?.prototype as GPUAdapter | undefined;\n const requestDevice = adapterProto?.requestDevice;\n if (!adapterProto || typeof requestDevice !== \"function\") return;\n\n adapterProto.requestDevice = function patchedRequestDevice(\n this: GPUAdapter,\n descriptor?: GPUDeviceDescriptor\n ): Promise<GPUDevice> {\n if (descriptor?.requiredLimits && typeof this.limits === \"object\") {\n const limits = descriptor.requiredLimits as Record<string, unknown>;\n const supported = this.limits as unknown as Record<string, unknown>;\n for (const key of Object.keys(limits)) {\n if (!(key in supported) || supported[key] === undefined) {\n delete limits[key];\n }\n }\n }\n return requestDevice.call(this, descriptor);\n };\n};\n\nconst ensureTrailingSlash = (value: string): string =>\n value.endsWith(\"/\") ? value : `${value}/`;\n\nconst toAbsoluteBase = (base: string): string => {\n const trimmed = base.trim();\n if (!trimmed) return trimmed;\n // Use window origin when available so Vite treats it as an external URL and does not try to transform public assets.\n if (typeof window !== \"undefined\" && typeof window.location?.origin === \"string\") {\n return ensureTrailingSlash(new URL(trimmed, window.location.origin).href);\n }\n return ensureTrailingSlash(new URL(trimmed, import.meta.url).href);\n};\n\nconst resolveWasmBase = (): string => {\n const globalBase = (globalThis as { __ZELDMINER_WASM_BASE__?: unknown })\n .__ZELDMINER_WASM_BASE__;\n if (typeof globalBase === \"string\" && globalBase.trim()) {\n return toAbsoluteBase(globalBase);\n }\n\n const envBase = (import.meta as ImportMeta & { env?: Record<string, unknown> })\n .env?.VITE_ZELDMINER_WASM_BASE;\n if (typeof envBase === \"string\" && envBase.trim()) {\n return toAbsoluteBase(envBase);\n }\n\n const viteBase = (import.meta as ImportMeta & { env?: Record<string, unknown> }).env?.BASE_URL;\n if (typeof viteBase === \"string\" && viteBase.trim()) {\n return toAbsoluteBase(`${ensureTrailingSlash(viteBase.trim())}wasm/`);\n }\n\n return toAbsoluteBase(\"/wasm/\");\n};\n\nconst WASM_BASE_URL = resolveWasmBase();\nconst WASM_JS_PATH = `${WASM_BASE_URL}zeldhash_miner_wasm.js`;\nconst WASM_BINARY_PATH = `${WASM_BASE_URL}zeldhash_miner_wasm_bg.wasm`;\n\nconst formatError = (err: unknown): string =>\n err instanceof Error ? err.message : String(err);\n\nconst loadModule = async (): Promise<WasmExports> => {\n installWebGpuLimitShim();\n\n let bindings: unknown;\n try {\n bindings = await import(/* @vite-ignore */ WASM_JS_PATH);\n } catch (err) {\n throw new Error(\n `Failed to import WASM bundle (${WASM_JS_PATH}). ` +\n `Did you run ./scripts/build-wasm.sh? (${formatError(err)})`\n );\n }\n\n const init = (bindings as { default?: unknown }).default;\n if (typeof init !== \"function\") {\n throw new Error(\"WASM init function is missing from the bundle.\");\n }\n\n try {\n const wasmUrl = new URL(WASM_BINARY_PATH, import.meta.url);\n await init({ module_or_path: wasmUrl });\n } catch (err) {\n throw new Error(\n `Failed to initialize WASM bundle: ${formatError(err)}`\n );\n }\n\n const typedBindings = bindings as WasmExports;\n try {\n typedBindings.init_panic_hook?.();\n } catch {\n /* ignore optional panic hook failures */\n }\n\n return typedBindings;\n};\n\nexport const loadWasm = async (): Promise<WasmExports> => {\n if (wasmModule) return wasmModule;\n if (!wasmInitPromise) {\n wasmInitPromise = loadModule()\n .then((mod) => {\n wasmModule = mod;\n return mod;\n })\n .catch((err) => {\n wasmInitPromise = null;\n throw err;\n });\n }\n return wasmInitPromise;\n};\n\nexport const getWasm = (): WasmExports | null => wasmModule;\n\nexport const resetWasm = (): void => {\n wasmModule = null;\n wasmInitPromise = null;\n};\n\n","const MAX_U64 = (1n << 64n) - 1n;\n\nexport interface NonceSegment {\n start: bigint;\n size: number;\n nonceLength: number;\n}\n\nexport const nonceLength = (nonce: bigint): number => {\n if (nonce < 0n) {\n throw new Error(\"nonce must be non-negative\");\n }\n\n if (nonce === 0n) return 1;\n\n let len = 0;\n let value = nonce;\n while (value > 0n) {\n len += 1;\n value >>= 8n;\n }\n return len;\n};\n\nexport const cborNonceLength = (nonce: bigint): number => {\n if (nonce < 0n) {\n throw new Error(\"nonce must be non-negative\");\n }\n\n if (nonce <= 23n) return 1;\n if (nonce <= 0xffn) return 2;\n if (nonce <= 0xffffn) return 3;\n if (nonce <= 0xffff_ffffn) return 5;\n if (nonce <= MAX_U64) return 9;\n\n throw new Error(\"nonce range exceeds u64\");\n};\n\nconst maxValueForLength = (len: number): bigint => {\n if (!Number.isInteger(len) || len <= 0 || len > 8) {\n throw new Error(\"nonceLength must be between 1 and 8\");\n }\n return (1n << BigInt(len * 8)) - 1n;\n};\n\nconst maxValueForCborLength = (len: number): bigint => {\n switch (len) {\n case 1:\n return 23n;\n case 2:\n return 0xffn;\n case 3:\n return 0xffffn;\n case 5:\n return 0xffff_ffffn;\n case 9:\n return MAX_U64;\n default:\n throw new Error(\"cbor nonceLength must be one of 1, 2, 3, 5, 9\");\n }\n};\n\nexport const splitNonceSegments = (startNonce: bigint, span: number): NonceSegment[] => {\n if (startNonce < 0n) {\n throw new Error(\"startNonce must be non-negative\");\n }\n if (!Number.isInteger(span) || span <= 0) {\n throw new Error(\"batchSize must be a positive integer\");\n }\n\n const end = startNonce + BigInt(span - 1);\n if (end > MAX_U64) {\n throw new Error(\"nonce range exceeds u64\");\n }\n\n const segments: NonceSegment[] = [];\n let current = startNonce;\n\n while (current <= end) {\n const len = nonceLength(current);\n const maxForLen = maxValueForLength(len);\n const segmentEnd = end < maxForLen ? end : maxForLen;\n const segmentSize = segmentEnd - current + 1n;\n\n if (segmentSize > BigInt(Number.MAX_SAFE_INTEGER)) {\n throw new Error(\"segment size exceeds safe integer range\");\n }\n\n segments.push({\n start: current,\n size: Number(segmentSize),\n nonceLength: len,\n });\n\n if (segmentEnd === end) {\n break;\n }\n\n current = segmentEnd + 1n;\n }\n\n return segments;\n};\n\nexport const maxNonceForLength = (len: number): bigint => maxValueForLength(len);\n\nexport const splitNonceSegmentsCbor = (startNonce: bigint, span: number): NonceSegment[] => {\n if (startNonce < 0n) {\n throw new Error(\"startNonce must be non-negative\");\n }\n if (!Number.isInteger(span) || span <= 0) {\n throw new Error(\"batchSize must be a positive integer\");\n }\n\n const end = startNonce + BigInt(span - 1);\n if (end > MAX_U64) {\n throw new Error(\"nonce range exceeds u64\");\n }\n\n const segments: NonceSegment[] = [];\n let current = startNonce;\n\n while (current <= end) {\n const len = cborNonceLength(current);\n const maxForLen = maxValueForCborLength(len);\n const segmentEnd = end < maxForLen ? end : maxForLen;\n const segmentSize = segmentEnd - current + 1n;\n\n if (segmentSize > BigInt(Number.MAX_SAFE_INTEGER)) {\n throw new Error(\"segment size exceeds safe integer range\");\n }\n\n segments.push({\n start: current,\n size: Number(segmentSize),\n nonceLength: len,\n });\n\n if (segmentEnd === end) {\n break;\n }\n\n current = segmentEnd + 1n;\n }\n\n return segments;\n};\n\n\n","import type {\n MiningTemplate,\n Network,\n TxInput,\n TxOutput,\n ValidationResult,\n WasmExports,\n} from \"./types\";\nimport { ZeldMinerErrorCode } from \"./types\";\nimport { createMinerError, toZeldMinerError } from \"./errors\";\nimport { loadWasm } from \"./wasm\";\nimport { cborNonceLength, nonceLength } from \"./nonce\";\n\nconst TXID_REGEX = /^[0-9a-fA-F]{64}$/;\nconst HEX_REGEX = /^[0-9a-fA-F]+$/;\nconst MAX_U64 = (1n << 64n) - 1n;\nconst MAX_U32 = 0xffff_ffff;\n\nconst dustLimitForAddress = (addressType?: \"p2wpkh\" | \"p2tr\"): number => {\n if (addressType === \"p2tr\") return 330;\n if (addressType === \"p2wpkh\") return 310;\n return 546; // conservative fallback for unexpected types\n};\n\nconst formatError = (err: unknown): string =>\n err instanceof Error ? err.message : String(err);\n\nconst includesAny = (haystack: string, needles: string[]): boolean =>\n needles.some((needle) => haystack.includes(needle));\n\nconst mapWasmError = (\n err: unknown,\n context: string,\n details?: Record<string, unknown>\n): never => {\n const message = formatError(err);\n const normalized = message.toLowerCase();\n\n if (includesAny(normalized, [\"insufficient funds\", \"insufficient_funds\"])) {\n throw createMinerError(\n ZeldMinerErrorCode.INSUFFICIENT_FUNDS,\n \"Insufficient funds for outputs and fee\",\n { ...details, cause: message }\n );\n }\n\n if (includesAny(normalized, [\"change would be dust\", \"output amount below dust limit\", \"dust\"])) {\n throw createMinerError(\n ZeldMinerErrorCode.DUST_OUTPUT,\n \"Change would be dust\",\n { ...details, cause: message }\n );\n }\n\n throw toZeldMinerError(err, ZeldMinerErrorCode.WORKER_ERROR, {\n ...details,\n context,\n });\n};\n\nconst normalizeNetwork = (network: Network): Network =>\n network === \"signet\" ? \"testnet\" : network;\n\nexport class TransactionBuilder {\n private readonly network: Network;\n private readonly satsPerVbyte: number;\n\n constructor(network: Network, satsPerVbyte: number) {\n if (!Number.isFinite(satsPerVbyte) || satsPerVbyte <= 0) {\n throw createMinerError(\n ZeldMinerErrorCode.INVALID_INPUT,\n \"satsPerVbyte must be a positive number\",\n { field: \"satsPerVbyte\" }\n );\n }\n this.network = network;\n this.satsPerVbyte = satsPerVbyte;\n }\n\n private async getWasm(): Promise<WasmExports> {\n return loadWasm();\n }\n\n private assertNonceRange(startNonce: bigint, batchSize: number, useCborNonce: boolean): number {\n if (startNonce < 0n || startNonce > MAX_U64) {\n throw createMinerError(\n ZeldMinerErrorCode.INVALID_INPUT,\n \"startNonce must be between 0 and 2^64 - 1\",\n { startNonce }\n );\n }\n if (!Number.isInteger(batchSize) || batchSize <= 0 || batchSize > MAX_U32) {\n throw createMinerError(\n ZeldMinerErrorCode.INVALID_INPUT,\n \"batchSize must be a positive 32-bit integer\",\n { batchSize }\n );\n }\n\n const lastNonce = startNonce + BigInt(batchSize - 1);\n if (lastNonce > MAX_U64) {\n throw createMinerError(\n ZeldMinerErrorCode.INVALID_INPUT,\n \"nonce range exceeds u64\",\n { startNonce, batchSize }\n );\n }\n\n const lengthFn = useCborNonce ? cborNonceLength : nonceLength;\n const startLen = lengthFn(startNonce);\n const lastLen = lengthFn(lastNonce);\n if (startLen !== lastLen) {\n const boundaryLabel = useCborNonce ? \"CBOR length\" : \"byte-length\";\n throw createMinerError(\n ZeldMinerErrorCode.INVALID_INPUT,\n `nonce range crosses ${boundaryLabel} boundary; reduce batch size`,\n { startNonce, batchSize }\n );\n }\n\n return startLen;\n }\n\n private cloneInputs(inputs: TxInput[]): TxInput[] {\n return inputs.map((input) => ({ ...input }));\n }\n\n private cloneOutputs(outputs: TxOutput[]): TxOutput[] {\n return outputs.map((output) => ({ ...output }));\n }\n\n private validateInputs(inputs: TxInput[]): void {\n if (!Array.isArray(inputs) || inputs.length === 0) {\n throw createMinerError(\n ZeldMinerErrorCode.INVALID_INPUT,\n \"At least one input is required\"\n );\n }\n\n inputs.forEach((input, idx) => {\n if (!TXID_REGEX.test(input.txid)) {\n throw createMinerError(\n ZeldMinerErrorCode.INVALID_INPUT,\n `inputs[${idx}].txid must be a 64-character hex`,\n { index: idx }\n );\n }\n if (!Number.isInteger(input.vout) || input.vout < 0) {\n throw createMinerError(\n ZeldMinerErrorCode.INVALID_INPUT,\n `inputs[${idx}].vout must be a non-negative integer`,\n { index: idx }\n );\n }\n if (!Number.isInteger(input.amount) || input.amount <= 0) {\n throw createMinerError(\n ZeldMinerErrorCode.INVALID_INPUT,\n `inputs[${idx}].amount must be a positive integer`,\n { index: idx }\n );\n }\n if (\n typeof input.scriptPubKey !== \"string\" ||\n input.scriptPubKey.length === 0 ||\n input.scriptPubKey.length % 2 !== 0 ||\n !HEX_REGEX.test(input.scriptPubKey)\n ) {\n throw createMinerError(\n ZeldMinerErrorCode.INVALID_INPUT,\n `inputs[${idx}].scriptPubKey must be valid hex`,\n { index: idx }\n );\n }\n });\n }\n\n private validateAddressResult(\n validation: ValidationResult,\n idx: number,\n network: Network\n ): void {\n if (!validation.ok) {\n const reason = validation.error ?? \"invalid address\";\n const normalized = reason.toLowerCase();\n const code = normalized.includes(\"unsupported\")\n ? ZeldMinerErrorCode.UNSUPPORTED_ADDRESS_TYPE\n : ZeldMinerErrorCode.INVALID_ADDRESS;\n\n throw createMinerError(\n code,\n `outputs[${idx}].address is invalid (${reason})`,\n { index: idx }\n );\n }\n\n if (\n validation.network &&\n validation.network !== network &&\n !(validation.network === \"testnet\" && network === \"signet\")\n ) {\n throw createMinerError(\n ZeldMinerErrorCode.INVALID_ADDRESS,\n `outputs[${idx}].address network mismatch`,\n { index: idx }\n );\n }\n\n if (\n validation.addressType &&\n validation.addressType !== \"p2tr\" &&\n validation.addressType !== \"p2wpkh\"\n ) {\n throw createMinerError(\n ZeldMinerErrorCode.UNSUPPORTED_ADDRESS_TYPE,\n `outputs[${idx}].address uses an unsupported type`,\n { index: idx, addressType: validation.addressType }\n );\n }\n }\n\n private async validateOutputs(outputs: TxOutput[]): Promise<void> {\n if (!Array.isArray(outputs) || outputs.length === 0) {\n throw createMinerError(\n ZeldMinerErrorCode.INVALID_INPUT,\n \"At least one output is required\"\n );\n }\n\n const changeCount = outputs.filter((o) => o.change).length;\n if (changeCount !== 1) {\n const code =\n changeCount === 0\n ? ZeldMinerErrorCode.NO_CHANGE_OUTPUT\n : ZeldMinerErrorCode.MULTIPLE_CHANGE_OUTPUTS;\n throw createMinerError(\n code,\n \"Exactly one change output is required\",\n { changeCount }\n );\n }\n\n const wasm = await this.getWasm();\n const net = normalizeNetwork(this.network);\n\n outputs.forEach((output, idx) => {\n const validation = wasm.validate_address(output.address, net);\n this.validateAddressResult(validation, idx, net);\n const dustLimit = dustLimitForAddress(validation.addressType);\n\n if (output.change) {\n if (\n output.amount !== undefined &&\n (!Number.isInteger(output.amount) || output.amount < 0)\n ) {\n throw createMinerError(\n ZeldMinerErrorCode.INVALID_INPUT,\n `outputs[${idx}].amount must be a non-negative integer when provided`,\n { index: idx }\n );\n }\n } else {\n if (\n !Number.isInteger(output.amount) ||\n (output.amount as number) < dustLimit\n ) {\n throw createMinerError(\n ZeldMinerErrorCode.DUST_OUTPUT,\n `outputs[${idx}].amount must be at least ${dustLimit} sats`,\n { index: idx, addressType: validation.addressType }\n );\n }\n }\n });\n }\n\n private validateDistribution(\n outputs: TxOutput[],\n distribution?: bigint[]\n ): bigint[] | undefined {\n if (distribution === undefined) return undefined;\n if (!Array.isArray(distribution)) {\n throw createMinerError(\n ZeldMinerErrorCode.INVALID_INPUT,\n \"distribution must be an array of bigint values\"\n );\n }\n\n if (distribution.length !== outputs.length) {\n throw createMinerError(\n ZeldMinerErrorCode.INVALID_INPUT,\n \"distribution length must match number of outputs\",\n { expected: outputs.length, actual: distribution.length }\n );\n }\n\n return distribution.map((value, idx) => {\n if (typeof value !== \"bigint\") {\n throw createMinerError(\n ZeldMinerErrorCode.INVALID_INPUT,\n \"distribution values must be bigint\",\n { index: idx }\n );\n }\n if (value < 0n) {\n throw createMinerError(\n ZeldMinerErrorCode.INVALID_INPUT,\n \"distribution values must be non-negative\",\n { index: idx }\n );\n }\n return value;\n });\n }\n\n async buildMiningTemplate(params: {\n inputs: TxInput[];\n outputs: TxOutput[];\n startNonce: bigint;\n batchSize: number;\n distribution?: bigint[];\n }): Promise<MiningTemplate & { nonceLength: number }> {\n const { inputs, outputs, startNonce, batchSize, distribution } = params;\n this.validateInputs(inputs);\n await this.validateOutputs(outputs);\n const validatedDistribution = this.validateDistribution(outputs, distribution);\n const useCborNonce = Array.isArray(validatedDistribution);\n const nonceLength = this.assertNonceRange(startNonce, batchSize, useCborNonce);\n\n const wasm = await this.getWasm();\n try {\n const template = wasm.build_mining_template(\n this.cloneInputs(inputs),\n this.cloneOutputs(outputs),\n normalizeNetwork(this.network),\n BigInt(this.satsPerVbyte),\n startNonce,\n batchSize,\n validatedDistribution ?? null\n );\n\n if (\n !template ||\n !(template.prefix instanceof Uint8Array) ||\n !(template.suffix instanceof Uint8Array)\n ) {\n throw createMinerError(\n ZeldMinerErrorCode.WORKER_ERROR,\n \"WASM returned an invalid mining template\"\n );\n }\n\n const templateUsesCbor = template.useCborNonce ?? useCborNonce;\n return { ...template, nonceLength, useCborNonce: templateUsesCbor };\n } catch (err) {\n throw mapWasmError(err, \"build_mining_template\", {\n startNonce,\n batchSize,\n distribution: validatedDistribution,\n });\n }\n }\n\n async buildPsbt(params: {\n inputs: TxInput[];\n outputs: TxOutput[];\n nonce: bigint;\n distribution?: bigint[];\n }): Promise<string> {\n const { inputs, outputs, nonce, distribution } = params;\n this.validateInputs(inputs);\n await this.validateOutputs(outputs);\n const validatedDistribution = this.validateDistribution(outputs, distribution);\n\n if (nonce < 0n || nonce > MAX_U64) {\n throw createMinerError(\n ZeldMinerErrorCode.INVALID_INPUT,\n \"nonce must be between 0 and 2^64 - 1\",\n { nonce }\n );\n }\n\n const wasm = await this.getWasm();\n try {\n return wasm.build_psbt(\n this.cloneInputs(inputs),\n this.cloneOutputs(outputs),\n normalizeNetwork(this.network),\n BigInt(this.satsPerVbyte),\n nonce,\n validatedDistribution ?? null\n );\n } catch (err) {\n throw mapWasmError(err, \"build_psbt\", { nonce, distribution: validatedDistribution });\n }\n }\n}\n\n","import { MiningCoordinator } from \"./coordinator\";\nimport { TransactionBuilder } from \"./builder\";\nimport { splitNonceSegments, splitNonceSegmentsCbor } from \"./nonce\";\nimport type {\n MineParams,\n MineResult,\n ProgressStats,\n WorkerMode,\n ZeldMinerOptions,\n} from \"./types\";\nimport { ZeldMinerErrorCode } from \"./types\";\nimport { createMinerError, toZeldMinerError, ZeldMinerError } from \"./errors\";\n\ntype ZeldMinerEvent = \"progress\" | \"found\" | \"error\" | \"stopped\";\n\ntype ZeldMinerEventMap = {\n progress: ProgressStats;\n found: MineResult;\n error: ZeldMinerError;\n stopped: void;\n};\n\nconst MIN_TARGET_ZEROS = 1;\nconst MAX_TARGET_ZEROS = 32;\n\nexport class ZeldMiner {\n private readonly options: ZeldMinerOptions;\n private readonly builder: TransactionBuilder;\n private coordinator: MiningCoordinator | null = null;\n private readonly listeners: {\n [K in ZeldMinerEvent]: Set<(payload: ZeldMinerEventMap[K]) => void>;\n };\n private state: \"idle\" | \"running\" | \"paused\" = \"idle\";\n private stopRequested = false;\n\n constructor(options: ZeldMinerOptions) {\n this.options = this.validateOptions(options);\n this.builder = new TransactionBuilder(options.network, options.satsPerVbyte);\n this.listeners = {\n progress: new Set(),\n found: new Set(),\n error: new Set(),\n stopped: new Set(),\n };\n }\n\n on<K extends ZeldMinerEvent>(\n event: K,\n handler: (payload: ZeldMinerEventMap[K]) => void\n ): void {\n this.listeners[event].add(handler);\n }\n\n off<K extends ZeldMinerEvent>(\n event: K,\n handler: (payload: ZeldMinerEventMap[K]) => void\n ): void {\n this.listeners[event].delete(handler);\n }\n\n private emit<K extends ZeldMinerEvent>(\n event: K,\n payload: ZeldMinerEventMap[K]\n ): void {\n this.listeners[event].forEach((handler) => handler(payload));\n }\n\n private validateOptions(options: ZeldMinerOptions): ZeldMinerOptions {\n if (!Number.isInteger(options.batchSize) || options.batchSize <= 0) {\n throw createMinerError(\n ZeldMinerErrorCode.INVALID_INPUT,\n \"batchSize must be a positive integer\",\n { field: \"batchSize\" }\n );\n }\n if (!Number.isInteger(options.workerThreads) || options.workerThreads <= 0) {\n throw createMinerError(\n ZeldMinerErrorCode.INVALID_INPUT,\n \"workerThreads must be a positive integer\",\n { field: \"workerThreads\" }\n );\n }\n if (!Number.isFinite(options.satsPerVbyte) || options.satsPerVbyte <= 0) {\n throw createMinerError(\n ZeldMinerErrorCode.INVALID_INPUT,\n \"satsPerVbyte must be a positive number\",\n { field: \"satsPerVbyte\" }\n );\n }\n return options;\n }\n\n private async selectBackend(): Promise<WorkerMode> {\n if (!this.options.useWebGPU) return \"cpu\";\n if (typeof navigator === \"undefined\") return \"cpu\";\n\n const gpu = (navigator as Navigator & { gpu?: { requestAdapter?: () => Promise<unknown> } }).gpu;\n const adapter =\n typeof gpu?.requestAdapter === \"function\" ? await gpu.requestAdapter() : null;\n return adapter ? \"gpu\" : \"cpu\";\n }\n\n private clearCoordinatorHandlers(\n coordinator: MiningCoordinator,\n handlers: Partial<Record<ZeldMinerEvent, (...args: any[]) => void>>\n ): void {\n if (handlers.progress) {\n coordinator.off(\"progress\", handlers.progress as (payload: ProgressStats) => void);\n }\n if (handlers.found) {\n coordinator.off(\"found\", handlers.found as (payload: MineResult) => void);\n }\n if (handlers.error) {\n coordinator.off(\"error\", handlers.error as (payload: Error) => void);\n }\n if (handlers.stopped) {\n coordinator.off(\"stopped\", handlers.stopped as (payload: void) => void);\n }\n }\n\n async mineTransaction(params: MineParams): Promise<MineResult> {\n if (this.state === \"running\") {\n throw createMinerError(\n ZeldMinerErrorCode.INVALID_INPUT,\n \"Mining is already in progress\"\n );\n }\n\n if (\n !Number.isInteger(params.targetZeros) ||\n params.targetZeros < MIN_TARGET_ZEROS ||\n params.targetZeros > MAX_TARGET_ZEROS\n ) {\n throw createMinerError(\n ZeldMinerErrorCode.INVALID_INPUT,\n `targetZeros must be an integer between ${MIN_TARGET_ZEROS} and ${MAX_TARGET_ZEROS}`,\n { targetZeros: params.targetZeros }\n );\n }\n\n const startNonce = params.startNonce ?? 0n;\n const batchSize = params.batchSize ?? this.options.batchSize;\n\n if (!Number.isInteger(batchSize) || batchSize <= 0) {\n throw createMinerError(\n ZeldMinerErrorCode.INVALID_INPUT,\n \"batchSize must be a positive integer\",\n { batchSize }\n );\n }\n\n if (params.signal?.aborted) {\n throw createMinerError(\n ZeldMinerErrorCode.MINING_ABORTED,\n \"Abort signal already triggered\"\n );\n }\n\n const distribution = params.distribution;\n const useCborNonce = Boolean(distribution && distribution.length > 0);\n let firstSegmentSize = batchSize;\n try {\n const [firstSegment] = useCborNonce\n ? splitNonceSegmentsCbor(startNonce, batchSize)\n : splitNonceSegments(startNonce, batchSize);\n if (!firstSegment) {\n throw createMinerError(\n ZeldMinerErrorCode.INVALID_INPUT,\n \"Failed to compute nonce segments\",\n { startNonce, batchSize }\n );\n }\n firstSegmentSize = firstSegment.size;\n } catch (err) {\n throw createMinerError(\n ZeldMinerErrorCode.INVALID_INPUT,\n err instanceof Error ? err.message : String(err),\n { startNonce, batchSize }\n );\n }\n\n const mode = await this.selectBackend();\n const template = await this.builder.buildMiningTemplate({\n inputs: params.inputs,\n outputs: params.outputs,\n startNonce,\n batchSize: firstSegmentSize,\n distribution,\n });\n\n const network =\n this.options.network === \"signet\" ? \"testnet\" : this.options.network;\n const coordinator = new MiningCoordinator({\n mode,\n batchSize,\n workerThreads: this.options.workerThreads,\n });\n\n this.coordinator = coordinator;\n this.state = \"running\";\n this.stopRequested = false;\n\n return new Promise<MineResult>((resolve, reject) => {\n let settled = false;\n\n const cleanup = (): void => {\n this.clearCoordinatorHandlers(coordinator, handlers);\n if (this.coordinator === coordinator) {\n this.coordinator = null;\n }\n this.state = \"idle\";\n this.stopRequested = false;\n };\n\n const resolveOnce = (value: MineResult): void => {\n if (settled) return;\n settled = true;\n cleanup();\n resolve(value);\n };\n\n const rejectOnce = (err: unknown): void => {\n if (settled) return;\n settled = true;\n const error = toZeldMinerError(err);\n cleanup();\n this.emit(\"error\", error);\n reject(error);\n };\n\n const handlers: Partial<Record<ZeldMinerEvent, (...args: any[]) => void>> = {};\n\n handlers.progress = (stats: ProgressStats): void => {\n this.emit(\"progress\", stats);\n };\n\n handlers.found = async (result: MineResult): Promise<void> => {\n try {\n const psbt = await this.builder.buildPsbt({\n inputs: params.inputs,\n outputs: params.outputs,\n nonce: result.nonce,\n distribution,\n });\n\n const finalResult: MineResult = { ...result, psbt };\n this.emit(\"found\", finalResult);\n resolveOnce(finalResult);\n } catch (err) {\n rejectOnce(err);\n }\n };\n\n handlers.error = (err: Error): void => {\n rejectOnce(err);\n };\n\n handlers.stopped = (): void => {\n if (settled) return;\n const reason = this.stopRequested\n ? createMinerError(\n ZeldMinerErrorCode.MINING_ABORTED,\n \"Mining stopped by caller\"\n )\n : createMinerError(\n ZeldMinerErrorCode.MINING_ABORTED,\n \"Mining halted\"\n );\n this.emit(\"stopped\", undefined as unknown as void);\n rejectOnce(reason);\n };\n\n coordinator.on(\"progress\", handlers.progress);\n coordinator.on(\"found\", handlers.found);\n coordinator.on(\"error\", handlers.error);\n coordinator.on(\"stopped\", handlers.stopped);\n\n coordinator\n .start({\n inputs: params.inputs,\n outputs: params.outputs,\n network,\n satsPerVbyte: this.options.satsPerVbyte,\n template,\n targetZeros: params.targetZeros,\n startNonce,\n signal: params.signal,\n distribution,\n })\n .catch(rejectOnce);\n });\n }\n\n stop(): void {\n if (!this.coordinator) return;\n this.stopRequested = true;\n this.coordinator.stop();\n }\n\n pause(): void {\n if (this.state !== \"running\" || !this.coordinator) return;\n this.state = \"paused\";\n this.coordinator.pause();\n }\n\n async resume(): Promise<void> {\n if (this.state !== \"paused\" || !this.coordinator) return;\n this.state = \"running\";\n await this.coordinator.resume();\n }\n}\n\nexport type {\n ZeldMinerOptions,\n MineParams,\n MineResult,\n ProgressStats,\n Network,\n TxInput,\n TxOutput,\n} from \"./types\";\nexport { ZeldMinerErrorCode } from \"./types\";\nexport { TransactionBuilder } from \"./builder\";\nexport { MiningCoordinator } from \"./coordinator\";\nexport {\n ZeldMinerError,\n createMinerError,\n toZeldMinerError,\n} from \"./errors\";\n\n"],"names":["ZeldMinerErrorCode","formatUnknownError","err","ZeldMinerError","code","message","details","toZeldMinerError","fallbackCode","createMinerError","safeBigIntToNumber","value","max","MiningCoordinator","options","event","handler","payload","readySignals","i","worker","state","resolve","handleReady","initMessage","attempts","total","duration","hashRate","adjustedResult","hashesProcessed","elapsedMs","progress","lastNonce","batchAdvance","params","inputs","outputs","network","satsPerVbyte","template","targetZeros","distribution","stride","idx","workerStart","wasmModule","wasmInitPromise","webGpuLimitShimInstalled","installWebGpuLimitShim","adapterProto","requestDevice","descriptor","limits","supported","key","ensureTrailingSlash","toAbsoluteBase","base","trimmed","resolveWasmBase","globalBase","envBase","__vite_import_meta_env__","viteBase","WASM_BASE_URL","WASM_JS_PATH","WASM_BINARY_PATH","formatError","loadModule","bindings","init","wasmUrl","typedBindings","loadWasm","mod","MAX_U64","nonceLength","nonce","len","cborNonceLength","maxValueForLength","maxValueForCborLength","splitNonceSegments","startNonce","span","end","segments","current","maxForLen","segmentEnd","segmentSize","splitNonceSegmentsCbor","TXID_REGEX","HEX_REGEX","MAX_U32","dustLimitForAddress","addressType","includesAny","haystack","needles","needle","mapWasmError","context","normalized","normalizeNetwork","TransactionBuilder","batchSize","useCborNonce","lengthFn","startLen","lastLen","boundaryLabel","input","output","validation","reason","changeCount","o","wasm","net","dustLimit","validatedDistribution","templateUsesCbor","MIN_TARGET_ZEROS","MAX_TARGET_ZEROS","ZeldMiner","gpu","coordinator","handlers","firstSegmentSize","firstSegment","mode","reject","settled","cleanup","resolveOnce","rejectOnce","error","stats","result","psbt","finalResult"],"mappings":"AAAO,IAAKA,sBAAAA,OACVA,EAAA,kBAAkB,mBAClBA,EAAA,2BAA2B,4BAC3BA,EAAA,qBAAqB,sBACrBA,EAAA,mBAAmB,oBACnBA,EAAA,0BAA0B,2BAC1BA,EAAA,gBAAgB,iBAChBA,EAAA,uBAAuB,wBACvBA,EAAA,eAAe,gBACfA,EAAA,iBAAiB,kBACjBA,EAAA,cAAc,eAVJA,IAAAA,KAAA,CAAA,CAAA;ACEZ,MAAMC,IAAqB,CAACC,MAC1BA,aAAe,QAAQA,EAAI,UAAU,OAAOA,CAAG;AAE1C,MAAMC,UAAuB,MAAM;AAAA,EAC/B;AAAA,EACA;AAAA,EAET,YACEC,GACAC,GACAC,GACA;AACA,UAAMD,CAAO,GACb,KAAK,OAAO,kBACZ,KAAK,OAAOD,GACZ,KAAK,UAAUE;AAAA,EACjB;AACF;AAEO,MAAMC,IAAmB,CAC9BL,GACAM,IAAmCR,EAAmB,cACtDM,MACmB;AACnB,MAAIJ,aAAeC;AACjB,WAAOD;AAGT,QAAMG,IAAUJ,EAAmBC,CAAG;AACtC,SAAO,IAAIC,EAAeK,GAAcH,GAASC,CAAO;AAC1D,GAEaG,IAAmB,CAC9BL,GACAC,GACAC,MACmB,IAAIH,EAAeC,GAAMC,GAASC,CAAO,GCaxDI,IAAqB,CAACC,MAA0B;AACpD,QAAMC,IAAM,OAAO,OAAO,gBAAgB;AAC1C,SAAID,IAAQC,IAAY,OAAO,mBAC3BD,IAAQ,CAACC,IAAY,CAAC,OAAO,mBAC1B,OAAOD,CAAK;AACrB;AAEO,MAAME,EAAkB;AAAA,EACZ;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EAGA,UAAyB,CAAA;AAAA,EACzB;AAAA,EACA;AAAA,EAET;AAAA,EACA,uBAAuB,MAAY;AACzC,IAAI,KAAK,kBACP,KAAK,cAAc,oBAAoB,SAAS,KAAK,YAAY,GACjE,KAAK,gBAAgB;AAAA,EAEzB;AAAA,EACQ,UAAU;AAAA,EACV,SAAS;AAAA,EACT,YAA2B;AAAA,EAC3B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,aAAqB;AAAA,EACrB;AAAA,EACA;AAAA,EACA,aAAa;AAAA,EAErB,YAAYC,GAAmC;AAC7C,SAAK,OAAOA,EAAQ,MACpB,KAAK,YAAYA,EAAQ,WACzB,KAAK,cACH,KAAK,SAAS,QAAQ,IAAI,KAAK,IAAI,GAAGA,EAAQ,aAAa,GAC7D,KAAK,SACH,KAAK,SAAS,QACV,OAAO,KAAK,SAAS,IACrB,OAAO,KAAK,SAAS,IAAI,OAAO,KAAK,WAAW,GAEtD,KAAK,YAAY;AAAA,MACf,2BAAW,IAAA;AAAA,MACX,8BAAc,IAAA;AAAA,MACd,2BAAW,IAAA;AAAA,MACX,2BAAW,IAAA;AAAA,MACX,6BAAa,IAAA;AAAA,IAAI,GAGnB,KAAK,eAAe,MAAM,KAAK,KAAA,GAC/B,KAAK,eAAe,KAAK,aAAA;AAAA,EAC3B;AAAA,EAEA,GACEC,GACAC,GACM;AACN,SAAK,UAAUD,CAAK,EAAE,IAAIC,CAAO;AAAA,EACnC;AAAA,EAEA,IACED,GACAC,GACM;AACN,SAAK,UAAUD,CAAK,EAAE,OAAOC,CAAO;AAAA,EACtC;AAAA,EAEQ,KACND,GACAE,GACM;AACN,SAAK,UAAUF,CAAK,EAAE,QAAQ,CAACC,MAAYA,EAAQC,CAAO,CAAC;AAAA,EAC7D;AAAA,EAEA,MAAc,eAA8B;AAC1C,UAAMC,IAAgC,CAAA;AAEtC,aAASC,IAAI,GAAGA,IAAI,KAAK,aAAaA,KAAK,GAAG;AAC5C,YAAMC,IAAS,IAAI,OAAO,IAAA;AAAA;AAAA,QAAA;AAAA,QAAA,YAAA;AAAA,MAAA,GAAyC;AAAA,QACjE,MAAM;AAAA;AAAA,QACa,MAAM,oBAAoBD,CAAC;AAAA,MAAA,CAC/C,GAEKE,IAAqB;AAAA,QACzB,QAAAD;AAAA,QACA,iBAAiB;AAAA,QACjB,UAAU;AAAA,QACV,WAAW;AAAA,QACX,eAAe;AAAA,MAAA;AAGjB,WAAK,QAAQ,KAAKC,CAAK,GAEvBH,EAAa;AAAA,QACX,IAAI,QAAc,CAACI,MAAY;AAC7B,gBAAMC,IAAc,CAACR,MAA8C;AACjE,YAAIA,EAAM,KAAK,SAAS,YACtBK,EAAO,oBAAoB,WAAWG,CAAW,GACjDD,EAAA;AAAA,UAEJ;AAEA,UAAAF,EAAO,iBAAiB,WAAWG,CAAW;AAAA,QAChD,CAAC;AAAA,MAAA,GAGHH,EAAO;AAAA,QAAiB;AAAA,QAAW,CAACL,MAClC,KAAK,oBAAoBM,GAAON,EAAM,IAAI;AAAA,MAAA;AAG5C,YAAMS,IAA6B,EAAE,MAAM,QAAQ,MAAM,KAAK,KAAA;AAC9D,MAAAJ,EAAO,YAAYI,CAAW;AAAA,IAChC;AAEA,UAAM,QAAQ,IAAIN,CAAY,GAC9B,KAAK,KAAK,SAAS,MAA4B;AAAA,EACjD;AAAA,EAEQ,oBACNG,GACAhB,GACM;AACN,YAAQA,EAAQ,MAAA;AAAA,MACd,KAAK;AACH;AAAA,MACF,KAAK;AACH,QAAAgB,EAAM,kBAAkBA,EAAM,gBAAgBhB,EAAQ,iBACtDgB,EAAM,WAAWhB,EAAQ,UACzBgB,EAAM,YAAYhB,EAAQ,aAAagB,EAAM,WAC7C,KAAK,aAAA;AACL;AAAA,MACF,KAAK;AACH,QAAAA,EAAM,YAAYhB,EAAQ,WAC1BgB,EAAM,YAAY,KAAK,iBAAiBhB,EAAQ,SAAS;AACzD;AAAA,MACF,KAAK;AACH,QAAAgB,EAAM,kBACJA,EAAM,iBAAiBhB,EAAQ,mBAAmBgB,EAAM,kBAC1DA,EAAM,WAAWhB,EAAQ,YAAYgB,EAAM,UAC3CA,EAAM,YAAYhB,EAAQ,aAAagB,EAAM;AAE7C,cAAMI,IAAW,KAAK,QAAQ;AAAA,UAC5B,CAACC,GAAON,MAAWM,IAAQN,EAAO;AAAA,UAClC;AAAA,QAAA,GAEIO,IAAW,KAAK,YAAY,YAAY,QAAQ,KAAK,YAAY,GACjEC,IACJD,IAAW,IACPjB,EAAmBe,CAAQ,KAAKE,IAAW,OAC3C,GAEAE,IAA6B;AAAA,UACjC,GAAGxB,EAAQ;AAAA,UACX,UAAAoB;AAAA,UACA,UAAAE;AAAA,UACA,UAAAC;AAAA,QAAA;AAGF,aAAK,UAAU,IACf,KAAK,SAAS,IACd,KAAK,iBAAA,GACL,KAAK,qBAAA,GACL,KAAK,KAAK,SAASC,CAAc;AACjC;AAAA,MACF,KAAK;AACH,aAAK,UAAU,IACf,KAAK,SAAS,IACd,KAAK,iBAAA,GACL,KAAK,qBAAA,GACL,KAAK;AAAA,UACH;AAAA,UACA,IAAI1B;AAAA,YACFE,EAAQ,QAAQL,EAAmB;AAAA,YACnCK,EAAQ;AAAA,YACR;AAAA,cACE,UAAUA,EAAQ;AAAA,cAClB,GAAIA,EAAQ,WAAW,CAAA;AAAA,YAAC;AAAA,UAC1B;AAAA,QACF;AAEF;AAAA,IAAA;AAAA,EAEN;AAAA,EAEQ,eAAqB;AAC3B,QAAI,CAAC,KAAK,QAAS;AAEnB,UAAMyB,IAAkB,KAAK,QAAQ;AAAA,MACnC,CAACJ,GAAON,MAAWM,IAAQN,EAAO;AAAA,MAClC;AAAA,IAAA,GAEIW,IAAY,KAAK,YAAY,YAAY,QAAQ,KAAK,YAAY,GAGlEH,IACJG,IAAY,IACRrB,EAAmBoB,CAAe,KAAKC,IAAY,OACnD,GAEAC,IAAgC;AAAA,MACpC,iBAAAF;AAAA,MACA,UAAAF;AAAA,MACA,WAAAG;AAAA,IAAA;AAGF,SAAK,KAAK,YAAYC,CAAQ;AAAA,EAChC;AAAA,EAEQ,iBAAiBC,GAA2B;AAClD,UAAMC,IAAe,KAAK,SAAS,OAAO,KAAK,SAAS;AACxD,WAAOD,IAAY,KAAKC;AAAA,EAC1B;AAAA,EAEQ,cAAoB;AAC1B,IAAI,KAAK,cACT,KAAK,QAAQ;AAAA,MAAQ,CAACb,MACpBA,EAAM,OAAO,YAAY,EAAE,MAAM,QAAgC;AAAA,IAAA;AAAA,EAErE;AAAA,EAEQ,mBAAyB;AAC/B,IAAI,KAAK,eACT,KAAK,YAAA,GACL,KAAK,QAAQ,QAAQ,CAACA,MAAU;AAC9B,UAAI;AACF,QAAAA,EAAM,OAAO,UAAA,GACbA,EAAM,aAAa;AAAA,MACrB,QAAQ;AAAA,MAER;AAAA,IACF,CAAC,GACD,KAAK,aAAa;AAAA,EACpB;AAAA,EAEA,MAAM,MAAMc,GAAoC;AAyB9C,QAxBA,MAAM,KAAK,cACX,KAAK,YAAA,GAEL,KAAK,UAAU,IACf,KAAK,SAAS,IACd,KAAK,YAAY,YAAY,IAAA,GAC7B,KAAK,WAAWA,EAAO,QACvB,KAAK,YAAYA,EAAO,SACxB,KAAK,YAAYA,EAAO,YAAY,WAAW,YAAYA,EAAO,SAClE,KAAK,eAAeA,EAAO,cAC3B,KAAK,WAAWA,EAAO,UACvB,KAAK,cAAcA,EAAO,aAC1B,KAAK,aAAaA,EAAO,cAAc,IACvC,KAAK,iBAAiBA,EAAO,cAEzB,KAAK,iBAAiB,KAAK,kBAAkBA,EAAO,UACtD,KAAK,qBAAA,GAGHA,EAAO,WACT,KAAK,gBAAgBA,EAAO,QAC5BA,EAAO,OAAO,iBAAiB,SAAS,KAAK,cAAc,EAAE,MAAM,IAAM,IAIzE,CAAC,KAAK,YACN,CAAC,KAAK,YACN,CAAC,KAAK,aACN,KAAK,gBAAgB,UACrB,KAAK,iBAAiB,UACtB,CAAC,KAAK;AAEN,YAAM,IAAI,MAAM,+BAA+B;AAGjD,UAAMC,IAAS,KAAK,UACdC,IAAU,KAAK,WACfC,IAAU,KAAK,WACfC,IAAe,KAAK,cACpBC,IAAW,KAAK,UAChBC,IAAc,KAAK,aACnBC,IAAe,KAAK,gBACpBC,IAAS,KAAK;AAEpB,SAAK,QAAQ,QAAQ,CAACtB,GAAOuB,MAAQ;AACnC,MAAAvB,EAAM,gBAAgB,IACtBA,EAAM,kBAAkB,IACxBA,EAAM,WAAW,GACjBA,EAAM,YAAY;AAClB,YAAMwB,IACJ,KAAK,aAAa,OAAOD,CAAG,IAAI,OAAO,KAAK,SAAS;AACvD,MAAAvB,EAAM,YAAYwB;AAElB,YAAMxC,IAAyB;AAAA,QAC7B,MAAM;AAAA,QACN,QAAA+B;AAAA,QACA,SAAAC;AAAA,QACA,SAAAC;AAAA,QACA,cAAAC;AAAA,QACA,UAAAC;AAAA,QACA,YAAYK;AAAA,QACZ,WAAW,KAAK;AAAA,QAChB,aAAAJ;AAAA,QACA,WAAWE;AAAA,QACX,cAAAD;AAAA,MAAA;AAGF,MAAArB,EAAM,OAAO,YAAYhB,CAAO;AAAA,IAClC,CAAC;AAAA,EACH;AAAA,EAEA,QAAc;AACZ,IAAK,KAAK,YACV,KAAK,UAAU,IACf,KAAK,SAAS,IACd,KAAK,YAAA;AAAA,EACP;AAAA,EAEA,MAAM,SAAwB;AAC5B,QACE,CAAC,KAAK,UACN,CAAC,KAAK,YACN,CAAC,KAAK,YACN,CAAC,KAAK,aACN,KAAK,gBAAgB,UACrB,KAAK,iBAAiB,UACtB,CAAC,KAAK;AAEN;AACF,UAAM,KAAK,cAEX,KAAK,UAAU,IACf,KAAK,SAAS,IACT,KAAK,cACR,KAAK,YAAY,YAAY,IAAA;AAG/B,UAAM+B,IAAS,KAAK,UACdC,IAAU,KAAK,WACfC,IAAU,KAAK,WACfC,IAAe,KAAK,cACpBC,IAAW,KAAK,UAChBC,IAAc,KAAK,aACnBC,IAAe,KAAK,gBACpBC,IAAS,KAAK;AAEpB,SAAK,QAAQ,QAAQ,CAACtB,GAAOuB,MAAQ;AACnC,MAAAvB,EAAM,gBAAgBA,EAAM,iBAC5BA,EAAM,WAAW;AACjB,YAAMwB,IACJxB,EAAM,aACN,KAAK,aAAa,OAAOuB,CAAG,IAAI,OAAO,KAAK,SAAS,GAEjDvC,IAAyB;AAAA,QAC7B,MAAM;AAAA,QACN,QAAA+B;AAAA,QACA,SAAAC;AAAA,QACA,SAAAC;AAAA,QACA,cAAAC;AAAA,QACA,UAAAC;AAAA,QACA,YAAYK;AAAA,QACZ,WAAW,KAAK;AAAA,QAChB,aAAAJ;AAAA,QACA,WAAWE;AAAA,QACX,cAAAD;AAAA,MAAA;AAGF,MAAArB,EAAM,OAAO,YAAYhB,CAAO;AAAA,IAClC,CAAC;AAAA,EACH;AAAA,EAEA,OAAa;AACX,IAAI,CAAC,KAAK,WAAW,CAAC,KAAK,WAC3B,KAAK,UAAU,IACf,KAAK,SAAS,IACd,KAAK,iBAAA,GACL,KAAK,qBAAA,GACL,KAAK,KAAK,WAAW,MAA4B;AAAA,EACnD;AACF;;AC/aA,IAAIyC,IAAiC,MACjCC,IAA+C,MAM/CC,IAA2B;AAC/B,MAAMC,IAAyB,MAAY;AACzC,MAAID,EAA0B;AAC9B,EAAAA,IAA2B;AAE3B,QAAME,IAAgB,WACnB,YAAY,WACTC,IAAgBD,GAAc;AACpC,EAAI,CAACA,KAAgB,OAAOC,KAAkB,eAE9CD,EAAa,gBAAgB,SAE3BE,GACoB;AACpB,QAAIA,GAAY,kBAAkB,OAAO,KAAK,UAAW,UAAU;AACjE,YAAMC,IAASD,EAAW,gBACpBE,IAAY,KAAK;AACvB,iBAAWC,KAAO,OAAO,KAAKF,CAAM;AAClC,SAAI,EAAEE,KAAOD,MAAcA,EAAUC,CAAG,MAAM,WAC5C,OAAOF,EAAOE,CAAG;AAAA,IAGvB;AACA,WAAOJ,EAAc,KAAK,MAAMC,CAAU;AAAA,EAC5C;AACF,GAEMI,IAAsB,CAAC7C,MAC3BA,EAAM,SAAS,GAAG,IAAIA,IAAQ,GAAGA,CAAK,KAElC8C,IAAiB,CAACC,MAAyB;AAC/C,QAAMC,IAAUD,EAAK,KAAA;AACrB,SAAKC,MAED,OAAO,SAAW,OAAe,OAAO,OAAO,UAAU,UAAW,WAC/DH,EAAoB,IAAI,IAAIG,GAAS,OAAO,SAAS,MAAM,EAAE,IAAI,IAEnEH,EAAoB,IAAI,IAAIG,GAAS,YAAY,GAAG,EAAE,IAAI;AACnE,GAEMC,IAAkB,MAAc;AACpC,QAAMC,IAAc,WACjB;AACH,MAAI,OAAOA,KAAe,YAAYA,EAAW;AAC/C,WAAOJ,EAAeI,CAAU;AAGlC,QAAMC,IAAWC,GACT;AACR,MAAI,OAAOD,KAAY,YAAYA,EAAQ;AACzC,WAAOL,EAAeK,CAAO;AAG/B,QAAME,IAAY;AAClB,SAAoCA,EAAS,SACpCP,EAAe,GAAGD,EAAoBQ,EAAS,KAAA,CAAM,CAAC,OAAO,IAG/DP,EAAe,QAAQ;AAChC,GAEMQ,IAAgBL,EAAA,GAChBM,IAAe,GAAGD,CAAa,0BAC/BE,IAAmB,GAAGF,CAAa,+BAEnCG,IAAc,CAAClE,MACnBA,aAAe,QAAQA,EAAI,UAAU,OAAOA,CAAG,GAE3CmE,IAAa,YAAkC;AACnD,EAAApB,EAAA;AAEA,MAAIqB;AACJ,MAAI;AACF,IAAAA,IAAW,MAAM;AAAA;AAAA,MAA0BJ;AAAA;AAAA,EAC7C,SAAShE,GAAK;AACZ,UAAM,IAAI;AAAA,MACR,iCAAiCgE,CAAY,4CACFE,EAAYlE,CAAG,CAAC;AAAA,IAAA;AAAA,EAE/D;AAEA,QAAMqE,IAAQD,EAAmC;AACjD,MAAI,OAAOC,KAAS;AAClB,UAAM,IAAI,MAAM,gDAAgD;AAGlE,MAAI;AACF,UAAMC,IAAU,IAAI,IAAIL,GAAkB,YAAY,GAAG;AACzD,UAAMI,EAAK,EAAE,gBAAgBC,GAAS;AAAA,EACxC,SAAStE,GAAK;AACZ,UAAM,IAAI;AAAA,MACR,qCAAqCkE,EAAYlE,CAAG,CAAC;AAAA,IAAA;AAAA,EAEzD;AAEA,QAAMuE,IAAgBH;AACtB,MAAI;AACF,IAAAG,EAAc,kBAAA;AAAA,EAChB,QAAQ;AAAA,EAER;AAEA,SAAOA;AACT,GAEaC,IAAW,YAClB5B,MACCC,MACHA,IAAkBsB,EAAA,EACf,KAAK,CAACM,OACL7B,IAAa6B,GACNA,EACR,EACA,MAAM,CAACzE,MAAQ;AACd,QAAA6C,IAAkB,MACZ7C;AACR,CAAC,IAEE6C,IC/HH6B,KAAW,MAAM,OAAO,IAQjBC,IAAc,CAACC,MAA0B;AACpD,MAAIA,IAAQ;AACV,UAAM,IAAI,MAAM,4BAA4B;AAG9C,MAAIA,MAAU,GAAI,QAAO;AAEzB,MAAIC,IAAM,GACNpE,IAAQmE;AACZ,SAAOnE,IAAQ;AACb,IAAAoE,KAAO,GACPpE,MAAU;AAEZ,SAAOoE;AACT,GAEaC,IAAkB,CAACF,MAA0B;AACxD,MAAIA,IAAQ;AACV,UAAM,IAAI,MAAM,4BAA4B;AAG9C,MAAIA,KAAS,IAAK,QAAO;AACzB,MAAIA,KAAS,MAAO,QAAO;AAC3B,MAAIA,KAAS,QAAS,QAAO;AAC7B,MAAIA,KAAS,YAAc,QAAO;AAClC,MAAIA,KAASF,EAAS,QAAO;AAE7B,QAAM,IAAI,MAAM,yBAAyB;AAC3C,GAEMK,IAAoB,CAACF,MAAwB;AACjD,MAAI,CAAC,OAAO,UAAUA,CAAG,KAAKA,KAAO,KAAKA,IAAM;AAC9C,UAAM,IAAI,MAAM,qCAAqC;AAEvD,UAAQ,MAAM,OAAOA,IAAM,CAAC,KAAK;AACnC,GAEMG,IAAwB,CAACH,MAAwB;AACrD,UAAQA,GAAA;AAAA,IACN,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AACH,aAAOH;AAAAA,IACT;AACE,YAAM,IAAI,MAAM,+CAA+C;AAAA,EAAA;AAErE,GAEaO,IAAqB,CAACC,GAAoBC,MAAiC;AACtF,MAAID,IAAa;AACf,UAAM,IAAI,MAAM,iCAAiC;AAEnD,MAAI,CAAC,OAAO,UAAUC,CAAI,KAAKA,KAAQ;AACrC,UAAM,IAAI,MAAM,sCAAsC;AAGxD,QAAMC,IAAMF,IAAa,OAAOC,IAAO,CAAC;AACxC,MAAIC,IAAMV;AACR,UAAM,IAAI,MAAM,yBAAyB;AAG3C,QAAMW,IAA2B,CAAA;AACjC,MAAIC,IAAUJ;AAEd,SAAOI,KAAWF,KAAK;AACrB,UAAMP,IAAMF,EAAYW,CAAO,GACzBC,IAAYR,EAAkBF,CAAG,GACjCW,IAAaJ,IAAMG,IAAYH,IAAMG,GACrCE,IAAcD,IAAaF,IAAU;AAE3C,QAAIG,IAAc,OAAO,OAAO,gBAAgB;AAC9C,YAAM,IAAI,MAAM,yCAAyC;AAS3D,QANAJ,EAAS,KAAK;AAAA,MACZ,OAAOC;AAAA,MACP,MAAM,OAAOG,CAAW;AAAA,MACxB,aAAaZ;AAAA,IAAA,CACd,GAEGW,MAAeJ;AACjB;AAGF,IAAAE,IAAUE,IAAa;AAAA,EACzB;AAEA,SAAOH;AACT,GAIaK,KAAyB,CAACR,GAAoBC,MAAiC;AAC1F,MAAID,IAAa;AACf,UAAM,IAAI,MAAM,iCAAiC;AAEnD,MAAI,CAAC,OAAO,UAAUC,CAAI,KAAKA,KAAQ;AACrC,UAAM,IAAI,MAAM,sCAAsC;AAGxD,QAAMC,IAAMF,IAAa,OAAOC,IAAO,CAAC;AACxC,MAAIC,IAAMV;AACR,UAAM,IAAI,MAAM,yBAAyB;AAG3C,QAAMW,IAA2B,CAAA;AACjC,MAAIC,IAAUJ;AAEd,SAAOI,KAAWF,KAAK;AACrB,UAAMP,IAAMC,EAAgBQ,CAAO,GAC7BC,IAAYP,EAAsBH,CAAG,GACrCW,IAAaJ,IAAMG,IAAYH,IAAMG,GACrCE,IAAcD,IAAaF,IAAU;AAE3C,QAAIG,IAAc,OAAO,OAAO,gBAAgB;AAC9C,YAAM,IAAI,MAAM,yCAAyC;AAS3D,QANAJ,EAAS,KAAK;AAAA,MACZ,OAAOC;AAAA,MACP,MAAM,OAAOG,CAAW;AAAA,MACxB,aAAaZ;AAAA,IAAA,CACd,GAEGW,MAAeJ;AACjB;AAGF,IAAAE,IAAUE,IAAa;AAAA,EACzB;AAEA,SAAOH;AACT,GCrIMM,KAAa,qBACbC,KAAY,kBACZlB,KAAW,MAAM,OAAO,IACxBmB,KAAU,YAEVC,KAAsB,CAACC,MACvBA,MAAgB,SAAe,MAC/BA,MAAgB,WAAiB,MAC9B,KAGH7B,KAAc,CAAClE,MACnBA,aAAe,QAAQA,EAAI,UAAU,OAAOA,CAAG,GAE3CgG,IAAc,CAACC,GAAkBC,MACrCA,EAAQ,KAAK,CAACC,MAAWF,EAAS,SAASE,CAAM,CAAC,GAE9CC,IAAe,CACnBpG,GACAqG,GACAjG,MACU;AACV,QAAMD,IAAU+D,GAAYlE,CAAG,GACzBsG,IAAanG,EAAQ,YAAA;AAE3B,QAAI6F,EAAYM,GAAY,CAAC,sBAAsB,oBAAoB,CAAC,IAChE/F;AAAA,IACJT,EAAmB;AAAA,IACnB;AAAA,IACA,EAAE,GAAGM,GAAS,OAAOD,EAAA;AAAA,EAAQ,IAI7B6F,EAAYM,GAAY,CAAC,wBAAwB,kCAAkC,MAAM,CAAC,IACtF/F;AAAA,IACJT,EAAmB;AAAA,IACnB;AAAA,IACA,EAAE,GAAGM,GAAS,OAAOD,EAAA;AAAA,EAAQ,IAI3BE,EAAiBL,GAAKF,EAAmB,cAAc;AAAA,IAC3D,GAAGM;AAAA,IACH,SAAAiG;AAAA,EAAA,CACD;AACH,GAEME,IAAmB,CAACnE,MACxBA,MAAY,WAAW,YAAYA;AAE9B,MAAMoE,GAAmB;AAAA,EACb;AAAA,EACA;AAAA,EAEjB,YAAYpE,GAAkBC,GAAsB;AAClD,QAAI,CAAC,OAAO,SAASA,CAAY,KAAKA,KAAgB;AACpD,YAAM9B;AAAA,QACJT,EAAmB;AAAA,QACnB;AAAA,QACA,EAAE,OAAO,eAAA;AAAA,MAAe;AAG5B,SAAK,UAAUsC,GACf,KAAK,eAAeC;AAAA,EACtB;AAAA,EAEA,MAAc,UAAgC;AAC5C,WAAOmC,EAAA;AAAA,EACT;AAAA,EAEQ,iBAAiBU,GAAoBuB,GAAmBC,GAA+B;AAC7F,QAAIxB,IAAa,MAAMA,IAAaR;AAClC,YAAMnE;AAAA,QACJT,EAAmB;AAAA,QACnB;AAAA,QACA,EAAE,YAAAoF,EAAA;AAAA,MAAW;AAGjB,QAAI,CAAC,OAAO,UAAUuB,CAAS,KAAKA,KAAa,KAAKA,IAAYZ;AAChE,YAAMtF;AAAA,QACJT,EAAmB;AAAA,QACnB;AAAA,QACA,EAAE,WAAA2G,EAAA;AAAA,MAAU;AAIhB,UAAM1E,IAAYmD,IAAa,OAAOuB,IAAY,CAAC;AACnD,QAAI1E,IAAY2C;AACd,YAAMnE;AAAA,QACJT,EAAmB;AAAA,QACnB;AAAA,QACA,EAAE,YAAAoF,GAAY,WAAAuB,EAAA;AAAA,MAAU;AAI5B,UAAME,IAAWD,IAAe5B,IAAkBH,GAC5CiC,IAAWD,EAASzB,CAAU,GAC9B2B,IAAUF,EAAS5E,CAAS;AAClC,QAAI6E,MAAaC,GAAS;AACxB,YAAMC,IAAgBJ,IAAe,gBAAgB;AACrD,YAAMnG;AAAA,QACJT,EAAmB;AAAA,QACnB,uBAAuBgH,CAAa;AAAA,QACpC,EAAE,YAAA5B,GAAY,WAAAuB,EAAA;AAAA,MAAU;AAAA,IAE5B;AAEA,WAAOG;AAAA,EACT;AAAA,EAEQ,YAAY1E,GAA8B;AAChD,WAAOA,EAAO,IAAI,CAAC6E,OAAW,EAAE,GAAGA,IAAQ;AAAA,EAC7C;AAAA,EAEQ,aAAa5E,GAAiC;AACpD,WAAOA,EAAQ,IAAI,CAAC6E,OAAY,EAAE,GAAGA,IAAS;AAAA,EAChD;AAAA,EAEQ,eAAe9E,GAAyB;AAC9C,QAAI,CAAC,MAAM,QAAQA,CAAM,KAAKA,EAAO,WAAW;AAC9C,YAAM3B;AAAA,QACJT,EAAmB;AAAA,QACnB;AAAA,MAAA;AAIJ,IAAAoC,EAAO,QAAQ,CAAC6E,GAAOrE,MAAQ;AAC7B,UAAI,CAACiD,GAAW,KAAKoB,EAAM,IAAI;AAC7B,cAAMxG;AAAA,UACJT,EAAmB;AAAA,UACnB,UAAU4C,CAAG;AAAA,UACb,EAAE,OAAOA,EAAA;AAAA,QAAI;AAGjB,UAAI,CAAC,OAAO,UAAUqE,EAAM,IAAI,KAAKA,EAAM,OAAO;AAChD,cAAMxG;AAAA,UACJT,EAAmB;AAAA,UACnB,UAAU4C,CAAG;AAAA,UACb,EAAE,OAAOA,EAAA;AAAA,QAAI;AAGjB,UAAI,CAAC,OAAO,UAAUqE,EAAM,MAAM,KAAKA,EAAM,UAAU;AACrD,cAAMxG;AAAA,UACJT,EAAmB;AAAA,UACnB,UAAU4C,CAAG;AAAA,UACb,EAAE,OAAOA,EAAA;AAAA,QAAI;AAGjB,UACE,OAAOqE,EAAM,gBAAiB,YAC9BA,EAAM,aAAa,WAAW,KAC9BA,EAAM,aAAa,SAAS,MAAM,KAClC,CAACnB,GAAU,KAAKmB,EAAM,YAAY;AAElC,cAAMxG;AAAA,UACJT,EAAmB;AAAA,UACnB,UAAU4C,CAAG;AAAA,UACb,EAAE,OAAOA,EAAA;AAAA,QAAI;AAAA,IAGnB,CAAC;AAAA,EACH;AAAA,EAEQ,sBACNuE,GACAvE,GACAN,GACM;AACN,QAAI,CAAC6E,EAAW,IAAI;AAClB,YAAMC,IAASD,EAAW,SAAS,mBAE7B/G,IADagH,EAAO,YAAA,EACF,SAAS,aAAa,IAC1CpH,EAAmB,2BACnBA,EAAmB;AAEvB,YAAMS;AAAA,QACJL;AAAA,QACA,WAAWwC,CAAG,yBAAyBwE,CAAM;AAAA,QAC7C,EAAE,OAAOxE,EAAA;AAAA,MAAI;AAAA,IAEjB;AAEA,QACEuE,EAAW,WACXA,EAAW,YAAY7E,KACvB,EAAE6E,EAAW,YAAY,aAAa7E,MAAY;AAElD,YAAM7B;AAAA,QACJT,EAAmB;AAAA,QACnB,WAAW4C,CAAG;AAAA,QACd,EAAE,OAAOA,EAAA;AAAA,MAAI;AAIjB,QACEuE,EAAW,eACXA,EAAW,gBAAgB,UAC3BA,EAAW,gBAAgB;AAE3B,YAAM1G;AAAA,QACJT,EAAmB;AAAA,QACnB,WAAW4C,CAAG;AAAA,QACd,EAAE,OAAOA,GAAK,aAAauE,EAAW,YAAA;AAAA,MAAY;AAAA,EAGxD;AAAA,EAEA,MAAc,gBAAgB9E,GAAoC;AAChE,QAAI,CAAC,MAAM,QAAQA,CAAO,KAAKA,EAAQ,WAAW;AAChD,YAAM5B;AAAA,QACJT,EAAmB;AAAA,QACnB;AAAA,MAAA;AAIJ,UAAMqH,IAAchF,EAAQ,OAAO,CAACiF,MAAMA,EAAE,MAAM,EAAE;AACpD,QAAID,MAAgB,GAAG;AACrB,YAAMjH,IACJiH,MAAgB,IACZrH,EAAmB,mBACnBA,EAAmB;AACzB,YAAMS;AAAA,QACJL;AAAA,QACA;AAAA,QACA,EAAE,aAAAiH,EAAA;AAAA,MAAY;AAAA,IAElB;AAEA,UAAME,IAAO,MAAM,KAAK,QAAA,GAClBC,IAAMf,EAAiB,KAAK,OAAO;AAEzC,IAAApE,EAAQ,QAAQ,CAAC6E,GAAQtE,MAAQ;AAC/B,YAAMuE,IAAaI,EAAK,iBAAiBL,EAAO,SAASM,CAAG;AAC5D,WAAK,sBAAsBL,GAAYvE,GAAK4E,CAAG;AAC/C,YAAMC,IAAYzB,GAAoBmB,EAAW,WAAW;AAE5D,UAAID,EAAO;AACT,YACEA,EAAO,WAAW,WACjB,CAAC,OAAO,UAAUA,EAAO,MAAM,KAAKA,EAAO,SAAS;AAErD,gBAAMzG;AAAA,YACJT,EAAmB;AAAA,YACnB,WAAW4C,CAAG;AAAA,YACd,EAAE,OAAOA,EAAA;AAAA,UAAI;AAAA,iBAKf,CAAC,OAAO,UAAUsE,EAAO,MAAM,KAC9BA,EAAO,SAAoBO;AAE5B,cAAMhH;AAAA,UACJT,EAAmB;AAAA,UACnB,WAAW4C,CAAG,6BAA6B6E,CAAS;AAAA,UACpD,EAAE,OAAO7E,GAAK,aAAauE,EAAW,YAAA;AAAA,QAAY;AAAA,IAI1D,CAAC;AAAA,EACH;AAAA,EAEQ,qBACN9E,GACAK,GACsB;AACtB,QAAIA,MAAiB,QACrB;AAAA,UAAI,CAAC,MAAM,QAAQA,CAAY;AAC7B,cAAMjC;AAAA,UACJT,EAAmB;AAAA,UACnB;AAAA,QAAA;AAIJ,UAAI0C,EAAa,WAAWL,EAAQ;AAClC,cAAM5B;AAAA,UACJT,EAAmB;AAAA,UACnB;AAAA,UACA,EAAE,UAAUqC,EAAQ,QAAQ,QAAQK,EAAa,OAAA;AAAA,QAAO;AAI5D,aAAOA,EAAa,IAAI,CAAC/B,GAAOiC,MAAQ;AACtC,YAAI,OAAOjC,KAAU;AACnB,gBAAMF;AAAA,YACJT,EAAmB;AAAA,YACnB;AAAA,YACA,EAAE,OAAO4C,EAAA;AAAA,UAAI;AAGjB,YAAIjC,IAAQ;AACV,gBAAMF;AAAA,YACJT,EAAmB;AAAA,YACnB;AAAA,YACA,EAAE,OAAO4C,EAAA;AAAA,UAAI;AAGjB,eAAOjC;AAAA,MACT,CAAC;AAAA;AAAA,EACH;AAAA,EAEA,MAAM,oBAAoBwB,GAM4B;AACpD,UAAM,EAAE,QAAAC,GAAQ,SAAAC,GAAS,YAAA+C,GAAY,WAAAuB,GAAW,cAAAjE,MAAiBP;AACjE,SAAK,eAAeC,CAAM,GAC1B,MAAM,KAAK,gBAAgBC,CAAO;AAClC,UAAMqF,IAAwB,KAAK,qBAAqBrF,GAASK,CAAY,GACvEkE,IAAe,MAAM,QAAQc,CAAqB,GAClD7C,IAAc,KAAK,iBAAiBO,GAAYuB,GAAWC,CAAY,GAEvEW,IAAO,MAAM,KAAK,QAAA;AACxB,QAAI;AACF,YAAM/E,IAAW+E,EAAK;AAAA,QACpB,KAAK,YAAYnF,CAAM;AAAA,QACvB,KAAK,aAAaC,CAAO;AAAA,QACzBoE,EAAiB,KAAK,OAAO;AAAA,QAC7B,OAAO,KAAK,YAAY;AAAA,QACxBrB;AAAA,QACAuB;AAAA,QACAe,KAAyB;AAAA,MAAA;AAG3B,UACE,CAAClF,KACD,EAAEA,EAAS,kBAAkB,eAC7B,EAAEA,EAAS,kBAAkB;AAE7B,cAAM/B;AAAA,UACJT,EAAmB;AAAA,UACnB;AAAA,QAAA;AAIJ,YAAM2H,IAAmBnF,EAAS,gBAAgBoE;AAClD,aAAO,EAAE,GAAGpE,GAAU,aAAAqC,GAAa,cAAc8C,EAAA;AAAA,IACnD,SAASzH,GAAK;AACZ,YAAMoG,EAAapG,GAAK,yBAAyB;AAAA,QAC/C,YAAAkF;AAAA,QACA,WAAAuB;AAAA,QACA,cAAce;AAAA,MAAA,CACf;AAAA,IACH;AAAA,EACF;AAAA,EAEA,MAAM,UAAUvF,GAKI;AAClB,UAAM,EAAE,QAAAC,GAAQ,SAAAC,GAAS,OAAAyC,GAAO,cAAApC,MAAiBP;AACjD,SAAK,eAAeC,CAAM,GAC1B,MAAM,KAAK,gBAAgBC,CAAO;AAClC,UAAMqF,IAAwB,KAAK,qBAAqBrF,GAASK,CAAY;AAE7E,QAAIoC,IAAQ,MAAMA,IAAQF;AACxB,YAAMnE;AAAA,QACJT,EAAmB;AAAA,QACnB;AAAA,QACA,EAAE,OAAA8E,EAAA;AAAA,MAAM;AAIZ,UAAMyC,IAAO,MAAM,KAAK,QAAA;AACxB,QAAI;AACF,aAAOA,EAAK;AAAA,QACV,KAAK,YAAYnF,CAAM;AAAA,QACvB,KAAK,aAAaC,CAAO;AAAA,QACzBoE,EAAiB,KAAK,OAAO;AAAA,QAC7B,OAAO,KAAK,YAAY;AAAA,QACxB3B;AAAA,QACA4C,KAAyB;AAAA,MAAA;AAAA,IAE7B,SAASxH,GAAK;AACZ,YAAMoG,EAAapG,GAAK,cAAc,EAAE,OAAA4E,GAAO,cAAc4C,GAAuB;AAAA,IACtF;AAAA,EACF;AACF;ACrXA,MAAME,IAAmB,GACnBC,IAAmB;AAElB,MAAMC,GAAU;AAAA,EACJ;AAAA,EACA;AAAA,EACT,cAAwC;AAAA,EAC/B;AAAA,EAGT,QAAuC;AAAA,EACvC,gBAAgB;AAAA,EAExB,YAAYhH,GAA2B;AACrC,SAAK,UAAU,KAAK,gBAAgBA,CAAO,GAC3C,KAAK,UAAU,IAAI4F,GAAmB5F,EAAQ,SAASA,EAAQ,YAAY,GAC3E,KAAK,YAAY;AAAA,MACf,8BAAc,IAAA;AAAA,MACd,2BAAW,IAAA;AAAA,MACX,2BAAW,IAAA;AAAA,MACX,6BAAa,IAAA;AAAA,IAAI;AAAA,EAErB;AAAA,EAEA,GACEC,GACAC,GACM;AACN,SAAK,UAAUD,CAAK,EAAE,IAAIC,CAAO;AAAA,EACnC;AAAA,EAEA,IACED,GACAC,GACM;AACN,SAAK,UAAUD,CAAK,EAAE,OAAOC,CAAO;AAAA,EACtC;AAAA,EAEQ,KACND,GACAE,GACM;AACN,SAAK,UAAUF,CAAK,EAAE,QAAQ,CAACC,MAAYA,EAAQC,CAAO,CAAC;AAAA,EAC7D;AAAA,EAEQ,gBAAgBH,GAA6C;AACnE,QAAI,CAAC,OAAO,UAAUA,EAAQ,SAAS,KAAKA,EAAQ,aAAa;AAC/D,YAAML;AAAA,QACJT,EAAmB;AAAA,QACnB;AAAA,QACA,EAAE,OAAO,YAAA;AAAA,MAAY;AAGzB,QAAI,CAAC,OAAO,UAAUc,EAAQ,aAAa,KAAKA,EAAQ,iBAAiB;AACvE,YAAML;AAAA,QACJT,EAAmB;AAAA,QACnB;AAAA,QACA,EAAE,OAAO,gBAAA;AAAA,MAAgB;AAG7B,QAAI,CAAC,OAAO,SAASc,EAAQ,YAAY,KAAKA,EAAQ,gBAAgB;AACpE,YAAML;AAAA,QACJT,EAAmB;AAAA,QACnB;AAAA,QACA,EAAE,OAAO,eAAA;AAAA,MAAe;AAG5B,WAAOc;AAAA,EACT;AAAA,EAEA,MAAc,gBAAqC;AAEjD,QADI,CAAC,KAAK,QAAQ,aACd,OAAO,YAAc,IAAa,QAAO;AAE7C,UAAMiH,IAAO,UAAgF;AAG7F,YADE,OAAOA,GAAK,kBAAmB,aAAa,MAAMA,EAAI,mBAAmB,QAC1D,QAAQ;AAAA,EAC3B;AAAA,EAEQ,yBACNC,GACAC,GACM;AACN,IAAIA,EAAS,YACXD,EAAY,IAAI,YAAYC,EAAS,QAA4C,GAE/EA,EAAS,SACXD,EAAY,IAAI,SAASC,EAAS,KAAsC,GAEtEA,EAAS,SACXD,EAAY,IAAI,SAASC,EAAS,KAAiC,GAEjEA,EAAS,WACXD,EAAY,IAAI,WAAWC,EAAS,OAAkC;AAAA,EAE1E;AAAA,EAEA,MAAM,gBAAgB9F,GAAyC;AAC7D,QAAI,KAAK,UAAU;AACjB,YAAM1B;AAAA,QACJT,EAAmB;AAAA,QACnB;AAAA,MAAA;AAIJ,QACE,CAAC,OAAO,UAAUmC,EAAO,WAAW,KACpCA,EAAO,cAAcyF,KACrBzF,EAAO,cAAc0F;AAErB,YAAMpH;AAAA,QACJT,EAAmB;AAAA,QACnB,0CAA0C4H,CAAgB,QAAQC,CAAgB;AAAA,QAClF,EAAE,aAAa1F,EAAO,YAAA;AAAA,MAAY;AAItC,UAAMiD,IAAajD,EAAO,cAAc,IAClCwE,IAAYxE,EAAO,aAAa,KAAK,QAAQ;AAEnD,QAAI,CAAC,OAAO,UAAUwE,CAAS,KAAKA,KAAa;AAC/C,YAAMlG;AAAA,QACJT,EAAmB;AAAA,QACnB;AAAA,QACA,EAAE,WAAA2G,EAAA;AAAA,MAAU;AAIhB,QAAIxE,EAAO,QAAQ;AACjB,YAAM1B;AAAA,QACJT,EAAmB;AAAA,QACnB;AAAA,MAAA;AAIJ,UAAM0C,IAAeP,EAAO,cACtByE,IAAe,GAAQlE,KAAgBA,EAAa,SAAS;AACnE,QAAIwF,IAAmBvB;AACvB,QAAI;AACF,YAAM,CAACwB,CAAY,IAAIvB,IACnBhB,GAAuBR,GAAYuB,CAAS,IAC5CxB,EAAmBC,GAAYuB,CAAS;AAC5C,UAAI,CAACwB;AACH,cAAM1H;AAAA,UACJT,EAAmB;AAAA,UACnB;AAAA,UACA,EAAE,YAAAoF,GAAY,WAAAuB,EAAA;AAAA,QAAU;AAG5B,MAAAuB,IAAmBC,EAAa;AAAA,IAClC,SAASjI,GAAK;AACZ,YAAMO;AAAA,QACJT,EAAmB;AAAA,QACnBE,aAAe,QAAQA,EAAI,UAAU,OAAOA,CAAG;AAAA,QAC/C,EAAE,YAAAkF,GAAY,WAAAuB,EAAA;AAAA,MAAU;AAAA,IAE5B;AAEA,UAAMyB,IAAO,MAAM,KAAK,cAAA,GAClB5F,IAAW,MAAM,KAAK,QAAQ,oBAAoB;AAAA,MACtD,QAAQL,EAAO;AAAA,MACf,SAASA,EAAO;AAAA,MAChB,YAAAiD;AAAA,MACA,WAAW8C;AAAA,MACX,cAAAxF;AAAA,IAAA,CACD,GAEKJ,IACJ,KAAK,QAAQ,YAAY,WAAW,YAAY,KAAK,QAAQ,SACzD0F,IAAc,IAAInH,EAAkB;AAAA,MACxC,MAAAuH;AAAA,MACA,WAAAzB;AAAA,MACA,eAAe,KAAK,QAAQ;AAAA,IAAA,CAC7B;AAED,gBAAK,cAAcqB,GACnB,KAAK,QAAQ,WACb,KAAK,gBAAgB,IAEd,IAAI,QAAoB,CAAC1G,GAAS+G,MAAW;AAClD,UAAIC,IAAU;AAEd,YAAMC,IAAU,MAAY;AAC1B,aAAK,yBAAyBP,GAAaC,CAAQ,GAC/C,KAAK,gBAAgBD,MACvB,KAAK,cAAc,OAErB,KAAK,QAAQ,QACb,KAAK,gBAAgB;AAAA,MACvB,GAEMQ,IAAc,CAAC7H,MAA4B;AAC/C,QAAI2H,MACJA,IAAU,IACVC,EAAA,GACAjH,EAAQX,CAAK;AAAA,MACf,GAEM8H,IAAa,CAACvI,MAAuB;AACzC,YAAIoI,EAAS;AACb,QAAAA,IAAU;AACV,cAAMI,IAAQnI,EAAiBL,CAAG;AAClC,QAAAqI,EAAA,GACA,KAAK,KAAK,SAASG,CAAK,GACxBL,EAAOK,CAAK;AAAA,MACd,GAEMT,IAAsE,CAAA;AAE5E,MAAAA,EAAS,WAAW,CAACU,MAA+B;AAClD,aAAK,KAAK,YAAYA,CAAK;AAAA,MAC7B,GAEAV,EAAS,QAAQ,OAAOW,MAAsC;AAC5D,YAAI;AACF,gBAAMC,IAAO,MAAM,KAAK,QAAQ,UAAU;AAAA,YACxC,QAAQ1G,EAAO;AAAA,YACf,SAASA,EAAO;AAAA,YAChB,OAAOyG,EAAO;AAAA,YACd,cAAAlG;AAAA,UAAA,CACD,GAEKoG,IAA0B,EAAE,GAAGF,GAAQ,MAAAC,EAAA;AAC7C,eAAK,KAAK,SAASC,CAAW,GAC9BN,EAAYM,CAAW;AAAA,QACzB,SAAS5I,GAAK;AACZ,UAAAuI,EAAWvI,CAAG;AAAA,QAChB;AAAA,MACF,GAEA+H,EAAS,QAAQ,CAAC/H,MAAqB;AACrC,QAAAuI,EAAWvI,CAAG;AAAA,MAChB,GAEA+H,EAAS,UAAU,MAAY;AAC7B,YAAIK,EAAS;AACb,cAAMlB,IAAS,KAAK,gBAChB3G;AAAA,UACET,EAAmB;AAAA,UACnB;AAAA,QAAA,IAEFS;AAAA,UACET,EAAmB;AAAA,UACnB;AAAA,QAAA;AAEN,aAAK,KAAK,WAAW,MAA4B,GACjDyI,EAAWrB,CAAM;AAAA,MACnB,GAEAY,EAAY,GAAG,YAAYC,EAAS,QAAQ,GAC5CD,EAAY,GAAG,SAASC,EAAS,KAAK,GACtCD,EAAY,GAAG,SAASC,EAAS,KAAK,GACtCD,EAAY,GAAG,WAAWC,EAAS,OAAO,GAE1CD,EACG,MAAM;AAAA,QACL,QAAQ7F,EAAO;AAAA,QACf,SAASA,EAAO;AAAA,QAChB,SAAAG;AAAA,QACA,cAAc,KAAK,QAAQ;AAAA,QAC3B,UAAAE;AAAA,QACA,aAAaL,EAAO;AAAA,QACpB,YAAAiD;AAAA,QACA,QAAQjD,EAAO;AAAA,QACf,cAAAO;AAAA,MAAA,CACD,EACA,MAAM+F,CAAU;AAAA,IACrB,CAAC;AAAA,EACH;AAAA,EAEA,OAAa;AACX,IAAK,KAAK,gBACV,KAAK,gBAAgB,IACrB,KAAK,YAAY,KAAA;AAAA,EACnB;AAAA,EAEA,QAAc;AACZ,IAAI,KAAK,UAAU,aAAa,CAAC,KAAK,gBACtC,KAAK,QAAQ,UACb,KAAK,YAAY,MAAA;AAAA,EACnB;AAAA,EAEA,MAAM,SAAwB;AAC5B,IAAI,KAAK,UAAU,YAAY,CAAC,KAAK,gBACrC,KAAK,QAAQ,WACb,MAAM,KAAK,YAAY,OAAA;AAAA,EACzB;AACF;"}
|
package/dist/worker.js
CHANGED
|
@@ -125,7 +125,7 @@ const Z = () => {
|
|
|
125
125
|
throw new Error("WASM init function is missing from the bundle.");
|
|
126
126
|
try {
|
|
127
127
|
const r = new URL(et, import.meta.url);
|
|
128
|
-
await e(r);
|
|
128
|
+
await e({ module_or_path: r });
|
|
129
129
|
} catch (r) {
|
|
130
130
|
throw new Error(
|
|
131
131
|
`Failed to initialize WASM bundle: ${z(r)}`
|
package/dist/worker.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"worker.js","sources":["src/types.ts","src/nonce.ts","src/wasm.ts","src/worker.ts"],"sourcesContent":["export enum ZeldMinerErrorCode {\n INVALID_ADDRESS = \"INVALID_ADDRESS\",\n UNSUPPORTED_ADDRESS_TYPE = \"UNSUPPORTED_ADDRESS_TYPE\",\n INSUFFICIENT_FUNDS = \"INSUFFICIENT_FUNDS\",\n NO_CHANGE_OUTPUT = \"NO_CHANGE_OUTPUT\",\n MULTIPLE_CHANGE_OUTPUTS = \"MULTIPLE_CHANGE_OUTPUTS\",\n INVALID_INPUT = \"INVALID_INPUT\",\n WEBGPU_NOT_AVAILABLE = \"WEBGPU_NOT_AVAILABLE\",\n WORKER_ERROR = \"WORKER_ERROR\",\n MINING_ABORTED = \"MINING_ABORTED\",\n DUST_OUTPUT = \"DUST_OUTPUT\",\n}\n\nexport type ZeldMinerErrorDetails = Record<string, unknown>;\n\nexport type Network = \"mainnet\" | \"testnet\" | \"signet\" | \"regtest\";\n\nexport interface ZeldMinerOptions {\n network: Network;\n batchSize: number;\n useWebGPU: boolean;\n workerThreads: number;\n satsPerVbyte: number;\n}\n\nexport interface MiningCoordinatorOptions {\n mode: WorkerMode;\n batchSize: number;\n workerThreads: number;\n}\n\nexport interface TxInput {\n txid: string;\n vout: number;\n scriptPubKey: string;\n amount: number;\n}\n\nexport interface TxOutput {\n address: string;\n amount?: number;\n change: boolean;\n}\n\nexport interface MineResult {\n psbt: string;\n txid: string;\n nonce: bigint;\n attempts: bigint;\n duration: number;\n hashRate: number;\n}\n\nexport interface ProgressEvent {\n hashesProcessed: bigint;\n hashRate: number;\n elapsedMs?: number;\n lastNonce?: bigint;\n workerId?: string;\n}\n\nexport type WorkerMode = \"cpu\" | \"gpu\";\n\nexport type WorkerMessage =\n | { type: \"init\"; mode: WorkerMode }\n | {\n type: \"mine\";\n inputs: TxInput[];\n outputs: TxOutput[];\n network: Network;\n satsPerVbyte: number;\n template: WorkerTemplate;\n startNonce: bigint;\n batchSize: number;\n targetZeros: number;\n nonceStep?: bigint;\n distribution?: bigint[];\n }\n | { type: \"stop\" };\n\nexport type WorkerResponse =\n | { type: \"ready\"; workerId?: string }\n | {\n type: \"progress\";\n hashesProcessed: bigint;\n hashRate: number;\n lastNonce?: bigint;\n workerId?: string;\n }\n | {\n type: \"found\";\n result: MineResult;\n hashesProcessed?: bigint;\n hashRate?: number;\n lastNonce?: bigint;\n workerId?: string;\n }\n | { type: \"batch_complete\"; lastNonce: bigint; workerId?: string }\n | {\n type: \"error\";\n message: string;\n code?: ZeldMinerErrorCode;\n details?: ZeldMinerErrorDetails;\n workerId?: string;\n };\n\nexport interface MiningState {\n mode: WorkerMode;\n running: boolean;\n startNonce: bigint;\n nextNonce: bigint;\n batchSize: number;\n targetZeros: number;\n hashesProcessed: bigint;\n lastHashRate?: number;\n}\n\nexport interface MiningTemplate {\n prefix: Uint8Array;\n suffix: Uint8Array;\n useCborNonce?: boolean;\n}\n\nexport interface WorkerTemplate extends MiningTemplate {\n nonceLength: number;\n useCborNonce?: boolean;\n}\n\nexport interface ValidationResult {\n ok: boolean;\n error?: string;\n addressType?: \"p2wpkh\" | \"p2tr\";\n network?: Network;\n}\n\nexport interface WasmExports {\n init_panic_hook: () => void;\n mine_batch_wasm: (\n txPrefix: Uint8Array,\n txSuffix: Uint8Array,\n startNonce: bigint,\n batchSize: number,\n targetZeros: number,\n useCborNonce?: boolean\n ) => ValidationResult | MineResult | null;\n mine_batch_gpu?: (\n txPrefix: Uint8Array,\n txSuffix: Uint8Array,\n startNonce: bigint,\n batchSize: number,\n targetZeros: number,\n useCborNonce?: boolean\n ) => Promise<ValidationResult | MineResult | null>;\n mine_range_wasm: (\n inputs: TxInput[],\n outputs: TxOutput[],\n network: Network,\n satsPerVbyte: bigint,\n startNonce: bigint,\n batchSize: number,\n targetZeros: number,\n distribution?: bigint[] | null\n ) => ValidationResult | MineResult | null;\n mine_range_gpu?: (\n inputs: TxInput[],\n outputs: TxOutput[],\n network: Network,\n satsPerVbyte: bigint,\n startNonce: bigint,\n batchSize: number,\n targetZeros: number,\n distribution?: bigint[] | null\n ) => Promise<ValidationResult | MineResult | null>;\n validate_address: (addr: string, network: Network) => ValidationResult;\n build_psbt: (\n inputs: TxInput[],\n outputs: TxOutput[],\n network: Network,\n satsPerVbyte: bigint,\n nonce: bigint,\n distribution?: bigint[] | null\n ) => string;\n build_mining_template: (\n inputs: TxInput[],\n outputs: TxOutput[],\n network: Network,\n satsPerVbyte: bigint,\n startNonce: bigint,\n batchSize: number,\n distribution?: bigint[] | null\n ) => MiningTemplate;\n compute_txid: (txBytes: Uint8Array) => string;\n init_gpu?: () => Promise<unknown>;\n calibrate_batch_size?: () => Promise<number>;\n}\n\nexport type ProgressStats = ProgressEvent;\n\nexport interface MineParams {\n inputs: TxInput[];\n outputs: TxOutput[];\n targetZeros: number;\n startNonce?: bigint;\n batchSize?: number;\n signal?: AbortSignal;\n distribution?: bigint[];\n}\n\n","const MAX_U64 = (1n << 64n) - 1n;\n\nexport interface NonceSegment {\n start: bigint;\n size: number;\n nonceLength: number;\n}\n\nexport const nonceLength = (nonce: bigint): number => {\n if (nonce < 0n) {\n throw new Error(\"nonce must be non-negative\");\n }\n\n if (nonce === 0n) return 1;\n\n let len = 0;\n let value = nonce;\n while (value > 0n) {\n len += 1;\n value >>= 8n;\n }\n return len;\n};\n\nexport const cborNonceLength = (nonce: bigint): number => {\n if (nonce < 0n) {\n throw new Error(\"nonce must be non-negative\");\n }\n\n if (nonce <= 23n) return 1;\n if (nonce <= 0xffn) return 2;\n if (nonce <= 0xffffn) return 3;\n if (nonce <= 0xffff_ffffn) return 5;\n if (nonce <= MAX_U64) return 9;\n\n throw new Error(\"nonce range exceeds u64\");\n};\n\nconst maxValueForLength = (len: number): bigint => {\n if (!Number.isInteger(len) || len <= 0 || len > 8) {\n throw new Error(\"nonceLength must be between 1 and 8\");\n }\n return (1n << BigInt(len * 8)) - 1n;\n};\n\nconst maxValueForCborLength = (len: number): bigint => {\n switch (len) {\n case 1:\n return 23n;\n case 2:\n return 0xffn;\n case 3:\n return 0xffffn;\n case 5:\n return 0xffff_ffffn;\n case 9:\n return MAX_U64;\n default:\n throw new Error(\"cbor nonceLength must be one of 1, 2, 3, 5, 9\");\n }\n};\n\nexport const splitNonceSegments = (startNonce: bigint, span: number): NonceSegment[] => {\n if (startNonce < 0n) {\n throw new Error(\"startNonce must be non-negative\");\n }\n if (!Number.isInteger(span) || span <= 0) {\n throw new Error(\"batchSize must be a positive integer\");\n }\n\n const end = startNonce + BigInt(span - 1);\n if (end > MAX_U64) {\n throw new Error(\"nonce range exceeds u64\");\n }\n\n const segments: NonceSegment[] = [];\n let current = startNonce;\n\n while (current <= end) {\n const len = nonceLength(current);\n const maxForLen = maxValueForLength(len);\n const segmentEnd = end < maxForLen ? end : maxForLen;\n const segmentSize = segmentEnd - current + 1n;\n\n if (segmentSize > BigInt(Number.MAX_SAFE_INTEGER)) {\n throw new Error(\"segment size exceeds safe integer range\");\n }\n\n segments.push({\n start: current,\n size: Number(segmentSize),\n nonceLength: len,\n });\n\n if (segmentEnd === end) {\n break;\n }\n\n current = segmentEnd + 1n;\n }\n\n return segments;\n};\n\nexport const maxNonceForLength = (len: number): bigint => maxValueForLength(len);\n\nexport const splitNonceSegmentsCbor = (startNonce: bigint, span: number): NonceSegment[] => {\n if (startNonce < 0n) {\n throw new Error(\"startNonce must be non-negative\");\n }\n if (!Number.isInteger(span) || span <= 0) {\n throw new Error(\"batchSize must be a positive integer\");\n }\n\n const end = startNonce + BigInt(span - 1);\n if (end > MAX_U64) {\n throw new Error(\"nonce range exceeds u64\");\n }\n\n const segments: NonceSegment[] = [];\n let current = startNonce;\n\n while (current <= end) {\n const len = cborNonceLength(current);\n const maxForLen = maxValueForCborLength(len);\n const segmentEnd = end < maxForLen ? end : maxForLen;\n const segmentSize = segmentEnd - current + 1n;\n\n if (segmentSize > BigInt(Number.MAX_SAFE_INTEGER)) {\n throw new Error(\"segment size exceeds safe integer range\");\n }\n\n segments.push({\n start: current,\n size: Number(segmentSize),\n nonceLength: len,\n });\n\n if (segmentEnd === end) {\n break;\n }\n\n current = segmentEnd + 1n;\n }\n\n return segments;\n};\n\n\n","import type { WasmExports } from \"./types\";\n\nlet wasmModule: WasmExports | null = null;\nlet wasmInitPromise: Promise<WasmExports> | null = null;\n\n// Chrome/Dawn can reject requestDevice when optional limits (e.g.\n// maxInterStageShaderComponents) are present but unsupported. Strip any\n// limit keys the adapter doesn't expose to keep WebGPU initialization\n// portable across browser versions.\nlet webGpuLimitShimInstalled = false;\nconst installWebGpuLimitShim = (): void => {\n if (webGpuLimitShimInstalled) return;\n webGpuLimitShimInstalled = true;\n\n const adapterProto = (globalThis as typeof globalThis & { GPUAdapter?: { prototype?: unknown } })\n .GPUAdapter?.prototype as GPUAdapter | undefined;\n const requestDevice = adapterProto?.requestDevice;\n if (!adapterProto || typeof requestDevice !== \"function\") return;\n\n adapterProto.requestDevice = function patchedRequestDevice(\n this: GPUAdapter,\n descriptor?: GPUDeviceDescriptor\n ): Promise<GPUDevice> {\n if (descriptor?.requiredLimits && typeof this.limits === \"object\") {\n const limits = descriptor.requiredLimits as Record<string, unknown>;\n const supported = this.limits as unknown as Record<string, unknown>;\n for (const key of Object.keys(limits)) {\n if (!(key in supported) || supported[key] === undefined) {\n delete limits[key];\n }\n }\n }\n return requestDevice.call(this, descriptor);\n };\n};\n\nconst ensureTrailingSlash = (value: string): string =>\n value.endsWith(\"/\") ? value : `${value}/`;\n\nconst toAbsoluteBase = (base: string): string => {\n const trimmed = base.trim();\n if (!trimmed) return trimmed;\n // Use window origin when available so Vite treats it as an external URL and does not try to transform public assets.\n if (typeof window !== \"undefined\" && typeof window.location?.origin === \"string\") {\n return ensureTrailingSlash(new URL(trimmed, window.location.origin).href);\n }\n return ensureTrailingSlash(new URL(trimmed, import.meta.url).href);\n};\n\nconst resolveWasmBase = (): string => {\n const globalBase = (globalThis as { __ZELDMINER_WASM_BASE__?: unknown })\n .__ZELDMINER_WASM_BASE__;\n if (typeof globalBase === \"string\" && globalBase.trim()) {\n return toAbsoluteBase(globalBase);\n }\n\n const envBase = (import.meta as ImportMeta & { env?: Record<string, unknown> })\n .env?.VITE_ZELDMINER_WASM_BASE;\n if (typeof envBase === \"string\" && envBase.trim()) {\n return toAbsoluteBase(envBase);\n }\n\n const viteBase = (import.meta as ImportMeta & { env?: Record<string, unknown> }).env?.BASE_URL;\n if (typeof viteBase === \"string\" && viteBase.trim()) {\n return toAbsoluteBase(`${ensureTrailingSlash(viteBase.trim())}wasm/`);\n }\n\n return toAbsoluteBase(\"/wasm/\");\n};\n\nconst WASM_BASE_URL = resolveWasmBase();\nconst WASM_JS_PATH = `${WASM_BASE_URL}zeldhash_miner_wasm.js`;\nconst WASM_BINARY_PATH = `${WASM_BASE_URL}zeldhash_miner_wasm_bg.wasm`;\n\nconst formatError = (err: unknown): string =>\n err instanceof Error ? err.message : String(err);\n\nconst loadModule = async (): Promise<WasmExports> => {\n installWebGpuLimitShim();\n\n let bindings: unknown;\n try {\n bindings = await import(/* @vite-ignore */ WASM_JS_PATH);\n } catch (err) {\n throw new Error(\n `Failed to import WASM bundle (${WASM_JS_PATH}). ` +\n `Did you run ./scripts/build-wasm.sh? (${formatError(err)})`\n );\n }\n\n const init = (bindings as { default?: unknown }).default;\n if (typeof init !== \"function\") {\n throw new Error(\"WASM init function is missing from the bundle.\");\n }\n\n try {\n const wasmUrl = new URL(WASM_BINARY_PATH, import.meta.url);\n await init(wasmUrl);\n } catch (err) {\n throw new Error(\n `Failed to initialize WASM bundle: ${formatError(err)}`\n );\n }\n\n const typedBindings = bindings as WasmExports;\n try {\n typedBindings.init_panic_hook?.();\n } catch {\n /* ignore optional panic hook failures */\n }\n\n return typedBindings;\n};\n\nexport const loadWasm = async (): Promise<WasmExports> => {\n if (wasmModule) return wasmModule;\n if (!wasmInitPromise) {\n wasmInitPromise = loadModule()\n .then((mod) => {\n wasmModule = mod;\n return mod;\n })\n .catch((err) => {\n wasmInitPromise = null;\n throw err;\n });\n }\n return wasmInitPromise;\n};\n\nexport const getWasm = (): WasmExports | null => wasmModule;\n\nexport const resetWasm = (): void => {\n wasmModule = null;\n wasmInitPromise = null;\n};\n\n","import type {\n MineResult,\n ValidationResult,\n WasmExports,\n WorkerMessage,\n WorkerMode,\n WorkerTemplate,\n WorkerResponse,\n} from \"./types\";\nimport { ZeldMinerErrorCode } from \"./types\";\nimport { splitNonceSegments, splitNonceSegmentsCbor } from \"./nonce\";\nimport { loadWasm } from \"./wasm\";\n\ntype MineMessage = Extract<WorkerMessage, { type: \"mine\" }>;\n\nconst ctx = self as unknown as DedicatedWorkerGlobalScope;\nconst workerId =\n (ctx as DedicatedWorkerGlobalScope & { name?: string }).name ?? undefined;\n\nconst formatError = (err: unknown): string =>\n err instanceof Error ? err.message : String(err);\n\nlet currentMode: WorkerMode = \"cpu\";\nlet miningAbort: AbortController | null = null;\nlet miningPromise: Promise<void> | null = null;\n\nconst post = (message: WorkerResponse): void => {\n ctx.postMessage({ ...message, workerId });\n};\n\nconst postError = (\n message: string,\n code: ZeldMinerErrorCode = ZeldMinerErrorCode.WORKER_ERROR,\n details?: Record<string, unknown>\n): void => {\n post({ type: \"error\", message, code, details });\n};\n\nconst isValidationResult = (val: unknown): val is ValidationResult =>\n typeof val === \"object\" && val !== null && \"ok\" in (val as object);\n\nconst isMineResult = (\n val: unknown\n): val is { nonce: bigint; txid: string } =>\n typeof val === \"object\" &&\n val !== null &&\n \"nonce\" in (val as object) &&\n \"txid\" in (val as object);\n\nconst safeBigIntToNumber = (value: bigint): number => {\n const max = BigInt(Number.MAX_SAFE_INTEGER);\n if (value > max) return Number.MAX_SAFE_INTEGER;\n if (value < -max) return -Number.MAX_SAFE_INTEGER;\n return Number(value);\n};\n\ntype TemplateCache = Map<number, WorkerTemplate>;\n\nconst cloneTemplate = (template: WorkerTemplate): WorkerTemplate => ({\n nonceLength: template.nonceLength,\n prefix: new Uint8Array(template.prefix),\n suffix: new Uint8Array(template.suffix),\n useCborNonce: template.useCborNonce,\n});\n\nconst cacheTemplate = (cache: TemplateCache, template: WorkerTemplate): void => {\n cache.set(template.nonceLength, cloneTemplate(template));\n};\n\nconst ensureTemplateForSegment = async (\n cache: TemplateCache,\n wasm: WasmExports,\n params: {\n inputs: MineMessage[\"inputs\"];\n outputs: MineMessage[\"outputs\"];\n satsPerVbyte: number;\n distribution?: bigint[];\n useCborNonce: boolean;\n },\n segment: { start: bigint; size: number; nonceLength: number },\n normalizedNetwork: MineMessage[\"network\"]\n): Promise<WorkerTemplate> => {\n const cached = cache.get(segment.nonceLength);\n if (cached) {\n return cached;\n }\n\n const template = wasm.build_mining_template(\n params.inputs,\n params.outputs,\n normalizedNetwork,\n BigInt(params.satsPerVbyte),\n segment.start,\n segment.size,\n params.distribution ?? null\n );\n\n const built: WorkerTemplate = {\n ...template,\n nonceLength: segment.nonceLength,\n useCborNonce: template.useCborNonce ?? params.useCborNonce,\n };\n\n cacheTemplate(cache, built);\n return built;\n};\n\nconst runBatch = async (\n wasm: WasmExports,\n mode: WorkerMode,\n prefix: Uint8Array,\n suffix: Uint8Array,\n startNonce: bigint,\n batchSize: number,\n targetZeros: number,\n useCborNonce: boolean\n): Promise<unknown> => {\n if (mode === \"gpu\") {\n if (!wasm.mine_batch_gpu) {\n throw new Error(\"GPU mining requested but mine_batch_gpu is unavailable\");\n }\n return wasm.mine_batch_gpu(\n prefix,\n suffix,\n startNonce,\n batchSize,\n targetZeros,\n useCborNonce\n );\n }\n\n return wasm.mine_batch_wasm(\n prefix,\n suffix,\n startNonce,\n batchSize,\n targetZeros,\n useCborNonce\n );\n};\n\nconst mineLoop = async (msg: MineMessage, abort: AbortController): Promise<void> => {\n let wasm: WasmExports;\n try {\n wasm = await loadWasm();\n if (currentMode === \"gpu\") {\n if (!wasm.mine_batch_gpu) {\n postError(\n \"GPU mining requested but mine_batch_gpu is unavailable\",\n ZeldMinerErrorCode.WEBGPU_NOT_AVAILABLE\n );\n return;\n }\n if (wasm.init_gpu) {\n await wasm.init_gpu();\n }\n }\n } catch (err) {\n const message = formatError(err);\n const code =\n currentMode === \"gpu\"\n ? ZeldMinerErrorCode.WEBGPU_NOT_AVAILABLE\n : ZeldMinerErrorCode.WORKER_ERROR;\n postError(`Failed to initialize WASM: ${message}`, code);\n return;\n }\n\n const templateCache: TemplateCache = new Map();\n const useCborNonce =\n msg.template.useCborNonce ?? Boolean(msg.distribution && msg.distribution.length > 0);\n cacheTemplate(templateCache, { ...msg.template, useCborNonce });\n\n const stride = msg.nonceStep ?? BigInt(msg.batchSize);\n const normalizedNetwork = msg.network === \"signet\" ? \"testnet\" : msg.network;\n let nextNonce = msg.startNonce;\n let hashesProcessed = 0n;\n const startedAt = performance.now();\n\n while (!abort.signal.aborted) {\n const iterationStart = nextNonce;\n let remaining = msg.batchSize;\n let processedInIteration = 0n;\n\n while (remaining > 0 && !abort.signal.aborted) {\n const segmentStart = iterationStart + processedInIteration;\n let segment: { start: bigint; size: number; nonceLength: number };\n\n try {\n const segments = useCborNonce\n ? splitNonceSegmentsCbor(segmentStart, remaining)\n : splitNonceSegments(segmentStart, remaining);\n segment = segments[0];\n } catch (err) {\n postError(\n `Invalid nonce range: ${formatError(err)}`,\n ZeldMinerErrorCode.INVALID_INPUT\n );\n abort.abort();\n return;\n }\n\n let template: WorkerTemplate;\n try {\n template = await ensureTemplateForSegment(\n templateCache,\n wasm,\n {\n inputs: msg.inputs,\n outputs: msg.outputs,\n satsPerVbyte: msg.satsPerVbyte,\n distribution: msg.distribution,\n useCborNonce,\n },\n segment,\n normalizedNetwork\n );\n } catch (err) {\n postError(\n `Failed to build mining template: ${formatError(err)}`,\n ZeldMinerErrorCode.WORKER_ERROR\n );\n abort.abort();\n return;\n }\n\n let output: unknown;\n const batchStartedAt = performance.now();\n try {\n output = await runBatch(\n wasm,\n currentMode,\n template.prefix,\n template.suffix,\n segment.start,\n segment.size,\n msg.targetZeros,\n useCborNonce\n );\n } catch (err) {\n const message = formatError(err);\n postError(\n `Batch mining failed: ${message}`,\n ZeldMinerErrorCode.WORKER_ERROR\n );\n abort.abort();\n return;\n }\n\n const batchDurationMs = performance.now() - batchStartedAt;\n\n if (isValidationResult(output)) {\n if (!output.ok) {\n postError(\n output.error ?? \"Validation failed\",\n ZeldMinerErrorCode.INVALID_INPUT\n );\n abort.abort();\n return;\n }\n } else if (isMineResult(output)) {\n const attemptsBefore = hashesProcessed + processedInIteration;\n const attemptsInSegment = BigInt(output.nonce) - segment.start + 1n;\n const totalAttempts = attemptsBefore + attemptsInSegment;\n const elapsedMs = performance.now() - startedAt;\n const hashRate =\n elapsedMs > 0\n ? safeBigIntToNumber(totalAttempts) / (elapsedMs / 1000)\n : 0;\n const lastNonce = segment.start + attemptsInSegment - 1n;\n\n const result: MineResult = {\n psbt: \"\",\n txid: output.txid,\n nonce: BigInt(output.nonce),\n attempts: totalAttempts,\n duration: elapsedMs,\n hashRate,\n };\n\n post({\n type: \"found\",\n result,\n hashesProcessed: totalAttempts,\n hashRate,\n lastNonce,\n });\n abort.abort();\n return;\n }\n\n hashesProcessed += BigInt(segment.size);\n processedInIteration += BigInt(segment.size);\n remaining -= segment.size;\n\n const hashRate =\n batchDurationMs > 0\n ? segment.size / (batchDurationMs / 1000)\n : segment.size;\n const lastNonce = segment.start + BigInt(segment.size) - 1n;\n\n post({ type: \"progress\", hashesProcessed, hashRate, lastNonce });\n }\n\n if (abort.signal.aborted) {\n break;\n }\n\n const lastNonce = iterationStart + BigInt(msg.batchSize) - 1n;\n post({ type: \"batch_complete\", lastNonce });\n\n nextNonce = iterationStart + stride;\n }\n};\n\nconst startMining = (msg: MineMessage): void => {\n const abort = new AbortController();\n miningAbort?.abort();\n miningAbort = abort;\n\n const promise = mineLoop(msg, abort).finally(() => {\n if (miningAbort === abort) {\n miningAbort = null;\n }\n if (miningPromise === promise) {\n miningPromise = null;\n }\n });\n\n miningPromise = promise;\n};\n\nctx.addEventListener(\"message\", (event: MessageEvent<WorkerMessage>) => {\n const data = event.data;\n\n switch (data.type) {\n case \"init\":\n currentMode = data.mode;\n post({ type: \"ready\" });\n break;\n case \"mine\":\n startMining(data);\n break;\n case \"stop\":\n miningAbort?.abort();\n break;\n default:\n postError(\n `Unknown message type: ${(data as { type?: string }).type}`,\n ZeldMinerErrorCode.WORKER_ERROR\n );\n }\n});\n\n"],"names":["ZeldMinerErrorCode","MAX_U64","nonceLength","nonce","len","value","cborNonceLength","maxValueForLength","maxValueForCborLength","splitNonceSegments","startNonce","span","end","segments","current","maxForLen","segmentEnd","segmentSize","splitNonceSegmentsCbor","wasmModule","wasmInitPromise","webGpuLimitShimInstalled","installWebGpuLimitShim","adapterProto","requestDevice","descriptor","limits","supported","key","ensureTrailingSlash","toAbsoluteBase","base","trimmed","resolveWasmBase","globalBase","envBase","__vite_import_meta_env__","viteBase","WASM_BASE_URL","WASM_JS_PATH","WASM_BINARY_PATH","formatError","err","loadModule","bindings","init","wasmUrl","typedBindings","loadWasm","mod","ctx","workerId","currentMode","miningAbort","post","message","postError","code","details","isValidationResult","val","isMineResult","safeBigIntToNumber","max","cloneTemplate","template","cacheTemplate","cache","ensureTemplateForSegment","wasm","params","segment","normalizedNetwork","cached","built","runBatch","mode","prefix","suffix","batchSize","targetZeros","useCborNonce","mineLoop","msg","abort","templateCache","stride","nextNonce","hashesProcessed","startedAt","iterationStart","remaining","processedInIteration","segmentStart","output","batchStartedAt","batchDurationMs","attemptsBefore","attemptsInSegment","totalAttempts","elapsedMs","hashRate","lastNonce","result","startMining","event","data"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"worker.js","sources":["src/types.ts","src/nonce.ts","src/wasm.ts","src/worker.ts"],"sourcesContent":["export enum ZeldMinerErrorCode {\n INVALID_ADDRESS = \"INVALID_ADDRESS\",\n UNSUPPORTED_ADDRESS_TYPE = \"UNSUPPORTED_ADDRESS_TYPE\",\n INSUFFICIENT_FUNDS = \"INSUFFICIENT_FUNDS\",\n NO_CHANGE_OUTPUT = \"NO_CHANGE_OUTPUT\",\n MULTIPLE_CHANGE_OUTPUTS = \"MULTIPLE_CHANGE_OUTPUTS\",\n INVALID_INPUT = \"INVALID_INPUT\",\n WEBGPU_NOT_AVAILABLE = \"WEBGPU_NOT_AVAILABLE\",\n WORKER_ERROR = \"WORKER_ERROR\",\n MINING_ABORTED = \"MINING_ABORTED\",\n DUST_OUTPUT = \"DUST_OUTPUT\",\n}\n\nexport type ZeldMinerErrorDetails = Record<string, unknown>;\n\nexport type Network = \"mainnet\" | \"testnet\" | \"signet\" | \"regtest\";\n\nexport interface ZeldMinerOptions {\n network: Network;\n batchSize: number;\n useWebGPU: boolean;\n workerThreads: number;\n satsPerVbyte: number;\n}\n\nexport interface MiningCoordinatorOptions {\n mode: WorkerMode;\n batchSize: number;\n workerThreads: number;\n}\n\nexport interface TxInput {\n txid: string;\n vout: number;\n scriptPubKey: string;\n amount: number;\n}\n\nexport interface TxOutput {\n address: string;\n amount?: number;\n change: boolean;\n}\n\nexport interface MineResult {\n psbt: string;\n txid: string;\n nonce: bigint;\n attempts: bigint;\n duration: number;\n hashRate: number;\n}\n\nexport interface ProgressEvent {\n hashesProcessed: bigint;\n hashRate: number;\n elapsedMs?: number;\n lastNonce?: bigint;\n workerId?: string;\n}\n\nexport type WorkerMode = \"cpu\" | \"gpu\";\n\nexport type WorkerMessage =\n | { type: \"init\"; mode: WorkerMode }\n | {\n type: \"mine\";\n inputs: TxInput[];\n outputs: TxOutput[];\n network: Network;\n satsPerVbyte: number;\n template: WorkerTemplate;\n startNonce: bigint;\n batchSize: number;\n targetZeros: number;\n nonceStep?: bigint;\n distribution?: bigint[];\n }\n | { type: \"stop\" };\n\nexport type WorkerResponse =\n | { type: \"ready\"; workerId?: string }\n | {\n type: \"progress\";\n hashesProcessed: bigint;\n hashRate: number;\n lastNonce?: bigint;\n workerId?: string;\n }\n | {\n type: \"found\";\n result: MineResult;\n hashesProcessed?: bigint;\n hashRate?: number;\n lastNonce?: bigint;\n workerId?: string;\n }\n | { type: \"batch_complete\"; lastNonce: bigint; workerId?: string }\n | {\n type: \"error\";\n message: string;\n code?: ZeldMinerErrorCode;\n details?: ZeldMinerErrorDetails;\n workerId?: string;\n };\n\nexport interface MiningState {\n mode: WorkerMode;\n running: boolean;\n startNonce: bigint;\n nextNonce: bigint;\n batchSize: number;\n targetZeros: number;\n hashesProcessed: bigint;\n lastHashRate?: number;\n}\n\nexport interface MiningTemplate {\n prefix: Uint8Array;\n suffix: Uint8Array;\n useCborNonce?: boolean;\n}\n\nexport interface WorkerTemplate extends MiningTemplate {\n nonceLength: number;\n useCborNonce?: boolean;\n}\n\nexport interface ValidationResult {\n ok: boolean;\n error?: string;\n addressType?: \"p2wpkh\" | \"p2tr\";\n network?: Network;\n}\n\nexport interface WasmExports {\n init_panic_hook: () => void;\n mine_batch_wasm: (\n txPrefix: Uint8Array,\n txSuffix: Uint8Array,\n startNonce: bigint,\n batchSize: number,\n targetZeros: number,\n useCborNonce?: boolean\n ) => ValidationResult | MineResult | null;\n mine_batch_gpu?: (\n txPrefix: Uint8Array,\n txSuffix: Uint8Array,\n startNonce: bigint,\n batchSize: number,\n targetZeros: number,\n useCborNonce?: boolean\n ) => Promise<ValidationResult | MineResult | null>;\n mine_range_wasm: (\n inputs: TxInput[],\n outputs: TxOutput[],\n network: Network,\n satsPerVbyte: bigint,\n startNonce: bigint,\n batchSize: number,\n targetZeros: number,\n distribution?: bigint[] | null\n ) => ValidationResult | MineResult | null;\n mine_range_gpu?: (\n inputs: TxInput[],\n outputs: TxOutput[],\n network: Network,\n satsPerVbyte: bigint,\n startNonce: bigint,\n batchSize: number,\n targetZeros: number,\n distribution?: bigint[] | null\n ) => Promise<ValidationResult | MineResult | null>;\n validate_address: (addr: string, network: Network) => ValidationResult;\n build_psbt: (\n inputs: TxInput[],\n outputs: TxOutput[],\n network: Network,\n satsPerVbyte: bigint,\n nonce: bigint,\n distribution?: bigint[] | null\n ) => string;\n build_mining_template: (\n inputs: TxInput[],\n outputs: TxOutput[],\n network: Network,\n satsPerVbyte: bigint,\n startNonce: bigint,\n batchSize: number,\n distribution?: bigint[] | null\n ) => MiningTemplate;\n compute_txid: (txBytes: Uint8Array) => string;\n init_gpu?: () => Promise<unknown>;\n calibrate_batch_size?: () => Promise<number>;\n}\n\nexport type ProgressStats = ProgressEvent;\n\nexport interface MineParams {\n inputs: TxInput[];\n outputs: TxOutput[];\n targetZeros: number;\n startNonce?: bigint;\n batchSize?: number;\n signal?: AbortSignal;\n distribution?: bigint[];\n}\n\n","const MAX_U64 = (1n << 64n) - 1n;\n\nexport interface NonceSegment {\n start: bigint;\n size: number;\n nonceLength: number;\n}\n\nexport const nonceLength = (nonce: bigint): number => {\n if (nonce < 0n) {\n throw new Error(\"nonce must be non-negative\");\n }\n\n if (nonce === 0n) return 1;\n\n let len = 0;\n let value = nonce;\n while (value > 0n) {\n len += 1;\n value >>= 8n;\n }\n return len;\n};\n\nexport const cborNonceLength = (nonce: bigint): number => {\n if (nonce < 0n) {\n throw new Error(\"nonce must be non-negative\");\n }\n\n if (nonce <= 23n) return 1;\n if (nonce <= 0xffn) return 2;\n if (nonce <= 0xffffn) return 3;\n if (nonce <= 0xffff_ffffn) return 5;\n if (nonce <= MAX_U64) return 9;\n\n throw new Error(\"nonce range exceeds u64\");\n};\n\nconst maxValueForLength = (len: number): bigint => {\n if (!Number.isInteger(len) || len <= 0 || len > 8) {\n throw new Error(\"nonceLength must be between 1 and 8\");\n }\n return (1n << BigInt(len * 8)) - 1n;\n};\n\nconst maxValueForCborLength = (len: number): bigint => {\n switch (len) {\n case 1:\n return 23n;\n case 2:\n return 0xffn;\n case 3:\n return 0xffffn;\n case 5:\n return 0xffff_ffffn;\n case 9:\n return MAX_U64;\n default:\n throw new Error(\"cbor nonceLength must be one of 1, 2, 3, 5, 9\");\n }\n};\n\nexport const splitNonceSegments = (startNonce: bigint, span: number): NonceSegment[] => {\n if (startNonce < 0n) {\n throw new Error(\"startNonce must be non-negative\");\n }\n if (!Number.isInteger(span) || span <= 0) {\n throw new Error(\"batchSize must be a positive integer\");\n }\n\n const end = startNonce + BigInt(span - 1);\n if (end > MAX_U64) {\n throw new Error(\"nonce range exceeds u64\");\n }\n\n const segments: NonceSegment[] = [];\n let current = startNonce;\n\n while (current <= end) {\n const len = nonceLength(current);\n const maxForLen = maxValueForLength(len);\n const segmentEnd = end < maxForLen ? end : maxForLen;\n const segmentSize = segmentEnd - current + 1n;\n\n if (segmentSize > BigInt(Number.MAX_SAFE_INTEGER)) {\n throw new Error(\"segment size exceeds safe integer range\");\n }\n\n segments.push({\n start: current,\n size: Number(segmentSize),\n nonceLength: len,\n });\n\n if (segmentEnd === end) {\n break;\n }\n\n current = segmentEnd + 1n;\n }\n\n return segments;\n};\n\nexport const maxNonceForLength = (len: number): bigint => maxValueForLength(len);\n\nexport const splitNonceSegmentsCbor = (startNonce: bigint, span: number): NonceSegment[] => {\n if (startNonce < 0n) {\n throw new Error(\"startNonce must be non-negative\");\n }\n if (!Number.isInteger(span) || span <= 0) {\n throw new Error(\"batchSize must be a positive integer\");\n }\n\n const end = startNonce + BigInt(span - 1);\n if (end > MAX_U64) {\n throw new Error(\"nonce range exceeds u64\");\n }\n\n const segments: NonceSegment[] = [];\n let current = startNonce;\n\n while (current <= end) {\n const len = cborNonceLength(current);\n const maxForLen = maxValueForCborLength(len);\n const segmentEnd = end < maxForLen ? end : maxForLen;\n const segmentSize = segmentEnd - current + 1n;\n\n if (segmentSize > BigInt(Number.MAX_SAFE_INTEGER)) {\n throw new Error(\"segment size exceeds safe integer range\");\n }\n\n segments.push({\n start: current,\n size: Number(segmentSize),\n nonceLength: len,\n });\n\n if (segmentEnd === end) {\n break;\n }\n\n current = segmentEnd + 1n;\n }\n\n return segments;\n};\n\n\n","import type { WasmExports } from \"./types\";\n\nlet wasmModule: WasmExports | null = null;\nlet wasmInitPromise: Promise<WasmExports> | null = null;\n\n// Chrome/Dawn can reject requestDevice when optional limits (e.g.\n// maxInterStageShaderComponents) are present but unsupported. Strip any\n// limit keys the adapter doesn't expose to keep WebGPU initialization\n// portable across browser versions.\nlet webGpuLimitShimInstalled = false;\nconst installWebGpuLimitShim = (): void => {\n if (webGpuLimitShimInstalled) return;\n webGpuLimitShimInstalled = true;\n\n const adapterProto = (globalThis as typeof globalThis & { GPUAdapter?: { prototype?: unknown } })\n .GPUAdapter?.prototype as GPUAdapter | undefined;\n const requestDevice = adapterProto?.requestDevice;\n if (!adapterProto || typeof requestDevice !== \"function\") return;\n\n adapterProto.requestDevice = function patchedRequestDevice(\n this: GPUAdapter,\n descriptor?: GPUDeviceDescriptor\n ): Promise<GPUDevice> {\n if (descriptor?.requiredLimits && typeof this.limits === \"object\") {\n const limits = descriptor.requiredLimits as Record<string, unknown>;\n const supported = this.limits as unknown as Record<string, unknown>;\n for (const key of Object.keys(limits)) {\n if (!(key in supported) || supported[key] === undefined) {\n delete limits[key];\n }\n }\n }\n return requestDevice.call(this, descriptor);\n };\n};\n\nconst ensureTrailingSlash = (value: string): string =>\n value.endsWith(\"/\") ? value : `${value}/`;\n\nconst toAbsoluteBase = (base: string): string => {\n const trimmed = base.trim();\n if (!trimmed) return trimmed;\n // Use window origin when available so Vite treats it as an external URL and does not try to transform public assets.\n if (typeof window !== \"undefined\" && typeof window.location?.origin === \"string\") {\n return ensureTrailingSlash(new URL(trimmed, window.location.origin).href);\n }\n return ensureTrailingSlash(new URL(trimmed, import.meta.url).href);\n};\n\nconst resolveWasmBase = (): string => {\n const globalBase = (globalThis as { __ZELDMINER_WASM_BASE__?: unknown })\n .__ZELDMINER_WASM_BASE__;\n if (typeof globalBase === \"string\" && globalBase.trim()) {\n return toAbsoluteBase(globalBase);\n }\n\n const envBase = (import.meta as ImportMeta & { env?: Record<string, unknown> })\n .env?.VITE_ZELDMINER_WASM_BASE;\n if (typeof envBase === \"string\" && envBase.trim()) {\n return toAbsoluteBase(envBase);\n }\n\n const viteBase = (import.meta as ImportMeta & { env?: Record<string, unknown> }).env?.BASE_URL;\n if (typeof viteBase === \"string\" && viteBase.trim()) {\n return toAbsoluteBase(`${ensureTrailingSlash(viteBase.trim())}wasm/`);\n }\n\n return toAbsoluteBase(\"/wasm/\");\n};\n\nconst WASM_BASE_URL = resolveWasmBase();\nconst WASM_JS_PATH = `${WASM_BASE_URL}zeldhash_miner_wasm.js`;\nconst WASM_BINARY_PATH = `${WASM_BASE_URL}zeldhash_miner_wasm_bg.wasm`;\n\nconst formatError = (err: unknown): string =>\n err instanceof Error ? err.message : String(err);\n\nconst loadModule = async (): Promise<WasmExports> => {\n installWebGpuLimitShim();\n\n let bindings: unknown;\n try {\n bindings = await import(/* @vite-ignore */ WASM_JS_PATH);\n } catch (err) {\n throw new Error(\n `Failed to import WASM bundle (${WASM_JS_PATH}). ` +\n `Did you run ./scripts/build-wasm.sh? (${formatError(err)})`\n );\n }\n\n const init = (bindings as { default?: unknown }).default;\n if (typeof init !== \"function\") {\n throw new Error(\"WASM init function is missing from the bundle.\");\n }\n\n try {\n const wasmUrl = new URL(WASM_BINARY_PATH, import.meta.url);\n await init({ module_or_path: wasmUrl });\n } catch (err) {\n throw new Error(\n `Failed to initialize WASM bundle: ${formatError(err)}`\n );\n }\n\n const typedBindings = bindings as WasmExports;\n try {\n typedBindings.init_panic_hook?.();\n } catch {\n /* ignore optional panic hook failures */\n }\n\n return typedBindings;\n};\n\nexport const loadWasm = async (): Promise<WasmExports> => {\n if (wasmModule) return wasmModule;\n if (!wasmInitPromise) {\n wasmInitPromise = loadModule()\n .then((mod) => {\n wasmModule = mod;\n return mod;\n })\n .catch((err) => {\n wasmInitPromise = null;\n throw err;\n });\n }\n return wasmInitPromise;\n};\n\nexport const getWasm = (): WasmExports | null => wasmModule;\n\nexport const resetWasm = (): void => {\n wasmModule = null;\n wasmInitPromise = null;\n};\n\n","import type {\n MineResult,\n ValidationResult,\n WasmExports,\n WorkerMessage,\n WorkerMode,\n WorkerTemplate,\n WorkerResponse,\n} from \"./types\";\nimport { ZeldMinerErrorCode } from \"./types\";\nimport { splitNonceSegments, splitNonceSegmentsCbor } from \"./nonce\";\nimport { loadWasm } from \"./wasm\";\n\ntype MineMessage = Extract<WorkerMessage, { type: \"mine\" }>;\n\nconst ctx = self as unknown as DedicatedWorkerGlobalScope;\nconst workerId =\n (ctx as DedicatedWorkerGlobalScope & { name?: string }).name ?? undefined;\n\nconst formatError = (err: unknown): string =>\n err instanceof Error ? err.message : String(err);\n\nlet currentMode: WorkerMode = \"cpu\";\nlet miningAbort: AbortController | null = null;\nlet miningPromise: Promise<void> | null = null;\n\nconst post = (message: WorkerResponse): void => {\n ctx.postMessage({ ...message, workerId });\n};\n\nconst postError = (\n message: string,\n code: ZeldMinerErrorCode = ZeldMinerErrorCode.WORKER_ERROR,\n details?: Record<string, unknown>\n): void => {\n post({ type: \"error\", message, code, details });\n};\n\nconst isValidationResult = (val: unknown): val is ValidationResult =>\n typeof val === \"object\" && val !== null && \"ok\" in (val as object);\n\nconst isMineResult = (\n val: unknown\n): val is { nonce: bigint; txid: string } =>\n typeof val === \"object\" &&\n val !== null &&\n \"nonce\" in (val as object) &&\n \"txid\" in (val as object);\n\nconst safeBigIntToNumber = (value: bigint): number => {\n const max = BigInt(Number.MAX_SAFE_INTEGER);\n if (value > max) return Number.MAX_SAFE_INTEGER;\n if (value < -max) return -Number.MAX_SAFE_INTEGER;\n return Number(value);\n};\n\ntype TemplateCache = Map<number, WorkerTemplate>;\n\nconst cloneTemplate = (template: WorkerTemplate): WorkerTemplate => ({\n nonceLength: template.nonceLength,\n prefix: new Uint8Array(template.prefix),\n suffix: new Uint8Array(template.suffix),\n useCborNonce: template.useCborNonce,\n});\n\nconst cacheTemplate = (cache: TemplateCache, template: WorkerTemplate): void => {\n cache.set(template.nonceLength, cloneTemplate(template));\n};\n\nconst ensureTemplateForSegment = async (\n cache: TemplateCache,\n wasm: WasmExports,\n params: {\n inputs: MineMessage[\"inputs\"];\n outputs: MineMessage[\"outputs\"];\n satsPerVbyte: number;\n distribution?: bigint[];\n useCborNonce: boolean;\n },\n segment: { start: bigint; size: number; nonceLength: number },\n normalizedNetwork: MineMessage[\"network\"]\n): Promise<WorkerTemplate> => {\n const cached = cache.get(segment.nonceLength);\n if (cached) {\n return cached;\n }\n\n const template = wasm.build_mining_template(\n params.inputs,\n params.outputs,\n normalizedNetwork,\n BigInt(params.satsPerVbyte),\n segment.start,\n segment.size,\n params.distribution ?? null\n );\n\n const built: WorkerTemplate = {\n ...template,\n nonceLength: segment.nonceLength,\n useCborNonce: template.useCborNonce ?? params.useCborNonce,\n };\n\n cacheTemplate(cache, built);\n return built;\n};\n\nconst runBatch = async (\n wasm: WasmExports,\n mode: WorkerMode,\n prefix: Uint8Array,\n suffix: Uint8Array,\n startNonce: bigint,\n batchSize: number,\n targetZeros: number,\n useCborNonce: boolean\n): Promise<unknown> => {\n if (mode === \"gpu\") {\n if (!wasm.mine_batch_gpu) {\n throw new Error(\"GPU mining requested but mine_batch_gpu is unavailable\");\n }\n return wasm.mine_batch_gpu(\n prefix,\n suffix,\n startNonce,\n batchSize,\n targetZeros,\n useCborNonce\n );\n }\n\n return wasm.mine_batch_wasm(\n prefix,\n suffix,\n startNonce,\n batchSize,\n targetZeros,\n useCborNonce\n );\n};\n\nconst mineLoop = async (msg: MineMessage, abort: AbortController): Promise<void> => {\n let wasm: WasmExports;\n try {\n wasm = await loadWasm();\n if (currentMode === \"gpu\") {\n if (!wasm.mine_batch_gpu) {\n postError(\n \"GPU mining requested but mine_batch_gpu is unavailable\",\n ZeldMinerErrorCode.WEBGPU_NOT_AVAILABLE\n );\n return;\n }\n if (wasm.init_gpu) {\n await wasm.init_gpu();\n }\n }\n } catch (err) {\n const message = formatError(err);\n const code =\n currentMode === \"gpu\"\n ? ZeldMinerErrorCode.WEBGPU_NOT_AVAILABLE\n : ZeldMinerErrorCode.WORKER_ERROR;\n postError(`Failed to initialize WASM: ${message}`, code);\n return;\n }\n\n const templateCache: TemplateCache = new Map();\n const useCborNonce =\n msg.template.useCborNonce ?? Boolean(msg.distribution && msg.distribution.length > 0);\n cacheTemplate(templateCache, { ...msg.template, useCborNonce });\n\n const stride = msg.nonceStep ?? BigInt(msg.batchSize);\n const normalizedNetwork = msg.network === \"signet\" ? \"testnet\" : msg.network;\n let nextNonce = msg.startNonce;\n let hashesProcessed = 0n;\n const startedAt = performance.now();\n\n while (!abort.signal.aborted) {\n const iterationStart = nextNonce;\n let remaining = msg.batchSize;\n let processedInIteration = 0n;\n\n while (remaining > 0 && !abort.signal.aborted) {\n const segmentStart = iterationStart + processedInIteration;\n let segment: { start: bigint; size: number; nonceLength: number };\n\n try {\n const segments = useCborNonce\n ? splitNonceSegmentsCbor(segmentStart, remaining)\n : splitNonceSegments(segmentStart, remaining);\n segment = segments[0];\n } catch (err) {\n postError(\n `Invalid nonce range: ${formatError(err)}`,\n ZeldMinerErrorCode.INVALID_INPUT\n );\n abort.abort();\n return;\n }\n\n let template: WorkerTemplate;\n try {\n template = await ensureTemplateForSegment(\n templateCache,\n wasm,\n {\n inputs: msg.inputs,\n outputs: msg.outputs,\n satsPerVbyte: msg.satsPerVbyte,\n distribution: msg.distribution,\n useCborNonce,\n },\n segment,\n normalizedNetwork\n );\n } catch (err) {\n postError(\n `Failed to build mining template: ${formatError(err)}`,\n ZeldMinerErrorCode.WORKER_ERROR\n );\n abort.abort();\n return;\n }\n\n let output: unknown;\n const batchStartedAt = performance.now();\n try {\n output = await runBatch(\n wasm,\n currentMode,\n template.prefix,\n template.suffix,\n segment.start,\n segment.size,\n msg.targetZeros,\n useCborNonce\n );\n } catch (err) {\n const message = formatError(err);\n postError(\n `Batch mining failed: ${message}`,\n ZeldMinerErrorCode.WORKER_ERROR\n );\n abort.abort();\n return;\n }\n\n const batchDurationMs = performance.now() - batchStartedAt;\n\n if (isValidationResult(output)) {\n if (!output.ok) {\n postError(\n output.error ?? \"Validation failed\",\n ZeldMinerErrorCode.INVALID_INPUT\n );\n abort.abort();\n return;\n }\n } else if (isMineResult(output)) {\n const attemptsBefore = hashesProcessed + processedInIteration;\n const attemptsInSegment = BigInt(output.nonce) - segment.start + 1n;\n const totalAttempts = attemptsBefore + attemptsInSegment;\n const elapsedMs = performance.now() - startedAt;\n const hashRate =\n elapsedMs > 0\n ? safeBigIntToNumber(totalAttempts) / (elapsedMs / 1000)\n : 0;\n const lastNonce = segment.start + attemptsInSegment - 1n;\n\n const result: MineResult = {\n psbt: \"\",\n txid: output.txid,\n nonce: BigInt(output.nonce),\n attempts: totalAttempts,\n duration: elapsedMs,\n hashRate,\n };\n\n post({\n type: \"found\",\n result,\n hashesProcessed: totalAttempts,\n hashRate,\n lastNonce,\n });\n abort.abort();\n return;\n }\n\n hashesProcessed += BigInt(segment.size);\n processedInIteration += BigInt(segment.size);\n remaining -= segment.size;\n\n const hashRate =\n batchDurationMs > 0\n ? segment.size / (batchDurationMs / 1000)\n : segment.size;\n const lastNonce = segment.start + BigInt(segment.size) - 1n;\n\n post({ type: \"progress\", hashesProcessed, hashRate, lastNonce });\n }\n\n if (abort.signal.aborted) {\n break;\n }\n\n const lastNonce = iterationStart + BigInt(msg.batchSize) - 1n;\n post({ type: \"batch_complete\", lastNonce });\n\n nextNonce = iterationStart + stride;\n }\n};\n\nconst startMining = (msg: MineMessage): void => {\n const abort = new AbortController();\n miningAbort?.abort();\n miningAbort = abort;\n\n const promise = mineLoop(msg, abort).finally(() => {\n if (miningAbort === abort) {\n miningAbort = null;\n }\n if (miningPromise === promise) {\n miningPromise = null;\n }\n });\n\n miningPromise = promise;\n};\n\nctx.addEventListener(\"message\", (event: MessageEvent<WorkerMessage>) => {\n const data = event.data;\n\n switch (data.type) {\n case \"init\":\n currentMode = data.mode;\n post({ type: \"ready\" });\n break;\n case \"mine\":\n startMining(data);\n break;\n case \"stop\":\n miningAbort?.abort();\n break;\n default:\n postError(\n `Unknown message type: ${(data as { type?: string }).type}`,\n ZeldMinerErrorCode.WORKER_ERROR\n );\n }\n});\n\n"],"names":["ZeldMinerErrorCode","MAX_U64","nonceLength","nonce","len","value","cborNonceLength","maxValueForLength","maxValueForCborLength","splitNonceSegments","startNonce","span","end","segments","current","maxForLen","segmentEnd","segmentSize","splitNonceSegmentsCbor","wasmModule","wasmInitPromise","webGpuLimitShimInstalled","installWebGpuLimitShim","adapterProto","requestDevice","descriptor","limits","supported","key","ensureTrailingSlash","toAbsoluteBase","base","trimmed","resolveWasmBase","globalBase","envBase","__vite_import_meta_env__","viteBase","WASM_BASE_URL","WASM_JS_PATH","WASM_BINARY_PATH","formatError","err","loadModule","bindings","init","wasmUrl","typedBindings","loadWasm","mod","ctx","workerId","currentMode","miningAbort","post","message","postError","code","details","isValidationResult","val","isMineResult","safeBigIntToNumber","max","cloneTemplate","template","cacheTemplate","cache","ensureTemplateForSegment","wasm","params","segment","normalizedNetwork","cached","built","runBatch","mode","prefix","suffix","batchSize","targetZeros","useCborNonce","mineLoop","msg","abort","templateCache","stride","nextNonce","hashesProcessed","startedAt","iterationStart","remaining","processedInIteration","segmentStart","output","batchStartedAt","batchDurationMs","attemptsBefore","attemptsInSegment","totalAttempts","elapsedMs","hashRate","lastNonce","result","startMining","event","data"],"mappings":"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"}
|
package/package.json
CHANGED
package/wasm/package.json
CHANGED
|
@@ -1366,12 +1366,8 @@ function initSync(module) {
|
|
|
1366
1366
|
if (wasm !== undefined) return wasm;
|
|
1367
1367
|
|
|
1368
1368
|
|
|
1369
|
-
if (typeof module !== 'undefined') {
|
|
1370
|
-
|
|
1371
|
-
({module} = module)
|
|
1372
|
-
} else {
|
|
1373
|
-
console.warn('using deprecated parameters for `initSync()`; pass a single object instead')
|
|
1374
|
-
}
|
|
1369
|
+
if (typeof module !== 'undefined' && Object.getPrototypeOf(module) === Object.prototype) {
|
|
1370
|
+
({module} = module)
|
|
1375
1371
|
}
|
|
1376
1372
|
|
|
1377
1373
|
const imports = __wbg_get_imports();
|
|
@@ -1386,12 +1382,8 @@ async function __wbg_init(module_or_path) {
|
|
|
1386
1382
|
if (wasm !== undefined) return wasm;
|
|
1387
1383
|
|
|
1388
1384
|
|
|
1389
|
-
if (typeof module_or_path !== 'undefined') {
|
|
1390
|
-
|
|
1391
|
-
({module_or_path} = module_or_path)
|
|
1392
|
-
} else {
|
|
1393
|
-
console.warn('using deprecated parameters for the initialization function; pass a single object instead')
|
|
1394
|
-
}
|
|
1385
|
+
if (typeof module_or_path !== 'undefined' && Object.getPrototypeOf(module_or_path) === Object.prototype) {
|
|
1386
|
+
({module_or_path} = module_or_path)
|
|
1395
1387
|
}
|
|
1396
1388
|
|
|
1397
1389
|
if (typeof module_or_path === 'undefined') {
|
|
Binary file
|