Validators & Rewards

Register as a protocol validator, participate in entropy rounds, and claim your share of randomness fees.

Validator Registry

Registered

0

Active

0

Min stake

1,000 XNT

Committee size

n=7 commit, m=5 reveal to finalize

Loading validators…

Round Health

Since round 2,383 (2026-05-29) — historical rounds excluded

Loading round stats…

A round is counted as failed when its WrapperRound PDA is non-aggregated and older than the maximum round duration (~7.5 min). Causes: validator ran out of funds, coordinator did not cancel a stuck CommitPhase round, or fewer than m=5 validators revealed. Track this over time to decide whether a program upgrade is warranted.

Register as Validator

Requirements: ≥1,000 XNT delegated stake, active vote account voting within 500 slots (~3 min). Stake is verified on-chain at registration and on each round refresh — offline validators are kicked automatically.

Option A — Register here (no npm)

Connect your X1 Wallet below. The connected wallet address becomes your validator identity key on-chain. Use this if your identity key is in your browser wallet.

Option B — Register on the server (no npm)

If your identity key lives on the validator server, run this single-file script — no npm install needed:

node keeper/register.js \
  --keypair ~/.config/solana/identity.json \
  --vote    <vote_pubkey> \
  --stake   <stake_pubkey>

Connect your X1 Wallet to register or deregister (Option A).

How Validators Earn

1

Register

Call register_validator with your vote account and a stake account delegated to it. The program verifies ≥1,000 XNT stake and that you voted within 500 slots. No whitelist — fully permissionless.

2

Run validator-daemon.js

Each validator runs their own daemon independently. It monitors the chain, checks your on-chain entropy-based eligibility each round, and calls commit_via_ee (SHA256(secret ‖ nonce ‖ pubkey), stakes 0.01 XNT, returned on reveal). n=7 validators are selected to commit each round; m=5 reveals suffice to finalize (up to 2 non-reveals tolerated).

3

Reveal before reveal_deadline

After commit_deadline (~200 slots / ~75s), submit your preimage before reveal_deadline (~600 slots / ~3.75 min from round init). Stake returns immediately. A ValidatorReveal PDA is written recording your contribution. Miss the deadline and you forfeit the stake.

4

Claim reward

After finalize + distribute_fees (crank earns 5%), call claim_validator_reward once per round. Pays: round_fees × 95% ÷ reveal_count. Example: 3 requests × 0.01 XNT × 95% ÷ 3 revealers = 0.0095 XNT each.

Liveness Requirements

Min stake

1,000 XNT delegated to your vote account

Max vote staleness

500 slots (~3 min) — checked at every commit

Consecutive miss limit

5 misses → validator marked inactive, excluded from rounds

Kick mechanism

Any wallet calls mark_validator_missed; slashes are automatic on finalize

Recover from inactive

Run --refresh on your validator server: VALIDATOR_KEYPAIR=~/.config/solana/identity.json node keeper/validator-daemon.js --refresh (requires cold identity key)

Committee size

Minimum 2 validators per round — single-validator entropy is impossible

Validator Daemon Setup

Each validator runs their own daemon independently. The daemon holds only the validator's own key — no other validator's keys needed. On-chain entropy-derived eligibility determines who commits each round.

Step 1 — Register (one-time, no npm required)

Use the form above (Option A), or run this directly on your server with Node.js only — no npm install:

# No npm needed — uses only built-in Node.js modules
node keeper/register.js \
  --keypair ~/.config/solana/identity.json \
  --vote    <your_vote_account_pubkey> \
  --stake   <your_stake_account_pubkey>

# Check status
node keeper/register.js --status --keypair ~/.config/solana/identity.json

# Deregister
node keeper/register.js --deregister --keypair ~/.config/solana/identity.json

Step 2 — Generate a hot key and rotate (on your validator server)

The daemon runs on a separate server with only the hot key. The identity key never leaves your validator.

# On your VALIDATOR server

# 0. Note your identity pubkey — you will need it in Step 3
solana-keygen pubkey ~/.config/solana/identity.json

# 1. Generate hot key
solana-keygen new --no-bip39-passphrase -o ~/.config/solana/x1randomness-hotkey.json

# 2. Fund the hot key (~0.5 XNT is plenty for transaction fees)
solana transfer $(solana-keygen pubkey ~/.config/solana/x1randomness-hotkey.json) 0.5 \
  --url https://rpc.mainnet.x1.xyz --keypair ~/.config/solana/identity.json

# 3. Pull latest daemon code (or clone if not already present)
#    Already have it?  cd x1-randomness-protocol && git pull
#    First time?       git clone https://github.com/Commoneffort/x1-randomness-protocol && cd x1-randomness-protocol/keeper && npm install

# 4. Rotate — identity key signs once, then stays offline forever
VALIDATOR_KEYPAIR=~/.config/solana/identity.json \
  node keeper/validator-daemon.js --rotate-authority \
  $(solana-keygen pubkey ~/.config/solana/x1randomness-hotkey.json)

# 5. Stop any daemon already running on this server (the new server takes over)
pkill -f validator-daemon.js || true

# 6. Copy ONLY the hot key to your randomness server (never copy identity.json!)
scp ~/.config/solana/x1randomness-hotkey.json user@randomness-server:~/.config/solana/

Step 3 — Set up the randomness server (separate machine)

Install Node.js, clone the repo, and start the daemon using only the hot key + your identity pubkey (no secret).

# ── On your RANDOMNESS SERVER ─────────────────────────────

# 1. Install Node.js 22 via nvm
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.3/install.sh | bash
source ~/.bashrc   # or open a new shell
nvm install 22

# 2. Clone repo and install deps
git clone https://github.com/Commoneffort/x1-randomness-protocol
cd x1-randomness-protocol/keeper
npm install

# 3. The hot key should already be at ~/.config/solana/x1randomness-hotkey.json
#    (copied from validator server in Step 2)

# 4. Set up systemd service
# Replace AAAAAA...  with your validator identity pubkey (base58, public — no secret)
sudo tee /etc/systemd/system/x1randomness-validator.service << 'EOF'
[Unit]
Description=X1 Randomness Protocol Validator Daemon
After=network.target

[Service]
User=YOUR_USER
Environment=VALIDATOR_IDENTITY_PUBKEY=YOUR_IDENTITY_PUBKEY_BASE58
Environment=X1_RANDOMNESS_KEYPAIR=/home/YOUR_USER/.config/solana/x1randomness-hotkey.json
ExecStart=/home/YOUR_USER/.nvm/versions/node/v22.22.2/bin/node /home/YOUR_USER/x1-randomness-protocol/keeper/validator-daemon.js --loop
WorkingDirectory=/home/YOUR_USER/x1-randomness-protocol/keeper
Restart=always
RestartSec=10
StandardOutput=journal
StandardError=journal

[Install]
WantedBy=multi-user.target
EOF

sudo systemctl daemon-reload
sudo systemctl enable x1randomness-validator
sudo systemctl start x1randomness-validator

# 5. Check logs
sudo journalctl -u x1randomness-validator -f

Reactivation (if your validator goes inactive)

After 5 missed rounds the protocol marks your validator inactive. The daemon cannot fix this itself — run this on your validator server:

# On your VALIDATOR server (where identity.json lives)
VALIDATOR_KEYPAIR=~/.config/solana/identity.json \
  node keeper/validator-daemon.js --refresh

The identity key (cold) signs only registration, rotation, and reactivation — all one-time or rare operations. The hot key (on the randomness server) handles all daily operations: commit, reveal, open new rounds (init_ee_round), and claim rewards. The crank (run-round.js) is separate and permissionless — any wallet can run it and earn the 5% crank reward.

Your Pending Rewards

Connect your X1 Wallet to see your ValidatorReveal PDAs and pending rewards.