Skip to content

Instantly share code, notes, and snippets.

@zmanian
Created June 20, 2025 14:53
Show Gist options
  • Save zmanian/d7cc8c5a212c39a81202b3d7340aaffe to your computer and use it in GitHub Desktop.
Save zmanian/d7cc8c5a212c39a81202b3d7340aaffe to your computer and use it in GitHub Desktop.
#!/bin/zsh
# Get bonded validators sorted by voting power (descending)
echo "Getting bonded validators sorted by voting power..."
validators=$(sommelier q staking validators --node https://sommelier-rpc.polkachu.com:443 --output json | \
jq -r '.validators[] | select(.status == "BOND_STATUS_BONDED") | [.operator_address, .tokens, .description.moniker] | @tsv' | \
sort -k2 -nr)
# Get total staking pool
echo "Getting total staking pool..."
total_bonded_tokens=$(sommelier query staking pool --node https://sommelier-rpc.polkachu.com:443 --output json | jq -r '.bonded_tokens')
# Get pubsub subscribers
echo "Getting pubsub subscribers..."
subscribers=$(sommelier q pubsub subscribers --node https://sommelier-rpc.polkachu.com:443 --output json)
echo "Checking all bonded validators for steward endpoints..."
echo "Total bonded tokens in pool: $total_bonded_tokens"
echo
# Create temporary file for subscriber mapping
temp_subscriber_map=$(mktemp)
# Build a map of validator addresses to push URLs
echo "$subscribers" | tr -d '\000-\037' | jq -r '.subscribers[] | [.address, .push_url] | @tsv' 2>/dev/null | while IFS=$'\t' read -r orchestrator_address push_url; do
[[ -z "$orchestrator_address" ]] && continue
# Get validator operator address from orchestrator address
validator_address=$(sommelier q gravity delegate-keys-by-orchestrator "$orchestrator_address" \
--node https://sommelier-rpc.polkachu.com:443 --output json 2>/dev/null | \
jq -r '.validator_address' 2>/dev/null)
if [[ -n "$validator_address" && "$validator_address" != "null" ]]; then
echo "$validator_address|$push_url" >> "$temp_subscriber_map"
fi
done
# Process each bonded validator
echo "$validators" | while IFS=$'\t' read -r operator_address tokens moniker; do
[[ -z "$operator_address" ]] && continue
# Calculate percentage of total staking pool
if [[ -n "$total_bonded_tokens" && "$total_bonded_tokens" != "0" ]]; then
percentage=$(echo "scale=2; $tokens * 100 / $total_bonded_tokens" | bc -l)
else
percentage="0.00"
fi
# Check if this validator has a steward endpoint
push_url=$(grep "^$operator_address|" "$temp_subscriber_map" | cut -d'|' -f2)
if [[ -z "$push_url" ]]; then
echo "– $moniker (${percentage}%, no steward endpoint)"
continue
fi
# Remove protocol prefix if present (http://, https://)
clean_url=$(echo "$push_url" | sed -E 's|^https?://||')
# Extract FQDN and port
if [[ "$clean_url" =~ ^([^:]+):([0-9]+)$ ]]; then
fqdn="$match[1]"
port="$match[2]"
else
echo "? $moniker (${percentage}%, invalid URL format: $push_url)"
continue
fi
# Test connectivity with netcat (timeout after 5 seconds)
if timeout 5 nc -z "$fqdn" "$port" >/dev/null 2>&1; then
echo "✓ $moniker (${percentage}%, $fqdn)"
else
echo "✗ $moniker (${percentage}%, $fqdn)"
fi
done
# Clean up temporary file
rm -f "$temp_subscriber_map"
echo
echo "Legend:"
echo "✓ - Steward endpoint reachable"
echo "✗ - Steward endpoint unreachable"
echo "– - Incomplete validator setup (no subscriber, no delegate keys, etc.)"
echo "? - Invalid steward endpoint format"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment