Run a validator
A validator signs blocks. On sanect only the top 50 by stake sit in the active set at any moment — but registrations are unlimited: anyone can register, the top 50 by stake form the active consensus set, and the rest sit on a waitlist that rotates in when they outstake someone above rank 50. To actually validate you need (a) a running full node with a unique validator key, and (b) enough stake (self or delegated) to crack the top 50. Jailed for downtime? The staking dApp ships a one-click Unjail action.
This page covers a single validator. If you're scaling 1 → 50 (or beyond) on Railway, also read 1 → 50 validators on Railway.
Mental model
A validator is a full node plus a private signing key (priv_validator_key.json) plus an on-chain MsgCreateValidator transaction binding that key to a delegator account with some stake. Each pair of (node, key) is one validator identity. The key must be unique per validator.
Two ways to become a validator
A) Genesis validator
Your validator's gentx is part of genesis.json. The chain starts with you in the active set on block 1. Used when bootstrapping a new chain. Today sanect's testnet was bootstrapped this way with a single validator.
B) Post-genesis validator (more common)
The chain is already running. You spin up a new node, sync to the tip, then submit a MsgCreateValidator transaction. If your stake lands you in the top 50, you're active and start signing the next epoch.
For sanect testnet today, use path B unless you're rebooting the chain.
Hardware requirements
| Resource | Minimum | Recommended |
|---|---|---|
| CPU | 4 cores | 8+ cores |
| RAM | 8 GB | 16 GB |
| Storage | 200 GB SSD | 500 GB+ NVMe SSD |
| Network | 100 Mbps | 1 Gbps |
NVMe strongly recommended
Mainnet validators should use local NVMe storage (not network-attached or shared ZFS). CometBFT's fsync-heavy write pattern benefits significantly from NVMe IOPS. Shared storage (e.g. Railway ZFS) can push block time from ~400ms to ~700ms due to ZIL contention.
Path B — Add a validator to a running chain
Testnet
# 1. Run a full node that's caught up to the tip.
# (See "Run a full / RPC node".) Confirm it's at chain tip:
curl -s localhost:26657/status | jq .result.sync_info.catching_up
# -> false
# 2. Create a delegator key (this account holds your stake).
sanectd keys add mykey --keyring-backend test --home /data/.sanectd
# ^ for production, use --keyring-backend os or file.
# 3. Fund that address with some SNCT (faucet / transfer from another account).
# 4. Submit the create-validator tx (testnet: min-self-delegation 100 SNCT).
sanectd tx staking create-validator \
--amount=1000000000000000000000asnct \
--pubkey=$(sanectd cometbft show-validator --home /data/.sanectd) \
--moniker="my-validator" \
--chain-id=sanect_76287-1 \
--commission-rate=0.10 \
--commission-max-rate=0.20 \
--commission-max-change-rate=0.01 \
--min-self-delegation=100000000000000000000 \
--from=mykey \
--keyring-backend=test \
--home=/data/.sanectd \
--gas=auto \
--gas-prices=1000000000asnct \
--yesMainnet
# Same steps as testnet, but with mainnet chain ID and higher min-self-delegation.
# Mainnet min-self-delegation: 1000 SNCT (10^21 asnct).
sanectd tx staking create-validator \
--amount=10000000000000000000000asnct \
--pubkey=$(sanectd cometbft show-validator --home /data/.sanectd) \
--moniker="my-validator" \
--chain-id=sanect_7628-1 \
--commission-rate=0.10 \
--commission-max-rate=0.20 \
--commission-max-change-rate=0.01 \
--min-self-delegation=1000000000000000000000 \
--from=mykey \
--keyring-backend=os \
--home=/data/.sanectd \
--gas=auto \
--gas-prices=1000000000asnct \
--yesIf your stake is enough to land in the top 50, you start signing the next block your node sees.
Operational must-haves
- Never run two nodes with the same
priv_validator_key.json. They will both sign at the same height and the chain slashes the validator for double-signing. This is the single biggest footgun in BFT validation. - Back up
priv_validator_key.jsonto somewhere offline. You can rebuild the rest of a node; you can't recover this key. - Keep
priv_validator_state.jsonin sync with the actual signed state. Don't roll back the volume — it can cause double-sign. - Monitor liveness. If your validator misses too many blocks in the
signed_blocks_window, it gets jailed for downtime. Restart it before the window closes.
Delegation (without running a node)
Anyone can delegate SNCT to an existing validator to share in its rewards (minus the validator's commission). Use any Cosmos-SDK wallet (Keplr, Leap) or the CLI:
# Testnet
sanectd tx staking delegate <validator-address> 1000000000000000000asnct \
--from=mykey --chain-id=sanect_76287-1 \
--gas-prices=1000000000asnct --yes
# Mainnet
sanectd tx staking delegate <validator-address> 1000000000000000000asnct \
--from=mykey --chain-id=sanect_7628-1 \
--gas-prices=1000000000asnct --yesNext step
→ 1 → 50 validators on Railway for the operational playbook of adding multiple validators on Railway (including why you must not use replicas).