⛓️ Worrell Testnet Full Node & Validator Setup Guide
A complete guide to running a Worrell testnet full node and registering as a validator Prebuilt binary or build from source, Cosmovisor, genesis, peers, systemd service, and validator creation — step by step.
Author: HazenNetworkSolutions Network: Worrell Testnet (Chain ID: worrell-testnet-1) Version: v0.1.2 Last Updated: September 2026
Table of Contents
- Hardware Requirements
- Network Endpoints
- Step 1 — System Verification
- Step 2 — System Update and Dependencies
- Step 3 — Install worrelld (choose ONE option)
- Step 4 — Set Up Cosmovisor
- Step 5 — Initialize the Node
- Step 6 — Download and Verify Genesis
- Step 7 — Configure Peers (config.toml)
- Step 8 — Set the Minimum Gas Price (app.toml)
- Step 9 — Configure Custom Ports (Optional)
- Step 10 — Enable Prometheus (Optional)
- Step 11 — Create Systemd Service
- Step 12 — Start the Node
- Step 13 — Verify Sync
- Step 14 — Create a Wallet and Fund It (Faucet)
- Step 15 — Register as a Validator
- Monitoring & Avoiding Jailing
- Useful Commands
- Firewall
Hardware Requirements
| Component | Minimum (Testnet) |
|---|---|
| Operating System | Ubuntu 22.04 LTS |
| CPU | 2 vCPU |
| RAM | 4 GB |
| Disk | 100 GB SSD |
| Network | Stable connection, public IP for P2P |
Mainnet, when it launches, will require more headroom (4+ vCPU, 16+ GB RAM, 500 GB+ NVMe SSD) since a validator must sign blocks continuously and keep history. This guide targets the testnet.
Network Endpoints
| Type | Endpoint |
|---|---|
| Chain ID | worrell-testnet-1 |
| REST API | https://worrell.api.t.anode.team (community, by ANODE.TEAM) |
| Explorer | https://test.anode.team/worrell (community, by ANODE.TEAM) |
| Genesis | https://raw.githubusercontent.com/worrellchain/networks/main/worrell-testnet-1/genesis.json |
| Genesis sha256 | a81c507b12ba0678c3172394ff4bb03e1c3db60050cc5568c127a24ec19378fd |
| Persistent peer | [email protected]:26656 |
| Faucet | POST http://164.68.98.186:4500 (500 WORRELL, 1/hour per address) |
| Node source | https://github.com/worrellchain/worrell |
| Network configs | https://github.com/worrellchain/networks |
| Website | https://worrellchain.com |
| Validator alerts | https://t.me/worrellvalidators |
Step 1 — System Verification
After SSH-ing into your server, verify the system meets requirements:
lsb_release -a
uname -r
lscpu | grep -E "Model name|CPU\(s\)|Thread|Socket|Core"
free -h
df -h
Step 2 — System Update and Dependencies
sudo apt update && sudo apt upgrade -y
sudo apt install -y git curl build-essential jq wget tmux htop unzip
Step 3 — Install worrelld (choose ONE option)
There are two ways to get the worrelld binary — pick one, not both:
- Option A (recommended): download the prebuilt tarball. Faster, no build tools needed.
- Option B: build from source. Slower, but lets you audit the code you're running.
Whichever you pick, the result is the same: worrelld ends up at $HOME/go/bin/worrelld, which is what Cosmovisor (Step 4) expects.
Option A — Prebuilt Binary (recommended)
The worrelld binary is statically linked and self-contained — no Go toolchain required. Pick the tarball matching your platform from the releases page:
Platform (uname -s / uname -m) | Tarball |
|---|---|
Linux / x86_64 | v0.1.2_linux_amd64.tar.gz |
Linux / aarch64 | v0.1.2_linux_arm64.tar.gz |
Darwin / arm64 (Apple Silicon) | v0.1.2_darwin_arm64.tar.gz |
Darwin / x86_64 (Intel Mac) | v0.1.2_darwin_amd64.tar.gz |
cd $HOME
curl -LO https://github.com/worrellchain/worrell/releases/download/v0.1.2/v0.1.2_linux_amd64.tar.gz
# Verify against the release_checksum file published on the releases page before extracting
sha256sum v0.1.2_linux_amd64.tar.gz
tar -xzf v0.1.2_linux_amd64.tar.gz
mkdir -p $HOME/go/bin && mv worrelld $HOME/go/bin/
echo 'export PATH=$PATH:$HOME/go/bin' >> ~/.bash_profile
source ~/.bash_profile
Verify:
worrelld version --long | head -5
# should report cosmos_sdk_version: v0.53.6
worrelld --help
✅ Done? Skip Option B below and go straight to Step 4 — Set Up Cosmovisor.
Option B — Build from Source
Only do this if you did not already install the binary via Option A above.
Dependencies: Go 1.25+ (check go.mod in the repo for the exact minimum), git, make, build-essential.
sudo apt update && sudo apt install -y git curl build-essential
Install Go 1.25:
curl -LO https://go.dev/dl/go1.25.13.linux-amd64.tar.gz
sudo rm -rf /usr/local/go && sudo tar -C /usr/local -xzf go1.25.13.linux-amd64.tar.gz
[ ! -f ~/.bash_profile ] && touch ~/.bash_profile
echo 'export PATH=$PATH:/usr/local/go/bin:$HOME/go/bin' >> ~/.bash_profile
echo 'export GOPATH=$HOME/go' >> ~/.bash_profile
source ~/.bash_profile
[ ! -d ~/go/bin ] && mkdir -p ~/go/bin
go version
Clone and build the published release tag:
git clone https://github.com/worrellchain/worrell.git $HOME/worrell
cd $HOME/worrell
git checkout v0.1.2
make install
make install compiles worrelld and places it in $HOME/go/bin.
worrelld version --long | head -5
Step 4 — Set Up Cosmovisor
Continue here regardless of which option you chose in Step 3.
Cosmovisor manages the worrelld binary as a subprocess and automates future upgrades (a new binary just gets dropped into the right folder — no manual downtime). Install it and lay out the directory structure:
go install cosmossdk.io/tools/cosmovisor/cmd/[email protected]
Create the genesis upgrade directory and place the binary:
mkdir -p $HOME/.worrell/cosmovisor/genesis/bin
cp $HOME/go/bin/worrelld $HOME/.worrell/cosmovisor/genesis/bin/
Create the symlink so Cosmovisor points to the current version:
sudo ln -sfn $HOME/.worrell/cosmovisor/genesis $HOME/.worrell/cosmovisor/current
sudo ln -sfn $HOME/.worrell/cosmovisor/current/bin/worrelld /usr/local/bin/worrelld
Verify:
cosmovisor version
worrelld version --long | head -5
Future governance upgrades: place the new binary at
$HOME/.worrell/cosmovisor/upgrades/<UPGRADE-NAME>/bin/worrelld, and Cosmovisor will automatically swap to it when the upgrade height is reached. Announcements are posted on t.me/worrellvalidators.
Step 5 — Initialize the Node
Pick a moniker (your node's public display name) and initialize the data directory:
MONIKER="YOUR_MONIKER"
worrelld init "$MONIKER" --chain-id worrell-testnet-1
echo "export MONIKER=$MONIKER" >> $HOME/.bash_profile
echo "export WORRELL_CHAIN_ID=\"worrell-testnet-1\"" >> $HOME/.bash_profile
echo "export WORRELL_HOME=\"$HOME/.worrell\"" >> $HOME/.bash_profile
source $HOME/.bash_profile
ℹ️ Replace
YOUR_MONIKERwith your own node display name.
This populates ~/.worrell with:
config/genesis.json— genesis (replaced in the next step)config/config.toml— CometBFT configuration (peers, P2P, RPC)config/app.toml— application configuration (gas, API, gRPC)config/priv_validator_key.json— validator signing key (protect it!)config/node_key.json— node network identitycosmovisor/— Cosmovisor's own directory structure (from Step 4)
Step 6 — Download and Verify Genesis
Pull the canonical testnet genesis from the official worrellchain/networks repo and verify the checksum before continuing:
curl -s https://raw.githubusercontent.com/worrellchain/networks/main/worrell-testnet-1/genesis.json \
-o ~/.worrell/config/genesis.json
worrelld genesis validate-genesis
Verify the sha256 checksum:
sha256sum ~/.worrell/config/genesis.json
# expected: a81c507b12ba0678c3172394ff4bb03e1c3db60050cc5568c127a24ec19378fd
⚠️ If the checksum does not match, do not continue. Re-download the genesis file from the official repo.
Step 7 — Configure Peers (config.toml)
Set the persistent peer in the [p2p] section of config.toml. The up-to-date peer list is published in worrell-testnet-1/chain.json (peers section) — check it if this guide is older than a few weeks.
sed -i.bak 's|^persistent_peers *=.*|persistent_peers = "[email protected]:26656"|' "$WORRELL_HOME/config/config.toml"
Optional — advertise your public IP for inbound P2P:
# Replace <PUBLIC_IP> with your actual server IP
sed -i.bak -e "s|^external_address *=.*|external_address = \"<PUBLIC_IP>:26656\"|" "$WORRELL_HOME/config/config.toml"
Verify:
grep -E '^(persistent_peers|external_address) ' "$WORRELL_HOME/config/config.toml"
Step 8 — Set the Minimum Gas Price (app.toml)
This is mandatory for the node to accept and process transactions:
sed -i.bak 's|^minimum-gas-prices *=.*|minimum-gas-prices = "0.025uworrell"|' "$WORRELL_HOME/config/app.toml"
Recommended additional settings:
# Pruning (use "nothing" for archive nodes)
sed -i -e 's/^pruning *=.*/pruning = "default"/' "$WORRELL_HOME/config/app.toml"
sed -i -e 's/^pruning-keep-recent *=.*/pruning-keep-recent = "100"/' "$WORRELL_HOME/config/app.toml"
sed -i -e 's/^pruning-interval *=.*/pruning-interval = "10"/' "$WORRELL_HOME/config/app.toml"
By default the REST API (1317) and gRPC (9090) listen only on localhost — leave them that way unless you intend to serve public endpoints behind a reverse proxy.
Step 9 — Configure Custom Ports (Optional)
Useful if you plan to run more than one node on the same server. Enter a 2-digit prefix (e.g. 46) and rewrite the relevant ports in both files:
read -p "Enter your PORT prefix (2-digit, e.g. 46): " WORRELL_PORT
echo "export WORRELL_PORT=$WORRELL_PORT" >> $HOME/.bash_profile
source $HOME/.bash_profile
Apply to app.toml:
sed -i.bak -e "s%:1317%:${WORRELL_PORT}317%g" \
-e "s%:9090%:${WORRELL_PORT}090%g" \
-e "s%:9091%:${WORRELL_PORT}091%g" \
"$WORRELL_HOME/config/app.toml"
Apply to config.toml:
⚠️ Do NOT use a blanket
s/:26656/:XX656/greplace onconfig.toml. Yourpersistent_peersline (Step 7) also contains the literal string:26656— but that's the remote peer's port (164.68.98.186:26656) and must stay untouched. A generic global replace corrupts it into164.68.98.186:${WORRELL_PORT}656, which doesn't exist, and your node will loop forever withdial tcp ...: i/o timeout. The patterns below are anchored to the exact localladdr/proxy_applines so they can never touchpersistent_peers,seeds, orexternal_address's IP.
sed -i.bak \
-e "s|^proxy_app = \"tcp://127.0.0.1:26658\"|proxy_app = \"tcp://127.0.0.1:${WORRELL_PORT}658\"|" \
-e "s|^laddr = \"tcp://127.0.0.1:26657\"|laddr = \"tcp://127.0.0.1:${WORRELL_PORT}657\"|" \
-e "s|^laddr = \"tcp://0.0.0.0:26656\"|laddr = \"tcp://0.0.0.0:${WORRELL_PORT}656\"|" \
-e "s|^prometheus_listen_addr = \":26660\"|prometheus_listen_addr = \":${WORRELL_PORT}660\"|" \
"$WORRELL_HOME/config/config.toml"
# If you set a real external_address in Step 7, update its port too (keeps your public IP intact):
sed -i.bak -E "s|^(external_address = \"[^:\"]+):26656\"|\1:${WORRELL_PORT}656\"|" "$WORRELL_HOME/config/config.toml"
Verify — and specifically confirm persistent_peers was not touched:
grep -E '^persistent_peers' "$WORRELL_HOME/config/config.toml"
# must still show [email protected]:26656 — the REMOTE port never changes
grep -E ":(${WORRELL_PORT})" "$WORRELL_HOME/config/config.toml" | head -5
grep -E ":(${WORRELL_PORT})" "$WORRELL_HOME/config/app.toml" | head -5
If you skip this step, the defaults (
26656/26657/1317/9090) are used throughout the rest of this guide.
Step 10 — Enable Prometheus (Optional)
sed -i -e "s/prometheus = false/prometheus = true/" "$WORRELL_HOME/config/config.toml"
sed -i -e 's/^prometheus_listen_addr *=.*/prometheus_listen_addr = ":26660"/' "$WORRELL_HOME/config/config.toml"
Metrics become available at http://127.0.0.1:26660/metrics.
Step 11 — Create Systemd Service
Run the node under systemd through Cosmovisor so future upgrades are picked up automatically and the process restarts on failure — a node that restarts quickly after a crash is much less likely to be jailed for downtime.
sudo bash -c "cat > /etc/systemd/system/worrelld.service" << EOF
[Unit]
Description=worrelld node service
After=network-online.target
Wants=network-online.target
[Service]
User=$USER
ExecStart=$(which cosmovisor) run start
Restart=on-failure
RestartSec=3
LimitNOFILE=65535
Environment="DAEMON_HOME=$HOME/.worrell"
Environment="DAEMON_NAME=worrelld"
Environment="UNSAFE_SKIP_BACKUP=true"
Environment="PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin:$HOME/.worrell/cosmovisor/current/bin"
Environment="LD_LIBRARY_PATH=$HOME/.worrell"
[Install]
WantedBy=multi-user.target
EOF
sudo systemctl daemon-reload
sudo systemctl enable worrelld
Step 12 — Start the Node
sudo systemctl start worrelld
sudo journalctl -u worrelld -f --no-pager -o cat
Verify the service is running:
sudo systemctl status worrelld --no-pager
Expected output:
● worrelld.service - worrelld node service
Active: active (running) since ...
Step 13 — Verify Sync
worrelld status 2>&1 | jq '.sync_info | {latest_block_height, catching_up}'
Compare against the public REST API / explorer:
curl -s https://worrell.api.t.anode.team/cosmos/base/tendermint/v1beta1/blocks/latest \
| jq '.block.header.height'
⚠️ Wait until
catching_upisfalsebefore creating a validator. The network has State Sync enabled, allowing fast synchronization without downloading the full history — see the official validator guide if you want to configure it.
Step 14 — Create a Wallet and Fund It (Faucet)
worrelld keys add wallet
CRITICAL: Save your mnemonic phrase in a secure location. Without it, you cannot recover your wallet.
To recover an existing wallet:
worrelld keys add wallet --recover
Check your address:
worrelld keys show wallet -a
Request testnet funds from the faucet (500 WORRELL per request, rate-limited to once per hour per address):
curl -X POST http://164.68.98.186:4500 \
-H "Content-Type: application/json" \
-d "{\"address\":\"$(worrelld keys show wallet -a)\"}"
Check your balance:
worrelld query bank balances $(worrelld keys show wallet -a) \
--node https://worrell.api.t.anode.team 2>/dev/null \
|| worrelld query bank balances $(worrelld keys show wallet -a)
Step 15 — Register as a Validator
The node must be fully synchronized (
catching_up: false) before creating a validator.
15.1 Get the consensus public key
worrelld tendermint show-validator
Returns a value like {"@type":"/cosmos.crypto.ed25519.PubKey","key":"..."}.
15.2 Create the validator JSON
cat > $HOME/validator.json << EOF
{
"pubkey": $(worrelld tendermint show-validator),
"amount": "20000000000000uworrell",
"moniker": "$MONIKER",
"identity": "",
"website": "",
"security": "",
"details": "Worrell testnet validator",
"commission-rate": "0.05",
"commission-max-rate": "0.25",
"commission-max-change-rate": "0.01",
"min-self-delegation": "1000000"
}
EOF
15.3 Submit the transaction
worrelld tx staking create-validator $HOME/validator.json \
--from wallet \
--chain-id worrell-testnet-1 \
--gas auto \
--gas-adjustment 1.5 \
--gas-prices 0.025uworrell \
--yes
15.4 Field reference
| Flag / field | Example value | Meaning |
|---|---|---|
amount | 20000000000000uworrell | Initial self-delegation (20,000,000 WORRELL in this example). Adjust to your case and available balance. |
commission-rate | 0.05 | Current commission: 5%. Cannot be lower than the global network minimum (5%). |
commission-max-rate | 0.25 | Maximum commission this validator allows itself. Cannot be raised later — choose carefully. |
commission-max-change-rate | 0.01 | Maximum commission change per day: 1%. |
min-self-delegation | 1000000 | Minimum self-delegation to maintain, in uworrell. 1000000 uworrell = 1 WORRELL. |
⚠️ Critical:
min-self-delegationis expressed inuworrell, not WORRELL. To guarantee 1 WORRELL minimum, use"1000000". Never use"1"— that means 0.000001 WORRELL and leaves your validator far below the intended minimum.
ℹ️ The 5% (
0.05) minimum commission is global — no validator can go below it. The maximum commission and max daily change rate are set per-validator at creation time and the max cannot be increased afterward.
15.5 Verify the validator
worrelld query staking validator $(worrelld keys show wallet --bech val -a)
Confirm status is BOND_STATUS_BONDED and jailed is false.
Monitoring & Avoiding Jailing
Relevant slashing parameters
| Parameter | Value | Meaning |
|---|---|---|
| Signed-blocks window | 10,000 blocks | Period over which availability is measured |
| Minimum signed per window | 5% | Must sign at least 5% of blocks in the window |
| Downtime slashing | 0.01% | Slash on jailing for inactivity |
| Double-sign slashing | 5% + permanent tombstone | Slash for signing two blocks at the same height |
| Jail duration (downtime) | 1 hour on testnet / 12h on mainnet | Minimum time jailed |
To avoid jailing due to downtime:
- Run the node under
systemd+ Cosmovisor with automatic restart (Step 11). - Keep disk/CPU headroom — a node that can't keep up misses blocks.
- Never run two instances with the same
priv_validator_key.jsonat once — this causes a double sign and a 5% + permanent tombstone slash, far worse than downtime jailing. - Enable Prometheus (Step 10) and set up alerts on missed blocks.
- Subscribe to t.me/worrellvalidators for upgrade/governance announcements.
Check signing info
worrelld query slashing signing-info $(worrelld tendermint show-address)
Watch missed_blocks_counter and jailed_until.
Unjail after downtime
worrelld tx slashing unjail \
--from wallet \
--chain-id worrell-testnet-1 \
--gas auto \
--gas-adjustment 1.5 \
--gas-prices 0.025uworrell \
--yes
Useful Commands
Service Management
sudo systemctl start worrelld
sudo systemctl stop worrelld
sudo systemctl restart worrelld
sudo systemctl status worrelld
Logs & Sync
# Live logs
sudo journalctl -u worrelld -f --no-pager -o cat
# Logs from last hour
sudo journalctl -u worrelld --since "1 hour ago"
# Sync status
worrelld status 2>&1 | jq '.sync_info | {latest_block_height, catching_up}'
# Connected peers
worrelld status 2>&1 | jq '.node_info.moniker'
Wallet & Balance
# List wallets
worrelld keys list
# Show address
worrelld keys show wallet -a
# Check balance
worrelld query bank balances $(worrelld keys show wallet -a)
Staking
# Delegate tokens
worrelld tx staking delegate \
$(worrelld keys show wallet --bech val -a) 1000000uworrell \
--from wallet --chain-id worrell-testnet-1 \
--gas auto --gas-adjustment 1.5 --gas-prices 0.025uworrell -y
# Redelegate tokens
worrelld tx staking redelegate \
$(worrelld keys show wallet --bech val -a) \
<NEW_VALOPER> 1000000uworrell \
--from wallet --chain-id worrell-testnet-1 \
--gas auto --gas-adjustment 1.5 --gas-prices 0.025uworrell -y
# Undelegate tokens
worrelld tx staking unbond \
$(worrelld keys show wallet --bech val -a) 1000000uworrell \
--from wallet --chain-id worrell-testnet-1 \
--gas auto --gas-adjustment 1.5 --gas-prices 0.025uworrell -y
Rewards
# Withdraw all rewards
worrelld tx distribution withdraw-all-rewards \
--from wallet --chain-id worrell-testnet-1 \
--gas auto --gas-adjustment 1.5 --gas-prices 0.025uworrell -y
# Withdraw commission
worrelld tx distribution withdraw-rewards \
$(worrelld keys show wallet --bech val -a) \
--commission \
--from wallet --chain-id worrell-testnet-1 \
--gas auto --gas-adjustment 1.5 --gas-prices 0.025uworrell -y
Governance
# List proposals
worrelld query gov proposals
# Vote on a proposal
worrelld tx gov vote 1 yes \
--from wallet --chain-id worrell-testnet-1 \
--gas auto --gas-adjustment 1.5 --gas-prices 0.025uworrell -y
Governance parameters:
| Parameter | Standard | Expedited |
|---|---|---|
| Minimum deposit | 1,500 WORRELL | 7,500 WORRELL |
| Voting period (mainnet) | 5 days | 24 hours |
| Quorum | 33.4% | 33.4% |
| Pass threshold | 50% | 66.7% |
| Veto threshold | 33.4% | 33.4% |
Validator Operations
# Edit validator
worrelld tx staking edit-validator \
--new-moniker "NEW_MONIKER" \
--identity "YOUR_KEYBASE_ID" \
--website "https://your-website.com" \
--security-contact "[email protected]" \
--details "Your validator description" \
--from wallet --chain-id worrell-testnet-1 \
--gas auto --gas-adjustment 1.5 --gas-prices 0.025uworrell -y
# Unjail validator
worrelld tx slashing unjail \
--from wallet --chain-id worrell-testnet-1 \
--gas auto --gas-adjustment 1.5 --gas-prices 0.025uworrell -y
# Check signing info
worrelld query slashing signing-info $(worrelld tendermint show-address)
Cosmovisor Upgrades
mkdir -p $HOME/.worrell/cosmovisor/upgrades/<UPGRADE-NAME>/bin
cp <new-worrelld-binary> $HOME/.worrell/cosmovisor/upgrades/<UPGRADE-NAME>/bin/worrelld
chmod +x $HOME/.worrell/cosmovisor/upgrades/<UPGRADE-NAME>/bin/worrelld
Cosmovisor automatically swaps to the new binary and restarts worrelld once the upgrade height is reached — no manual systemctl intervention needed.
Firewall
The P2P port must be reachable from outside; keep RPC/API/gRPC restricted to localhost or trusted IPs unless you intend to serve public endpoints behind a reverse proxy.
# P2P — must be open to the public
sudo ufw allow 26656/tcp comment "worrell P2P"
# RPC — open only if you serve public endpoints
sudo ufw allow 26657/tcp comment "worrell RPC"
# REST API
sudo ufw allow 1317/tcp comment "worrell REST"
# gRPC
sudo ufw allow 9090/tcp comment "worrell gRPC"
(Adjust the port numbers if you applied the custom prefix in Step 9.)
About the Author
This guide was prepared by HazenNetworkSolutions. 🌐 hazennetworksolutions.com