Beacon Real-Time Data: Validator Monitoring

This document explains the process of utilizing ZettaBlock's Beacon real-time data to monitor a validators state, balance as well as other fields.

Both for Liquid Staking (LSTs) and Liquid Restaking (LRTs) protocols, monitoring their validator node is one of the most crucial requirements.

πŸ“˜

Find the query here.

The SQL query below is designed to fetch information about a validator based on the validator's pubkey.

πŸ”

Feel free to change the pubkey filter to test with your own node, or if you know the index (validatorIndex) field, feel free to filter using this. Beacon Holesky is also supported!

select
*
from beacon_mainnet.validators
where pubkey = '0xaf5a20ae1f9d3fa1913923b05a5d3d0e7982c29c7c42684eedc41aa34a87fba5731fdb906b1ee08050f46e59263794f0'
order by index desc

What is also important is monitoring deposits of a validator(s) of interest, see bellow:

with validators_of_interest as (
select
  index as validator_index,
  withdrawal_credentials,
  pubkey,
  balance,
  status
from beacon_mainnet.validators
where pubkey IN ('0xaf5a20ae1f9d3fa1913923b05a5d3d0e7982c29c7c42684eedc41aa34a87fba5731fdb906b1ee08050f46e59263794f0',
  '0xb18adb5c8ec3f775127307e00f6f619e2bf9e5547377c286cbe44a049dfd473e441836436852caa3471110d1388a1e7e'
)
)
SELECT
  v.validator_index,
  v.balance as latest_balance,
  v.status as latest_status,
  d.index as deposit_index,
  d.slot_number as deposit_slot,
  d.amount as deposit_amount,
  d.block_time as deposit_time,
  d.block_hash as deposit_l1_block_hash,
  d.signature as deposit_signature,
  v.withdrawal_credentials,
  v.pubkey,
  d.proof as deposit_proof,
  d.block_date as deposit_date
FROM validators_of_interest as v
INNER JOIN beacon_mainnet.deposits as d
ON d.pubkey=v.pubkey
ORDER BY slot_number DESC
LIMIT 1000

πŸ“˜

Find the query here.

Also important is monitoring withdrawals of a validator(s) of interest, see bellow:

with validators_of_interest as (
select
  index as validator_index,
  withdrawal_credentials,
  pubkey,
  balance,
  status
from beacon_mainnet.validators
where pubkey IN ('0xaf5a20ae1f9d3fa1913923b05a5d3d0e7982c29c7c42684eedc41aa34a87fba5731fdb906b1ee08050f46e59263794f0',
  '0xb18adb5c8ec3f775127307e00f6f619e2bf9e5547377c286cbe44a049dfd473e441836436852caa3471110d1388a1e7e'
)
)
SELECT
  v.validator_index,
  v.balance as latest_balance,
  v.status as latest_status,
  w.index as withdarawal_index,
  w.slot_number as withdrawal_slot,
    ROW_NUMBER() OVER (
        PARTITION BY slot_number
        ORDER BY
          w.INDEX
      ) - 1 AS withdrawal_index_normalized,
  w.amount as withdrawal_amount,
  w.address as withdrawal_address,
  w.block_time as withdrawal_time,
  w.block_hash as withdrawal_l1_block_hash,
  v.withdrawal_credentials,
  v.pubkey,
  w.block_date as withdrawal_date
FROM validators_of_interest as v
INNER JOIN beacon_mainnet.withdrawals as w
ON w.validator_index=v.validator_index
ORDER BY slot_number DESC
LIMIT 1000

πŸ“˜

Find the query here.

Creating Real-Time API

Once you run any of the above queries, you can create the GraphQL endpoint with one click, click on Use and fill in the following (for example):

And voila, you have your API that can be queried from your application.