SAS attestation
Look up a wallet's Entros attestation through the Solana Attestation Service.
SAS is the recommended composability surface. Reading an attestation is one function call; the function does the PDA derivation, account fetch, and schema deserialization for you.
Lookup
import { verifyEntrosAttestation } from "@entros/pulse-sdk";
import { Connection } from "@solana/web3.js";
const connection = new Connection("https://api.devnet.solana.com");
const attestation = await verifyEntrosAttestation(walletBase58, connection);
if (!attestation) {
// wallet has no Entros attestation
}
if (attestation.expired) {
// attestation exists but has expired
}
if (attestation.isHuman && attestation.trustScore >= 250) {
// pass the gate
}The function returns null if the wallet has no attestation. Otherwise it returns:
type EntrosAttestation = {
isHuman: boolean;
trustScore: number;
verifiedAt: number;
mode: "wallet-connected" | "walletless";
expired: boolean;
};When to read the attestation versus the Anchor PDA
The attestation is a snapshot of the Anchor at verification time. The Anchor is the live source. They are usually identical; the difference matters in two cases.
The attestation has expired but the user has re-verified. A 30-day-old attestation is stale; a fresh re-verification updates the Anchor immediately and produces a fresh attestation moments later. If your application needs the most recent state, prefer the Anchor PDA directly.
The attestation says the user is verified, but the score has decayed. Trust Scores decay. The attestation snapshots the score at verification time; the live Anchor reflects the decayed score. For applications where the snapshot is the meaningful number (e.g. "did this user pass our threshold at the time of attestation"), the attestation is correct. For applications where the live score matters, read the Anchor.
A reasonable default: read the attestation for membership checks, read the Anchor for live thresholds.
Schema fields
The Entros schema, registered on SAS, has four fields:
| Field | Type | Meaning |
|---|---|---|
isHuman | bool | Whether the attestation issuer believes the wallet is operated by a verified human |
trustScore | u16 | The Trust Score recorded at attestation time |
verifiedAt | i64 | Unix timestamp of the verification this attestation snapshots |
mode | string | "wallet-connected" or "walletless" |
The schema is deployed at:
EPkajiGQjycPwcc3pupqExVdAmSfxWd31tRYZezd8c5gThe credential issuing the attestations:
GaPTkZC6JEGds1G5h645qyUrogx7NWghR2JgjvKQwTDoReading from another program
For an Anchor program that gates on the attestation rather than the underlying Anchor PDA, pass the attestation account as a constraint and deserialize the four fields. The schema layout is documented in the SAS specification; the Entros credential and schema PDAs are the two values your program needs to know.
Walletless vs wallet-connected
The Solana Attestation Service is wallet-only: every successful attestation is bound to a wallet that signed an ownership proof at issue time. The walletless tier — designed for CAPTCHA-equivalent one-shot human signals — does not write to SAS. Walletless integrations rely on a client-side ephemeral receipt produced by the executor, not a persistent on-chain attestation.
The earlier walletless-on-SAS path was removed because it created a griefing surface where any caller could issue an attestation against any target wallet pubkey without proof of control. /attest now requires wallet_address, nonce, signature, and message together on every call; missing any of those returns HTTP 400 with error: "wallet_ownership_required". See Errors → SDK and HTTP errors for the response shape.
The mode field on EntrosAttestation is preserved for forward compatibility (always "wallet-connected" in current production) and gates that depend on temporal-identity claims — re-verification cadence, accumulated score, returning-operator reasoning — can ignore it:
if (!attestation.isHuman || attestation.expired) {
// route to your no-attestation handling
}Where to look next
- Concepts: SAS Attestations—why attestations are the recommended composability surface
- Read on-chain—when to read the Anchor directly instead
- Reference: SDK—the full
verifyEntrosAttestationsignature