Releases: zeldhash/zeldhash-miner
Releases · zeldhash/zeldhash-miner
v0.3.2
[0.3.2] - 2026-01-25
Security
RBF Disabled by Default
- Sequence number changed from
0xffff_fffdto0xffff_fffe: This disables Replace-By-Fee (BIP-125) while still allowing relative timelocks (BIP-68) - Prevents wasted mining work: Mined transactions can no longer be replaced before confirmation
- Mitigates double-spend risk: Attackers cannot replace a mined transaction with a higher-fee version
v0.3.1
[0.3.1] - 2026-01-24
Changed
Unified Assets Folder
- Simplified asset distribution: All static assets (WASM + worker) are now bundled in a single
assets/folder. Integration is now a single copy command:cp -r node_modules/zeldhash-miner/assets public/zeldhash-miner - New default path: Asset resolution changed from
/wasm/+/worker.jsto unified/zeldhash-miner/folder - Self-contained worker bundle: Worker is now built as a standalone bundle with no shared chunks, eliminating the need to copy additional files like
nonce.js
Added
Composer Mode
targetZeros: 0now accepted: Allows transaction construction without mining, useful for testing or pre-composing transactions before actual mining
Documentation
- Rewrote
INTEGRATION.mdwith simplified setup instructions - Updated all framework examples (Vite, Next.js, CRA) to use the new asset structure
v0.3.0
[0.3.0] - 2026-01-11
Changed
Optional Change Output (Breaking)
- Change output is now optional: Transactions can be built without a change output, enabling wallet sweep use cases
TransactionPlan.change_indexis nowOption<usize>instead ofusize—Nonewhen no change output is present
Automatic Dust Change Handling
- Dust change is automatically omitted: When change would fall below the dust limit (310 sats P2WPKH / 330 sats P2TR), the change output is removed and the extra sats are counted as miner fees
calculate_change()now returnsResult<Option<u64>, FeeError>:Ok(Some(amount))when change is above dust limitOk(None)when change would be dust (caller should omit the change output)Err(InsufficientFunds)when inputs can't cover outputs + fees
- When a ZELD distribution is provided and change is omitted, the distribution array is automatically adjusted to match the final output count
Removed
Error Codes (Breaking)
FeeError::DustOutputremoved — dust change is now handled gracefully instead of erroringMinerError::MissingChangeOutputremoved — change output is no longer required- TypeScript:
ZeldMinerErrorCode.NO_CHANGE_OUTPUTremoved
Fixed
- Updated homepage URLs to
https://zeldhash.comacross all crates and packages
Migration Guide
Rust:
// Before (0.2.x)
let change_index: usize = plan.change_index;
// After (0.3.0)
match plan.change_index {
Some(idx) => { /* change output at idx */ }
None => { /* no change output (dust or sweep) */ }
}TypeScript:
// Before (0.2.x) — required exactly one change output
outputs: [
{ address: userAddr, amount: 60000, change: false },
{ address: changeAddr, change: true }, // required
]
// After (0.3.0) — change is optional; if provided but dust, it's omitted
outputs: [
{ address: userAddr, amount: 60000, change: false },
// No change output = sweep entire balance minus fees
]v0.2.5
[0.2.5] - 2025-12-28
Fixed
Web Demo
- Fixed worker loading error in dev mode: Added Vite plugin to redirect
/worker.jsrequests to the worker entry point, and created a worker shim (src/worker.ts) that imports the library's worker module. Previously, theMiningCoordinatortried to load/worker.jswhich didn't exist, causing "MIME type text/html" errors - Fixed worker output in production build: Added Rollup configuration to generate
worker.jsat the root of the dist folder for proper resolution
v0.2.4
[0.2.4] - 2025-12-28
Fixed
TypeScript SDK
- Fixed missing
worker.jsin npm package: The build now generatesdist/worker.jsas a separate entry point. Previously, onlydist/index.jswas built, causing consumer scripts (likezeldwallet-setup) to fail when trying to copy the worker file
v0.2.3
[0.2.3] - 2025-12-28
Fixed
TypeScript SDK
- Fixed worker URL resolution for bundlers: Worker URL now resolves via
location.origin(orself.location.originin worker contexts) before falling back toimport.meta.url, ensuring correct paths when hosted applications use bundlers - Fixed WASM dynamic import for bundlers: WASM module is now loaded via runtime
eval-based dynamic import to prevent bundlers (Vite, Webpack, etc.) from rewriting the import path, ensuring the WASM is fetched from the public/wasm/directory
v0.2.2
[0.2.2] - 2025-12-28
Fixed
TypeScript SDK
- Fixed WASM loading in Vite dev mode: Added automatic bootstrap that sets
globalThis.__ZELDMINER_WASM_BASE__to/wasm/on the application's origin, preventing 404 errors when loading WASM fromnode_modules. Both the main bundle and worker now resolve WASM paths relative to the host application instead ofimport.meta.url
v0.2.1
[0.2.1] - 2025-12-28
Fixed
TypeScript SDK
- Fixed Vite
baseconfig to use relative paths ("./") so worker and script URLs stay relative in the published npm build
v0.2.0
[0.2.0] - 2025-12-27
Changed
Output Ordering (Breaking)
- Stable output order: Non-OP_RETURN outputs now preserve the exact order provided by the caller, including the change output at its specified position
- OP_RETURN always last: The OP_RETURN output is always appended as the final output in the transaction
TransactionPlanrefactored: Replaceduser_outputs+change_outputwith a unifiedoutputsarray andchange_indexfield
Migration: If you relied on the previous ordering (user outputs → OP_RETURN → change), update your code to expect the new order (caller-specified outputs → OP_RETURN). The change output is now at the index you specified, not always last.
Fixed
WASM Module
- Fixed deprecated
init()call syntax in TypeScript SDK — now passes{ module_or_path: url }object instead of URL directly - Build script now strips wasm-bindgen deprecation warnings from generated JS glue code
Release Scripts
- Fixed
release-crate.sharray parsing with properread -rasyntax - Added crate existence check to skip already published versions on crates.io
- Fixed
tomllib.load()to use binary file mode (Python 3.11+ compliance) - Fixed
release-npm.shNode.js heredoc syntax for cross-platform compatibility - Added
User-Agentheader to crates.io API requests (required by their rate limiting)
CI/CD
- Release workflow now triggers on GitHub release publish events
- Added
environment: defaultfor proper secrets access
Documentation
- Updated README with stable output ordering behavior
- Updated
ARCHITECTURE.mdwith newTransactionPlanstructure
v0.1.0
[0.1.0] - 2024-12-25
Added
Core Mining Engine
- Bitcoin vanity transaction miner that finds txids with leading zero hex digits
- Double-SHA256 hash computation with configurable difficulty target (0-32 leading zeros)
- Nonce iteration via
OP_RETURNoutput modification - Mining template system with prefix/suffix splitting for efficient batch processing
- Minimal big-endian nonce encoding with automatic segment splitting at byte boundaries
Transaction Construction
- SegWit support for P2WPKH and P2TR (Taproot) addresses
- Bech32/Bech32m address parsing and validation
- PSBT generation with
WITNESS_UTXOfor wallet signing - Virtual size (vsize) and fee estimation with configurable sats/vbyte
- Dust limit enforcement (310 sats for P2WPKH, 330 sats for P2TR)
- RBF-enabled transactions (default sequence
0xFFFFFFFD)
ZELD Distribution
- Optional CBOR-encoded distribution array in
OP_RETURN - Format:
OP_RETURN | "ZELD" | CBOR([distribution..., nonce]) - CBOR nonce encoding following RFC 8949
Multi-Platform Support
- Rust SDK (
zeldhash-minercrate) with CPU and optional GPU backends - TypeScript SDK (
zeldhash-minernpm package) with WebAssembly bindings no_stdcompatible core library (zeldhash-miner-core) using onlyalloc
CPU Parallelization
- Multi-threaded mining with Rayon (Rust native)
- Web Workers support for browser environments (TypeScript SDK)
- Stride-based work distribution across workers
- Atomic early termination when a match is found
GPU Acceleration
- WebGPU compute shaders (WGSL) for parallel hash computation
- 256-thread workgroups with automatic batch size tuning
- Buffer pooling and template caching for performance
- Graceful fallback to CPU when GPU is unavailable
Control Flow
- Pause/resume/stop controls for mining operations
- Progress callbacks with hash rate and elapsed time
- Event emitter pattern in TypeScript SDK (
on('progress'),on('found'), etc.)
Developer Experience
- Comprehensive error handling with typed error codes
- Optional
serdesupport for Rust types - Full API documentation in SDK READMEs
- Web demo application (Vite-based)
Architecture
zeldhash-miner/
├── crates/
│ ├── core/ # no_std algorithms (hash, tx, psbt, fees, nonce)
│ ├── gpu/ # WebGPU backend with WGSL shaders
│ ├── wasm/ # wasm-bindgen bindings
│ └── python-core/ # Placeholder for future pyo3 wheel
├── facades/
│ ├── rust/ # crates.io SDK
│ └── typescript/ # npm SDK + WASM artifacts
└── examples/
└── web-demo/ # Browser demo application
Performance
| Backend | Typical Hash Rate |
|---|---|
| CPU (single core) | 200-500 KH/s |
| CPU (8 cores) | 1-3 MH/s |
| Integrated GPU | 5-20 MH/s |
| Discrete GPU | 50-200+ MH/s |
Security
- Produces unsigned PSBTs only — no private keys handled
- Input validation for addresses, amounts, and script lengths
- Deterministic outputs for reproducible builds
- GPU shaders run in browser sandbox