Testnet. QBTC is pre-mainnet (targeting Q3 2026). The instructions below stand up a node against the current public testnet. Endpoints, the chain ID, and the pinned version change as the testnet progresses — always cross-check the chain repository for the latest values.
qbtcd— the chain daemon (Cosmos SDK + the ML-DSA CometBFT fork). This is the node.bifrost— the sidecar that connects to a Bitcoin full node, watches for new Bitcoin blocks, and relays them to the chain. See Architecture for how the two fit together.
bifrost to read blocks from). It can run on the same machine or a separate one.
Prerequisites
- A Linux host (the installer targets
linux-amd64release binaries andsystemd). curl,tar,sudo,sha256sum, andsystemctlavailable on the host.- A reachable Bitcoin full node with RPC enabled (host, port, RPC username, and password).
- For building from source instead of using release binaries: Go 1.22+ and Make.
Quick install (recommended)
The chain repo ships an install script that downloads theqbtcd and bifrost binaries to /usr/local/bin, optionally sets up Cosmovisor for upgrade management, initializes the node home directory, downloads the genesis file, writes a bifrost config template, and installs systemd services.
What the installer creates
Configure bifrost
Before starting the services, pointbifrost at your Bitcoin full node. Edit its config:
Start the node
Ports
Open
26656 and 30006 to peers so your node can sync and gossip Bitcoin blocks. Keep 26657, 9090, and the Bitcoin RPC port firewalled to localhost or trusted hosts.
Building from source
If you would rather build the binaries yourself:make build produces all of the chain binaries into ./build/: qbtcd, bifrost, zkprover (the local ZK proof CLI — see Claim Mechanism), proof-service (the optional hosted PLONK prover), and utxo-indexer (builds the genesis UTXO snapshot). Run the test suite with:
Keeping your node updated
Newqbtcd / bifrost releases are published on the releases page. There are two kinds of update, and they are handled differently.
Minor / patch releases (no consensus break)
For a routine version bump, you replace the binaries directly — no governance proposal. Theqbtcd binary lives in two places, and both must be updated so it does not matter whether systemd launches the daemon directly or through Cosmovisor:
/usr/local/bin/qbtcd~/.qbtc/cosmovisor/current/bin/qbtcd
bifrost runs from /usr/local/bin/bifrost.
Major / consensus-breaking upgrades (governance)
Consensus-breaking upgrades ship through an on-chain software-upgrade proposal and are applied by Cosmovisor at the scheduled block height. Because the installer setsDAEMON_ALLOW_DOWNLOAD_BINARIES=false, Cosmovisor will not fetch the binary for you — stage it ahead of the upgrade height:
current symlink, and (with DAEMON_RESTART_AFTER_UPGRADE=true) restarts automatically. Follow the release notes for the exact upgrade name and height.
Chain ID for transactions
The live testnet reports its chain ID asqbtc (confirmed from …/cosmos/base/tendermint/v1beta1/blocks/latest). The installer’s client config currently sets a different value, so if you sign and broadcast transactions, pass the chain ID explicitly to avoid a signature-mismatch error:
Querying without your own node
To read chain state without running a full node, use the public Cosmos REST gateway documented in the API Reference. Note it proxies only standard/cosmos/... module queries — CometBFT RPC and custom x/qbtc routes are not exposed.
Becoming a validator
Validator creation is the standard Cosmos SDKx/staking flow (qbtcd tx staking create-validator), with three QBTC-specific differences:
- Consensus keys are ML-DSA, not Ed25519. The validator pubkey you submit has
@type/cosmos.crypto.mldsa.PubKey. You get it fromqbtcd comet show-validatorexactly as on any Cosmos chain — the key material is just post-quantum. - Account keys are also ML-DSA, not secp256k1.
qbtcd keys addgenerates a post-quantum account key. This is unusual (most Cosmos chains use secp256k1 accounts) and means generic secp256k1 tooling and hardware wallets will not sign QBTC transactions. - A validator must also run
bifrostand register it on-chain. Block production depends on validators attesting Bitcoin blocks (see Architecture). Beyond running the sidecar, you publish its peer address with a customx/qbtctransaction so other validators can reach it — see Register your bifrost peer address. Skipping this leaves your validator unable to attest.
Network parameters (current testnet)
Verified live; all change at mainnet relaunch.Step by step
-
Sync a full node and run
bifrost(sections above). Wait untilqbtcdis caught up (qbtcd status→sync_info.catching_up: false). -
Create your validator account key (this is an ML-DSA key):
-
Fund the account. On testnet, send your
qbtc1…address to the team and they fund it. Confirm the balance: -
Get your consensus pubkey:
-
Write
validator.json— paste the pubkey output verbatim into thepubkeyfield:amountis your self-bond, in base units (1000000000qbtc= 10 QBTC). It must be ≤ your funded balance. -
Submit the transaction:
-
Verify you are bonded:
or via the public gateway:
…/qbtc-rpc/cosmos/staking/v1beta1/validators.
Register your bifrost peer address
This is a QBTC-specific step with no Cosmos equivalent, and it comes after your validator is created and bonded — not before.- It is order-enforced. The
set-node-peer-addresstransaction is rejected unless the signer is an already-bonded validator (the handler requiresvalidator.Status == Bonded, otherwise it returnsunauthorized: validator is not bonded). Run it beforecreate-validator, or while your validator is still unbonded or jailed, and it fails. ConfirmBOND_STATUS_BONDEDfrom the verify step above first. - Bonding alone is not enough. Your validator’s
bifrostalso has to be discoverable so other validators’bifrostprocesses can connect and exchange Bitcoin blocks. A bonded but unregistered validator cannot attest BTC blocks and risks downtime jailing.
-
Set
external_ipand restart bifrost. Confirmexternal_ipin~/.bifrost/config.jsonis your node’s public IP (see the bifrost config tip), then: -
Read your full peer address from the bifrost HTTP API. It returns
<peerID>@<external_ip>:<p2p-port>ready to use:If the IP comes back as0.0.0.0,external_ipis unset — fix step 1 first. -
Register it on-chain with the custom
x/qbtcmessage, signed by your validator account: -
Verify peering and the on-chain mapping:
The custom
x/qbtcqueries are served by your own node, not the public REST gateway. If a subcommand differs on your build, checkqbtcd query qbtc --help.
Placement and latency
QBTC blocks are large, and this makes validator placement a real operational concern. ML-DSA consensus signatures are about 3.3 KB each (versus 64 bytes for Ed25519), and when a Bitcoin block is ingested it is shipped into a QBTC block that can be very large. A validator that is network-distant from the rest of the active set may not receive and precommit these large blocks within the consensus timeouts — so it misses precommits and is jailed for downtime, even while it keeps up fine on small blocks. This is not hypothetical. A validator roughly 225 ms RTT from the majority of voting power consistently missed precommits on the large blocks and was jailed; its small-block participation was unaffected.- Run close to the rest of the active set. Minimize round-trip latency to the other validators. On the current testnet the majority of voting power runs in Singapore — place your validator in or near the region where the active set is concentrated (confirm the current location with the team) rather than across an ocean.
- Measure before you commit to a region. A few hundred milliseconds of RTT to your peers is enough to miss large blocks. Check latency first.
- Do not change the consensus timeouts on your own.
timeout_propose,timeout_commit, and the related values inconfig.tomlare effectively network-wide; the team may tune them for large post-quantum blocks, so follow the published values rather than diverging unilaterally.
Running multiple validators
Repeat the whole flow per validator, on separate machines (or separate--home directories and ports), each with its own account, its own consensus key, and its own bifrost. Fund each account separately; each self-bonds independently.
The exact subcommand names and flags above follow Cosmos SDK v0.53. If anything differs on your build, the binary is the source of truth — check
qbtcd tx staking create-validator --help and qbtcd comet --help. See Consensus & Validators for the economic model.See also
- Architecture, how
qbtcd,bifrost, and the Bitcoin node fit together. - Consensus & Validators, validator economics and emission.
- Chain repository, source of truth for versions and endpoints.