Secure validator with HW wallet
This guide updates your vote account’s withdraw authority from a local keypair (id.json) to a Ledger hardware wallet address, without plugging the Ledger into the server.
Step 1 — Check your current vote account (server)
On your server:
solana show-vote-account <VOTE_PUBKEY>Confirm the Withdraw Authority matches the id.json key you plan to replace.
Verify the pubkey of id.json:
solana-keygen pubkey ~/.config/solana/id.jsonThis ensures you’re confirming the correct
id.jsonkey before updating its withdraw authority.
Step 2 — Get your Ledger’s public key (on your computer)
Plug in your Ledger, open the Solana app, and run:
solana-keygen pubkey "usb://ledger?key=0/0"Copy the output — this is your Ledger withdraw authority address:
<LEDGER_PUBKEY>You only need the public key. No Ledger connection is required on the server.
Step 3 — Set your RPC cluster (server)
Example for X1 testnet:
solana config set --url https://rpc.testnet.x1.xyzStep 4 — Change the withdraw authority (server)
Run this on the server:
solana vote-authorize-withdrawer-checked \
<VOTE_PUBKEY> \
~/.config/solana/id.json \
<LEDGER_PUBKEY> \
--fee-payer ~/.config/solana/id.json \
--url https://rpc.testnet.x1.xyzSigns with your current withdraw authority (
id.json)Assigns your Ledger as the new withdraw authority
Pays the transaction fee from the same account
You are changing who can withdraw rewards. Validator operations are unaffected.
Step 5 — Verify on-chain (server or computer)
solana show-vote-account <VOTE_PUBKEY> --url https://rpc.testnet.x1.xyz | grep "Withdraw Authority"You should see:
Withdraw Authority: <LEDGER_PUBKEY>Step 6 — Back up and clean up (server)
🔐 Back up id.json safely
id.json safelyCreate a structured backup and store it in your password manager or encrypted vault:
mkdir -p ~/X1-backups/keys
cp ~/.config/solana/id.json ~/X1-backups/keys/
PUBKEY=$(solana-keygen pubkey ~/X1-backups/keys/id.json)
SHA256=$(shasum -a 256 ~/X1-backups/keys/id.json | awk '{print $1}')
cat > ~/X1-backups/keys/id_key_metadata.txt <<EOF
--- PRIVATE KEY (id.json) ---
$(cat ~/X1-backups/keys/id.json)
--- PUBLIC KEY ---
$PUBKEY
--- SHA256 (file checksum) ---
$SHA256
EOFIf you’re on macOS:
pbcopy < ~/X1-backups/keys/id_key_metadata.txt
echo "✅ id_key_metadata.txt copied to clipboard — paste it into your password manager."🔒 Tighten permissions
chmod 700 ~/.config/solana
chmod 600 ~/.config/solana/*.jsonThis ensures only your current Linux user can access key files — protecting against accidental leaks or unauthorized reads.
Final State
Validator identity
identity.json
Operates the validator node
Vote account
vote.json
Account linked to validator for consensus/rewards
Withdraw authority (new)
Ledger hardware wallet
Securely holds withdraw rights
Withdraw authority (old)
id.json (backed up)
Former hot key, no longer used as withdraw authority
Troubleshooting
“insufficient funds for fee”
id.jsonhas 0 balance. Send a small amount of testnet XNT to it before retrying.“Signature verification failed”
id.jsonis not the current withdraw authority for this vote account, or you’re pointed at the wrong cluster.“This account may not be used to pay transaction fees” You tried to use a restricted account (e.g., validator identity) as fee-payer. Use a normal wallet or
id.jsonitself.
Last updated

