v0.3.0TypeScriptMIT
s0nar SDK
Read Solana network health from on-chain oracle accounts. s0nar-sdk wraps oracle accounts into typed objects and exposes read methods, instruction builders, event listeners, PDA helpers, and score utilities.
Install
shell
pnpm add s0nar-sdk @solana/web3.jsA wallet is optional — only required when composing write transactions.
Quick start
typescript
import { Connection } from "@solana/web3.js";
import { createS0narClient } from "s0nar-sdk";
const connection = new Connection("https://api.devnet.solana.com");
const client = createS0narClient({ connection });
const health = await client.getNetworkHealth();
console.log(health.healthScore); // 0–100
console.log(health.tpuReachabilityPct); // validator reachability %
console.log(health.avgSlotLatencyMs); // slot propagation latency
console.log(health.agaveCount); // validator client diversityClient diversity counts and stake-weighted reach are returned on
NetworkHealth, RegionScore, and Attestation.Client
typescript
const client = createS0narClient({
connection, // required — Solana RPC connection
programId, // optional — defaults to s0nar devnet program
wallet, // optional — needed for instruction builders
});| Option | Type | Required | Description |
|---|---|---|---|
connection | Connection | Yes | Solana RPC connection. |
programId | PublicKey | No | Override the default s0nar devnet program ID. |
wallet | Wallet | No | Anchor wallet for instruction builders. |
Read methods
| Method | Returns | Description |
|---|---|---|
getNetworkHealth() | Promise<NetworkHealth> | Global score, latency, reachability, and per-region scores. |
getRegistry() | Promise<Registry> | Program authority, observer counts, stake config, and pause state. |
getObserver(pubkey) | Promise<Observer> | Single observer account by wallet public key. |
getAllObservers() | Promise<Observer[]> | All observer accounts via getProgramAccounts. |
getObserversByRegion(region) | Promise<Observer[]> | Observer accounts filtered by Region enum. |
Read methods perform direct RPC account reads and return plain TypeScript objects. For production UIs, wrap reads in retry and cache logic.
Types
NetworkHealth
| Field | Type | Description |
|---|---|---|
healthScore | number | Global 0–100 health score. |
tpuReachabilityPct | number | Percent of probed TPU endpoints reachable. |
avgSlotLatencyMs | number | Average slot propagation latency in ms. |
activeObserverCount | number | Observers included in the current score. |
activeRegionCount | number | Regions with active data. |
lastUpdatedSlot | bigint | Slot of the last score update. |
lastUpdatedTs | bigint | Unix timestamp of the last score update. |
totalAttestations | bigint | Lifetime submitted attestations. |
regionScores | RegionScore[] | Per-region score breakdown. |
minHealthEver | number | null | Lowest global score observed. |
maxHealthEver | number | Highest global score observed. |
agaveCount | number | Network-wide Agave validators seen. |
firedancerCount | number | Network-wide Firedancer validators seen. |
jitoCount | number | Network-wide Jito validators seen. |
solanaLabsCount | number | Network-wide Solana Labs validators seen. |
otherCount | number | Network-wide other-client validators seen. |
RegionScore
| Field | Type | Description |
|---|---|---|
region | Region | Region enum value. |
observerCount | number | Observer contributions in this aggregate. |
healthScore | number | Regional 0-100 health score. |
reachabilityPct | number | Regional TPU reachability percent. |
avgRttUs | number | Average RTT in microseconds. |
slotLatencyMs | number | Slot propagation latency in ms. |
agaveCount | number | Agave validators seen in this region. |
firedancerCount | number | Firedancer validators seen in this region. |
jitoCount | number | Jito validators seen in this region. |
solanaLabsCount | number | Solana Labs validators seen in this region. |
otherCount | number | Other-client validators seen in this region. |
reachableStakePct | number | Stake-weighted reachability for this region. |
Observer
| Field | Type | Description |
|---|---|---|
publicKey | PublicKey | Observer account address. |
authority | PublicKey | Wallet authorized to report. |
region | Region | Observer region enum value. |
stakeLamports | bigint | Registered stake amount. |
lastAttestationSlot | bigint | Latest submitted attestation slot. |
attestationCount | bigint | Total attestations submitted. |
latestAttestation | Attestation | Latest measurement payload. |
isActive | boolean | Whether the observer is active. |
Attestation
| Field | Type | Description |
|---|---|---|
slot | bigint | Solana slot measured. |
timestamp | bigint | Measurement timestamp. |
avgRttUs | number | Average RTT in microseconds. |
p95RttUs | number | P95 RTT in microseconds. |
slotLatencyMs | number | Slot propagation latency in ms. |
tpuReachable | number | Reachable validators probed. |
tpuProbed | number | Total validators probed. |
agaveCount | number | Agave validators seen. |
firedancerCount | number | Firedancer validators seen. |
jitoCount | number | Jito validators seen. |
solanaLabsCount | number | Solana Labs validators seen. |
otherCount | number | Other-client validators seen. |
reachableStakePct | number | Reachable stake share. |
Registry
| Field | Type | Description |
|---|---|---|
authority | PublicKey | Program authority. |
pendingAuthority | PublicKey | null | In-progress authority transfer target. |
minStakeLamports | bigint | Minimum observer stake to register. |
observerCount | number | Total registered observers. |
activeCount | number | Currently active observers. |
maxObservers | number | Registry capacity. |
paused | boolean | Whether writes are paused. |
version | number | Registry schema version. |
Helpers
| Function | Returns | Description |
|---|---|---|
healthStatus(health, currentSlot?) | "healthy" | "degraded" | "critical" | "stale" | Human-readable health state. |
isStale(health, currentSlot) | boolean | True when oracle data is older than 150 slots. |
isObserverStale(observer, currentSlot) | boolean | True when an observer has not reported recently. |
isDegraded(health, threshold?) | boolean | True when score is below threshold (default 70). |
regionLabel(region) | string | UI label for a Region enum value. |
lamportsToSol(lamports) | number | Converts bigint lamports to SOL. |
latencyScore(slotLatencyMs) | number | Computes the latency component of the score formula. |
isConsensusCritical(reachableStakePct) | boolean | True when stake reach is below the 67% finality threshold. |
stakeReachStatus(reachableStakePct) | "healthy" | "degraded" | "critical" | Classifies stake-weighted reachability. |
dominantClient(region) | "agave" | "firedancer" | "jito" | "other" | Returns the largest validator client count in a region. |
clientDiversityIndex(region) | number | 0-100 score; higher means a more even client distribution. |
Score formula
healthScore = (reachabilityPct × 0.70) + (latencyScore × 0.30)
latencyScore = max(0, (400 − slotLatencyMs) × 100 / 400)
Events
typescript
const id = client.onAttestationSubmitted((event, slot) => {
console.log(event.observer.toBase58(), event.score, slot);
});
await client.removeEventListener(id);| Method | Event type |
|---|---|
onAttestationSubmitted(cb) | AttestationSubmittedEvent |
onObserverRegistered(cb) | ObserverRegisteredEvent |
onObserverDeregistered(cb) | ObserverDeregisteredEvent |
onObserverSlashed(cb) | ObserverSlashedEvent |
onConfigUpdated(cb) | ConfigUpdatedEvent |
removeEventListener(id) | Promise<void> |
Instruction builders
All builders return Promise<TransactionInstruction>. Compose the instruction into your own transaction and signing flow.
| Builder | Caller | Description |
|---|---|---|
registerObserver(observer, region) | New observer | Register a new observer with a region. |
submitAttestation(authority, params) | Existing observer | Submit a new attestation payload. |
deregisterObserver(caller, observerWallet) | Observer or authority | Remove an observer from the registry. |
crankAggregation(cranker, observerAccounts) | Anyone | Aggregate observer scores on-chain. |
initialize(authority, minStakeLamports, maxObservers) | Authority | First-time program setup. |
slashObserver(authority, observerWallet, treasury, slashBps) | Authority | Slash an observer's stake by basis points. |
updateConfig(authority, params) | Authority | Update program configuration. |
proposeAuthority(authority, newAuthority) | Authority | Initiate a two-step authority transfer. |
acceptAuthority(newAuthority) | New authority | Confirm a pending authority transfer. |
Two-step transfer: call
proposeAuthority first, then acceptAuthority from the new authority wallet to confirm.PDAs & regions
| Helper | Returns |
|---|---|
getRegistryPDA(programId?) | [PublicKey, number] |
getNetworkHealthPDA(programId?) | [PublicKey, number] |
getObserverPDA(observer, programId?) | [PublicKey, number] |
Region enum
Region.AsiaRegion.USRegion.EURegion.SouthAmericaRegion.AfricaRegion.OceaniaRegion.Other