Lineagei
Frameworki
What's Anchor?
Batteries-included Rust framework. Ships account-validation codegen, 8-byte instruction discriminators, and an on-chain IDL — the program describes itself.
Bigger binary and higher rent in exchange for safety rails, introspection, and dev speed. The choice of a team optimizing for correctness over on-chain footprint.
Originally Coral (Armani Ferrante); now community-maintained.
What it is
The de facto standard. Rust macros (#[program], #[derive(Accounts)]) eliminate boilerplate: it auto-generates 8-byte account and instruction discriminators — SHA256("account:<Name>")[..8] and SHA256("global:<ix>")[..8] — handles Borsh (de)serialization, enforces account constraints declaratively (mut, has_one, seeds, init), and emits a JSON IDL that client libraries consume directly. The cost: Borsh copies data on every deserialize (not zero-copy), and the macro machinery adds binary bloat and compute overhead — irrelevant for ~99% of programs.
When to pick it
Building a new protocol, moving fast, or wanting maximum ecosystem compatibility. It's the beginner default and stays the right call for most production programs.
How it looks on-chain
The most recognizable framework. Every account it owns begins with an 8-byte discriminator, and the IDL is often published on-chain at a PDA derived from the program id. Both are strong, reliable fingerprints — this is the only framework we can label with confidence.
Others in the wild: Steel (Ore team — near-native performance on solana-program), Seahorse (Python → Anchor), and Poseidon & Quasar (TypeScript → Rust). Transpilers inherit their lowering target's fingerprint: a Quasar or Poseidon program that compiles down to Anchor will look like Anchor on-chain — discriminators and all.
Anchor docsFootprinti
Recovered architecturei
Reachi
Controli
What's upgrade authority?
The upgrade authority is the account allowed to replace a program's code after it's deployed.
If it's set (mutable), that key can push new bytecode at any time — including malicious code, the classic "rug" vector. If it's null (immutable / frozen), the code can never change; what 's on-chain is final. A Squads multisig sits in between — upgrades are possible but need M-of-N signers, not one hot wallet. So mutable + single hot-wallet = highest risk; immutable or multisig = stronger guarantees.
What's a verified build?
A verified build proves the program running on-chain was compiled from the public source you can read — nothing hidden.
Someone re-compiles the source in a deterministic (Docker) environment and checks the resulting bytecode is byte-for-byte identical to what's deployed; tools like solana-verify do this and record it with a verification service. "Not verified" isn't a red flag by itself — most programs simply never submit one. It just means you're trusting the deployed bytecode as-is, with no source cross-check.
Convictioni
Interface — the on-chain IDLi
5 of 13 instructions used · 8 never called in this window
Hanko — Solana Agent Trust Registry (ERC-8004 port)
Instructions 13
commit_validation
Validator commits its own re-executed result hash. Must land strictly before the deadline; because the expected value is only a commitment at this point, no `matches` verdict can (or should) be asserted here.
- validatorsignerwritable
- request
- responsewritable
- system_program
- result_hash[u8; 32]
initialize_config
Initialize the program config, setting the initial slash admin. Called once by the deployer immediately after deploy.
- authoritysignerwritable
- configwritable
- system_program
- adminpubkey
post_attestation
Post a client-signed attestation about a sealed agent. The caller MUST prepend an Ed25519 sig-verify instruction that signs `canonical_attestation_message(client, agent, score, tag, uri_hash, nonce)` under `client`'s Ed25519 keypair.
- payersignerwritable
- client
- identity
- attestationwritable
- instructions
- system_program
- scorei8
- tag_bitmapu64
- uri_hash[u8; 32]
- ed25519_sig[u8; 64]
- nonceu64
register_agent
Register a fresh agent identity and lock an initial bond. The `agent` keypair MUST co-sign so that an identity can only be created by (or with the consent of) the party that controls the agent key. This is the on-chain analogue of ERC-8004's msg.sender binding and blocks identity squatting / front-running. The Bond PDA is always created (amount may be zero) so that later `stake_bond` / `withdraw_bond` / `slash` calls never have to worry about missing state.
- ownersignerwritable
- agentsigner
- identitywritable
- bondwritable
- hanko_mint
- owner_token_accountwritable
- bond_vault_authority
- bond_vaultwritable
- token_program
- associated_token_program
- system_program
- rent
- agentcard_uristring
- domainstring
- bond_amountu64
request_validation
Requester opens a validation challenge and locks a stake against a *commitment* to the expected result. Validators independently re-execute and commit their own `result_hash` before the deadline; the requester reveals the pre-image at `resolve_validation`.
- requestersignerwritable
- identity
- requestwritable
- hanko_mint
- requester_token_accountwritable
- stake_vault_authority
- stake_vaultwritable
- token_program
- associated_token_program
- system_program
- rent
- task_hash[u8; 32]
- expected_commit[u8; 32]
- stakeu64
- deadline_tsi64
resolve_validation
Requester closes the challenge after the deadline by revealing the expected result pre-image (`expected_hash` + `salt`) that opens the stored commitment, then reclaims the escrowed stake. The off-chain indexer tallies validator `result_hash`es against the now-public `expected_hash` to drive karma.
- requestersignerwritable
- requestwritable
- hanko_mint
- requester_token_accountwritable
- stake_vault_authority
- stake_vaultwritable
- token_program
- expected_hash[u8; 32]
- salt[u8; 32]
seal_agent
Seal a pending agent. Only the owner may seal, and only once.
- ownersigner
- identitywritable
set_admin
Rotate the slash admin. Only the current admin may call this — the path used to hand governance to a Squads multisig.
- adminsigner
- configwritable
- new_adminpubkey
slash
Slash a sealed agent. Up to 50% of the bond is burned and the remainder is transferred to the reporter's ATA; the identity always transitions to `Slashed` even if the bond is empty (so a zero-bond fraud agent can still be flagged on-chain). Authority is the `Config.admin`, NOT the SPL mint authority — slashing survives a mint-authority renounce and can be handed to a multisig.
- slasher_authoritysignerwritable
- config
- identitywritable
- bondwritable
- hanko_mintwritable
- bond_vault_authority
- bond_vaultwritable
- reporter
- reporter_token_accountwritable
- token_program
- evidence_hash[u8; 32]
stake_bond
Top up an existing bond.
- ownersignerwritable
- identitywritable
- bondwritable
- hanko_mint
- owner_token_accountwritable
- bond_vault_authority
- bond_vaultwritable
- token_program
- amountu64
update_attestation
Refresh an existing (agent, client) attestation. Requires a strictly increasing `nonce` so an old signature cannot be replayed, enabling reputation to evolve over time without spawning unbounded PDAs.
- payersignerwritable
- client
- identity
- attestationwritable
- instructions
- scorei8
- tag_bitmapu64
- uri_hash[u8; 32]
- ed25519_sig[u8; 64]
- nonceu64
update_domain
Rebind a fresh domain to the identity (JWS re-verification happens off-chain).
- ownersigner
- identitywritable
- new_domainstring
withdraw_bond
Owner withdraws part of their bond. Disallowed once slashed.
- ownersignerwritable
- identitywritable
- bondwritable
- hanko_mint
- owner_token_accountwritable
- bond_vault_authority
- bond_vaultwritable
- token_program
- amountu64
Accounts 6
AgentIdentity
no fields
Attestation
no fields
Bond
no fields
Config
no fields
ValidationRequest
no fields
ValidationResponse
no fields
Types 21
AdminChangedstruct
- old_adminpubkey
- new_adminpubkey
- slotu64
- timestampi64
AgentIdentitystruct
- ownerpubkeyWallet that registered and controls this identity.
- agentpubkeyAgent's on-chain pubkey (also the seed component). The agent co-signs registration, so a Sealed identity is a real proof of key control.
- agentcard_uristringA2A AgentCard URI (`/.well-known/agent-card.json`).
- domainstringBound host domain (JWS + DNS-verified off-chain).
- bond_amountu64Currently locked bond amount (HANKO token).
- karma_snapshotu32Karma is computed entirely by the off-chain indexer; this on-chain field is always 0 in v1 and exists only as reserved space for a future governance push.
- statusAgentStatus
- registered_ati64
- bumpu8
AgentRegisteredstruct
- agentpubkey
- ownerpubkey
- bond_amountu64
- registered_ati64
- slotu64
AgentSealedstruct
- agentpubkey
- ownerpubkey
- sealed_ati64
- slotu64
AgentSlashedstruct
- agentpubkey
- reporterpubkey
- burnedu64
- paid_to_reporteru64
- evidence_hash[u8; 32]
- slotu64
- timestampi64
AgentStatusenum
- Pending
- Sealed
- Slashed
Attestationstruct
- agentpubkey
- clientpubkey
- scorei8Signed opinion, range -100 (fraud) to +100 (verified).
- tag_bitmapu64Categorical tags bitmap (e.g. `capability:image-gen | tone:polite`).
- uri_hash[u8; 32]Off-chain evidence blob hash (IPFS CID or arweave TX id, hashed).
- ed25519_sig[u8; 64]Ed25519 signature over the canonical attestation message.
- nonceu64Last accepted nonce. Monotonic replay guard: a re-attestation must carry a strictly larger nonce than the one persisted here.
- attested_ati64
- bumpu8
AttestationPostedstruct
- agentpubkey
- clientpubkey
- scorei8
- tag_bitmapu64
- nonceu64
- slotu64
- timestampi64
AttestationUpdatedstruct
- agentpubkey
- clientpubkey
- scorei8
- tag_bitmapu64
- nonceu64
- slotu64
- timestampi64
Bondstruct
- ownerpubkey
- amountu64
- bumpu8
BondStakedstruct
- agentpubkey
- ownerpubkey
- amountu64
- new_totalu64
- slotu64
- timestampi64
BondWithdrawnstruct
- agentpubkey
- ownerpubkey
- amountu64
- remainingu64
- slotu64
- timestampi64
Configstruct
- adminpubkeyAuthority permitted to call `slash`. Intended to be handed off to a Squads multisig within 30 days of mainnet launch.
- bumpu8
ConfigInitializedstruct
- adminpubkey
- slotu64
- timestampi64
DomainUpdatedstruct
- agentpubkey
- domainstring
- slotu64
- timestampi64
ValStatusenum
- Open
- Resolved
ValidationCommittedstruct
- requestpubkey
- validatorpubkey
- result_hash[u8; 32]
- commit_slotu64Slot the validator committed at. Lets an indexer subscribing to the event stream reconstruct commit ordering without fetching the ValidationResponse account.
- deadlinei64Deadline copied from the request so subscribers can flag late-arriving commits from the event alone.
- timestampi64
ValidationRequeststruct
- requesterpubkey
- agentpubkey
- task_hash[u8; 32]Task fingerprint (client-computed hash of the task specification).
- expected_commit[u8; 32]`sha256(expected_hash || salt)`. Hidden until reveal.
- expected_hash[u8; 32]Revealed expected result. All-zero until `resolve_validation` reveals it.
- stakeu64Requester stake, escrowed in the dedicated stake vault until resolution.
- deadlinei64Unix timestamp deadline; validators may only commit strictly before it.
- statusValStatus
- bumpu8
ValidationRequestedstruct
- requestpubkey
- requesterpubkey
- agentpubkey
- stakeu64
- deadlinei64
- slotu64
- timestampi64
ValidationResolvedstruct
- requestpubkey
- agentpubkey
- expected_hash[u8; 32]
- stake_refundedu64
- requesterpubkeyRequester that revealed and closed the challenge.
- resolved_ati64Timestamp of the reveal, so karma tallying can be event-driven.
- slotu64
ValidationResponsestruct
- requestpubkey
- validatorpubkey
- result_hash[u8; 32]
- commit_slotu64Slot at which the validator committed (used for tie-break ordering).
- bumpu8
Events 13
AdminChanged
no fields
AgentRegistered
no fields
AgentSealed
no fields
AgentSlashed
no fields
AttestationPosted
no fields
AttestationUpdated
no fields
BondStaked
no fields
BondWithdrawn
no fields
ConfigInitialized
no fields
DomainUpdated
no fields
ValidationCommitted
no fields
ValidationRequested
no fields
ValidationResolved
no fields
Errors 32
- 6000UriTooLongagentcard URI exceeds 128 bytes
- 6001DomainTooLongdomain exceeds 64 bytes
- 6002InvalidScoreattestation score must be in range -100..=100
- 6003AlreadySealedagent is already sealed
- 6004AgentNotSealedagent must be sealed before this operation
- 6005AgentSlashedagent has been slashed and cannot mutate
- 6006ZeroStakestake amount must be greater than zero
- 6007DeadlineInPastdeadline must be in the future
- 6008DeadlineNotReacheddeadline has not been reached yet
- 6009ValidationClosedvalidation request is not in Open state
- 6010NoBondbond has zero balance
- 6011InsufficientBondbond balance is less than requested withdrawal
- 6012MathOverflowarithmetic overflow
- 6013MissingEd25519Instructionexpected a preceding Ed25519 sig-verify instruction
- 6014InvalidEd25519Programpreceding instruction is not the Ed25519 program
- 6015MalformedEd25519Datamalformed Ed25519 sig-verify instruction data
- 6016Ed25519SignerMismatchEd25519 signer pubkey does not match the client account
- 6017Ed25519SignatureMismatchEd25519 signature bytes do not match the on-chain attestation record
- 6018CanonicalMessageMismatchcanonical attestation message does not match the signed payload
- 6019Ed25519IndexMismatchEd25519 instruction-index fields must all reference the verifier instruction itself
- 6020Ed25519LayoutMismatchEd25519 sig-verify instruction uses a non-standard offset layout
- 6021ResolverForbiddenresolver may not settle the request (requester-only)
- 6022OwnerMismatchonly the identity owner may perform this action
- 6023AdminMismatchonly the configured admin may perform this action
- 6024DeadlinePassedvalidator commit window has closed (deadline passed)
- 6025DeadlineTooFardeadline is too far in the future
- 6026CommitmentMismatchrevealed value does not match the on-chain commitment
- 6027StaleNonceattestation nonce must be strictly greater than the previous one
- 6028EmptyUriagentcard URI must not be empty
- 6029SelfAttestationForbiddenan agent may not attest to itself
- 6030SelfValidationForbiddenthe requester may not validate its own request
- 6031EmptyRevealrevealed expected result must not be all-zero
What's an IDL?
An IDL — Interface Description Language — is a JSON spec that describes how to talk to a program: its instructions, the accounts each one needs, argument and account types, events, and errors.
Anchor auto-generates it at build time. A program can publish it on-chain at a PDA derived from its id, so any client or explorer can decode the program's transactions without its source code.
Why it's often missing
Publishing is opt-in — a courtesy, not a requirement. Many programs never do, and non-Anchor frameworks (Pinocchio, native, Steel) don't produce one at all; their interface lives in an off-chain Shank/Codama artifact, or nowhere public. Absence means you can't auto-decode it — not that anything is wrong.
5 of 13 instructions used · 8 never called in this window · +2 more