From 561a0ca0d0206a0bda8ef5f77b0c35f021191c8c Mon Sep 17 00:00:00 2001 From: bubbapang Date: Thu, 3 Sep 2026 15:04:56 +0800 Subject: [PATCH] Build verified one-command mining onboarding Pin one supported Planck node and miner pair in a machine-readable compatibility manifest. Verify release checksums before installation, keep wallet recovery input local, add clear status and restart checks, and publish direct desktop preview downloads with platform verification commands. Add automated compatibility, checksum, redaction, command, and documentation tests. --- bun.lock | 5 + docs/guides/miner-app.md | 80 ++-- docs/guides/mining.md | 309 ++++---------- package.json | 3 + src/components/DocActionButtons/index.tsx | 26 +- static/mining-compatibility.json | 42 ++ static/scripts/quantus-mining.sh | 477 ++++++++++++++-------- static/scripts/quantus-mining.sh.sha256 | 1 + static/skills/mining-skill.md | 330 ++------------- tests/mining-onboarding.test.ts | 202 +++++++++ 10 files changed, 739 insertions(+), 736 deletions(-) create mode 100644 static/mining-compatibility.json create mode 100644 static/scripts/quantus-mining.sh.sha256 create mode 100644 tests/mining-onboarding.test.ts diff --git a/bun.lock b/bun.lock index 83f8645..4d75164 100644 --- a/bun.lock +++ b/bun.lock @@ -22,6 +22,7 @@ "@docusaurus/module-type-aliases": "^3.10.2", "@docusaurus/tsconfig": "^3.10.2", "@docusaurus/types": "^3.10.2", + "@types/bun": "^1.4.0", "typescript": "~5.6.2", }, }, @@ -742,6 +743,8 @@ "@types/bonjour": ["@types/bonjour@3.5.13", "", { "dependencies": { "@types/node": "*" } }, "sha512-z9fJ5Im06zvUL548KvYNecEVlA7cVDkGUi6kZusb04mpyEFKCIZJvloCcmpmLaIahDpOQGHaHmG6imtPMmPXGQ=="], + "@types/bun": ["@types/bun@1.4.0", "", { "dependencies": { "bun-types": "1.4.0" } }, "sha512-K+lZULY23vRgK/CfTjFIV+tyifaNdSMlPh9j+6mQ/cLfpOznLyAuzgV/JQysyECpkBQLVMSyvjlr2fBUSA9wFQ=="], + "@types/connect": ["@types/connect@3.4.38", "", { "dependencies": { "@types/node": "*" } }, "sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug=="], "@types/connect-history-api-fallback": ["@types/connect-history-api-fallback@1.5.4", "", { "dependencies": { "@types/express-serve-static-core": "*", "@types/node": "*" } }, "sha512-n6Cr2xS1h4uAulPRdlw6Jl6s1oG8KrVilPN2yUITEs+K48EzMJJ3W1xy8K5eWuFvjp3R74AOIGSmp2UfBJ8HFw=="], @@ -1016,6 +1019,8 @@ "buffer-from": ["buffer-from@1.1.2", "", {}, "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ=="], + "bun-types": ["bun-types@1.4.0", "", { "dependencies": { "@types/node": "*" } }, "sha512-iIKw23BspnQQYd3prITOBxeUsxBHnwzX6YJfGMuNOZzeNcMmVqzIIVGRm1l69ogaPQmb4wB6BN8mA5bE9YuC5Q=="], + "bundle-name": ["bundle-name@4.1.0", "", { "dependencies": { "run-applescript": "^7.0.0" } }, "sha512-tjwM5exMg6BGRI+kNmTntNsvdZS1X8BFYS6tnJ2hdH0kVxM6/eVZ2xy+FqStSWvYmtfFMDLIxurorHwDKfDz5Q=="], "bytes": ["bytes@3.0.0", "", {}, "sha512-pMhOfFDPiv9t5jjIXkHosWmkSyQbvsgEVNkz0ERHbuLh2T/7j4Mqqpz523Fe8MVY89KC6Sh/QfS2sM+SjgFDcw=="], diff --git a/docs/guides/miner-app.md b/docs/guides/miner-app.md index 593c330..95784aa 100644 --- a/docs/guides/miner-app.md +++ b/docs/guides/miner-app.md @@ -1,55 +1,71 @@ --- sidebar_position: 2 -title: Miner App (GUI) -draft: true +title: Miner App Preview --- -# Miner App +# Miner App Preview -The Quantus Miner App is the easiest way to start mining. It provides a graphical interface for both CPU and GPU mining -- no terminal required. +The Quantus Miner App provides one desktop interface for wallet setup, node sync, CPU or GPU mining, hash rate, and rewards. Release `miner-v0.6.1` is a **preview**, not the verified beginner path. -## Download +The app downloads and starts node and miner binaries at runtime. It does not bundle them, pin the shared compatibility manifest, or verify their release checksums in this release. Use a dedicated Planck testnet wallet and do not use the app for assets with monetary value. -Download the latest Miner App for your platform from [GitHub Releases](https://github.com/Quantus-Network/quantus-apps/releases/latest): +## Direct downloads -| Platform | File | -|----------|------| -| macOS (Intel / Apple Silicon) | `quantus_miner_macos.zip` | -| Linux (x64) | `quantus_miner_linux.tar.gz` | -| Windows (x64) | `quantus_miner_windows.zip` | +| Platform | Download | SHA-256 | +| --- | --- | --- | +| Windows x64 | [quantus_miner_windows.zip](https://github.com/Quantus-Network/quantus-apps/releases/download/miner-v0.6.1/quantus_miner_windows.zip) | `081308152ba6f9eba62b9ac143f8c9e115ffab400a978a9d03a996e55ece8ad1` | +| macOS | [quantus_miner_macos.zip](https://github.com/Quantus-Network/quantus-apps/releases/download/miner-v0.6.1/quantus_miner_macos.zip) | `fb4769d4c1e8ccd3c480e0caeca07c9baa2b3ef0540828894dddeea3d4ed016e` | +| Linux x64 | [quantus_miner_linux.tar.gz](https://github.com/Quantus-Network/quantus-apps/releases/download/miner-v0.6.1/quantus_miner_linux.tar.gz) | `fd2755f2fe5df05af3deb8e1081fa808f6c872bd9d4bf2853eea0fe354655076` | -## Prerequisites +These URLs and hashes are also recorded in the [compatibility manifest](/mining-compatibility.json). -Before you start mining, you need: +Verify the downloaded archive before opening it. -1. A Quantus wallet address to receive rewards. Download the Quantus mobile wallet from [quantus.com/wallet](https://www.quantus.com/wallet/) and create an account. +### Windows PowerShell -## Installation +```powershell +(Get-FileHash .\quantus_miner_windows.zip -Algorithm SHA256).Hash.ToLower() +# Expected: 081308152ba6f9eba62b9ac143f8c9e115ffab400a978a9d03a996e55ece8ad1 +``` -**macOS:** Download the `.zip` file, extract it into your desired directory, and run `Quantus Miner.app`. If macOS blocks the app, go to System Settings > Privacy & Security and click "Open Anyway." +### macOS Terminal -**Linux:** Download the `.tar.gz` file, extract it into your desired directory, and run the `quantus_miner` executable. +```bash +shasum -a 256 quantus_miner_macos.zip +# Expected: fb4769d4c1e8ccd3c480e0caeca07c9baa2b3ef0540828894dddeea3d4ed016e +``` -## Note on Syncing -Once you input your inner hash (or seed phrase) you can begin syncing your node. +### Linux Terminal -Wait until the node is fully synced, and then begin mining. +```bash +sha256sum quantus_miner_linux.tar.gz +# Expected: fd2755f2fe5df05af3deb8e1081fa808f6c872bd9d4bf2853eea0fe354655076 +``` -Depending on your internet speed it may take 5-30 minutes for the node to full sync. +## Install -## Monitoring +### Windows -Check your mining progress on the [telemetry dashboard](https://telemetry.quantus.cat/). +1. Download and extract `quantus_miner_windows.zip`. +2. Open the extracted folder and run `quantus_miner.exe`. +3. If Windows Defender warns, verify the SHA-256 above before choosing to run it. -## Troubleshooting +### macOS -| Problem | Solution | -|---------|----------| -| macOS blocks the app | System Settings > Privacy & Security > "Open Anyway" | -| App won't connect | Make sure your Quantus node is running first | -| Low hash rate | Increase CPU workers or enable GPU mining in settings | -| Mining not producing blocks | Verify your node is fully synced before mining | +1. Download and extract `quantus_miner_macos.zip`. +2. Open `Quantus Miner.app`. +3. If macOS blocks it, open System Settings, Privacy & Security, then choose Open Anyway. -## Next Steps +### Linux x64 -For advanced mining configuration (external miner, build from source), see the full [Mining and Running a Node](./mining) guide. +1. Download and extract `quantus_miner_linux.tar.gz`. +2. Mark `quantus_miner` executable with `chmod u+x quantus_miner`. +3. Run `./quantus_miner`. + +The release does not publish minimum OS versions. The release team must supply those facts before the app can be presented as universally supported. + +## What the app handles + +The app downloads the node and external miner, creates the local node identity, starts both processes, monitors sync, and shows mining statistics. A recovery phrase entered into the app is handled locally by its wallet flow. + +The app is ready to become the primary route after it consumes the shared compatibility manifest, verifies every runtime download, and avoids exposing reward material in logs or process arguments. Until then, use the [verified terminal guide](/guides/mining) where supported. diff --git a/docs/guides/mining.md b/docs/guides/mining.md index 67f110e..5cef359 100644 --- a/docs/guides/mining.md +++ b/docs/guides/mining.md @@ -1,284 +1,113 @@ --- sidebar_position: 1 -title: Mining and Running a Node +title: Start Mining --- -# Mining and Running a Node +# Start Mining -This guide covers connecting to the Quantus Planck testnet and mining. Works on macOS and Linux (including WSL2 on Windows). +This guide connects a computer to the **Planck testnet** and starts the supported Quantus node and miner pair. Planck tokens have no monetary value and the network may reset. -Use the **Copy Context** button at the top of this page to copy everything as Markdown -- the full guide plus an AI mining skill. Paste it to an agent like Claude Code to be walked through setup interactively, or keep it as an offline reference. +## Before you start -## Prerequisites +You need a Quantus wallet with its 24-word recovery phrase. Keep that phrase offline. Never paste it into chat, email, a support ticket, or a command. -Before starting, you will need: +The verified script supports macOS, Linux x64, and WSL2 on Windows. Native Windows users can review the [desktop Miner App preview](/guides/miner-app). -1. **Quantus wallet.** Download the [Quantus wallet](https://linktr.ee/quantusnetwork) to hold funds, send transactions, and spend your mining rewards. +## Three steps -2. **A mnemonic / seed phrase.** You can create one in the wallet app or in the CLI. +### 1. Open Terminal -3. **A wormhole address for rewards.** The chain only accumulates mining rewards to **wormhole addresses** -- not regular wallet addresses. The wallet app supports wormhole addresses and encrypted accounts, so rewards mined to your wormhole address show up in the app and can be spent directly from your wormhole balance -- no separate claiming step. You'll generate your wormhole address in the setup below. +On Windows, open an Ubuntu WSL2 terminal. On macOS or Linux, open Terminal. -## Understanding Wormhole Addresses +### 2. Run the verified installer -Mining rewards are sent to a **wormhole address** derived from a 32-byte preimage you generate during setup (aka your inner hash). - -This is privacy-preserving by default. All mining rewards are paid to wormhole addresses. - -Wormhole addresses look identical to regular transparent addresses, but they have a separate derivation path. - -**If you already have an existing wallet:** You can derive a wormhole keypair from an existing mnemonic or seed instead of generating a fresh one. This is the recommended approach if you are mining for the first time -- use the same seed phrase as your wallet app, and your mining rewards will appear in the app automatically, spendable straight from your wormhole balance. - -During setup you will run `key quantus --scheme wormhole`, which outputs three values: - -| Value | What it is | What to do | -|-------|-----------|------------| -| **Address** | Your wormhole address (where rewards are sent) | Note for monitoring | -| **Inner Hash** | 32-byte preimage | Pass to the node via `--rewards-inner-hash` | -| **Secret phrase** | The mnemonic that proves ownership | Back up securely -- this recovers everything | - -The node derives your wormhole address from the `inner_hash` and logs it on startup. - -The most important thing to back up is your 24 word phrase. - -You should keep both your 24 word phrase and your secret secure and do not share either with anyone. - ---- - -## Automated Setup - -For a guided terminal workflow, use the mining setup script (macOS, Linux, or WSL2): - -```bash -curl -fsSL https://docs.quantus.com/scripts/quantus-mining.sh -o quantus-mining.sh -chmod +x quantus-mining.sh -./quantus-mining.sh setup -./quantus-mining.sh start -``` - -The script generates your wormhole inner hash, node identity, and a config file at `~/quantus-mining/mining.conf`. It downloads native `quantus-node` and `quantus-miner` binaries into `~/quantus-mining/bin/`. GPU mining is recommended; the miner runs on the host so it can use Metal / Vulkan / DirectX. - -The script checks the downloaded pair's `--help` output and only passes auth/TLS flags when **both** binaries support miner QUIC auth (`quantus-miner/2`). Mixing an auth-capable node with a pre-auth miner (or the reverse) is rejected. Pin a matching pair with `NODE_VERSION` / `MINER_VERSION` in `mining.conf` (or `./quantus-mining.sh config set NODE_VERSION `), then run `./quantus-mining.sh setup --force` to download those tags. Environment variables of the same name override the file. Unset pins fetch GitHub `releases/latest` independently and may not match. - -**Linux ARM64:** there is no native `quantus-miner` release. Mine from macOS or Linux x86_64. - -If an older installer created a Docker stack under `~/quantus-mining/docker/`, `./quantus-mining.sh stop` and `uninstall` still shut it down. New Docker setup is not supported (`setup --mode docker` is rejected). After stopping, migrate with `./quantus-mining.sh setup --force`. - -### Running the stack - -**One terminal:** `./quantus-mining.sh start` - -Node output in your terminal (foreground); miner runs in the background (`~/quantus-mining/logs/miner.log`). Ctrl+C stops both. - -**Two terminals (matches the manual steps below):** run `./quantus-mining.sh start-node` in one terminal, then `./quantus-mining.sh start-miner` in another after the node is listening. - -Add `-d` or `--detach` to run both in the background. Stop with `./quantus-mining.sh stop` from any terminal (works for foreground and detached runs). - -Manage settings with `./quantus-mining.sh config show` or `./quantus-mining.sh config set CPU_WORKERS 4`. Editable keys: `NODE_NAME`, `CPU_WORKERS`, `GPU_DEVICES`, `MINER_LISTEN_PORT`, `CHAIN`, `NODE_VERSION`, `MINER_VERSION`. Changing version pins does not swap binaries until you re-run `setup --force`. - -GPU mining is recommended when available. Mining rewards accumulate at your wormhole address and appear in the wallet app, ready to spend. - -The script wires miner authentication when the downloaded pair supports it: after the node starts it reads `miner-auth-token` and `miner-tls-cert-sha256` from the node's chain directory and passes them to the miner. You do not need to copy those values by hand. If the pair predates miner auth, the script starts without those flags. - -Example config template: [mining.conf.example](/scripts/mining.conf.example). - -## Manual Installation (Mac / Linux) - -### 1. Download the Node Binary - -Get a `quantus-node` binary that matches your miner from [GitHub Releases](https://github.com/Quantus-Network/chain/releases). Do not mix `chain/releases/latest` with an unrelated `quantus-miner` latest tag — they are published independently and may not speak the same miner protocol. - -Download it in your working directory. - -Extract it into your working directory (on macOS, double-clicking the archive works). - -Note: `aarch64-apple` builds are for Apple Silicon Macs (M1 and above); `x86-apple` is for Intel-based Macs. - -Now open your terminal to generate your node key and inner hash, and run the node in this terminal window. - -**macOS only -- fix Gatekeeper permissions:** - -```bash -xattr -d com.apple.quarantine quantus-node -chmod u+x quantus-node -``` - -### 2. Generate Node Identity - -```bash -./quantus-node key generate-node-key --file node_key.p2p -``` - -### 3. Generate Inner Hash -Have the 24 word secret phrase from your wallet app ready. - -**Note: Keep this secret phrase secure and do not share it with anyone. It is used to access your rewards, move funds, and derive any information you need in the future.** - -Run the command below. It prompts for your 24 words and reads them **without echoing** -- the phrase is never passed on the command line, so it stays out of your shell history. - -Save the `Inner Hash` from the output: - -```sh -./quantus-node key quantus --scheme wormhole --words -``` - -Alternatively, to generate a fresh wallet separate from the one in your wallet app: +This downloads the script to disk, verifies its SHA-256 checksum, and only then runs it. It does not pipe remote code into a shell. ```bash -./quantus-node key quantus --scheme wormhole +curl --proto '=https' --tlsv1.2 -fsS https://docs.quantus.com/scripts/quantus-mining.sh -o quantus-mining.sh && \ +curl --proto '=https' --tlsv1.2 -fsS https://docs.quantus.com/scripts/quantus-mining.sh.sha256 -o quantus-mining.sh.sha256 && \ +{ if command -v sha256sum >/dev/null 2>&1; then sha256sum -c quantus-mining.sh.sha256; else shasum -a 256 -c quantus-mining.sh.sha256; fi; } && \ +chmod u+x quantus-mining.sh && ./quantus-mining.sh mine ``` -Copy the words from the output -- that is your secret phrase. - -**Note: Save this secret phrase securely and do not share with anyone. It is used to access your rewards, move funds, and derive any information you need in the future.** - - -### 4. Start the Node - -Replace the two placeholders before running: - -- `` -- any name you like (this is how your node appears on [telemetry](https://telemetry.quantus.cat/)) -- `` -- the `inner_hash` value from step 3 - -`node_key.p2p` is the file generated in step 2. - -```bash -./quantus-node \ - --name \ - --validator \ - --miner-listen-port 9833 \ - --chain planck \ - --node-key-file node_key.p2p \ - --rewards-inner-hash \ - --max-blocks-per-request 64 \ - --sync full -``` -#### Note on Syncing -Once you begin syncing your node, wait until the node is fully synced before you begin mining. Blocks mined before your node reaches the chain tip are orphans and earn nothing (the miner pauses automatically if your node has no peers). - -Sync time grows with the chain: expect anywhere from ~15 minutes to a couple of hours depending on your hardware and connection. Your node is synced when the log switches from `Syncing` to `Idle` at the current tip. - -**Run the node version that matches the network.** If your node stalls mid-sync with `Verification failed` errors and drops to 0 peers, your node version is out of step with the network -- check [Releases](https://github.com/Quantus-Network/chain/releases) and community announcements for which version the network is currently running. - -On first start with `--miner-listen-port`, the node writes miner auth material under the chain directory (token is **not** logged -- read the file): - -| File | Purpose | -|------|---------| -| `miner-auth-token` | Shared secret the miner sends in `Ready`. Mode `0600`. Never put this on the command line or in logs. | -| `miner-tls-cert-sha256` | SHA-256 of the miner QUIC cert. Miners must pin this. Also printed in node logs. | -| `miner-tls-cert.der` / `miner-tls-key.der` | Node TLS material (do not copy the private key to miners). | +The installer selects the published pair from the [compatibility manifest](/mining-compatibility.json): node `v0.10.0`, miner `v4.0.2`, and protocol `quantus-miner/2`. It verifies every release asset before installation. There are no version or network choices. -Default chain directory: +### 3. Enter your recovery phrase locally -| Platform | Path | -|----------|------| -| Linux | `~/.local/share/quantus-node/chains/planck/` | -| macOS | `~/Library/Application Support/quantus-node/chains/planck/` | +The prompt is hidden. The phrase is used locally to derive your wormhole reward address, then discarded. It is not saved, logged, sent over the network, or placed in command history. -Wait until logs show the miner server is listening (and the auth/TLS file paths) before starting the miner. If miner-server startup fails, the node exits -- it does not fall back to local mining. +The installer names the node, detects a conservative CPU or GPU configuration, starts both processes, and prints status. Initial chain sync can take from minutes to hours and does not count as hands-on setup time. -### 5. Start the Miner +## Know when it works -Download the miner binary from [Miner Releases](https://github.com/Quantus-Network/quantus-miner/releases). Node and miner versions must be a matching pair: the authenticated wire protocol ALPN is `quantus-miner/2`. Confirm `quantus-node --help` lists `--miner-auth-token-file` and `quantus-miner serve --help` lists `--auth-token-file` before using the commands below. A mismatched pair fails at TLS handshake with "no application protocol". Older releases (node v0.9.0, miner v3.3.1 and earlier) do not include miner auth — omit the auth/TLS flags and connect with `--node-addr` only. - -**Open a new terminal window (cmd + t). Let the node run in the original terminal.** - -**macOS only:** - -```bash -xattr -d com.apple.quarantine quantus-miner-macos-aarch64 && chmod u+x quantus-miner-macos-aarch64 -``` - -Wait for the node logs to show the miner server is listening, then run the following in the **separate terminal**. Quote `CHAIN_DIR` — the macOS path contains a space. If not on Apple Silicon, replace `quantus-miner-macos-aarch64` with your platform's binary name. +Run: ```bash -CHAIN_DIR="$HOME/Library/Application Support/quantus-node/chains/planck" -# Linux: CHAIN_DIR="$HOME/.local/share/quantus-node/chains/planck" - -./quantus-miner-macos-aarch64 serve \ - --cpu-workers 4 \ - --gpu-devices 0 \ - --node-addr 127.0.0.1:9833 \ - --auth-token-file "$CHAIN_DIR/miner-auth-token" \ - --tls-cert-sha256-file "$CHAIN_DIR/miner-tls-cert-sha256" +./quantus-mining.sh status ``` -Prefer `--auth-token-file` / `--tls-cert-sha256-file` over inline `--auth-token` / `--tls-cert-sha256` so the secret is not stored in shell history. When the node/miner pair includes miner auth, both flags are required; a wrong token or TLS pin is a permanent error (the miner will not reconnect-loop). On pre-auth releases, omit those flags. +A complete success state shows: -Depending on your machine and resources you can adjust `--gpu-devices` and `--cpu-workers` to see what provides the best balance of hash rate and system usability. +| Field | Ready value | +| --- | --- | +| Network | `Planck testnet` | +| Compatibility | node `v0.10.0` + miner `v4.0.2` | +| Node | `Running` | +| Sync | `Synced` | +| Miner | `Running` | +| Hash rate | a live rate from the miner | +| Reward address | your public wormhole address | +| Telemetry | your node name at [telemetry.quantus.cat](https://telemetry.quantus.cat/) | -The above command is fairly conservative for most modern hardware. - -For example if you want to use your GPU and have many CPU cores available you could run +Confirm stop-start recovery once: ```bash -CHAIN_DIR="$HOME/Library/Application Support/quantus-node/chains/planck" -# Linux: CHAIN_DIR="$HOME/.local/share/quantus-node/chains/planck" - -./quantus-miner-macos-aarch64 serve \ - --cpu-workers 8 \ - --gpu-devices 1 \ - --node-addr 127.0.0.1:9833 \ - --auth-token-file "$CHAIN_DIR/miner-auth-token" \ - --tls-cert-sha256-file "$CHAIN_DIR/miner-tls-cert-sha256" +./quantus-mining.sh restart-check ``` -If the miner exits immediately, it is usually auth or version mismatch: confirm both files exist, that you waited for the miner server to listen, and that node and miner releases match (`quantus-miner/2`). A wrong token or TLS pin is a permanent error -- re-read the files (the token is never logged). - -## Monitoring +## Daily commands -### Your Rewards +| Goal | Command | +| --- | --- | +| Start or resume | `./quantus-mining.sh mine` | +| Check readiness | `./quantus-mining.sh status` | +| Stop | `./quantus-mining.sh stop` | +| Reinstall the supported pair | `./quantus-mining.sh setup --force` | +| Change resource use | `./quantus-mining.sh config set CPU_WORKERS 4` | -Rewards accumulate at your wormhole address as you mine. The wallet app supports wormhole addresses and encrypted accounts, so if you mine with the same seed phrase as your app wallet, rewards appear in the app and are spendable directly from your wormhole balance -- there is no separate claiming step. +## Security boundary -### Monitoring Your Node -- **Telemetry dashboard:** [telemetry.quantus.cat](https://telemetry.quantus.cat/) -- find your node by name -- **Prometheus metrics (detailed node metrics):** `http://localhost:9615/metrics` -- **RPC endpoint:** `http://localhost:9944` -- **Check your address in the explorer:** Your wormhole address is in the `Address` field from key generation, or in your node's startup logs. +- Only port `30333` should be public for peer-to-peer networking. +- Keep miner `9833/UDP`, RPC `9944`, and metrics `9615` private and local. +- The miner reads its auth token and TLS pin from local files. Do not paste either value into chat or command arguments. +- The recovery phrase is entered only into the hidden local prompt. +- The reward preimage is stored locally with owner-only permissions because the current node requires it at startup. +- `status` redacts 64-character secret-like values from log excerpts. +- The installer refuses unsupported networks, protocols, release URLs, assets, and checksums. +## Compatibility policy +The machine-readable [compatibility manifest](/mining-compatibility.json) is the release source of truth. The current pair is grounded in the `v4.0.0` miner release note, which requires node `v0.10.0+`. The installer does not resolve independent `latest` releases. -### **Logs & Diagnostics** +The manifest currently publishes minimum OS versions as `not-published`. That is an owner fact still needed from the release team. It does not claim a launch date, mainnet support, or rewards with monetary value. -```bash -# Linux -tail -f ~/.local/share/quantus-node/chains/planck/network/quantus-node.log +## One-copy AI prompt -# macOS -tail -f ~/Library/Application\ Support/quantus-node/chains/planck/network/quantus-node.log - -# Or run with verbose logging -RUST_LOG=info ./quantus-node [options] +```text +Help me start Quantus Planck testnet mining on this computer using https://docs.quantus.com/guides/mining and its compatibility manifest. Use the verified quantus-mining.sh flow and do not choose versions independently. Never ask me to paste, upload, reveal, or store my recovery phrase, private key, reward preimage, miner auth token, or TLS material in chat, command arguments, logs, telemetry, or a repository. Pause while I enter recovery words locally into the hidden prompt. Keep miner, RPC, and metrics ports private. Do not switch networks or claim monetary rewards. Finish only when status shows the network, supported pair, sync state, Mining state, hash rate, reward address, telemetry route, and a passed restart check. ``` -#### **Inspect your node's P2P identity:** - -```bash -./quantus-node key inspect-node-key --file node_key.p2p -``` - -## Security Best Practices - -### Key Management - -- **Back up your seed phrase securely** - -### Node Security - -- **Firewall:** Only expose port 30333 (P2P). Keep 9833/UDP (miner), 9944 (RPC), and 9615 (metrics) on localhost. The miner port binds `0.0.0.0` -- reachability is entirely your firewall. Auth + TLS pinning do **not** make it safe to publish to the internet. -- **Miner secrets:** Treat `miner-auth-token` like a password. Back it up with the same care as other node files; anyone with the token and network access to port 9833 can submit job results and observe mining jobs. -- **Remote miners:** Put node and miners on a private network or VPN (WireGuard, Tailscale, VPC). Do not open 9833/UDP to `0.0.0.0/0`. -- **Updates:** Check [GitHub Releases](https://github.com/Quantus-Network/chain/releases/latest) for new versions regularly. Node and miner must ship the same miner protocol (`quantus-miner/2`). -- **Monitoring:** Watch for unusual peer counts, sync stalls, or dropped miner connections - -### Testnet Disclaimer - -Planck is testnet software for testing purposes only. Tokens have no monetary value. The network may be reset periodically, and breaking changes are expected between releases. - +## Fix one problem at a time -### Getting Help +| Problem | One recovery action | +| --- | --- | +| Checksum failed | Delete the named download and run the verified installer again. | +| Unsupported platform | Use macOS, Linux x64, or WSL2 on an x64 Windows machine. | +| Installed pair is stale | Run `./quantus-mining.sh setup --force`. | +| Node or miner stopped | Run `./quantus-mining.sh mine`. | +| Sync still says `Syncing` | Leave the process running and check `status` later. | +| macOS blocks a binary | Run `xattr -d com.apple.quarantine ~/quantus-mining/bin/quantus-node ~/quantus-mining/bin/quantus-miner`. | +| No hash rate after sync | Run `./quantus-mining.sh setup --force` to restore the supported pair. | +| Computer is sluggish | Run `./quantus-mining.sh config set CPU_WORKERS 1`, then `./quantus-mining.sh restart-check`. | -- **GitHub Issues:** [Report bugs](https://github.com/Quantus-Network/chain/issues) -- **Telegram:** [Quantus community](https://t.me/quantusnetwork) -- **Research forum:** [research.quantus.com](https://research.quantus.com) -- deeper technical discussion with the Quantus team \ No newline at end of file +For protocol development and manual commands, use the chain repository's [MINING.md](https://github.com/Quantus-Network/chain/blob/main/MINING.md). Report reproducible defects in [GitHub Issues](https://github.com/Quantus-Network/chain/issues). diff --git a/package.json b/package.json index 41c905f..9d8d2cc 100644 --- a/package.json +++ b/package.json @@ -10,6 +10,8 @@ "deploy": "docusaurus deploy", "clear": "docusaurus clear", "serve": "docusaurus serve", + "test": "bun test", + "check": "bun run typecheck && bun test && bun run build", "write-translations": "docusaurus write-translations", "write-heading-ids": "docusaurus write-heading-ids", "typecheck": "tsc" @@ -32,6 +34,7 @@ "@docusaurus/module-type-aliases": "^3.10.2", "@docusaurus/tsconfig": "^3.10.2", "@docusaurus/types": "^3.10.2", + "@types/bun": "^1.4.0", "typescript": "~5.6.2" }, "browserslist": { diff --git a/src/components/DocActionButtons/index.tsx b/src/components/DocActionButtons/index.tsx index 26cc872..a0d4977 100644 --- a/src/components/DocActionButtons/index.tsx +++ b/src/components/DocActionButtons/index.tsx @@ -27,6 +27,7 @@ export default function DocActionButtons(): ReactNode { const [container, setContainer] = useState(null); const location = useLocation(); const skillUrl = useBaseUrl('/skills/mining-skill.md'); + const compatibilityUrl = useBaseUrl('/mining-compatibility.json'); const isMiningPage = location.pathname.replace(/\/$/, '') === MINING_PATH; @@ -53,16 +54,31 @@ export default function DocActionButtons(): ReactNode { if (isMiningPage) { try { - const res = await fetch(skillUrl); - if (!res.ok) { - throw new Error(`Skill fetch returned ${res.status}`); + const [skillResponse, compatibilityResponse] = await Promise.all([ + fetch(skillUrl), + fetch(compatibilityUrl), + ]); + if (!skillResponse.ok) { + throw new Error(`Skill fetch returned ${skillResponse.status}`); } - const skill = await res.text(); + if (!compatibilityResponse.ok) { + throw new Error( + `Compatibility fetch returned ${compatibilityResponse.status}`, + ); + } + const skill = await skillResponse.text(); + const compatibility = await compatibilityResponse.text(); text = [ '', '', skill.trim(), '', + '## Pinned compatibility manifest', + '', + '```json', + compatibility.trim(), + '```', + '', '---', '', '# Reference: full mining guide (docs.quantus.com/guides/mining)', @@ -81,7 +97,7 @@ export default function DocActionButtons(): ReactNode { await copyTextToClipboard(text); setCopyState('copied'); setTimeout(() => setCopyState('idle'), 2000); - }, [isMiningPage, skillUrl]); + }, [compatibilityUrl, isMiningPage, skillUrl]); if (!container) return null; diff --git a/static/mining-compatibility.json b/static/mining-compatibility.json new file mode 100644 index 0000000..67d8ea7 --- /dev/null +++ b/static/mining-compatibility.json @@ -0,0 +1,42 @@ +{ + "schemaVersion": "1", + "updatedAt": "2026-09-03T07:00:00Z", + "status": "supported", + "networkId": "planck", + "networkLabel": "Planck testnet", + "networkKind": "testnet", + "tokenValue": "none", + "minerProtocol": "quantus-miner/2", + "compatibilityEvidenceUrl": "https://github.com/Quantus-Network/quantus-miner/releases/tag/v4.0.0", + "nodeVersion": "v0.10.0", + "minerVersion": "v4.0.2", + "desktopAppVersion": "miner-v0.6.1", + "desktopAppStatus": "preview", + "desktopAppBundlesRuntime": "false", + "desktopAppVerifiesRuntimeDownloads": "false", + "minimumMacos": "not-published", + "minimumLinux": "not-published", + "minimumWindows": "not-published", + "nodeDarwinArm64Url": "https://github.com/Quantus-Network/chain/releases/download/v0.10.0/quantus-node-v0.10.0-aarch64-apple-darwin.tar.gz", + "nodeDarwinArm64Sha256": "978feecb876e9cfb671a62481a3f5b58190ca94d0df98cf4a903cc4dc9be9b92", + "minerDarwinArm64Url": "https://github.com/Quantus-Network/quantus-miner/releases/download/v4.0.2/quantus-miner-macos-aarch64", + "minerDarwinArm64Sha256": "0d991ecab2734d31c18b9f83c23512e2f6d39b2f7962e6f8efd3235c767523f9", + "nodeDarwinX8664Url": "https://github.com/Quantus-Network/chain/releases/download/v0.10.0/quantus-node-v0.10.0-x86_64-apple-darwin.tar.gz", + "nodeDarwinX8664Sha256": "a78d228bd44a304f284b716ef312d2f7aa14f8a4fefa7752b4d861a9bd42babe", + "minerDarwinX8664Url": "https://github.com/Quantus-Network/quantus-miner/releases/download/v4.0.2/quantus-miner-macos-x86_64", + "minerDarwinX8664Sha256": "709615a5d10086d82be1caa18aee0dae259d71617599037500d1fa86620a14e9", + "nodeLinuxX8664Url": "https://github.com/Quantus-Network/chain/releases/download/v0.10.0/quantus-node-v0.10.0-x86_64-unknown-linux-gnu.tar.gz", + "nodeLinuxX8664Sha256": "de1a3aa85fb83780b8880b74516824c95b42d4e081c06d7a32d477c78a160bcc", + "minerLinuxX8664Url": "https://github.com/Quantus-Network/quantus-miner/releases/download/v4.0.2/quantus-miner-linux-x86_64", + "minerLinuxX8664Sha256": "614a71f8d3a421ad186b973c744c93d0e54c5a1aaa7629e1763db41e019a8993", + "nodeWindowsX8664Url": "https://github.com/Quantus-Network/chain/releases/download/v0.10.0/quantus-node-v0.10.0-x86_64-pc-windows-msvc.zip", + "nodeWindowsX8664Sha256": "5d0816d5fc3d78920f4eab932bde35700766f1989e3f52756aca3d244ff485e6", + "minerWindowsX8664Url": "https://github.com/Quantus-Network/quantus-miner/releases/download/v4.0.2/quantus-miner-windows-x86_64.exe", + "minerWindowsX8664Sha256": "6b9a27aaf0ad394f095d88939bab47a7613f8edd355e61ea5457a906ce3890ce", + "desktopAppMacosUrl": "https://github.com/Quantus-Network/quantus-apps/releases/download/miner-v0.6.1/quantus_miner_macos.zip", + "desktopAppMacosSha256": "fb4769d4c1e8ccd3c480e0caeca07c9baa2b3ef0540828894dddeea3d4ed016e", + "desktopAppLinuxUrl": "https://github.com/Quantus-Network/quantus-apps/releases/download/miner-v0.6.1/quantus_miner_linux.tar.gz", + "desktopAppLinuxSha256": "fd2755f2fe5df05af3deb8e1081fa808f6c872bd9d4bf2853eea0fe354655076", + "desktopAppWindowsUrl": "https://github.com/Quantus-Network/quantus-apps/releases/download/miner-v0.6.1/quantus_miner_windows.zip", + "desktopAppWindowsSha256": "081308152ba6f9eba62b9ac143f8c9e115ffab400a978a9d03a996e55ece8ad1" +} diff --git a/static/scripts/quantus-mining.sh b/static/scripts/quantus-mining.sh index ae654a3..1ddc96d 100755 --- a/static/scripts/quantus-mining.sh +++ b/static/scripts/quantus-mining.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash # -# quantus-mining.sh — Set up and manage Quantus Planck testnet mining. +# quantus-mining.sh - Set up and manage verified Quantus Planck testnet mining. # # Supports macOS, Linux, and WSL2. Requires bash, curl, and tar. # @@ -8,11 +8,13 @@ # Config file: ~/quantus-mining/mining.conf (mode 600) # # Usage: +# ./quantus-mining.sh mine # ./quantus-mining.sh setup [--force] # ./quantus-mining.sh config show|set KEY VALUE|edit # ./quantus-mining.sh start [-d|--detach] # ./quantus-mining.sh start-node|start-miner # ./quantus-mining.sh stop|restart [-d|--detach] +# ./quantus-mining.sh status|restart-check # ./quantus-mining.sh uninstall [--force] # ./quantus-mining.sh help # @@ -31,15 +33,23 @@ readonly MINER_BIN="${BIN_DIR}/quantus-miner" readonly NODE_PID_FILE="${MINING_DIR}/node.pid" readonly MINER_PID_FILE="${MINING_DIR}/miner.pid" readonly NODE_KEY_PATH="${MINING_DIR}/node_key.p2p" +readonly INNER_HASH_FILE="${MINING_DIR}/rewards-inner-hash" +readonly COMPATIBILITY_FILE="${MINING_DIR}/mining-compatibility.json" +readonly COMPATIBILITY_URL="${QUANTUS_COMPATIBILITY_URL:-https://docs.quantus.com/mining-compatibility.json}" readonly CHAIN_REPO="Quantus-Network/chain" readonly MINER_REPO="Quantus-Network/quantus-miner" -readonly EDITABLE_KEYS="NODE_NAME CPU_WORKERS GPU_DEVICES MINER_LISTEN_PORT CHAIN NODE_VERSION MINER_VERSION" +readonly EDITABLE_KEYS="NODE_NAME CPU_WORKERS GPU_DEVICES MINER_LISTEN_PORT" OS="" ARCH="" +PLATFORM_KEY="" NODE_TARGET="" MINER_ASSET="" +NODE_DOWNLOAD_URL="" +NODE_DOWNLOAD_SHA256="" +MINER_DOWNLOAD_URL="" +MINER_DOWNLOAD_SHA256="" DOCKER_COMPOSE="" NODE_LAUNCH_ARGS=() @@ -78,9 +88,11 @@ detect_platform() { x86_64|amd64) ARCH="x86_64" if [ "$OS" = "linux" ]; then + PLATFORM_KEY="LinuxX8664" NODE_TARGET="x86_64-unknown-linux-gnu" MINER_ASSET="quantus-miner-linux-x86_64" else + PLATFORM_KEY="DarwinX8664" NODE_TARGET="x86_64-apple-darwin" MINER_ASSET="quantus-miner-macos-x86_64" fi @@ -88,9 +100,11 @@ detect_platform() { arm64|aarch64) ARCH="arm64" if [ "$OS" = "linux" ]; then + PLATFORM_KEY="LinuxArm64" NODE_TARGET="aarch64-unknown-linux-gnu" MINER_ASSET="" else + PLATFORM_KEY="DarwinArm64" NODE_TARGET="aarch64-apple-darwin" MINER_ASSET="quantus-miner-macos-aarch64" fi @@ -260,21 +274,116 @@ tolower() { printf '%s' "$1" | tr '[:upper:]' '[:lower:]' } -fetch_latest_tag() { - local repo="$1" - local release_json tag +manifest_string() { + local file="$1" key="$2" + sed -n "s/^[[:space:]]*\"${key}\"[[:space:]]*:[[:space:]]*\"\([^\"]*\)\"[,[:space:]]*$/\1/p" "$file" \ + | head -n 1 +} + +require_manifest_string() { + local file="$1" key="$2" value + value="$(manifest_string "$file" "$key")" + [ -n "$value" ] || die "Compatibility manifest is missing ${key}. No files were installed." + printf '%s' "$value" +} + +sha256_file() { + local file="$1" + if command -v sha256sum >/dev/null 2>&1; then + sha256sum "$file" | awk '{print $1}' + elif command -v shasum >/dev/null 2>&1; then + shasum -a 256 "$file" | awk '{print $1}' + else + die "No SHA-256 tool found. Install sha256sum (Linux) or use macOS shasum, then retry." + fi +} + +verify_sha256() { + local file="$1" expected="$2" actual + case "$expected" in + *[!0-9a-f]*|'') die "Invalid SHA-256 value for $(basename "$file"). No files were installed." ;; + esac + [ "${#expected}" -eq 64 ] \ + || die "Invalid SHA-256 length for $(basename "$file"). No files were installed." + + actual="$(sha256_file "$file")" + if [ "$actual" != "$expected" ]; then + die "Checksum verification failed for $(basename "$file"). +Expected: ${expected} +Actual: ${actual} +The file was not installed. Delete the download and retry." + fi + info "Verified SHA-256: $(basename "$file")" +} - release_json="$(curl -fsSL "https://api.github.com/repos/${repo}/releases/latest")" \ - || die "Failed to fetch latest release for ${repo}" +validate_release_url() { + local url="$1" repo="$2" version="$3" + case "$url" in + "https://github.com/${repo}/releases/download/${version}/"*) ;; + *) die "Compatibility manifest contains an unexpected download URL for ${repo}. No files were installed." ;; + esac +} + +load_compatibility_manifest() { + local file="$1" status network_kind token_value evidence + local node_url_key node_sha_key miner_url_key miner_sha_key + + [ -s "$file" ] || die "Compatibility manifest not found at ${file}. Run: ${SCRIPT_NAME} setup --force" - tag="$(printf '%s' "$release_json" | grep -o '"tag_name": "[^"]*"' | head -n 1 | cut -d'"' -f4)" - [ -n "$tag" ] || die "Could not determine latest release tag for ${repo}" - printf '%s' "$tag" + status="$(require_manifest_string "$file" status)" + [ "$status" = "supported" ] \ + || die "Mining compatibility status is '${status}', not 'supported'. Nothing will be installed or started." + + CHAIN="$(require_manifest_string "$file" networkId)" + network_kind="$(require_manifest_string "$file" networkKind)" + token_value="$(require_manifest_string "$file" tokenValue)" + NODE_VERSION="$(require_manifest_string "$file" nodeVersion)" + MINER_VERSION="$(require_manifest_string "$file" minerVersion)" + MINER_PROTOCOL="$(require_manifest_string "$file" minerProtocol)" + evidence="$(require_manifest_string "$file" compatibilityEvidenceUrl)" + + [ "$CHAIN" = "planck" ] && [ "$network_kind" = "testnet" ] && [ "$token_value" = "none" ] \ + || die "This installer is restricted to the Planck testnet. The manifest requested a different network." + [ "$MINER_PROTOCOL" = "quantus-miner/2" ] \ + || die "Unsupported miner protocol '${MINER_PROTOCOL}'. Nothing will be installed or started." + case "$evidence" in + https://github.com/Quantus-Network/quantus-miner/releases/tag/*) ;; + *) die "Compatibility evidence URL is not an official Quantus miner release." ;; + esac + + node_url_key="node${PLATFORM_KEY}Url" + node_sha_key="node${PLATFORM_KEY}Sha256" + miner_url_key="miner${PLATFORM_KEY}Url" + miner_sha_key="miner${PLATFORM_KEY}Sha256" + NODE_DOWNLOAD_URL="$(require_manifest_string "$file" "$node_url_key")" + NODE_DOWNLOAD_SHA256="$(require_manifest_string "$file" "$node_sha_key")" + MINER_DOWNLOAD_URL="$(require_manifest_string "$file" "$miner_url_key")" + MINER_DOWNLOAD_SHA256="$(require_manifest_string "$file" "$miner_sha_key")" + + validate_release_url "$NODE_DOWNLOAD_URL" "$CHAIN_REPO" "$NODE_VERSION" + validate_release_url "$MINER_DOWNLOAD_URL" "$MINER_REPO" "$MINER_VERSION" + case "$(basename "$NODE_DOWNLOAD_URL")" in + "quantus-node-${NODE_VERSION}-${NODE_TARGET}.tar.gz") ;; + *) die "Node asset does not match ${OS}/${ARCH}. No files were installed." ;; + esac + [ "$(basename "$MINER_DOWNLOAD_URL")" = "$MINER_ASSET" ] \ + || die "Miner asset does not match ${OS}/${ARCH}. No files were installed." +} + +fetch_compatibility_manifest() { + local temp_file="${COMPATIBILITY_FILE}.download" + info "Fetching the supported Planck release pair..." + curl --proto '=https' --tlsv1.2 -fsSL "$COMPATIBILITY_URL" -o "$temp_file" \ + || die "Could not download ${COMPATIBILITY_URL}. Check your connection and retry." + load_compatibility_manifest "$temp_file" + mv "$temp_file" "$COMPATIBILITY_FILE" + chmod 600 "$COMPATIBILITY_FILE" + info "Supported pair: node ${NODE_VERSION} + miner ${MINER_VERSION} (${MINER_PROTOCOL})" } # Miner protocol this script can drive: # auth = Ready { token } + TLS pin (quantus-miner/2) -# legacy = unauthenticated Ready (pre-auth releases, e.g. node v0.9.0 / miner v3.3.1) +# legacy = unauthenticated Ready from older release pairs MINER_PROTOCOL="" incompatible_miner_pair_die() { @@ -284,14 +393,8 @@ incompatible_miner_pair_die() { Miner --auth-token-file / --tls-cert-sha256-file: ${miner_auth} Do not mix a release that requires Ready { token } (quantus-miner/2) with one that does not. -GitHub latest tags are published independently — pin a matching pair: - - NODE_VERSION= - MINER_VERSION= - -in ${CONFIG_FILE}, or re-run setup after coordinated releases: - https://github.com/${CHAIN_REPO}/releases - https://github.com/${MINER_REPO}/releases" +Run ${SCRIPT_NAME} setup --force to reinstall the supported pair from: + ${COMPATIBILITY_URL}" } classify_miner_protocol() { @@ -342,18 +445,22 @@ maybe_wait_for_miner_auth_files() { } download_node_binary() { - local tag="$1" - local asset="quantus-node-${tag}-${NODE_TARGET}.tar.gz" - local url="https://github.com/${CHAIN_REPO}/releases/download/${tag}/${asset}" + local tag="$1" url="$2" expected_sha256="$3" + local asset local temp_dir asset_path + asset="$(basename "$url")" + info "Downloading quantus-node ${tag} for ${NODE_TARGET}..." temp_dir="$(mktemp -d)" asset_path="${temp_dir}/${asset}" - curl -fsSL "$url" -o "$asset_path" || { rm -rf "$temp_dir"; die "Failed to download ${url}"; } + curl --proto '=https' --tlsv1.2 -fsSL "$url" -o "$asset_path" \ + || { rm -rf "$temp_dir"; die "Failed to download ${url}"; } + verify_sha256 "$asset_path" "$expected_sha256" - tar -xzf "$asset_path" -C "$temp_dir" + tar -xzf "$asset_path" -C "$temp_dir" \ + || { rm -rf "$temp_dir"; die "Could not extract ${asset}. Delete the download and retry."; } if [ ! -f "${temp_dir}/quantus-node" ]; then rm -rf "$temp_dir" die "quantus-node not found in archive" @@ -366,162 +473,81 @@ download_node_binary() { } download_miner_binary() { - local tag="$1" - local url="https://github.com/${MINER_REPO}/releases/download/${tag}/${MINER_ASSET}" + local tag="$1" url="$2" expected_sha256="$3" + local temp_file info "Downloading quantus-miner ${tag} (${MINER_ASSET})..." - curl -fsSL "$url" -o "$MINER_BIN" || die "Failed to download ${url}" + temp_file="${MINER_BIN}.download" + curl --proto '=https' --tlsv1.2 -fsSL "$url" -o "$temp_file" \ + || die "Failed to download ${url}" + verify_sha256 "$temp_file" "$expected_sha256" + mv "$temp_file" "$MINER_BIN" make_executable "$MINER_BIN" info "Installed quantus-miner to ${MINER_BIN}" } -read_conf_value() { - local key="$1" - local raw="" - [ -f "$CONFIG_FILE" ] || return 0 - raw="$(grep -E "^${key}=" "$CONFIG_FILE" 2>/dev/null | head -n 1 | cut -d= -f2- || true)" - raw="${raw#\"}" - raw="${raw%\"}" - printf '%s' "$raw" -} - -# Env NODE_VERSION / MINER_VERSION override mining.conf. Empty pins fetch GitHub latest. -load_version_pins() { - local conf_node conf_miner - conf_node="$(read_conf_value NODE_VERSION)" - conf_miner="$(read_conf_value MINER_VERSION)" - if [ -z "${NODE_VERSION:-}" ] && [ -n "$conf_node" ]; then - NODE_VERSION="$conf_node" - fi - if [ -z "${MINER_VERSION:-}" ] && [ -n "$conf_miner" ]; then - MINER_VERSION="$conf_miner" - fi -} - download_binaries() { - local force="${1:-false}" - local node_tag miner_tag - - load_version_pins - - if [ "$force" = "true" ] || [ ! -x "$NODE_BIN" ]; then - node_tag="${NODE_VERSION:-}" - [ -n "$node_tag" ] || node_tag="$(fetch_latest_tag "$CHAIN_REPO")" - download_node_binary "$node_tag" - else - node_tag="${NODE_VERSION:-}" - [ -n "$node_tag" ] || node_tag="$(fetch_latest_tag "$CHAIN_REPO")" - info "Using existing quantus-node at ${NODE_BIN}" - fi - - if [ "$force" = "true" ] || [ ! -x "$MINER_BIN" ]; then - miner_tag="${MINER_VERSION:-}" - [ -n "$miner_tag" ] || miner_tag="$(fetch_latest_tag "$MINER_REPO")" - download_miner_binary "$miner_tag" - else - miner_tag="${MINER_VERSION:-}" - [ -n "$miner_tag" ] || miner_tag="$(fetch_latest_tag "$MINER_REPO")" - info "Using existing quantus-miner at ${MINER_BIN}" - fi - - NODE_VERSION="$node_tag" - MINER_VERSION="$miner_tag" + fetch_compatibility_manifest + download_node_binary "$NODE_VERSION" "$NODE_DOWNLOAD_URL" "$NODE_DOWNLOAD_SHA256" + download_miner_binary "$MINER_VERSION" "$MINER_DOWNLOAD_URL" "$MINER_DOWNLOAD_SHA256" detect_binary_miner_protocol + [ "$MINER_PROTOCOL" = "auth" ] \ + || die "The downloaded binaries do not implement the manifest protocol quantus-miner/2. Nothing will be started." } parse_wormhole_output() { local output="$1" - local line WORMHOLE_ADDRESS="$(printf '%s\n' "$output" | grep -E '^Address:' | head -n 1 | awk '{print $2}')" INNER_HASH="$(printf '%s\n' "$output" | grep -E '^Inner [Hh]ash:' | head -n 1 | awk '{print $3}')" if [ -z "$INNER_HASH" ]; then INNER_HASH="$(printf '%s\n' "$output" | grep -E '^inner_hash:' | head -n 1 | awk '{print $2}')" fi - WORMHOLE_SECRET="" - line="$(printf '%s\n' "$output" | grep -E '^Secret:' | head -n 1 || true)" - if [ -n "$line" ]; then - WORMHOLE_SECRET="$(printf '%s' "$line" | awk '{print $2}')" - fi - - line="$(printf '%s\n' "$output" | grep -E '^Secret phrase:' | head -n 1 || true)" - if [ -n "$line" ]; then - WORMHOLE_SECRET_PHRASE="${line#*Secret phrase: }" - else - WORMHOLE_SECRET_PHRASE="" - fi - [ -n "$WORMHOLE_ADDRESS" ] || die "Could not parse wormhole Address from keygen output" [ -n "$INNER_HASH" ] || die "Could not parse Inner Hash from keygen output" } generate_wormhole_keys() { - local choice output mnemonic + local output mnemonic echo "" - echo "Wormhole address generation:" - echo " [1] Derive from existing 24-word wallet mnemonic (recommended)" - echo " [2] Generate a fresh keypair" - read -r -p "Enter choice (1/2) [1]: " choice - choice="${choice:-1}" - - case "$choice" in - 1) - echo "Enter your 24-word mnemonic (input hidden):" - read -r -s mnemonic - echo "" - [ -n "$mnemonic" ] || die "Mnemonic cannot be empty" - output="$(printf '%s\n' "$mnemonic" | wormhole_keygen --words)" - ;; - 2) - output="$(wormhole_keygen)" - ;; - *) - die "Invalid choice: $choice" - ;; - esac + info "Wallet step: enter your existing Quantus 24-word recovery phrase locally." + info "Input is hidden and is not written to disk, logs, command arguments, or network requests." + info "Never paste a recovery phrase into chat or a support ticket." + read -r -s -p "Recovery phrase: " mnemonic + echo "" + [ -n "$mnemonic" ] || die "Recovery phrase cannot be empty. Open your Quantus wallet backup and retry." + output="$(printf '%s\n' "$mnemonic" | wormhole_keygen --words)" + unset mnemonic parse_wormhole_output "$output" + unset output + + printf '%s\n' "$INNER_HASH" > "$INNER_HASH_FILE" + chmod 600 "$INNER_HASH_FILE" echo "" - echo "Wormhole keypair generated. Save these values securely:" - echo "$output" - echo "" - warn "Back up your 24-word seed phrase. Loss means loss of mining rewards." + info "Reward address: ${WORMHOLE_ADDRESS}" + info "Your recovery phrase was not saved. Keep your existing offline backup." } -prompt_resource_allocation() { - local cores has_gpu choice default_workers +configure_resource_defaults() { + local cores default_workers cores="$(cpu_count)" - echo "" - echo "This machine has ${cores} CPU cores." - echo "GPU mining is strongly recommended (~500-1000 MH/s vs ~15 MH/s per CPU worker)." - read -r -p "Do you have a GPU available for mining? (y/N): " has_gpu - - case "$(tolower "$has_gpu")" in - y|yes) - GPU_DEVICES=1 - CPU_WORKERS=0 - info "Default: GPU mining with --gpu-devices 1 --cpu-workers 0" - ;; - *) - default_workers=$((cores - 2)) - [ "$default_workers" -lt 1 ] && default_workers=1 - GPU_DEVICES=0 - CPU_WORKERS="$default_workers" - info "Default: CPU-only mining with --cpu-workers ${CPU_WORKERS} (leaving 2 cores for OS/node)" - ;; - esac - - read -r -p "CPU workers [${CPU_WORKERS}]: " choice - if [ -n "$choice" ]; then - CPU_WORKERS="$choice" - fi - - read -r -p "GPU devices [${GPU_DEVICES}]: " choice - if [ -n "$choice" ]; then - GPU_DEVICES="$choice" + default_workers=$((cores - 2)) + [ "$default_workers" -lt 1 ] && default_workers=1 + + if [ "$OS" = "macos" ] \ + || command -v nvidia-smi >/dev/null 2>&1 \ + || command -v vulkaninfo >/dev/null 2>&1; then + GPU_DEVICES=1 + CPU_WORKERS=0 + info "Mining resources: one detected GPU, CPU reserved for the node." + else + GPU_DEVICES=0 + CPU_WORKERS="$default_workers" + info "Mining resources: ${CPU_WORKERS} CPU workers, two cores reserved when available." fi } @@ -532,12 +558,11 @@ write_config() { GPU_DEVICES="${GPU_DEVICES:-0}" cat > "$CONFIG_FILE" </dev/null)"; then + case "$health" in + *'"isSyncing":false'*) sync_state="Synced" ;; + *'"isSyncing":true'*) sync_state="Syncing" ;; + esac + fi + + if [ -f "${LOG_DIR}/miner.log" ]; then + latest_rate="$(grep -Ei 'hash.?rate|[0-9]+([.][0-9]+)?[[:space:]]*[kmg]?h/s' "${LOG_DIR}/miner.log" 2>/dev/null \ + | tail -n 1 | redact_sensitive_stream || true)" + [ -z "$latest_rate" ] || hash_rate="$latest_rate" + fi + + if [ "$node_state" = "Running" ] && [ "$miner_state" = "Running" ] \ + && [ "$sync_state" = "Synced" ] && [ -n "$latest_rate" ]; then + overall="MINING" + elif [ "$node_state" = "Stopped" ] || [ "$miner_state" = "Stopped" ]; then + overall="STOPPED" + fi + + cat <