posthuman - nodes
NEAR Testnet
NEAR Testnet websiteNEAR Testnet twitterNEAR Testnet discord

NEAR Testnet

type:
testnet
chain id:
testnet
  • install guide
  • contributions

NEAR Testnet Validator Guide

Testnet mirrors mainnet mechanics: neard runs the node, each epoch the validator set is decided by a stake auction, and a validator that misses the seat price simply does not validate that epoch. It is the right place to rehearse the rhythm — pool creation, ping, key rotation, upgrades — because falling out of the set is a normal event rather than an incident.

What differs from mainnet

MainnetTestnet
Chain IDmainnettestnet
Release channellatest stable taglatest release candidate
Staking-pool factorypoolv1.nearpool.f863973.m0
Pool account<name>.poolv1.near<name>.pool.f863973.m0
Owner account suffix.near.testnet
Tokensboughtfaucet
Public RPChttps://free.rpc.fastnear.comhttps://test.rpc.fastnear.com, https://rpc.testnet.near.org
Explorernearblocks.iotestnet.nearblocks.io

Epoch length is the same in blocks, so the feedback loop for "did my change work" is still hours, not minutes. Plan rehearsals accordingly.

Hardware

RoleCPURAMStorage
Chunk/block producer (recommended)8+ physical cores32 GB1 TB SSD, 15k IOPS
Chunk validator (recommended)8+ physical cores16 GB512 GB SSD
Chunk validator (minimum)8+ physical cores8 GB1.5 TB NVMe

Source: near-nodes.io archival/validator hardware.

1. Build the release candidate

Testnet runs RC builds ahead of mainnet. Check nearcore releases and pick the latest RC tag.

sudo apt update && sudo apt install -y git curl jq build-essential pkg-config \ libssl-dev clang cmake protobuf-compiler llvm curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y source "$HOME/.cargo/env" git clone https://github.com/near/nearcore && cd nearcore git fetch origin --tags git tag -l --sort=-v:refname | head -10 git checkout tags/<latest-rc-tag> -b testnet-node make neard sudo install -m 0755 target/release/neard /usr/local/bin/neard neard --version

2. Initialise

neard --home ~/.near init --chain-id testnet --download-genesis --download-config validator

The testnet genesis file is large (6 GB+) and the download runs for a long time with no progress output. That is expected.

Confirm the chain ID before starting. A node initialised against the wrong chain runs perfectly and is on the wrong network:

jq -r '.chain_id' ~/.near/genesis.json

Use --download-config rpc instead if this host is an RPC node rather than a validator, or archival for full history.

3. Refresh boot nodes and start

BOOT_NODES=$(curl -s -X POST https://rpc.testnet.near.org \ -H "Content-Type: application/json" \ -d '{"jsonrpc":"2.0","method":"network_info","params":[],"id":"dontcare"}' \ | jq -r '.result.active_peers as $active | .result.known_producers as $known | $active[] as $peer | $known[] | select(.peer_id == $peer.id) | "\(.peer_id)@\($peer.addr)"' | paste -sd "," -) cp ~/.near/config.json ~/.near/config.json.backup jq --arg newBootNodes "$BOOT_NODES" '.network.boot_nodes = $newBootNodes' \ ~/.near/config.json > ~/.near/config.tmp && mv ~/.near/config.tmp ~/.near/config.json
sudo tee /etc/systemd/system/neard.service > /dev/null <<'EOF' [Unit] Description=NEAR testnet node After=network-online.target Wants=network-online.target [Service] User=near Group=near Type=simple ExecStart=/usr/local/bin/neard --home /home/near/.near run Restart=on-failure RestartSec=30 KillSignal=SIGINT TimeoutStopSec=45 LimitNOFILE=1000000 Environment=RUST_LOG=info [Install] WantedBy=multi-user.target EOF sudo systemctl daemon-reload sudo systemctl enable --now neard journalctl -u neard -f
sudo ufw allow 22/tcp sudo ufw allow 24567/tcp comment 'NEAR P2P' sudo ufw enable

Keep 3030 on loopback. It serves both RPC and Prometheus metrics.

4. Verify sync

curl -s -X POST http://127.0.0.1:3030 -H 'Content-Type: application/json' \ -d '{"jsonrpc":"2.0","id":1,"method":"status","params":[]}' \ | jq '{chain: .result.chain_id, version: .result.version.version, height: .result.sync_info.latest_block_height, syncing: .result.sync_info.syncing}' curl -s -X POST https://rpc.testnet.near.org -H 'Content-Type: application/json' \ -d '{"jsonrpc":"2.0","id":1,"method":"status","params":[]}' \ | jq -r '.result.sync_info.latest_block_height'

syncing must be false and the two heights must be close before you go further.

5. Accounts and tokens

npm install -g near-cli-rs@latest near-validator # create a testnet account funded by the faucet near account create-account sponsor-by-faucet-service <you>.testnet \ autogenerate-new-keypair save-to-keychain network-config testnet create

Top it up at near-faucet.io. You need 30 NEAR for pool storage plus gas plus the stake you intend to self-bond.

6. Generate the staking key

near generate-keypair save-to-file ~/near-staking-key.json chmod 600 ~/near-staking-key.json

This is the key neard signs with. It is not a full-access key on any account and must never be confused with the owner key.

7. Deploy the staking pool

export OWNER=<you>.testnet export POOL=<pool-name> export STAKE_PUBKEY=ed25519:<public-key-from-step-6> near contract call-function as-transaction pool.f863973.m0 create_staking_pool \ json-args "{\"staking_pool_id\": \"$POOL\", \"owner_id\": \"$OWNER\", \"stake_public_key\": \"$STAKE_PUBKEY\", \"reward_fee_fraction\": {\"numerator\": 5, \"denominator\": 100}}" \ prepaid-gas '300.0 Tgas' \ attached-deposit '30 NEAR' \ sign-as "$OWNER" \ network-config testnet \ sign-with-keychain \ send

Your pool is now <pool-name>.pool.f863973.m0.

8. Install validator_key.json

{ "account_id": "<pool-name>.pool.f863973.m0", "public_key": "ed25519:<public-key>", "secret_key": "ed25519:<secret-key>" }
chmod 600 ~/.near/validator_key.json sudo systemctl restart neard

account_id is the pool, not the owner. The private field is secret_key, not private_key. A running neard does not reload this file — restart, never start.

9. Stake and ping

near contract call-function as-transaction "$POOL.pool.f863973.m0" deposit_and_stake \ json-args '{}' prepaid-gas '300.0 Tgas' attached-deposit '<amount> NEAR' \ sign-as "$OWNER" network-config testnet sign-with-keychain send near contract call-function as-transaction "$POOL.pool.f863973.m0" ping \ json-args '{}' prepaid-gas '300.0 Tgas' attached-deposit '0 NEAR' \ sign-as "$OWNER" network-config testnet sign-with-keychain send

Ping every epoch. Set the same systemd timer you will use on mainnet — testnet is where you find out it silently fails.

10. Confirm you are in the set

Proposals apply two epochs out.

near-validator proposals network-config testnet near-validator validators network-config testnet next near-validator validators network-config testnet now
curl -s -X POST https://rpc.testnet.near.org -H 'Content-Type: application/json' \ -d '{"jsonrpc":"2.0","id":1,"method":"validators","params":[null]}' \ | jq --arg p "$POOL.pool.f863973.m0" '.result.current_validators[] | select(.account_id==$p) | {stake, blocks: "\(.num_produced_blocks)/\(.num_expected_blocks)", chunks: "\(.num_produced_chunks)/\(.num_expected_chunks)", endorsements: "\(.num_produced_endorsements)/\(.num_expected_endorsements)"}'

Produced close to expected is the real health signal. A validator in the set producing far less than expected is being penalised, and the cause is almost always the host.

What to rehearse here before touching mainnet

  • Staking-key rotation: update_staking_key on the pool, then replace validator_key.json and restart — in that order, at the start of an epoch.
  • A neard version upgrade, including any database migration in the release notes, and the rollback path.
  • The ping timer failing, and whether your monitoring notices.
  • Commission change and its visibility to delegators.
  • Full host rebuild from backed-up keys.

Related guides

The mainnet guides apply unchanged except for the factory and network name: Installation guide, Create validator, Keys & custody, Security, Monitoring, State sync, Upgrades.


Created by POSTHUMAN validators — https://posthuman.digital