zeldhash-miner 0.2.4 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -194,7 +194,6 @@ try {
194
194
  | `INVALID_ADDRESS` | Address parsing failed |
195
195
  | `UNSUPPORTED_ADDRESS_TYPE` | Only P2WPKH and P2TR supported |
196
196
  | `INSUFFICIENT_FUNDS` | Inputs don't cover outputs + fees |
197
- | `NO_CHANGE_OUTPUT` | No output marked as change |
198
197
  | `MULTIPLE_CHANGE_OUTPUTS` | More than one change output |
199
198
  | `INVALID_INPUT` | Bad parameter |
200
199
  | `WEBGPU_NOT_AVAILABLE` | WebGPU requested but unavailable |
@@ -202,6 +201,10 @@ try {
202
201
  | `MINING_ABORTED` | Mining was stopped |
203
202
  | `DUST_OUTPUT` | Output below dust limit (310 sats P2WPKH / 330 sats P2TR) |
204
203
 
204
+ Notes:
205
+ - A change output is optional. If provided but the computed change would be below the dust limit, the change is omitted and the extra sats are counted as fees.
206
+ - You can also build transactions with no change output (e.g., sweeping a wallet).
207
+
205
208
  ## Runtime Notes
206
209
 
207
210
  ### WASM Asset Loading
package/dist/index.d.ts CHANGED
@@ -188,7 +188,6 @@ export declare enum ZeldMinerErrorCode {
188
188
  INVALID_ADDRESS = "INVALID_ADDRESS",
189
189
  UNSUPPORTED_ADDRESS_TYPE = "UNSUPPORTED_ADDRESS_TYPE",
190
190
  INSUFFICIENT_FUNDS = "INSUFFICIENT_FUNDS",
191
- NO_CHANGE_OUTPUT = "NO_CHANGE_OUTPUT",
192
191
  MULTIPLE_CHANGE_OUTPUTS = "MULTIPLE_CHANGE_OUTPUTS",
193
192
  INVALID_INPUT = "INVALID_INPUT",
194
193
  WEBGPU_NOT_AVAILABLE = "WEBGPU_NOT_AVAILABLE",
package/dist/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  import { Z as I, l as H, c as F, n as K, s as v, a as f } from "./nonce.js";
2
- const S = (o) => o instanceof Error ? o.message : String(o);
2
+ const S = (n) => n instanceof Error ? n.message : String(n);
3
3
  class N extends Error {
4
4
  code;
5
5
  details;
@@ -7,14 +7,14 @@ class N extends Error {
7
7
  super(e), this.name = "ZeldMinerError", this.code = t, this.details = s;
8
8
  }
9
9
  }
10
- const Y = (o, t = I.WORKER_ERROR, e) => {
11
- if (o instanceof N)
12
- return o;
13
- const s = S(o);
10
+ const Y = (n, t = I.WORKER_ERROR, e) => {
11
+ if (n instanceof N)
12
+ return n;
13
+ const s = S(n);
14
14
  return new N(t, s, e);
15
- }, i = (o, t, e) => new N(o, t, e), B = (o) => {
15
+ }, i = (n, t, e) => new N(n, t, e), B = (n) => {
16
16
  const t = BigInt(Number.MAX_SAFE_INTEGER);
17
- return o > t ? Number.MAX_SAFE_INTEGER : o < -t ? -Number.MAX_SAFE_INTEGER : Number(o);
17
+ return n > t ? Number.MAX_SAFE_INTEGER : n < -t ? -Number.MAX_SAFE_INTEGER : Number(n);
18
18
  };
19
19
  class T {
20
20
  mode;
@@ -70,14 +70,14 @@ class T {
70
70
  type: "module",
71
71
  /* @vite-ignore */
72
72
  name: `zeldminer-worker-${s}`
73
- }), n = {
73
+ }), o = {
74
74
  worker: g,
75
75
  hashesProcessed: 0n,
76
76
  hashRate: 0,
77
77
  nextNonce: 0n,
78
78
  processedBase: 0n
79
79
  };
80
- this.workers.push(n), t.push(
80
+ this.workers.push(o), t.push(
81
81
  new Promise((C) => {
82
82
  const c = (d) => {
83
83
  d.data.type === "ready" && (g.removeEventListener("message", c), C());
@@ -86,7 +86,7 @@ class T {
86
86
  })
87
87
  ), g.addEventListener(
88
88
  "message",
89
- (C) => this.handleWorkerMessage(n, C.data)
89
+ (C) => this.handleWorkerMessage(o, C.data)
90
90
  );
91
91
  const r = { type: "init", mode: this.mode };
92
92
  g.postMessage(r);
@@ -108,11 +108,11 @@ class T {
108
108
  const s = this.workers.reduce(
109
109
  (C, c) => C + c.hashesProcessed,
110
110
  0n
111
- ), g = this.startedAt ? performance.now() - this.startedAt : 0, n = g > 0 ? B(s) / (g / 1e3) : 0, r = {
111
+ ), g = this.startedAt ? performance.now() - this.startedAt : 0, o = g > 0 ? B(s) / (g / 1e3) : 0, r = {
112
112
  ...e.result,
113
113
  attempts: s,
114
114
  duration: g,
115
- hashRate: n
115
+ hashRate: o
116
116
  };
117
117
  this.running = !1, this.paused = !1, this.terminateWorkers(), this.cleanupExternalAbort(), this.emit("found", r);
118
118
  break;
@@ -134,7 +134,7 @@ class T {
134
134
  emitProgress() {
135
135
  if (!this.running) return;
136
136
  const t = this.workers.reduce(
137
- (n, r) => n + r.hashesProcessed,
137
+ (o, r) => o + r.hashesProcessed,
138
138
  0n
139
139
  ), e = this.startedAt ? performance.now() - this.startedAt : 0, s = e > 0 ? B(t) / (e / 1e3) : 0, g = {
140
140
  hashesProcessed: t,
@@ -163,7 +163,7 @@ class T {
163
163
  async start(t) {
164
164
  if (await this.readyPromise, this.stopWorkers(), this.running = !0, this.paused = !1, this.startedAt = performance.now(), this.txInputs = t.inputs, this.txOutputs = t.outputs, this.txNetwork = t.network === "signet" ? "testnet" : t.network, this.satsPerVbyte = t.satsPerVbyte, this.template = t.template, this.targetZeros = t.targetZeros, this.startNonce = t.startNonce ?? 0n, this.txDistribution = t.distribution, this.externalAbort && this.externalAbort !== t.signal && this.cleanupExternalAbort(), t.signal && (this.externalAbort = t.signal, t.signal.addEventListener("abort", this.abortHandler, { once: !0 })), !this.template || !this.txInputs || !this.txOutputs || this.targetZeros === void 0 || this.satsPerVbyte === void 0 || !this.txNetwork)
165
165
  throw new Error("Mining parameters are missing");
166
- const e = this.txInputs, s = this.txOutputs, g = this.txNetwork, n = this.satsPerVbyte, r = this.template, C = this.targetZeros, c = this.txDistribution, d = this.stride;
166
+ const e = this.txInputs, s = this.txOutputs, g = this.txNetwork, o = this.satsPerVbyte, r = this.template, C = this.targetZeros, c = this.txDistribution, d = this.stride;
167
167
  this.workers.forEach((A, l) => {
168
168
  A.processedBase = 0n, A.hashesProcessed = 0n, A.hashRate = 0, A.lastNonce = void 0;
169
169
  const u = this.startNonce + BigInt(l) * BigInt(this.batchSize);
@@ -173,7 +173,7 @@ class T {
173
173
  inputs: e,
174
174
  outputs: s,
175
175
  network: g,
176
- satsPerVbyte: n,
176
+ satsPerVbyte: o,
177
177
  template: r,
178
178
  startNonce: u,
179
179
  batchSize: this.batchSize,
@@ -191,7 +191,7 @@ class T {
191
191
  if (!this.paused || !this.template || !this.txInputs || !this.txOutputs || this.targetZeros === void 0 || this.satsPerVbyte === void 0 || !this.txNetwork)
192
192
  return;
193
193
  await this.readyPromise, this.running = !0, this.paused = !1, this.startedAt || (this.startedAt = performance.now());
194
- const t = this.txInputs, e = this.txOutputs, s = this.txNetwork, g = this.satsPerVbyte, n = this.template, r = this.targetZeros, C = this.txDistribution, c = this.stride;
194
+ const t = this.txInputs, e = this.txOutputs, s = this.txNetwork, g = this.satsPerVbyte, o = this.template, r = this.targetZeros, C = this.txDistribution, c = this.stride;
195
195
  this.workers.forEach((d, A) => {
196
196
  d.processedBase = d.hashesProcessed, d.hashRate = 0;
197
197
  const l = d.nextNonce || this.startNonce + BigInt(A) * BigInt(this.batchSize), u = {
@@ -200,7 +200,7 @@ class T {
200
200
  outputs: e,
201
201
  network: s,
202
202
  satsPerVbyte: g,
203
- template: n,
203
+ template: o,
204
204
  startNonce: l,
205
205
  batchSize: this.batchSize,
206
206
  targetZeros: r,
@@ -214,8 +214,8 @@ class T {
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 U = /^[0-9a-fA-F]{64}$/, k = /^[0-9a-fA-F]+$/, p = (1n << 64n) - 1n, z = 4294967295, P = (o) => o === "p2tr" ? 330 : o === "p2wpkh" ? 310 : 546, Q = (o) => o instanceof Error ? o.message : String(o), R = (o, t) => t.some((e) => o.includes(e)), w = (o, t, e) => {
218
- const s = Q(o), g = s.toLowerCase();
217
+ const U = /^[0-9a-fA-F]{64}$/, k = /^[0-9a-fA-F]+$/, p = (1n << 64n) - 1n, z = 4294967295, P = (n) => n === "p2tr" ? 330 : n === "p2wpkh" ? 310 : 546, Q = (n) => n instanceof Error ? n.message : String(n), R = (n, t) => t.some((e) => n.includes(e)), w = (n, t, e) => {
218
+ const s = Q(n), g = s.toLowerCase();
219
219
  throw R(g, ["insufficient funds", "insufficient_funds"]) ? i(
220
220
  I.INSUFFICIENT_FUNDS,
221
221
  "Insufficient funds for outputs and fee",
@@ -224,11 +224,11 @@ const U = /^[0-9a-fA-F]{64}$/, k = /^[0-9a-fA-F]+$/, p = (1n << 64n) - 1n, z = 4
224
224
  I.DUST_OUTPUT,
225
225
  "Change would be dust",
226
226
  { ...e, cause: s }
227
- ) : Y(o, I.WORKER_ERROR, {
227
+ ) : Y(n, I.WORKER_ERROR, {
228
228
  ...e,
229
229
  context: t
230
230
  });
231
- }, W = (o) => o === "signet" ? "testnet" : o;
231
+ }, W = (n) => n === "signet" ? "testnet" : n;
232
232
  class O {
233
233
  network;
234
234
  satsPerVbyte;
@@ -264,7 +264,7 @@ class O {
264
264
  "nonce range exceeds u64",
265
265
  { startNonce: t, batchSize: e }
266
266
  );
267
- const n = s ? F : K, r = n(t), C = n(g);
267
+ const o = s ? F : K, r = o(t), C = o(g);
268
268
  if (r !== C) {
269
269
  const c = s ? "CBOR length" : "byte-length";
270
270
  throw i(
@@ -342,28 +342,26 @@ class O {
342
342
  I.INVALID_INPUT,
343
343
  "At least one output is required"
344
344
  );
345
- const e = t.filter((n) => n.change).length;
346
- if (e !== 1) {
347
- const n = e === 0 ? I.NO_CHANGE_OUTPUT : I.MULTIPLE_CHANGE_OUTPUTS;
345
+ const e = t.filter((o) => o.change).length;
346
+ if (e > 1)
348
347
  throw i(
349
- n,
350
- "Exactly one change output is required",
348
+ I.MULTIPLE_CHANGE_OUTPUTS,
349
+ "At most one change output is allowed",
351
350
  { changeCount: e }
352
351
  );
353
- }
354
352
  const s = await this.getWasm(), g = W(this.network);
355
- t.forEach((n, r) => {
356
- const C = s.validate_address(n.address, g);
353
+ t.forEach((o, r) => {
354
+ const C = s.validate_address(o.address, g);
357
355
  this.validateAddressResult(C, r, g);
358
356
  const c = P(C.addressType);
359
- if (n.change) {
360
- if (n.amount !== void 0 && (!Number.isInteger(n.amount) || n.amount < 0))
357
+ if (o.change) {
358
+ if (o.amount !== void 0 && (!Number.isInteger(o.amount) || o.amount < 0))
361
359
  throw i(
362
360
  I.INVALID_INPUT,
363
361
  `outputs[${r}].amount must be a non-negative integer when provided`,
364
362
  { index: r }
365
363
  );
366
- } else if (!Number.isInteger(n.amount) || n.amount < c)
364
+ } else if (!Number.isInteger(o.amount) || o.amount < c)
367
365
  throw i(
368
366
  I.DUST_OUTPUT,
369
367
  `outputs[${r}].amount must be at least ${c} sats`,
@@ -402,9 +400,9 @@ class O {
402
400
  }
403
401
  }
404
402
  async buildMiningTemplate(t) {
405
- const { inputs: e, outputs: s, startNonce: g, batchSize: n, distribution: r } = t;
403
+ const { inputs: e, outputs: s, startNonce: g, batchSize: o, distribution: r } = t;
406
404
  this.validateInputs(e), await this.validateOutputs(s);
407
- const C = this.validateDistribution(s, r), c = Array.isArray(C), d = this.assertNonceRange(g, n, c), A = await this.getWasm();
405
+ const C = this.validateDistribution(s, r), c = Array.isArray(C), d = this.assertNonceRange(g, o, c), A = await this.getWasm();
408
406
  try {
409
407
  const l = A.build_mining_template(
410
408
  this.cloneInputs(e),
@@ -412,7 +410,7 @@ class O {
412
410
  W(this.network),
413
411
  BigInt(this.satsPerVbyte),
414
412
  g,
415
- n,
413
+ o,
416
414
  C ?? null
417
415
  );
418
416
  if (!l || !(l.prefix instanceof Uint8Array) || !(l.suffix instanceof Uint8Array))
@@ -425,15 +423,15 @@ class O {
425
423
  } catch (l) {
426
424
  throw w(l, "build_mining_template", {
427
425
  startNonce: g,
428
- batchSize: n,
426
+ batchSize: o,
429
427
  distribution: C
430
428
  });
431
429
  }
432
430
  }
433
431
  async buildPsbt(t) {
434
- const { inputs: e, outputs: s, nonce: g, distribution: n } = t;
432
+ const { inputs: e, outputs: s, nonce: g, distribution: o } = t;
435
433
  this.validateInputs(e), await this.validateOutputs(s);
436
- const r = this.validateDistribution(s, n);
434
+ const r = this.validateDistribution(s, o);
437
435
  if (g < 0n || g > p)
438
436
  throw i(
439
437
  I.INVALID_INPUT,
@@ -533,10 +531,10 @@ class E {
533
531
  I.MINING_ABORTED,
534
532
  "Abort signal already triggered"
535
533
  );
536
- const g = t.distribution, n = !!(g && g.length > 0);
534
+ const g = t.distribution, o = !!(g && g.length > 0);
537
535
  let r = s;
538
536
  try {
539
- const [l] = n ? v(e, s) : f(e, s);
537
+ const [l] = o ? v(e, s) : f(e, s);
540
538
  if (!l)
541
539
  throw i(
542
540
  I.INVALID_INPUT,
@@ -564,15 +562,15 @@ class E {
564
562
  });
565
563
  return this.coordinator = A, this.state = "running", this.stopRequested = !1, new Promise((l, u) => {
566
564
  let h = !1;
567
- const G = () => {
565
+ const V = () => {
568
566
  this.clearCoordinatorHandlers(A, b), this.coordinator === A && (this.coordinator = null), this.state = "idle", this.stopRequested = !1;
569
567
  }, J = (a) => {
570
- h || (h = !0, G(), l(a));
568
+ h || (h = !0, V(), l(a));
571
569
  }, Z = (a) => {
572
570
  if (h) return;
573
571
  h = !0;
574
572
  const m = Y(a);
575
- G(), this.emit("error", m), u(m);
573
+ V(), this.emit("error", m), u(m);
576
574
  }, b = {};
577
575
  b.progress = (a) => {
578
576
  this.emit("progress", a);
@@ -583,8 +581,8 @@ class E {
583
581
  outputs: t.outputs,
584
582
  nonce: a.nonce,
585
583
  distribution: g
586
- }), V = { ...a, psbt: m };
587
- this.emit("found", V), J(V);
584
+ }), G = { ...a, psbt: m };
585
+ this.emit("found", G), J(G);
588
586
  } catch (m) {
589
587
  Z(m);
590
588
  }
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":["../src/errors.ts","../src/coordinator.ts","../src/builder.ts","../src/index.ts"],"sourcesContent":["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 resolveWorkerUrl(): string {\n const origin =\n typeof location !== \"undefined\" && location.origin\n ? location.origin\n : typeof self !== \"undefined\" &&\n (self as { location?: { origin?: string } }).location?.origin\n ? (self as { location?: { origin?: string } }).location!.origin\n : undefined;\n if (origin) return `${origin}/worker.js`;\n return new URL(\"./worker.ts\", import.meta.url).href;\n }\n\n private async spawnWorkers(): Promise<void> {\n const readySignals: Promise<void>[] = [];\n const workerUrl = this.resolveWorkerUrl();\n\n for (let i = 0; i < this.workerCount; i += 1) {\n const worker = new Worker(workerUrl, {\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 {\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":["formatUnknownError","err","ZeldMinerError","code","message","details","toZeldMinerError","fallbackCode","ZeldMinerErrorCode","createMinerError","safeBigIntToNumber","value","max","MiningCoordinator","options","event","handler","payload","origin","readySignals","workerUrl","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","TXID_REGEX","HEX_REGEX","MAX_U64","MAX_U32","dustLimitForAddress","addressType","formatError","includesAny","haystack","needles","needle","mapWasmError","context","normalized","normalizeNetwork","TransactionBuilder","loadWasm","startNonce","batchSize","useCborNonce","lengthFn","cborNonceLength","nonceLength","startLen","lastLen","boundaryLabel","input","output","validation","reason","changeCount","o","wasm","net","dustLimit","validatedDistribution","templateUsesCbor","nonce","MIN_TARGET_ZEROS","MAX_TARGET_ZEROS","ZeldMiner","gpu","coordinator","handlers","firstSegmentSize","firstSegment","splitNonceSegmentsCbor","splitNonceSegments","mode","reject","settled","cleanup","resolveOnce","rejectOnce","error","stats","result","psbt","finalResult"],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sources":["../src/errors.ts","../src/coordinator.ts","../src/builder.ts","../src/index.ts"],"sourcesContent":["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 resolveWorkerUrl(): string {\n const origin =\n typeof location !== \"undefined\" && location.origin\n ? location.origin\n : typeof self !== \"undefined\" &&\n (self as { location?: { origin?: string } }).location?.origin\n ? (self as { location?: { origin?: string } }).location!.origin\n : undefined;\n if (origin) return `${origin}/worker.js`;\n return new URL(\"./worker.ts\", import.meta.url).href;\n }\n\n private async spawnWorkers(): Promise<void> {\n const readySignals: Promise<void>[] = [];\n const workerUrl = this.resolveWorkerUrl();\n\n for (let i = 0; i < this.workerCount; i += 1) {\n const worker = new Worker(workerUrl, {\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 {\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 throw createMinerError(\n ZeldMinerErrorCode.MULTIPLE_CHANGE_OUTPUTS,\n \"At most one change output is allowed\",\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":["formatUnknownError","err","ZeldMinerError","code","message","details","toZeldMinerError","fallbackCode","ZeldMinerErrorCode","createMinerError","safeBigIntToNumber","value","max","MiningCoordinator","options","event","handler","payload","origin","readySignals","workerUrl","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","TXID_REGEX","HEX_REGEX","MAX_U64","MAX_U32","dustLimitForAddress","addressType","formatError","includesAny","haystack","needles","needle","mapWasmError","context","normalized","normalizeNetwork","TransactionBuilder","loadWasm","startNonce","batchSize","useCborNonce","lengthFn","cborNonceLength","nonceLength","startLen","lastLen","boundaryLabel","input","output","validation","reason","changeCount","wasm","net","dustLimit","validatedDistribution","templateUsesCbor","nonce","MIN_TARGET_ZEROS","MAX_TARGET_ZEROS","ZeldMiner","gpu","coordinator","handlers","firstSegmentSize","firstSegment","splitNonceSegmentsCbor","splitNonceSegments","mode","reject","settled","cleanup","resolveOnce","rejectOnce","error","stats","result","psbt","finalResult"],"mappings":"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"}
package/dist/nonce.js CHANGED
@@ -1,4 +1,4 @@
1
- var S = /* @__PURE__ */ ((e) => (e.INVALID_ADDRESS = "INVALID_ADDRESS", e.UNSUPPORTED_ADDRESS_TYPE = "UNSUPPORTED_ADDRESS_TYPE", e.INSUFFICIENT_FUNDS = "INSUFFICIENT_FUNDS", e.NO_CHANGE_OUTPUT = "NO_CHANGE_OUTPUT", e.MULTIPLE_CHANGE_OUTPUTS = "MULTIPLE_CHANGE_OUTPUTS", e.INVALID_INPUT = "INVALID_INPUT", e.WEBGPU_NOT_AVAILABLE = "WEBGPU_NOT_AVAILABLE", e.WORKER_ERROR = "WORKER_ERROR", e.MINING_ABORTED = "MINING_ABORTED", e.DUST_OUTPUT = "DUST_OUTPUT", e))(S || {});
1
+ var S = /* @__PURE__ */ ((e) => (e.INVALID_ADDRESS = "INVALID_ADDRESS", e.UNSUPPORTED_ADDRESS_TYPE = "UNSUPPORTED_ADDRESS_TYPE", e.INSUFFICIENT_FUNDS = "INSUFFICIENT_FUNDS", e.MULTIPLE_CHANGE_OUTPUTS = "MULTIPLE_CHANGE_OUTPUTS", e.INVALID_INPUT = "INVALID_INPUT", e.WEBGPU_NOT_AVAILABLE = "WEBGPU_NOT_AVAILABLE", e.WORKER_ERROR = "WORKER_ERROR", e.MINING_ABORTED = "MINING_ABORTED", e.DUST_OUTPUT = "DUST_OUTPUT", e))(S || {});
2
2
  const A = {};
3
3
  if (typeof globalThis.__ZELDMINER_WASM_BASE__ > "u")
4
4
  try {
@@ -14,16 +14,16 @@ const I = () => {
14
14
  const e = globalThis.GPUAdapter?.prototype, t = e?.requestDevice;
15
15
  !e || typeof t != "function" || (e.requestDevice = function(r) {
16
16
  if (r?.requiredLimits && typeof this.limits == "object") {
17
- const i = r.requiredLimits, o = this.limits;
18
- for (const s of Object.keys(i))
19
- (!(s in o) || o[s] === void 0) && delete i[s];
17
+ const i = r.requiredLimits, s = this.limits;
18
+ for (const o of Object.keys(i))
19
+ (!(o in s) || s[o] === void 0) && delete i[o];
20
20
  }
21
21
  return t.call(this, r);
22
22
  });
23
23
  }, l = (e) => e.endsWith("/") ? e : `${e}/`, u = (e) => {
24
24
  const t = e.trim();
25
25
  return t && (typeof window < "u" && typeof window.location?.origin == "string" ? l(new URL(t, window.location.origin).href) : l(new URL(t, import.meta.url).href));
26
- }, N = () => {
26
+ }, b = () => {
27
27
  const e = globalThis.__ZELDMINER_WASM_BASE__;
28
28
  if (typeof e == "string" && e.trim())
29
29
  return u(e);
@@ -32,11 +32,11 @@ const I = () => {
32
32
  return u(t);
33
33
  const n = "./";
34
34
  return n.trim() ? u(`${l(n.trim())}wasm/`) : u("/wasm/");
35
- }, E = N(), h = `${E}zeldhash_miner_wasm.js`, b = `${E}zeldhash_miner_wasm_bg.wasm`, T = async (e) => (0, eval)("s => import(s)")(e), g = (e) => e instanceof Error ? e.message : String(e), L = async () => {
35
+ }, E = b(), h = `${E}zeldhash_miner_wasm.js`, N = `${E}zeldhash_miner_wasm_bg.wasm`, d = async (e) => (0, eval)("s => import(s)")(e), g = (e) => e instanceof Error ? e.message : String(e), L = async () => {
36
36
  I();
37
37
  let e;
38
38
  try {
39
- e = await T(
39
+ e = await d(
40
40
  /* @vite-ignore */
41
41
  h
42
42
  );
@@ -49,7 +49,7 @@ const I = () => {
49
49
  if (typeof t != "function")
50
50
  throw new Error("WASM init function is missing from the bundle.");
51
51
  try {
52
- const r = new URL(b, import.meta.url);
52
+ const r = new URL(N, import.meta.url);
53
53
  await t({ module_or_path: r });
54
54
  } catch (r) {
55
55
  throw new Error(
@@ -64,7 +64,7 @@ const I = () => {
64
64
  return n;
65
65
  }, D = async () => m || (f || (f = L().then((e) => (m = e, e)).catch((e) => {
66
66
  throw f = null, e;
67
- })), f), _ = (1n << 64n) - 1n, U = (e) => {
67
+ })), f), _ = (1n << 64n) - 1n, T = (e) => {
68
68
  if (e < 0n)
69
69
  throw new Error("nonce must be non-negative");
70
70
  if (e === 0n) return 1;
@@ -72,7 +72,7 @@ const I = () => {
72
72
  for (; n > 0n; )
73
73
  t += 1, n >>= 8n;
74
74
  return t;
75
- }, d = (e) => {
75
+ }, p = (e) => {
76
76
  if (e < 0n)
77
77
  throw new Error("nonce must be non-negative");
78
78
  if (e <= 23n) return 1;
@@ -81,11 +81,11 @@ const I = () => {
81
81
  if (e <= 0xffffffffn) return 5;
82
82
  if (e <= _) return 9;
83
83
  throw new Error("nonce range exceeds u64");
84
- }, p = (e) => {
84
+ }, R = (e) => {
85
85
  if (!Number.isInteger(e) || e <= 0 || e > 8)
86
86
  throw new Error("nonceLength must be between 1 and 8");
87
87
  return (1n << BigInt(e * 8)) - 1n;
88
- }, R = (e) => {
88
+ }, U = (e) => {
89
89
  switch (e) {
90
90
  case 1:
91
91
  return 23n;
@@ -111,13 +111,13 @@ const I = () => {
111
111
  const r = [];
112
112
  let i = e;
113
113
  for (; i <= n; ) {
114
- const o = U(i), s = p(o), a = n < s ? n : s, c = a - i + 1n;
114
+ const s = T(i), o = R(s), a = n < o ? n : o, c = a - i + 1n;
115
115
  if (c > BigInt(Number.MAX_SAFE_INTEGER))
116
116
  throw new Error("segment size exceeds safe integer range");
117
117
  if (r.push({
118
118
  start: i,
119
119
  size: Number(c),
120
- nonceLength: o
120
+ nonceLength: s
121
121
  }), a === n)
122
122
  break;
123
123
  i = a + 1n;
@@ -134,13 +134,13 @@ const I = () => {
134
134
  const r = [];
135
135
  let i = e;
136
136
  for (; i <= n; ) {
137
- const o = d(i), s = R(o), a = n < s ? n : s, c = a - i + 1n;
137
+ const s = p(i), o = U(s), a = n < o ? n : o, c = a - i + 1n;
138
138
  if (c > BigInt(Number.MAX_SAFE_INTEGER))
139
139
  throw new Error("segment size exceeds safe integer range");
140
140
  if (r.push({
141
141
  start: i,
142
142
  size: Number(c),
143
- nonceLength: o
143
+ nonceLength: s
144
144
  }), a === n)
145
145
  break;
146
146
  i = a + 1n;
@@ -150,9 +150,9 @@ const I = () => {
150
150
  export {
151
151
  S as Z,
152
152
  B as a,
153
- d as c,
153
+ p as c,
154
154
  D as l,
155
- U as n,
155
+ T as n,
156
156
  y as s
157
157
  };
158
158
  //# sourceMappingURL=nonce.js.map
package/dist/nonce.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"nonce.js","sources":["../src/types.ts","../src/wasm.ts","../src/nonce.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 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 dynamicImport = async <T>(specifier: string): Promise<T> => {\n // Use eval to avoid bundlers rewriting the import path when we intentionally\n // want to fetch from the public /wasm/ directory.\n const importer = (0, eval)(\"s => import(s)\") as (s: string) => Promise<T>;\n return importer(specifier);\n};\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 dynamicImport<WasmExports>(/* @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"],"names":["ZeldMinerErrorCode","origin","wasmModule","wasmInitPromise","webGpuLimitShimInstalled","installWebGpuLimitShim","adapterProto","requestDevice","descriptor","limits","supported","key","ensureTrailingSlash","value","toAbsoluteBase","base","trimmed","resolveWasmBase","globalBase","envBase","__vite_import_meta_env__","viteBase","WASM_BASE_URL","WASM_JS_PATH","WASM_BINARY_PATH","dynamicImport","specifier","formatError","err","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"],"mappings":"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"}
1
+ {"version":3,"file":"nonce.js","sources":["../src/types.ts","../src/wasm.ts","../src/nonce.ts"],"sourcesContent":["export enum ZeldMinerErrorCode {\n INVALID_ADDRESS = \"INVALID_ADDRESS\",\n UNSUPPORTED_ADDRESS_TYPE = \"UNSUPPORTED_ADDRESS_TYPE\",\n INSUFFICIENT_FUNDS = \"INSUFFICIENT_FUNDS\",\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 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 dynamicImport = async <T>(specifier: string): Promise<T> => {\n // Use eval to avoid bundlers rewriting the import path when we intentionally\n // want to fetch from the public /wasm/ directory.\n const importer = (0, eval)(\"s => import(s)\") as (s: string) => Promise<T>;\n return importer(specifier);\n};\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 dynamicImport<WasmExports>(/* @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"],"names":["ZeldMinerErrorCode","origin","wasmModule","wasmInitPromise","webGpuLimitShimInstalled","installWebGpuLimitShim","adapterProto","requestDevice","descriptor","limits","supported","key","ensureTrailingSlash","value","toAbsoluteBase","base","trimmed","resolveWasmBase","globalBase","envBase","__vite_import_meta_env__","viteBase","WASM_BASE_URL","WASM_JS_PATH","WASM_BINARY_PATH","dynamicImport","specifier","formatError","err","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"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "zeldhash-miner",
3
- "version": "0.2.4",
3
+ "version": "0.3.0",
4
4
  "author": "Ouziel Slama <ouziel@gmail.com>",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -28,7 +28,7 @@
28
28
  "type": "git",
29
29
  "url": "https://github.com/zeldhash/zeldhash-miner.git"
30
30
  },
31
- "homepage": "https://github.com/zeldhash/zeldhash-miner",
31
+ "homepage": "https://zeldhash.com",
32
32
  "bugs": {
33
33
  "url": "https://github.com/zeldhash/zeldhash-miner/issues"
34
34
  },
package/wasm/README.md ADDED
@@ -0,0 +1,5 @@
1
+ # zeldhash-miner-wasm
2
+
3
+ WASM bindings for the Zeldhash miner with optional WebGPU acceleration.
4
+
5
+ Learn more at https://zeldhash.com.
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.3",
8
+ "version": "0.3.0",
9
9
  "license": "MIT",
10
10
  "repository": {
11
11
  "type": "git",
@@ -17,7 +17,7 @@
17
17
  "zeldhash_miner_wasm.d.ts"
18
18
  ],
19
19
  "main": "zeldhash_miner_wasm.js",
20
- "homepage": "https://github.com/zeldhash/zeldhash-miner",
20
+ "homepage": "https://zeldhash.com",
21
21
  "types": "zeldhash_miner_wasm.d.ts",
22
22
  "sideEffects": [
23
23
  "./snippets/*"
Binary file