zeldhash-miner 0.2.1 → 0.2.2

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/README.md CHANGED
@@ -204,9 +204,39 @@ try {
204
204
 
205
205
  ## Runtime Notes
206
206
 
207
- - The WASM artifacts live in `node_modules/zeldhash-miner/wasm`. Most modern bundlers copy them automatically because the SDK loads them via `new URL("./wasm/zeldhash_miner_wasm_bg.wasm", import.meta.url)`.
208
- - If your bundler does not copy assets automatically, copy the `wasm/` folder to your public/static assets.
209
- - WebGPU is optional. When `useWebGPU` is `true`, the miner auto-detects support and silently falls back to CPU.
207
+ ### WASM Asset Loading
208
+
209
+ The SDK automatically loads WASM assets from `/wasm/` on your application's origin. This works out of the box with most setups:
210
+
211
+ 1. **Copy assets to your public folder**: Copy the `wasm/` folder from `node_modules/zeldhash-miner/` to your app's `public/` directory:
212
+ ```bash
213
+ cp -r node_modules/zeldhash-miner/wasm public/wasm
214
+ ```
215
+
216
+ 2. **Also copy the worker**: The worker script needs to be served from your app as well:
217
+ ```bash
218
+ cp node_modules/zeldhash-miner/dist/worker.js public/worker.js
219
+ ```
220
+
221
+ The SDK bootstraps `globalThis.__ZELDMINER_WASM_BASE__` to `/wasm/` (relative to your app's origin) automatically, so WASM files are fetched from `https://your-app.com/wasm/` rather than from inside `node_modules/`.
222
+
223
+ ### Custom WASM Path
224
+
225
+ If you need to serve WASM assets from a different location, you can override the base path:
226
+
227
+ ```ts
228
+ // Set before importing ZeldMiner
229
+ globalThis.__ZELDMINER_WASM_BASE__ = "/custom/path/to/wasm/";
230
+ ```
231
+
232
+ Or use environment variables with Vite:
233
+ ```bash
234
+ VITE_ZELDMINER_WASM_BASE=/custom/wasm/
235
+ ```
236
+
237
+ ### WebGPU
238
+
239
+ WebGPU is optional. When `useWebGPU` is `true`, the miner auto-detects support and silently falls back to CPU.
210
240
 
211
241
  ## Build & Test
212
242
 
package/dist/index.js CHANGED
@@ -12,11 +12,11 @@ const M = (s, t = o.WORKER_ERROR, e) => {
12
12
  return s;
13
13
  const r = $(s);
14
14
  return new A(t, r, e);
15
- }, u = (s, t, e) => new A(s, t, e), k = (s) => {
15
+ }, u = (s, t, e) => new A(s, t, e), D = (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
  };
19
- class C {
19
+ class Z {
20
20
  mode;
21
21
  batchSize;
22
22
  workerCount;
@@ -108,7 +108,7 @@ class C {
108
108
  const r = this.workers.reduce(
109
109
  (h, c) => h + c.hashesProcessed,
110
110
  0n
111
- ), n = this.startedAt ? performance.now() - this.startedAt : 0, i = n > 0 ? k(r) / (n / 1e3) : 0, a = {
111
+ ), n = this.startedAt ? performance.now() - this.startedAt : 0, i = n > 0 ? D(r) / (n / 1e3) : 0, a = {
112
112
  ...e.result,
113
113
  attempts: r,
114
114
  duration: n,
@@ -136,7 +136,7 @@ class C {
136
136
  const t = this.workers.reduce(
137
137
  (i, a) => i + a.hashesProcessed,
138
138
  0n
139
- ), e = this.startedAt ? performance.now() - this.startedAt : 0, r = e > 0 ? k(t) / (e / 1e3) : 0, n = {
139
+ ), e = this.startedAt ? performance.now() - this.startedAt : 0, r = e > 0 ? D(t) / (e / 1e3) : 0, n = {
140
140
  hashesProcessed: t,
141
141
  hashRate: r,
142
142
  elapsedMs: e
@@ -166,22 +166,22 @@ class C {
166
166
  const e = this.txInputs, r = this.txOutputs, n = this.txNetwork, i = this.satsPerVbyte, a = this.template, h = this.targetZeros, c = this.txDistribution, p = this.stride;
167
167
  this.workers.forEach((l, d) => {
168
168
  l.processedBase = 0n, l.hashesProcessed = 0n, l.hashRate = 0, l.lastNonce = void 0;
169
- const m = this.startNonce + BigInt(d) * BigInt(this.batchSize);
170
- l.nextNonce = m;
171
- const w = {
169
+ const w = this.startNonce + BigInt(d) * BigInt(this.batchSize);
170
+ l.nextNonce = w;
171
+ const m = {
172
172
  type: "mine",
173
173
  inputs: e,
174
174
  outputs: r,
175
175
  network: n,
176
176
  satsPerVbyte: i,
177
177
  template: a,
178
- startNonce: m,
178
+ startNonce: w,
179
179
  batchSize: this.batchSize,
180
180
  targetZeros: h,
181
181
  nonceStep: p,
182
182
  distribution: c
183
183
  };
184
- l.worker.postMessage(w);
184
+ l.worker.postMessage(m);
185
185
  });
186
186
  }
187
187
  pause() {
@@ -194,7 +194,7 @@ class C {
194
194
  const t = this.txInputs, e = this.txOutputs, r = this.txNetwork, n = this.satsPerVbyte, i = this.template, a = this.targetZeros, h = this.txDistribution, c = this.stride;
195
195
  this.workers.forEach((p, l) => {
196
196
  p.processedBase = p.hashesProcessed, p.hashRate = 0;
197
- const d = p.nextNonce || this.startNonce + BigInt(l) * BigInt(this.batchSize), m = {
197
+ const d = p.nextNonce || this.startNonce + BigInt(l) * BigInt(this.batchSize), w = {
198
198
  type: "mine",
199
199
  inputs: t,
200
200
  outputs: e,
@@ -207,18 +207,25 @@ class C {
207
207
  nonceStep: c,
208
208
  distribution: h
209
209
  };
210
- p.worker.postMessage(m);
210
+ p.worker.postMessage(w);
211
211
  });
212
212
  }
213
213
  stop() {
214
214
  !this.running && !this.paused || (this.running = !1, this.paused = !1, this.terminateWorkers(), this.cleanupExternalAbort(), this.emit("stopped", void 0));
215
215
  }
216
216
  }
217
- const q = {};
218
- let P = null, N = null, D = !1;
219
- const Z = () => {
220
- if (D) return;
221
- D = !0;
217
+ const C = {};
218
+ if (typeof globalThis.__ZELDMINER_WASM_BASE__ > "u")
219
+ try {
220
+ const s = typeof window < "u" && window.location?.origin ? window.location.origin : typeof self < "u" && self.location?.origin ? self.location.origin : "http://localhost";
221
+ globalThis.__ZELDMINER_WASM_BASE__ = new URL("/wasm/", s).href;
222
+ } catch {
223
+ globalThis.__ZELDMINER_WASM_BASE__ = "/wasm/";
224
+ }
225
+ let y = null, N = null, k = !1;
226
+ const q = () => {
227
+ if (k) return;
228
+ k = !0;
222
229
  const s = globalThis.GPUAdapter?.prototype, t = s?.requestDevice;
223
230
  !s || typeof t != "function" || (s.requestDevice = function(r) {
224
231
  if (r?.requiredLimits && typeof this.limits == "object") {
@@ -235,13 +242,13 @@ const Z = () => {
235
242
  const s = globalThis.__ZELDMINER_WASM_BASE__;
236
243
  if (typeof s == "string" && s.trim())
237
244
  return _(s);
238
- const t = q?.VITE_ZELDMINER_WASM_BASE;
245
+ const t = C?.VITE_ZELDMINER_WASM_BASE;
239
246
  if (typeof t == "string" && t.trim())
240
247
  return _(t);
241
248
  const e = "./";
242
249
  return e.trim() ? _(`${S(e.trim())}wasm/`) : _("/wasm/");
243
250
  }, 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
- Z();
251
+ q();
245
252
  let s;
246
253
  try {
247
254
  s = await import(
@@ -270,7 +277,7 @@ const Z = () => {
270
277
  } catch {
271
278
  }
272
279
  return e;
273
- }, j = async () => P || (N || (N = K().then((s) => (P = s, s)).catch((s) => {
280
+ }, j = async () => y || (N || (N = K().then((s) => (y = s, s)).catch((s) => {
274
281
  throw N = null, s;
275
282
  })), N), E = (1n << 64n) - 1n, z = (s) => {
276
283
  if (s < 0n)
@@ -368,7 +375,7 @@ const Z = () => {
368
375
  ...e,
369
376
  context: t
370
377
  });
371
- }, y = (s) => s === "signet" ? "testnet" : s;
378
+ }, P = (s) => s === "signet" ? "testnet" : s;
372
379
  class ot {
373
380
  network;
374
381
  satsPerVbyte;
@@ -491,7 +498,7 @@ class ot {
491
498
  { changeCount: e }
492
499
  );
493
500
  }
494
- const r = await this.getWasm(), n = y(this.network);
501
+ const r = await this.getWasm(), n = P(this.network);
495
502
  t.forEach((i, a) => {
496
503
  const h = r.validate_address(i.address, n);
497
504
  this.validateAddressResult(h, a, n);
@@ -549,7 +556,7 @@ class ot {
549
556
  const d = l.build_mining_template(
550
557
  this.cloneInputs(e),
551
558
  this.cloneOutputs(r),
552
- y(this.network),
559
+ P(this.network),
553
560
  BigInt(this.satsPerVbyte),
554
561
  n,
555
562
  i,
@@ -560,8 +567,8 @@ class ot {
560
567
  o.WORKER_ERROR,
561
568
  "WASM returned an invalid mining template"
562
569
  );
563
- const m = d.useCborNonce ?? c;
564
- return { ...d, nonceLength: p, useCborNonce: m };
570
+ const w = d.useCborNonce ?? c;
571
+ return { ...d, nonceLength: p, useCborNonce: w };
565
572
  } catch (d) {
566
573
  throw O(d, "build_mining_template", {
567
574
  startNonce: n,
@@ -585,7 +592,7 @@ class ot {
585
592
  return h.build_psbt(
586
593
  this.cloneInputs(e),
587
594
  this.cloneOutputs(r),
588
- y(this.network),
595
+ P(this.network),
589
596
  BigInt(this.satsPerVbyte),
590
597
  n,
591
598
  a ?? null
@@ -697,22 +704,22 @@ class at {
697
704
  startNonce: e,
698
705
  batchSize: a,
699
706
  distribution: n
700
- }), p = this.options.network === "signet" ? "testnet" : this.options.network, l = new C({
707
+ }), p = this.options.network === "signet" ? "testnet" : this.options.network, l = new Z({
701
708
  mode: h,
702
709
  batchSize: r,
703
710
  workerThreads: this.options.workerThreads
704
711
  });
705
- return this.coordinator = l, this.state = "running", this.stopRequested = !1, new Promise((d, m) => {
706
- let w = !1;
712
+ return this.coordinator = l, this.state = "running", this.stopRequested = !1, new Promise((d, w) => {
713
+ let m = !1;
707
714
  const R = () => {
708
715
  this.clearCoordinatorHandlers(l, g), this.coordinator === l && (this.coordinator = null), this.state = "idle", this.stopRequested = !1;
709
716
  }, G = (f) => {
710
- w || (w = !0, R(), d(f));
717
+ m || (m = !0, R(), d(f));
711
718
  }, I = (f) => {
712
- if (w) return;
713
- w = !0;
719
+ if (m) return;
720
+ m = !0;
714
721
  const b = M(f);
715
- R(), this.emit("error", b), m(b);
722
+ R(), this.emit("error", b), w(b);
716
723
  }, g = {};
717
724
  g.progress = (f) => {
718
725
  this.emit("progress", f);
@@ -731,7 +738,7 @@ class at {
731
738
  }, g.error = (f) => {
732
739
  I(f);
733
740
  }, g.stopped = () => {
734
- if (w) return;
741
+ if (m) return;
735
742
  const f = this.stopRequested ? u(
736
743
  o.MINING_ABORTED,
737
744
  "Mining stopped by caller"
@@ -764,7 +771,7 @@ class at {
764
771
  }
765
772
  }
766
773
  export {
767
- C as MiningCoordinator,
774
+ Z as MiningCoordinator,
768
775
  ot as TransactionBuilder,
769
776
  at as ZeldMiner,
770
777
  A as ZeldMinerError,
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({ 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":"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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\n// Bootstrap: define a sensible default for WASM base path so consumers don't\n// need to patch the library. In Vite/dev the import.meta.url points inside\n// node_modules which is not served, so we derive a public path from the window\n// origin when available.\nif (typeof (globalThis as { __ZELDMINER_WASM_BASE__?: unknown }).__ZELDMINER_WASM_BASE__ === \"undefined\") {\n try {\n const origin =\n typeof window !== \"undefined\" && window.location?.origin\n ? window.location.origin\n : typeof self !== \"undefined\" && (self as { location?: { origin?: string } }).location?.origin\n ? (self as { location?: { origin?: string } }).location!.origin\n : \"http://localhost\";\n (globalThis as { __ZELDMINER_WASM_BASE__?: string }).__ZELDMINER_WASM_BASE__ = new URL(\"/wasm/\", origin!).href;\n } catch {\n (globalThis as { __ZELDMINER_WASM_BASE__?: string }).__ZELDMINER_WASM_BASE__ = \"/wasm/\";\n }\n}\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","origin","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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"}
package/dist/worker.js CHANGED
@@ -43,21 +43,21 @@ const R = (1n << 64n) - 1n, K = (t) => {
43
43
  const n = t + BigInt(e - 1);
44
44
  if (n > R)
45
45
  throw new Error("nonce range exceeds u64");
46
- const r = [];
47
- let i = t;
48
- for (; i <= n; ) {
49
- const o = K(i), s = X(o), c = n < s ? n : s, f = c - i + 1n;
50
- if (f > BigInt(Number.MAX_SAFE_INTEGER))
46
+ const i = [];
47
+ let r = t;
48
+ for (; r <= n; ) {
49
+ const s = K(r), o = X(s), a = n < o ? n : o, l = a - r + 1n;
50
+ if (l > BigInt(Number.MAX_SAFE_INTEGER))
51
51
  throw new Error("segment size exceeds safe integer range");
52
- if (r.push({
53
- start: i,
54
- size: Number(f),
55
- nonceLength: o
56
- }), c === n)
52
+ if (i.push({
53
+ start: r,
54
+ size: Number(l),
55
+ nonceLength: s
56
+ }), a === n)
57
57
  break;
58
- i = c + 1n;
58
+ r = a + 1n;
59
59
  }
60
- return r;
60
+ return i;
61
61
  }, J = (t, e) => {
62
62
  if (t < 0n)
63
63
  throw new Error("startNonce must be non-negative");
@@ -66,48 +66,55 @@ const R = (1n << 64n) - 1n, K = (t) => {
66
66
  const n = t + BigInt(e - 1);
67
67
  if (n > R)
68
68
  throw new Error("nonce range exceeds u64");
69
- const r = [];
70
- let i = t;
71
- for (; i <= n; ) {
72
- const o = H(i), s = j(o), c = n < s ? n : s, f = c - i + 1n;
73
- if (f > BigInt(Number.MAX_SAFE_INTEGER))
69
+ const i = [];
70
+ let r = t;
71
+ for (; r <= n; ) {
72
+ const s = H(r), o = j(s), a = n < o ? n : o, l = a - r + 1n;
73
+ if (l > BigInt(Number.MAX_SAFE_INTEGER))
74
74
  throw new Error("segment size exceeds safe integer range");
75
- if (r.push({
76
- start: i,
77
- size: Number(f),
78
- nonceLength: o
79
- }), c === n)
75
+ if (i.push({
76
+ start: r,
77
+ size: Number(l),
78
+ nonceLength: s
79
+ }), a === n)
80
80
  break;
81
- i = c + 1n;
81
+ r = a + 1n;
82
82
  }
83
- return r;
83
+ return i;
84
84
  }, Q = {};
85
- let U = null, d = null, x = !1;
85
+ if (typeof globalThis.__ZELDMINER_WASM_BASE__ > "u")
86
+ try {
87
+ const t = typeof window < "u" && window.location?.origin ? window.location.origin : typeof self < "u" && self.location?.origin ? self.location.origin : "http://localhost";
88
+ globalThis.__ZELDMINER_WASM_BASE__ = new URL("/wasm/", t).href;
89
+ } catch {
90
+ globalThis.__ZELDMINER_WASM_BASE__ = "/wasm/";
91
+ }
92
+ let y = null, d = null, O = !1;
86
93
  const Z = () => {
87
- if (x) return;
88
- x = !0;
94
+ if (O) return;
95
+ O = !0;
89
96
  const t = globalThis.GPUAdapter?.prototype, e = t?.requestDevice;
90
- !t || typeof e != "function" || (t.requestDevice = function(r) {
91
- if (r?.requiredLimits && typeof this.limits == "object") {
92
- const i = r.requiredLimits, o = this.limits;
93
- for (const s of Object.keys(i))
94
- (!(s in o) || o[s] === void 0) && delete i[s];
97
+ !t || typeof e != "function" || (t.requestDevice = function(i) {
98
+ if (i?.requiredLimits && typeof this.limits == "object") {
99
+ const r = i.requiredLimits, s = this.limits;
100
+ for (const o of Object.keys(r))
101
+ (!(o in s) || s[o] === void 0) && delete r[o];
95
102
  }
96
- return e.call(this, r);
103
+ return e.call(this, i);
97
104
  });
98
- }, y = (t) => t.endsWith("/") ? t : `${t}/`, I = (t) => {
105
+ }, U = (t) => t.endsWith("/") ? t : `${t}/`, A = (t) => {
99
106
  const e = t.trim();
100
- return e && (typeof window < "u" && typeof window.location?.origin == "string" ? y(new URL(e, window.location.origin).href) : y(new URL(e, import.meta.url).href));
107
+ return e && (typeof window < "u" && typeof window.location?.origin == "string" ? U(new URL(e, window.location.origin).href) : U(new URL(e, import.meta.url).href));
101
108
  }, tt = () => {
102
109
  const t = globalThis.__ZELDMINER_WASM_BASE__;
103
110
  if (typeof t == "string" && t.trim())
104
- return I(t);
111
+ return A(t);
105
112
  const e = Q?.VITE_ZELDMINER_WASM_BASE;
106
113
  if (typeof e == "string" && e.trim())
107
- return I(e);
114
+ return A(e);
108
115
  const n = "./";
109
- return n.trim() ? I(`${y(n.trim())}wasm/`) : I("/wasm/");
110
- }, M = tt(), W = `${M}zeldhash_miner_wasm.js`, et = `${M}zeldhash_miner_wasm_bg.wasm`, z = (t) => t instanceof Error ? t.message : String(t), nt = async () => {
116
+ return n.trim() ? A(`${U(n.trim())}wasm/`) : A("/wasm/");
117
+ }, z = tt(), W = `${z}zeldhash_miner_wasm.js`, et = `${z}zeldhash_miner_wasm_bg.wasm`, x = (t) => t instanceof Error ? t.message : String(t), nt = async () => {
111
118
  Z();
112
119
  let t;
113
120
  try {
@@ -115,20 +122,20 @@ const Z = () => {
115
122
  /* @vite-ignore */
116
123
  W
117
124
  );
118
- } catch (r) {
125
+ } catch (i) {
119
126
  throw new Error(
120
- `Failed to import WASM bundle (${W}). Did you run ./scripts/build-wasm.sh? (${z(r)})`
127
+ `Failed to import WASM bundle (${W}). Did you run ./scripts/build-wasm.sh? (${x(i)})`
121
128
  );
122
129
  }
123
130
  const e = t.default;
124
131
  if (typeof e != "function")
125
132
  throw new Error("WASM init function is missing from the bundle.");
126
133
  try {
127
- const r = new URL(et, import.meta.url);
128
- await e({ module_or_path: r });
129
- } catch (r) {
134
+ const i = new URL(et, import.meta.url);
135
+ await e({ module_or_path: i });
136
+ } catch (i) {
130
137
  throw new Error(
131
- `Failed to initialize WASM bundle: ${z(r)}`
138
+ `Failed to initialize WASM bundle: ${x(i)}`
132
139
  );
133
140
  }
134
141
  const n = t;
@@ -137,69 +144,77 @@ const Z = () => {
137
144
  } catch {
138
145
  }
139
146
  return n;
140
- }, rt = async () => U || (d || (d = nt().then((t) => (U = t, t)).catch((t) => {
147
+ }, it = async () => y || (d || (d = nt().then((t) => (y = t, t)).catch((t) => {
141
148
  throw d = null, t;
142
- })), d), B = self, it = B.name ?? void 0, N = (t) => t instanceof Error ? t.message : String(t);
143
- let A = "cpu", w = null;
144
- const E = (t) => {
145
- B.postMessage({ ...t, workerId: it });
146
- }, m = (t, e = u.WORKER_ERROR, n) => {
147
- E({ type: "error", message: t, code: e, details: n });
148
- }, st = (t) => typeof t == "object" && t !== null && "ok" in t, ot = (t) => typeof t == "object" && t !== null && "nonce" in t && "txid" in t, ct = (t) => {
149
+ })), d);
150
+ if (typeof globalThis.__ZELDMINER_WASM_BASE__ > "u")
151
+ try {
152
+ const t = typeof self < "u" && self.location?.origin ? self.location.origin : "http://localhost";
153
+ globalThis.__ZELDMINER_WASM_BASE__ = new URL("/wasm/", t).href;
154
+ } catch {
155
+ globalThis.__ZELDMINER_WASM_BASE__ = "/wasm/";
156
+ }
157
+ const B = self, rt = B.name ?? void 0, I = (t) => t instanceof Error ? t.message : String(t);
158
+ let N = "cpu", b = null;
159
+ const w = (t) => {
160
+ B.postMessage({ ...t, workerId: rt });
161
+ }, h = (t, e = u.WORKER_ERROR, n) => {
162
+ w({ type: "error", message: t, code: e, details: n });
163
+ }, ot = (t) => typeof t == "object" && t !== null && "ok" in t, st = (t) => typeof t == "object" && t !== null && "nonce" in t && "txid" in t, at = (t) => {
149
164
  const e = BigInt(Number.MAX_SAFE_INTEGER);
150
165
  return t > e ? Number.MAX_SAFE_INTEGER : t < -e ? -Number.MAX_SAFE_INTEGER : Number(t);
151
- }, at = (t) => ({
166
+ }, ct = (t) => ({
152
167
  nonceLength: t.nonceLength,
153
168
  prefix: new Uint8Array(t.prefix),
154
169
  suffix: new Uint8Array(t.suffix),
155
170
  useCborNonce: t.useCborNonce
156
171
  }), F = (t, e) => {
157
- t.set(e.nonceLength, at(e));
158
- }, ut = async (t, e, n, r, i) => {
159
- const o = t.get(r.nonceLength);
160
- if (o)
161
- return o;
162
- const s = e.build_mining_template(
172
+ t.set(e.nonceLength, ct(e));
173
+ }, ut = async (t, e, n, i, r) => {
174
+ const s = t.get(i.nonceLength);
175
+ if (s)
176
+ return s;
177
+ const o = e.build_mining_template(
163
178
  n.inputs,
164
179
  n.outputs,
165
- i,
180
+ r,
166
181
  BigInt(n.satsPerVbyte),
167
- r.start,
168
- r.size,
182
+ i.start,
183
+ i.size,
169
184
  n.distribution ?? null
170
- ), c = {
171
- ...s,
172
- nonceLength: r.nonceLength,
173
- useCborNonce: s.useCborNonce ?? n.useCborNonce
185
+ ), a = {
186
+ ...o,
187
+ nonceLength: i.nonceLength,
188
+ useCborNonce: o.useCborNonce ?? n.useCborNonce
174
189
  };
175
- return F(t, c), c;
176
- }, ft = async (t, e, n, r, i, o, s, c) => {
190
+ return F(t, a), a;
191
+ }, lt = async (t, e, n, i, r, s, o, a) => {
177
192
  if (e === "gpu") {
178
193
  if (!t.mine_batch_gpu)
179
194
  throw new Error("GPU mining requested but mine_batch_gpu is unavailable");
180
195
  return t.mine_batch_gpu(
181
196
  n,
182
- r,
183
197
  i,
184
- o,
198
+ r,
185
199
  s,
186
- c
200
+ o,
201
+ a
187
202
  );
188
203
  }
189
204
  return t.mine_batch_wasm(
190
205
  n,
191
- r,
192
206
  i,
193
- o,
207
+ r,
194
208
  s,
195
- c
209
+ o,
210
+ a
196
211
  );
197
- }, lt = async (t, e) => {
212
+ }, ft = async (t, e) => {
198
213
  let n;
199
214
  try {
200
- if (n = await rt(), A === "gpu") {
215
+ if (n = await it(), N === "gpu") {
201
216
  if (!n.mine_batch_gpu) {
202
- m(
217
+ h(
203
218
  "GPU mining requested but mine_batch_gpu is unavailable",
204
219
  u.WEBGPU_NOT_AVAILABLE
205
220
  );
@@ -207,27 +222,27 @@ const E = (t) => {
207
222
  }
208
223
  n.init_gpu && await n.init_gpu();
209
224
  }
210
- } catch (g) {
211
- const _ = N(g), b = A === "gpu" ? u.WEBGPU_NOT_AVAILABLE : u.WORKER_ERROR;
212
- m(`Failed to initialize WASM: ${_}`, b);
225
+ } catch (m) {
226
+ const g = I(m), E = N === "gpu" ? u.WEBGPU_NOT_AVAILABLE : u.WORKER_ERROR;
227
+ h(`Failed to initialize WASM: ${g}`, E);
213
228
  return;
214
229
  }
215
- const r = /* @__PURE__ */ new Map(), i = t.template.useCborNonce ?? !!(t.distribution && t.distribution.length > 0);
216
- F(r, { ...t.template, useCborNonce: i });
217
- const o = t.nonceStep ?? BigInt(t.batchSize), s = t.network === "signet" ? "testnet" : t.network;
218
- let c = t.startNonce, f = 0n;
230
+ const i = /* @__PURE__ */ new Map(), r = t.template.useCborNonce ?? !!(t.distribution && t.distribution.length > 0);
231
+ F(i, { ...t.template, useCborNonce: r });
232
+ const s = t.nonceStep ?? BigInt(t.batchSize), o = t.network === "signet" ? "testnet" : t.network;
233
+ let a = t.startNonce, l = 0n;
219
234
  const G = performance.now();
220
235
  for (; !e.signal.aborted; ) {
221
- const g = c;
222
- let _ = t.batchSize, b = 0n;
223
- for (; _ > 0 && !e.signal.aborted; ) {
224
- const P = g + b;
225
- let a;
236
+ const m = a;
237
+ let g = t.batchSize, E = 0n;
238
+ for (; g > 0 && !e.signal.aborted; ) {
239
+ const D = m + E;
240
+ let c;
226
241
  try {
227
- a = (i ? J(P, _) : Y(P, _))[0];
228
- } catch (h) {
229
- m(
230
- `Invalid nonce range: ${N(h)}`,
242
+ c = (r ? J(D, g) : Y(D, g))[0];
243
+ } catch (_) {
244
+ h(
245
+ `Invalid nonce range: ${I(_)}`,
231
246
  u.INVALID_INPUT
232
247
  ), e.abort();
233
248
  return;
@@ -235,102 +250,102 @@ const E = (t) => {
235
250
  let S;
236
251
  try {
237
252
  S = await ut(
238
- r,
253
+ i,
239
254
  n,
240
255
  {
241
256
  inputs: t.inputs,
242
257
  outputs: t.outputs,
243
258
  satsPerVbyte: t.satsPerVbyte,
244
259
  distribution: t.distribution,
245
- useCborNonce: i
260
+ useCborNonce: r
246
261
  },
247
- a,
248
- s
262
+ c,
263
+ o
249
264
  );
250
- } catch (h) {
251
- m(
252
- `Failed to build mining template: ${N(h)}`,
265
+ } catch (_) {
266
+ h(
267
+ `Failed to build mining template: ${I(_)}`,
253
268
  u.WORKER_ERROR
254
269
  ), e.abort();
255
270
  return;
256
271
  }
257
- let l;
272
+ let f;
258
273
  const k = performance.now();
259
274
  try {
260
- l = await ft(
275
+ f = await lt(
261
276
  n,
262
- A,
277
+ N,
263
278
  S.prefix,
264
279
  S.suffix,
265
- a.start,
266
- a.size,
280
+ c.start,
281
+ c.size,
267
282
  t.targetZeros,
268
- i
283
+ r
269
284
  );
270
- } catch (h) {
271
- const p = N(h);
272
- m(
285
+ } catch (_) {
286
+ const p = I(_);
287
+ h(
273
288
  `Batch mining failed: ${p}`,
274
289
  u.WORKER_ERROR
275
290
  ), e.abort();
276
291
  return;
277
292
  }
278
- const O = performance.now() - k;
279
- if (st(l)) {
280
- if (!l.ok) {
281
- m(
282
- l.error ?? "Validation failed",
293
+ const P = performance.now() - k;
294
+ if (ot(f)) {
295
+ if (!f.ok) {
296
+ h(
297
+ f.error ?? "Validation failed",
283
298
  u.INVALID_INPUT
284
299
  ), e.abort();
285
300
  return;
286
301
  }
287
- } else if (ot(l)) {
288
- const h = f + b, p = BigInt(l.nonce) - a.start + 1n, T = h + p, L = performance.now() - G, D = L > 0 ? ct(T) / (L / 1e3) : 0, q = a.start + p - 1n, C = {
302
+ } else if (st(f)) {
303
+ const _ = l + E, p = BigInt(f.nonce) - c.start + 1n, L = _ + p, T = performance.now() - G, M = T > 0 ? at(L) / (T / 1e3) : 0, q = c.start + p - 1n, C = {
289
304
  psbt: "",
290
- txid: l.txid,
291
- nonce: BigInt(l.nonce),
292
- attempts: T,
293
- duration: L,
294
- hashRate: D
305
+ txid: f.txid,
306
+ nonce: BigInt(f.nonce),
307
+ attempts: L,
308
+ duration: T,
309
+ hashRate: M
295
310
  };
296
- E({
311
+ w({
297
312
  type: "found",
298
313
  result: C,
299
- hashesProcessed: T,
300
- hashRate: D,
314
+ hashesProcessed: L,
315
+ hashRate: M,
301
316
  lastNonce: q
302
317
  }), e.abort();
303
318
  return;
304
319
  }
305
- f += BigInt(a.size), b += BigInt(a.size), _ -= a.size;
306
- const v = O > 0 ? a.size / (O / 1e3) : a.size, $ = a.start + BigInt(a.size) - 1n;
307
- E({ type: "progress", hashesProcessed: f, hashRate: v, lastNonce: $ });
320
+ l += BigInt(c.size), E += BigInt(c.size), g -= c.size;
321
+ const v = P > 0 ? c.size / (P / 1e3) : c.size, $ = c.start + BigInt(c.size) - 1n;
322
+ w({ type: "progress", hashesProcessed: l, hashRate: v, lastNonce: $ });
308
323
  }
309
324
  if (e.signal.aborted)
310
325
  break;
311
- const V = g + BigInt(t.batchSize) - 1n;
312
- E({ type: "batch_complete", lastNonce: V }), c = g + o;
326
+ const V = m + BigInt(t.batchSize) - 1n;
327
+ w({ type: "batch_complete", lastNonce: V }), a = m + s;
313
328
  }
314
- }, ht = (t) => {
329
+ }, _t = (t) => {
315
330
  const e = new AbortController();
316
- w?.abort(), w = e, lt(t, e).finally(() => {
317
- w === e && (w = null);
331
+ b?.abort(), b = e, ft(t, e).finally(() => {
332
+ b === e && (b = null);
318
333
  });
319
334
  };
320
335
  B.addEventListener("message", (t) => {
321
336
  const e = t.data;
322
337
  switch (e.type) {
323
338
  case "init":
324
- A = e.mode, E({ type: "ready" });
339
+ N = e.mode, w({ type: "ready" });
325
340
  break;
326
341
  case "mine":
327
- ht(e);
342
+ _t(e);
328
343
  break;
329
344
  case "stop":
330
- w?.abort();
345
+ b?.abort();
331
346
  break;
332
347
  default:
333
- m(
348
+ h(
334
349
  `Unknown message type: ${e.type}`,
335
350
  u.WORKER_ERROR
336
351
  );
@@ -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({ 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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"}
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\n// Bootstrap: define a sensible default for WASM base path so consumers don't\n// need to patch the library. In Vite/dev the import.meta.url points inside\n// node_modules which is not served, so we derive a public path from the window\n// origin when available.\nif (typeof (globalThis as { __ZELDMINER_WASM_BASE__?: unknown }).__ZELDMINER_WASM_BASE__ === \"undefined\") {\n try {\n const origin =\n typeof window !== \"undefined\" && window.location?.origin\n ? window.location.origin\n : typeof self !== \"undefined\" && (self as { location?: { origin?: string } }).location?.origin\n ? (self as { location?: { origin?: string } }).location!.origin\n : \"http://localhost\";\n (globalThis as { __ZELDMINER_WASM_BASE__?: string }).__ZELDMINER_WASM_BASE__ = new URL(\"/wasm/\", origin!).href;\n } catch {\n (globalThis as { __ZELDMINER_WASM_BASE__?: string }).__ZELDMINER_WASM_BASE__ = \"/wasm/\";\n }\n}\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","// Bootstrap: define a sensible default for WASM base path in worker context.\n// Workers don't have `window`, but `self` provides location. This must run\n// before any import that calls resolveWasmBase().\nif (typeof (globalThis as { __ZELDMINER_WASM_BASE__?: unknown }).__ZELDMINER_WASM_BASE__ === \"undefined\") {\n try {\n const origin =\n typeof self !== \"undefined\" && (self as { location?: { origin?: string } }).location?.origin\n ? (self as { location?: { origin?: string } }).location!.origin\n : \"http://localhost\";\n (globalThis as { __ZELDMINER_WASM_BASE__?: string }).__ZELDMINER_WASM_BASE__ = new URL(\"/wasm/\", origin!).href;\n } catch {\n (globalThis as { __ZELDMINER_WASM_BASE__?: string }).__ZELDMINER_WASM_BASE__ = \"/wasm/\";\n }\n}\n\nimport 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","origin","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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "zeldhash-miner",
3
- "version": "0.2.1",
3
+ "version": "0.2.2",
4
4
  "author": "Ouziel Slama <ouziel@gmail.com>",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
package/wasm/package.json CHANGED
@@ -5,7 +5,7 @@
5
5
  "Ouziel Slama <ouziel@gmail.com>"
6
6
  ],
7
7
  "description": "WASM bindings for the Zeldhash miner with optional WebGPU acceleration",
8
- "version": "0.2.1",
8
+ "version": "0.2.2",
9
9
  "license": "MIT",
10
10
  "repository": {
11
11
  "type": "git",
Binary file