Entros_docs
Integrate

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:

FieldTypeMeaning
anchorPdastringOperator's Entros Anchor PDA (base58)
trustScorenumberOperator's Trust Score at the time of attestation
verifiedAtnumberUnix timestamp when the operator was last verified
walletstringOperator'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:

  1. Reads the operator's Entros Anchor PDA from entros-anchor.
  2. Extracts trustScore and the last-verification timestamp from the on-chain account.
  3. JSON-serializes the four fields (anchorPda, trustScore, verifiedAt, wallet) and wraps them in the registry's Borsh Vec<u8> envelope.
  4. Calls the registry's set_metadata_pda instruction 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+");
}

trustScore and verifiedAt on this object are the values written when the operator linkage was attested, and that linkage is immutable. They describe the operator at that moment, which is the right signal for provenance and for auditing who registered what.

For a registration flow that acts on the answer now, read the operator's Anchor PDA as well and check last_verification_timestamp against your own window. Registering a new agent is also a natural place to ask the operator for a verification, which makes the score you read describe someone present.

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 ones.

Program IDs

NetworkRegistry program ID
Devnet8oo4J9tBB3Hna1jRQ3rWvJjojqM5DYTDJo5cejUuJy3C
Mainnet8oo4dC4JvBLwy5tGgiH3WwK4B9PWxL9Z4XjA2jzkQMbQ

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"),
    new PublicKey(agentAsset).toBuffer(),
    keyHash,
  ],
  REGISTRY_PROGRAM_ID,
);

Where to look next

On this page