Trango ComputeContextIQ
ERC-8004x402agent identityagent commerceENSDIDEASBasepre-payment check

Claimed vs Verified: What ERC-8004 Agent Identity Evidence Actually Proves Before an x402 Payment

What ERC-8004 agent identity evidence proves: on-chain getAgentWallet, ENS/DID/email linkage claimed vs verified, and .well-known ownership, before an x402 payment.

October 2, 2026Trango Compute Inc.

An ERC-8004 registration answers one question: did someone mint an agent identity? It doesn't answer the question an agent about to sign an x402 payment actually has: is the party behind this endpoint who they say they are? Those are different claims with different evidence, and a scoring system that blurs them hands out trust it hasn't earned.

This post describes how ContextIQ's Policy Check and ERC-8004 Inspector keep them apart. Every identity signal is labelled verified or claimed, and endpoint ownership is checked against the domain itself. If you're new to the standard, start with What Is ERC-8004?.

The Problem: Registration Is Cheap

Minting an agent ID on the ERC-8004 Identity Registry costs gas and nothing else. The registration file the token points to is self-authored: the registrant chooses the name, the services, and whether to list an ENS name, a DID, or an email address. Anyone can list research-agent.eth without owning it.

So an identity check that only asks "is there a registration, a wallet and a filled-in metadata file?" mostly measures effort to look legitimate. It rewards all of it whether or not any of it was independently checked.

The fix isn't to distrust everything. It's to record, for each signal, who vouches for it.

Three Kinds of Evidence

1. Agent wallet: authoritative, read from the chain

The payment wallet comes from the Identity Registry's getAgentWallet(agentId), not from the registration file. The EIP states that agentWallet is reserved, can't be set through setMetadata(), and is automatically cleared when the agent NFT is transferred, so the new owner must re-verify it.

That last property matters: a wallet that was valid for the previous owner can't silently carry over. The Inspector reports exactly what the call returned:

agentWalletEvidence.statusMeaning
verifiedgetAgentWallet returned a non-zero address (isAuthoritative: true)
zero_addressThe call succeeded and returned 0x000… — no wallet set, or cleared by a transfer
missingThe call reverted
unknownThe RPC request itself failed, so the chain was never actually asked (isAuthoritative: false)

The unknown case is the one that's easy to get wrong. Treating a failed RPC call as "no wallet" would penalize an agent for an infrastructure hiccup.

2. Human linkage: declared is not verified

Registration files commonly declare ENS, DID, email and web entries under services (older files used endpoints; both are read). ContextIQ parses these and reports them as:

{
  "humanLinkage": {
    "status": "claimed",
    "confidence": "medium",
    "sources": [
      { "type": "ENS", "value": "research-agent.eth", "verification": "declared", "weight": "weak" },
      { "type": "DID", "value": "did:web:research-agent.example", "verification": "declared", "weight": "weak" }
    ],
    "summary": "Agent declares ENS and DID, but no external proof-of-human signal was verified."
  }
}

The rules are deliberately strict:

  • ENS, DID, email and web values are claimed linkage. We don't resolve the ENS name or the DID document, so they stay declared.
  • Confidence is low for one declared type and medium for two or more. It never reaches high from self-declared data.
  • externally_verified is reserved for evidence that is actually checked: a World ID or Self proof, an Icebreaker credential, or an EAS attestation. No verifier exists yet, so nothing emits that status today. The type is in the response so the shape won't change when one ships.
  • Malformed values (an "ENS" entry that isn't a .eth name, a "DID" without a did: prefix) are ignored rather than counted.

3. Endpoint ownership: the domain vouches for the agent

The ERC-8004 spec defines an endpoint domain verification file. A domain that serves an agent's endpoint publishes https://{endpoint-domain}/.well-known/agent-registration.json:

{
  "registrations": [
    {
      "agentId": 22,
      "agentRegistry": "eip155:8453:0x8004A169FB4a3325136EB29fA0ceB6D2e539a432"
    }
  ]
}

Only whoever controls the domain can serve that file, so a matching entry ties the on-chain agent to the party operating the endpoint. Policy Check fetches it from the endpoint's own origin (SSRF-guarded) and returns one of four results:

endpointOwnershipEvidence.statusWhen
verifiedThe file lists this agentId on this registry
mismatchThe file lists other agents on this registry but not this one
unverifiedNo file, unreadable file, redirect to another domain, or the agent appears only on a different chain
not_checkedNo endpoint to check

Two details are worth stating. A missing or unreachable file is unverified, never mismatch: a domain that doesn't publish the file isn't contradicting anything. And a redirect to a different domain is ignored, since otherwise a third party could vouch for the endpoint. A tokenURI hosted on the same domain is noted as corroboration but doesn't count as verification, because the registrant can point the URI anywhere.

How the Evidence Feeds the Decision

Policy Check combines two kinds of input into one pre-payment decision: checks on the x402 endpoint's 402 challenge, and, when you supply an agentId, the evidence about the agent behind it. Each check is reported by name in the reasons list, so a decision can be traced to what produced it.

A few properties are worth stating:

  • Verified evidence counts for more than claimed evidence. A self-declared ENS name or email is credited far less than an on-chain read or a domain-published registration, and unverified proof-of-human signals earn nothing.
  • Hard failures still block. A malformed challenge, an unreachable endpoint, or an agent ID that isn't registered blocks the payment regardless of how strong the identity evidence is.
  • Weak identity behind a valid payment is a warning, not a block. Whether an unproven agent is acceptable is the caller's judgment, so Policy Check says "look closer" rather than deciding for them.
  • An ownership mismatch is surfaced as a warning. If the endpoint's domain vouches for a different agent than the one you supplied, the agent ID and the endpoint may not belong together. That is a strong signal rather than proof of fraud.
  • No agentId means identity isn't evaluated. The response says not_evaluated instead of substituting a default agent, and only the payment checks run.

The weighting behind these checks is not published and may change between releases. Treat the decision and the per-check reasons as the interface, and apply your own policy on top.

What Changes in the API Response

The request is untouched: { "endpoint", "agentId"?, "network"? }. The response gains fields, and reasons keeps its shape.

{
  "decision": "allow",
  "rubricVersion": 2,
  "trustEvidence": {
    "agentWallet":       { "status": "verified" },
    "humanLinkage":      { "status": "claimed", "confidence": "medium" },
    "endpointOwnership": { "status": "unverified" }
  }
}
  • trustEvidence summarizes each dimension, and reads not_evaluated when no agentId was supplied.
  • reasons gains checks for human linkage and endpoint ownership, and agent_wallet_set is now agent_wallet_verified.
  • rubricVersion records which scoring version produced a result, so a stored decision can be read against the right one.
  • The ERC-8004 Inspector response adds agentWalletEvidence, humanLinkage, endpointOwnershipEvidence and trustEvidenceSummary.

In the UI, each signal carries one of these labels: Verified, Claimed, Unverified, Missing or Mismatch, plus Not evaluated when nothing was checked. "Claimed" is a different color from "Verified" on purpose.

What This Doesn't Prove

  • Ownership isn't personhood. A verified .well-known file shows the endpoint's operator registered the agent. It says nothing about whether that operator is a person, a company, or a bot.
  • ENS and DID aren't resolved. Claimed means claimed. Resolving and verifying them, and checking EAS, Icebreaker, World ID or Self proofs, is where externally_verified would come from.
  • DNS races remain. The runtime resolves DNS itself, so a record could change between the safety check and the fetch. Checks and redirect re-validation reduce this but can't pin the IP.
  • It's a signal, not a verdict. ERC-8004 is a draft standard, and strong evidence means the identity is better supported, not that a payment is safe.

To see these fields for a real agent, look one up in the ERC-8004 Inspector, or run the combined check with an agent ID and an x402 endpoint in Policy Check. For what to verify on the payment side of the decision, see the x402 payment checklist.

Try ContextIQ free

Free tools for AI engineers.

Follow Trango Compute on LinkedIn

We post updates on new tools, context engineering patterns, and LLM cost research.

Follow on LinkedIn