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
Round Health
Since round 2,383 (2026-05-29) — historical rounds excluded
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
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.
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).
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.
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.