# QuipNetwork/quip-miner: a Python stack for mining a Substrate chain with CPU, GPU and QPU samplers

> quip-miner is the v0.2 mining stack for the quip-protocol-rs Substrate chain. It fetches the chain's mining snapshot, searches for Ising solutions, and submits QuantumPow proofs. The README calls it experimental software and warns there are no production warranties.

**QuipNetwork/quip-miner** — The quip network mining stack. This includes a coordinator and links all of the official quip network miners.

- Repository: https://github.com/QuipNetwork/quip-miner
- Website: https://quip.network/
- Stars: 11,595 · Forks: 162
- Language: Python
- License: AGPL-3.0
- Published: 2026-08-08 · Updated: 2026-08-18 · Language: en
- Canonical page: https://hysenlabs.com/projects/quipnetwork-quip-miner

## What quip-miner is for, and who it is not for

This repository is the coordinator and miner stack for the quip-protocol-rs Substrate chain. The README describes the loop directly: fetch the mining snapshot at each new chain head, search for valid Ising solutions, submit QuantumPow.submit_proof extrinsics, repeat. Three sampler families are wired in: CPU simulated annealing, GPU backends (CUDA, Metal, Modal), and QPU access through D-Wave.

The audience is narrow. You need a running Substrate node, a faucet to fund your account, and a topology registered on chain. The README points at the testing repository at nodes.quip.network for local-network setup, and the dev faucet now lives in its own repository at gitlab.com/quip.network/faucet. If you do not have that chain running, this stack has nothing to attach to.

The v0.2 line is a deliberate subtraction. In v0.1 the codebase shipped its own consensus, QUIC-based P2P, block store, REST API and SPHINCS+ block signer. All of that is gone. The chain is the source of truth and miners attach to it. That is a smaller surface to reason about, and it also means every failure mode of the chain becomes your failure mode.

## How the snapshot, Ising search and proof submission fit together

The README's architecture diagram shows a single read path into the chain over ws://localhost:9944 through a SubstrateClient with three operations: get_mining_snapshot, subscribe_new_heads, and submit_extrinsic. The client is a py-substrate-interface async wrapper, and the snapshot arrives through state_call rather than a custom RPC.

On the Python side, shared/substrate_miner_controller.py owns head subscription, snapshot fetch, dispatch, and receipt classification. shared/miner_core.py owns persistent MinerHandle workers, a hardware descriptor cache and aggregate stats. shared/base_miner.py defines a protocol-neutral mine_work_item(context, stop_event) loop, and shared/miner_worker.py scaffolds a two-process worker with a parent-child mp.Queue plus a stop_event. That two-process shape is worth noting: it means a sampler crash does not necessarily take down the controller.

The math helpers live in shared/quantum_proof_of_work.py: derive_nonce, generate_ising_model_from_nonce, evaluate_sampleset. Nonce derivation uses blake3. Ising sampling pulls dwave-ocean-sdk and numpy. Submission goes through shared/substrate_submitter.py, which encodes a MiningResult into a QuantumProof via SCALE. A separate Cargo workspace at the repository root holds the coordinator side in Rust, with the solver contract consumed from crates.io; the README's Python stack is what the quip-miner CLI drives.

## Installing quip-miner and bootstrapping an account

The README gives a virtualenv install. Creating the venv, upgrading pip, setuptools and wheel, then installing the package in editable mode pulls the dependency set declared in pyproject.toml.

```bash
python3 -m venv .quip
source .quip/bin/activate
pip install -U pip setuptools wheel
pip install -e .
```

Those dependencies include substrate-interface>=1.7.4 and scalecodec>=1.2 for chain RPC and SCALE, dwave-ocean-sdk>=9.0.0,<10 and numpy>=1.24.0 for Ising sampling, aiohttp>=3.9.0 for the telemetry server and faucet, click>=8.1.7 for the CLI, and blake3>=1.0.5 for nonce derivation. D-Wave QPU access requires DWAVE_API_KEY in .env, loaded via python-dotenv.

Bring the chain up first in a separate terminal, then confirm it is producing blocks before pointing the miner at it.

```bash
cd ../quip-protocol-rs
docker compose up -d
docker compose logs -f node1
```

Bootstrap is idempotent: it generates a keystore if missing, requests funds from the faucet, and submits register_miner. The --seed-chain flag additionally sudo-submits set_difficulty and register_topology on a fresh chain.

```bash
quip-miner bootstrap \
    --node-url ws://localhost:9944 \
    --faucet-url http://127.0.0.1:8087 \
    --seed-chain
```

Re-runs are documented as no-ops that verify state. Then start a CPU miner and query its telemetry surface.

```bash
quip-miner cpu \
    --node-url ws://localhost:9944 \
    --num-cpus 4 \
    --topology zephyr:9,2 \
    --rest-port 8086

curl http://localhost:8086/api/v1/status   | jq
curl http://localhost:8086/api/v1/stats    | jq
```

The telemetry envelope is {"success": bool, "data": ..., "error": ..., "timestamp": int}. Passing --rest-port -1 disables the HTTP surface entirely.

## The topology hash check that stops a misconfigured miner at startup

One design choice deserves attention because it decides whether your miner runs at all. Topology binding is enforced at startup: the CLI hashes the configured topology with the same blake2_256(SCALE((sorted_nodes, canonical_edges))) recipe the chain uses, and refuses to start if the hash does not match the chain's registered topology.

That is a strict check, and it is the right kind of strict. A sampler searching a different graph than the chain expects would produce proofs that cannot be accepted, and the failure would look like wasted compute rather than a configuration error. Failing fast at launch converts a silent waste into an immediate message.

The cost is that --topology is not a tuning knob you can vary freely. The default is zephyr:9,2, and bootstrap accepts --seed-topology 9,2 to register it on a fresh chain. If you change the topology on the miner side without registering the matching one on chain, startup fails. The README does not document a way to inspect the chain's registered topology other than through the hash comparison itself.

## Limits: plaintext keys, a disabled solve endpoint, and a missing rollback story

The keystore is the first real limitation. shared/keystore.py writes a 0o600 JSON file, and the README states plainly that the seed is stored in plaintext for dev, with passphrase-encrypted keystores shipping in Phase 7. A file mode of 0o600 is not encryption. Anyone who can read the file as your user owns the signing key. For a local devnet that is acceptable; for anything holding value it is not.

The telemetry API has holes left by the v0.2 rewrite. POST /api/v1/solve is disabled in v0.2, described as having been a direct DWave sample. The legacy /api/v1/peers, /api/v1/join, /api/v1/gossip, /api/v1/heartbeat and POST /api/v1/block paths are removed, and the README says they were P2P or consensus surfaces with no equivalent in substrate mode. The legacy /telemetry/* SSE stream and per-peer aggregator also moved out; the README directs consumers to substrate-side events and Prometheus at http://localhost:9615/metrics. If you have tooling built on those paths, it is broken, not deprecated.

There is also a hardware constraint that is easy to miss. The QPU subcommand adds --qpu-type and --daily-budget, and D-Wave access needs DWAVE_API_KEY. A daily budget flag implies metered access, and the README does not describe what happens when the budget is exhausted. Rollback and recovery after a failed submission are not documented either. The README is silent on both.

## Where quip-miner sits next to a generic Substrate miner

The obvious alternative is to write your own miner against the chain's RPC interface. substrate-interface and scalecodec are public crates and Python packages, and the operations this project uses are ordinary: subscribe to heads, call state_call for the snapshot, submit an extrinsic. A team with Substrate experience could reproduce the read path in a few hundred lines.

What they would then have to build is everything specific to this chain. The Ising model derivation from a nonce, the sampleset evaluation, the QuantumProof SCALE encoding, the topology hash recipe, and the two-process worker scaffolding that isolates a sampler crash from the controller. Those are the parts with no off-the-shelf equivalent. A generic Substrate miner also would not give you the quip-miner CLI's bootstrap pipeline, which chains keystore generation, faucet funding, sudo seeding of Difficulty and DefaultTopology, and register_miner into one idempotent command.

The honest comparison is that quip-miner saves you the chain-specific work and costs you the freedom to structure your own submission path. If you want to run a sampler that is not CPU SA, CUDA, Metal, Modal or D-Wave, you are writing that integration yourself either way.

## Conclusion

Adopt it if you already run the quip-protocol-rs chain locally and want to drive CPU, GPU or D-Wave samplers against the QuantumPow pallet from a single Python CLI. Do not adopt it if you need a stable public network miner, a passphrase-protected keystore, or anything the README does not label experimental. Before running it, verify three things: that the chain's registered topology hash matches your --topology value, that the faucet URL you pass to bootstrap is reachable, and that the chain actually produces blocks at ws://localhost:9944. The README's own warning line, experimental software, no production warranties, is the boundary to respect.

## FAQ

### What is Quip used for?

The README describes quip-miner as a Python mining stack for the quip-protocol-rs Substrate chain. It fetches the mining snapshot at each new chain head, searches for valid Ising solutions, and submits QuantumPow.submit_proof extrinsics.

### Can quantum computers be used to mine Bitcoin?

The README does not discuss Bitcoin. It describes QPU mining against this chain's QuantumPow pallet, with a qpu subcommand that takes --qpu-type and --daily-budget and requires DWAVE_API_KEY in .env for D-Wave access.

### Is Quip a Salesforce product?

The README describes QuipNetwork/quip-miner as a Python mining stack for the quip-protocol-rs Substrate chain, licensed AGPL-3.0, with its homepage at quip.network. Nothing in the README connects it to Salesforce.

## Sources

- [Official documentation](https://quip.network/)
- [Official README](https://github.com/QuipNetwork/quip-miner#readme)
- [Project repository](https://github.com/QuipNetwork/quip-miner)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/quipnetwork-quip-miner
