Every wallet verification system asks the same question: does this wallet meet these conditions? And every one returns a different answer format. The industry keeps debating which computation method should win. It is the wrong debate. Standardize the output. Let the implementations compete. In a multi-party system, the only thing that can be standardized is what one system hands to another.

Wallet authentication, token gating, and on-chain verification systems all face the same problem: incompatible output formats.

The OAuth analogy

OAuth did not standardize how identity providers store passwords or validate sessions. It standardized the token format, the verification flow, and the trust boundaries between issuers, relying parties, and resource owners. Google, GitHub, and a self-hosted Keycloak instance all emit the same kind of token. Relying parties do not care how the token was produced. They care that they can verify it.

OAuth standardized how tokens are issued, verified, and consumed across independent systems. Wallet attestation needs the same separation of concerns.

Wallet auth is stuck in the era before OAuth. Every project rolls its own attestation response shape. Some return raw balances. Some return booleans. Some sign their responses, some do not. Some anchor to a block, some do not. A relying party that integrates with one provider has to rewrite everything to integrate with another.

Format, not computation

The insight is simple: the protocol should standardize the format and verification model of eligibility attestations, not the underlying computation method.

A conforming implementation MUST emit a cryptographically signed, time-bounded attestation of eligibility that can be independently verified without real-time issuer communication. A conforming implementation MAY use any underlying computation method, including direct state retrieval, zero-knowledge proofs, or delegated verification.

This separation ensures that computation can evolve, while the interface remains stable. In multi-party and agent-driven systems, this is the only stable point of standardization. Computation varies. Trust representation must not.

This is the separation that makes the format useful:

What a conforming attestation looks like

The State Attestation Specification defines the format. A conforming attestation includes:

The signature proves the attestation was issued by an authority. The condition hashes prove it was not tampered with. The block anchor proves when the state was read. The expiry prevents replay. And the boolean format means the relying party never sees what the wallet actually holds.

Why booleans, not balances

The question is "does this wallet hold at least 1000 USDC on Ethereum?" The answer is yes or no. The fact that the wallet holds 47,392 USDC is nobody's business. Systems that require full-state disclosure to make a binary decision are mis-specified at the protocol level.

Systems that expose raw wallet state are not verification systems. They are data disclosure systems. Every verifier in the chain gets a full snapshot of the wallet's holdings. That is a surveillance architecture, not a verification protocol. The boolean constraint is not a limitation. It is the entire point.

When a relying party receives a signed attestation with met: true and a valid condition hash showing the predicate was USDC >= 1000 on chain 1, it has everything it needs. The raw balance is never transmitted, never stored, never leaked.

Why computation-agnostic

Making the format computation-agnostic is not just elegant. It is a survival strategy for the standard itself.

If you bake direct RPC reads into the spec, you exclude proof systems. If you bake ZK proofs into the spec, you exclude direct reads on chains where proofs are impractical. If you bake any specific computation method into the spec, you create a monoculture that cannot adapt when better methods emerge.

The spec says: a conforming implementation MUST emit a signed attestation in this format. It MAY use any computation method to evaluate conditions. MUST for the output. MAY for the computation. This makes the format mandatory while staying computation-agnostic.

Zero-knowledge proofs, Merkle storage proofs, trusted execution environments, delegated oracle networks, direct RPC reads: all of these are valid computation backends. A ZK proof can serve as the computation layer for a conforming attestation. It does not eliminate the need for a standard output. It feeds into the attestation layer rather than replacing it.

Offline verification changes everything

In distributed systems, verification must not depend on issuer availability. The JWKS distribution model means a relying party can verify attestations without ever contacting the issuer. Fetch the public key once, cache it, verify locally. This has profound implications:

Why this matters for agents

Autonomous systems cannot rely on session state, repeated callbacks, or issuer availability at decision time. They require stateless, portable trust objects that can be verified instantly and independently. A standard attestation format is not an optimization in agent systems. It is a requirement. Any model that requires live issuer interaction at decision time does not scale to autonomous systems.

When Agent B asks "does this wallet qualify?", it needs a signed answer it can verify locally, cache for the validity window, and act on without waiting for a round-trip to the issuer. That is exactly what a conforming attestation provides. The agent does not care whether the attestation was computed via direct reads, ZK proofs, or delegated verification. It cares that the format is standard, the signature is valid, and the conditions are tamper-sealed. AgentTalk is built on this principle: both agents verify wallet conditions before exchanging data, using the same signed attestation format, with no callbacks and no session state.

Try it yourself

The insumer-verify npm package implements the full verification algorithm in zero dependencies. But you do not need it. The format is open. The verify-manual.mjs example demonstrates full verification using only the Web Crypto API:

// Fetch the signing key from JWKS
const jwks = await fetch("https://api.insumermodel.com/v1/jwks").then(r => r.json());
const publicKey = await crypto.subtle.importKey("jwk",
  { kty: jwks.keys[0].kty, crv: jwks.keys[0].crv, x: jwks.keys[0].x, y: jwks.keys[0].y },
  { name: "ECDSA", namedCurve: "P-256" }, false, ["verify"]);

// Verify the signature over {id, pass, results, attestedAt}
const payload = JSON.stringify({
  id: attestation.id, pass: attestation.pass,
  results: attestation.results, attestedAt: attestation.attestedAt
});
const sigValid = await crypto.subtle.verify(
  { name: "ECDSA", hash: "SHA-256" }, publicKey,
  Uint8Array.from(atob(sig), c => c.charCodeAt(0)),
  new TextEncoder().encode(payload));

// Recompute condition hashes — sorted-key canonical JSON + SHA-256
for (const r of attestation.results) {
  const sorted = Object.keys(r.evaluatedCondition).sort();
  const hash = await crypto.subtle.digest("SHA-256",
    new TextEncoder().encode(JSON.stringify(r.evaluatedCondition, sorted)));
  const computed = "0x" + [...new Uint8Array(hash)]
    .map(b => b.toString(16).padStart(2, "0")).join("");
  // computed must equal r.conditionHash
}

No library. No dependency. Just the Web Crypto API and the spec. That is what makes it a standard, not a product feature.

What this standard does not define

This specification does not define how eligibility is computed. It does not mandate direct blockchain reads, proof systems, or any specific verification backend. It defines only the format and verification model of the resulting attestation.

Where this goes

This is an initial implementation of a standard interface for on-chain eligibility. The objective is not to define a provider. It is to ensure that any implementation can interoperate at the verification layer. Third parties are already verifying attestations in production: DJD Agent Score uses the format for AI agent wallet trust scoring in the Coinbase x402 ecosystem, and AsterPay KYA wires it into ERC-8183 agent trust.

The State Attestation Specification defines the format. insumer-verify is the reference implementation. The examples show every pattern from basic attestation to Express middleware to manual verification with no library.

OAuth proved that standardizing the output format matters more than standardizing the authentication method. Wallet auth needs the same separation of concerns. The on-chain verification API is an initial implementation of that separation, not a constraint on how it evolves.

Read the spec, run the examples

The State Attestation Spec and insumer-verify are open. Start verifying wallet conditions with a free API key and 10 credits.

View Developer Docs