LuckyHash is a solo BTC miner running entirely in the browser. It leverages GPU compute power via the WebGPU API to perform millions of SHA256d hashes per second, connecting directly to a Bitcoin pool via the Stratum protocol.
┌─────────────────────────────────────────────────────┐ │ BROWSER │ │ │ │ ┌─────────────┐ Stratum/WS ┌─────────────┐ │ │ │ miner.js │ ◄──────────► │ Proxy WS │ │ │ │ │ │ :3030 │ │ │ │ ┌────────┐ │ └──────┬──────┘ │ │ │ │WebGPU │ │ │ Stratum TCP │ │ │ │Compute │ │ ┌──────▼──────┐ │ │ │ │Shader │ │ │ Bitcoin │ │ │ │ │SHA256d │ │ │ Pool │ │ │ │ └────────┘ │ │ :3333 │ │ │ │ ┌────────┐ │ └─────────────┘ │ │ │ │CPU │ │ │ │ │ │Workers │ │ (fallback when no GPU) │ │ │ └────────┘ │ │ │ └─────────────┘ │ └─────────────────────────────────────────────────────┘
The miner opens a WebSocket to luckyhash_proxy. The proxy maintains a
TCP connection to the actual Bitcoin pool. The protocol uses Stratum JSON-RPC:
mining.subscribe → mining.authorize.
mining.notify)
The pool sends a job containing: prevHash, coinb1/coinb2,
merkleBranch, nBits, nTime, version.
The miner assembles the coinbase transaction and computes the Merkle Root via SHA256d.
Header is assembled from: version (4B) + prevHash (32B) + merkleRoot (32B) + nTime (4B) + nBits (4B) + nonce (4B). The nonce is the only field that changes on every attempt.
WebGPU: each GPU thread tries a unique nonce — 65K–4M nonces per batch.
CPU: multiple Web Worker threads split the nonce range.
Formula: hash = SHA256(SHA256(header_80_bytes)).
If hash < target the nonce is valid — the digest is compared as a
little-endian 256-bit integer (Bitcoin's uint256 convention, so a valid
digest has trailing zero bytes; the familiar leading-zero form is the
byte-reversed block-hash display).
The target is derived from nBits and the pool-set difficulty.
At difficulty = 1, the probability of any single hash being valid is ~1/2³².
mining.submit)
Send [worker, jobId, extranonce2, nTime, nonce] to the pool via WebSocket.
The pool responds with true (accepted) or an error (rejected).
If the share meets full network difficulty, it's a valid block — you win!
| GPU | CPU | |
|---|---|---|
| Parallel threads | Thousands | 4–16 |
| Batch/cycle | 4M nonces | Evenly split |
| Requirement | Chrome 113+ | Any browser |
| Shader | WGSL | JavaScript |
luckyhash_proxy runs a WebSocket server (port 3030) and bridges it
to the pool's Stratum TCP server (port 3333). All Stratum messages are forwarded
transparently through the proxy.
| SHA256d | Double SHA-256: SHA256(SHA256(data)) — Bitcoin's proof-of-work hash algorithm |
| Nonce | A 32-bit number iterated continuously to find a valid hash |
| Target | 256-bit threshold the resulting hash must be below to be accepted |
| Difficulty | A scalar that controls how small the target is — higher = harder |
| ExtraNonce | Extra entropy injected into the coinbase to extend the nonce search space |
| Merkle Root | Aggregated hash of all transactions in the block |
| WGSL | WebGPU Shading Language — used to write GPU compute shaders |
The odds of mining a Bitcoin block with consumer hardware are astronomically low — statistically it could take thousands of years. This is an experimental / educational tool, not a money-making application.
Continuous GPU mining can heat your device and significantly increase power draw. Ensure adequate cooling and do not run at full load for extended periods.
This software does not guarantee any financial return. Results depend entirely on luck and your share of the total network hashrate (currently >700 EH/s).
Users are solely responsible for complying with local laws and regulations regarding cryptocurrency mining. The authors accept no liability for any damages arising from the use of this software.
This software is provided "as is" — without warranty of any kind. Intended for educational, research, and WebGPU exploration purposes only.