Read on-chain (no SDK)
Direct PDA read for server actions, edge functions, Anchor programs, and any non-JS context.
The on-chain Anchor PDA is the source of truth for every other read path. Going directly to it removes one layer of dependency and works in any environment that can call a Solana RPC.
The TypeScript pattern
The same code path as the quickstart, shown here as a complete server action:
"use server";
import { Connection, PublicKey } from "@solana/web3.js";
const ENTROS_ANCHOR_PROGRAM_ID = new PublicKey(
"GZYwTp2ozeuRA5Gof9vs4ya961aANcJBdUzB7LN6q4b2",
);
const RPC_URL = process.env.SOLANA_RPC_URL ?? "https://api.devnet.solana.com";
export async function checkVerification(
walletBase58: string,
minScore = 100,
maxAgeSeconds = 86_400,
): Promise<{ verified: boolean; score: number | null }> {
const wallet = new PublicKey(walletBase58);
const [pda] = PublicKey.findProgramAddressSync(
[Buffer.from("identity"), wallet.toBuffer()],
ENTROS_ANCHOR_PROGRAM_ID,
);
const account = await new Connection(RPC_URL).getAccountInfo(pda);
if (!account) return { verified: false, score: null };
const lastVerifiedAt = Number(account.data.readBigInt64LE(48));
const score = account.data.readUInt16LE(60);
const age = Math.floor(Date.now() / 1000) - lastVerifiedAt;
return { verified: score >= minScore && age <= maxAgeSeconds, score };
}The Rust pattern
For an Anchor program that gates an instruction on Entros verification, declare the IdentityState PDA as a read-only account constraint and inspect the score in the instruction body:
use anchor_lang::prelude::*;
declare_id!("YourProgram11111111111111111111111111111111");
const ENTROS_ANCHOR: Pubkey = pubkey!("GZYwTp2ozeuRA5Gof9vs4ya961aANcJBdUzB7LN6q4b2");
#[derive(Accounts)]
pub struct DoSomething<'info> {
pub user: Signer<'info>,
#[account(
seeds = [b"identity", user.key().as_ref()],
bump,
seeds::program = ENTROS_ANCHOR,
)]
/// CHECK: PDA owned by entros-anchor; we read the trust_score field manually.
pub identity_state: AccountInfo<'info>,
}
pub fn do_something(
ctx: Context<DoSomething>,
min_score: u16,
max_age_secs: i64,
) -> Result<()> {
let data = ctx.accounts.identity_state.try_borrow_data()?;
let last_verified = i64::from_le_bytes(data[48..56].try_into().unwrap());
let trust_score = u16::from_le_bytes(data[60..62].try_into().unwrap());
let now = Clock::get()?.unix_timestamp;
require!(trust_score >= min_score, ErrorCode::InsufficientTrust);
require!(
now.saturating_sub(last_verified) <= max_age_secs,
ErrorCode::VerificationExpired
);
Ok(())
}The PDA is owned by entros-anchor; your program reads its bytes but does not write to it.
The Python pattern
from solders.pubkey import Pubkey
from solana.rpc.api import Client
ENTROS_ANCHOR = Pubkey.from_string("GZYwTp2ozeuRA5Gof9vs4ya961aANcJBdUzB7LN6q4b2")
def read_anchor(client: Client, wallet: Pubkey) -> tuple[int, int] | None:
"""Returns (trust_score, last_verified_at) or None if never verified."""
pda, _ = Pubkey.find_program_address([b"identity", bytes(wallet)], ENTROS_ANCHOR)
info = client.get_account_info(pda).value
if info is None:
return None
last_verified_at = int.from_bytes(info.data[48:56], "little", signed=True)
trust_score = int.from_bytes(info.data[60:62], "little")
return trust_score, last_verified_atWhat you cannot do without the SDK
- Verification. Submitting a new proof requires the Pulse SDK's capture and proof-generation pipeline. There is no direct path to write to the Anchor PDA without going through the verifier program.
- Attestation issuance. SAS attestations are issued by the Entros executor on successful verification. Direct issuance from a client is not a supported path.
The read patterns above cover scoring, display, and gating. Read both fields: trust_score for how consistently a wallet has verified, and last_verification_timestamp for how long ago it last did.
For a claim, a vote, or anything else worth the friction, have the client run a verification at the point of the action so the Anchor you read was written moments earlier. Writes go through the SDK.
Where to look next
- Reference: PDAs—every seed and derivation in one place
- Reference: Programs—full instruction set for the on-chain programs