Agent Anchor
Link a registered AI agent on the Solana Agent Registry to its verified human operator.
The Solana Agent Registry (the Solana implementation of the ERC-8004 agent identity spec) gives autonomous agents a canonical on-chain record. Agent Anchor extends that record with a metadata entry pointing to the operator's Entros Anchor—turning anonymous agent registrations into "Know Your Agent."
What it does
A registered agent on the registry has an agentAsset PDA. Agent Anchor writes a metadata entry against that PDA with four fields:
| Field | Type | Meaning |
|---|---|---|
anchorPda | string | Operator's Entros Anchor PDA (base58) |
trustScore | number | Operator's Trust Score at the time of attestation |
verifiedAt | number | Unix timestamp when the operator was last verified |
wallet | string | Operator's wallet pubkey (base58) |
The metadata is JSON-serialized inside the registry's Borsh Vec<u8> envelope, keyed under entros:human-operator, and marked immutable—once written, the operator linkage is permanent.
Attest a human operator
import { attestAgentOperator } from "@entros/pulse-sdk";
const agentAsset = "YourAgentAssetPubkey..."; // base58 string
const result = await attestAgentOperator(agentAsset, { wallet, connection });
if (!result.success) {
console.error(result.error);
}attestAgentOperator does four things in sequence:
- Reads the operator's Entros Anchor PDA from
entros-anchor. - Extracts
trustScoreand the last-verification timestamp from the on-chain account. - JSON-serializes the four fields (
anchorPda,trustScore,verifiedAt,wallet) and wraps them in the registry's BorshVec<u8>envelope. - Calls the registry's
set_metadata_pdainstruction to write the payload, marked immutable.
The wallet calling attestAgentOperator must be both the agent's owner on the registry and the holder of the operator Anchor.
Read the operator metadata
Any program—or any client—can read the operator linkage:
import { getAgentHumanOperator } from "@entros/pulse-sdk";
const operator = await getAgentHumanOperator(agentAsset, connection);
if (operator) {
console.log(`Trust Score: ${operator.trustScore}`);
console.log(`Verified at: ${new Date(operator.verifiedAt * 1000)}`);
}Returns null if no operator metadata is set, or { anchorPda, trustScore, verifiedAt, wallet } otherwise.
Gate a platform on operator score
Platforms accepting agent registrations can require a minimum operator Trust Score:
const operator = await getAgentHumanOperator(agentAsset, connection);
if (!operator || operator.trustScore < 500) {
return rejectAgent("operator must be a verified human with Trust Score 500+");
}This pattern turns "anyone can register an agent" into "any verified human with a sustained track record can register an agent." It does not stop a determined operator from registering many agents; combined with rate limits or per-operator caps, it stops the cheap-to-mass-register attacks.
Program IDs
| Network | Registry program ID |
|---|---|
| Devnet | 8oo4J9tBB3Hna1jRQ3rWvJjojqM5DYTDJo5cejUuJy3C |
| Mainnet | 8oo4dC4JvBLwy5tGgiH3WwK4B9PWxL9Z4XjA2jzkQMbQ |
The metadata PDA is derived from the agent asset and the first 16 bytes of the SHA256 hash of the metadata key. The SDK does this internally; the equivalent client-side derivation is:
const META_KEY = "entros:human-operator";
const keyBytes = new TextEncoder().encode(META_KEY);
const keyHashBuffer = await crypto.subtle.digest("SHA-256", keyBytes);
const keyHash = new Uint8Array(keyHashBuffer).slice(0, 16);
const [metaPda] = PublicKey.findProgramAddressSync(
[
new TextEncoder().encode("agent_meta"),
agentAsset.toBuffer(),
keyHash,
],
REGISTRY_PROGRAM_ID,
);Where to look next
- Concepts: Anchor PDA—the operator's Entros Anchor that this metadata points at
- Reference: SDK—full signatures of
attestAgentOperatorandgetAgentHumanOperator