@skeet-framework/solana-utils
Version:
Skeet Framework Plugin - Solana Utils
75 lines (71 loc) • 2.56 kB
text/typescript
import { ValidatorStatusParams } from '@/solanaUtilsTypes'
import * as solanaWeb3 from '@solana/web3.js'
/**
* Checks whether a validator is active on the Solana network.
*
* @param endpoint - The URL of the Solana RPC endpoint.
* @param voteAccountPubkey - The public key of the validator's vote account.
* @returns A `ValidatorStatusParams` object containing the validator's public key, activity status, and the reason for that status.
*
* @example
* ```typescript
* const endpoint = 'https://api.mainnet-beta.solana.com'
* const voteAccountPubkey = 'ExampleVoteAccountPubkey'
*
* const status = await isValidatorActive(endpoint, voteAccountPubkey)
* console.log(`Validator status: ${JSON.stringify(status)}`)
* ```
*
* @throws Throws an error if there is a problem accessing the network or querying validator status.
*/
export const isValidatorActive = async (
endpoint: string,
voteAccountPubkey: string,
) => {
try {
const connection = new solanaWeb3.Connection(endpoint, 'confirmed')
const voteAccounts = await connection.getVoteAccounts()
const validator = voteAccounts.current.find(
(v) => v.votePubkey === voteAccountPubkey,
)
if (!validator) {
// Validator is not in the current list, it might be delinquent.
const delinquentValidator = voteAccounts.delinquent.find(
(v) => v.votePubkey === voteAccountPubkey,
)
if (delinquentValidator) {
return {
pubkey: voteAccountPubkey,
isActive: false,
reason: 'Validator is delinquent.',
} as ValidatorStatusParams
} else {
return {
pubkey: voteAccountPubkey,
isActive: false,
reason:
'Validator is not found in both current and delinquent lists.',
} as ValidatorStatusParams
}
}
// Check the last vote timestamp.
const lastVoteSlot = validator.lastVote
const currentSlot = await connection.getSlot()
const slotsSinceLastVote = currentSlot - lastVoteSlot
if (slotsSinceLastVote > 128) {
// This is an arbitrary number, adjust based on your needs.
return {
pubkey: voteAccountPubkey,
isActive: false,
reason: `Validator has not voted for ${slotsSinceLastVote} slots.`,
} as ValidatorStatusParams
}
return {
pubkey: voteAccountPubkey,
isActive: true,
reason: 'Validator is active and voting.',
} as ValidatorStatusParams
} catch (error) {
throw new Error(`Error checking validator status: ${error}`)
}
}