Solana ProgramsAgentRegistry

AgentRegistry is the on-chain source of truth for whether an agent exists and whether it is active. Every off-chain claim about an agent can be checked against this program.

Program ID (devnet)5jBmqyeo1vUAjHbEFuY59NMGTQR8cEe9Jvz2uCwCjp3L
FrameworkAnchor 0.30
Upgradeable?No — non-upgradeable by design (ADR-010)
Sourcepackages/contracts-solana/programs/agent-registry

Account layout

Each agent gets a Program Derived Address (PDA) keyed by its agent ID hash:

#[account]
pub struct Agent {
    pub agent_id_hash: [u8; 32],          // sha256(agent_id)
    pub did_hash: [u8; 32],               // sha256(canonical DID payload)
    pub responsible_party_hash: [u8; 32], // sha256(responsible_party_id)
    pub status: AgentStatus,              // Active | Revoked
    pub registered_at: i64,               // unix seconds
    pub revoked_at: Option<i64>,
    pub bump: u8,
}

The PDA seed is [b"agent", agent_id_hash], so anyone can re-derive the address and read the account.

Only hashes are stored — never the raw agent ID, DID payload, or responsible-party ID. This is for privacy: the on-chain record proves existence and status but doesn’t disclose the human behind the agent.

Instructions

register_agent

Writes a new Agent account in Active state.

AccountTypeNotes
agentPDAInitialized; payer-funded
authoritySignerMust be the protocol authority
payerSignerPays rent
system_programProgram
ArgTypeNotes
agent_id_hash[u8; 32]SHA-256 of the agent ID string
did_hash[u8; 32]SHA-256 of the canonical DID document
responsible_party_hash[u8; 32]SHA-256 of the responsible party UUID

Reverts if the PDA already exists.

revoke_agent

Flips status to Revoked and stamps revoked_at.

AccountTypeNotes
agentMutable PDAMust exist; must be Active
authoritySignerMust be the protocol authority

Reverts if the agent doesn’t exist or is already revoked. The protocol’s blockchain-worker calls this when a responsible party (or automated workflow) revokes an agent off-chain.

Trust model

Only the protocol authority can call register_agent or revoke_agent. This is intentional:

  • Registration requires KYC verification, which the protocol enforces off-chain
  • Revocation must follow the responsible-party authorization model
  • A public, permissionless instruction would let anyone register or revoke arbitrary agents

The authority keypair lives in AWS KMS; only the blockchain-worker service can sign with it.

Verifying an agent off-chain

import { Connection, PublicKey } from "@solana/web3.js";
import { Program, AnchorProvider } from "@coral-xyz/anchor";
import { sha256 } from "js-sha256";
 
const connection = new Connection("https://api.devnet.solana.com");
const programId = new PublicKey("5jBmqyeo1vUAjHbEFuY59NMGTQR8cEe9Jvz2uCwCjp3L");
 
// Re-derive the agent's PDA
const agentIdHash = Buffer.from(sha256("agent_b1c59d23..."), "hex");
const [agentPda] = PublicKey.findProgramAddressSync(
  [Buffer.from("agent"), agentIdHash],
  programId,
);
 
// Read it
const account = await program.account.agent.fetch(agentPda);
console.log("Status:", account.status);          // Active | Revoked
console.log("Registered:", account.registeredAt);
console.log("Revoked:", account.revokedAt);

If the account is missing → the agent was never anchored. If status is Revoked → don’t trust any authorizations from this agent regardless of what the off-chain API says.