What Is On-Chain Attestation?: The API Primitive That Replaces Token Gating
Token gating checks if a wallet holds a token. On-chain attestation does that and more, returning cryptographically signed results verifiable offline. Here is the difference.
Token gating was the first generation of on-chain verification. Connect a wallet, check if it holds a specific token, grant or deny access. It works. But it is binary, platform-specific, unverifiable, and not composable. On-chain attestation is the infrastructure layer that replaces it. A signed, timestamped, independently verifiable statement that specific on-chain conditions were evaluated. Here is the difference, and why it matters.
What token gating actually does
The token gating pattern is familiar to anyone who has used Shopify's token-gated commerce plugins or Discord's wallet-verification bots. The flow is simple:
1. A user connects their wallet.
2. The platform reads the wallet's on-chain state to check if it holds a specific token.
3. If the token is present, access is granted. If not, access is denied.
This pattern powers NFT-gated Discord channels, Shopify storefronts that show exclusive products to token holders, and event platforms that restrict ticket purchases to specific communities. It works for what it does. But it has four limitations that prevent it from becoming real infrastructure.
Why token gating is limited
It is binary. Token gating answers one question: does this wallet hold this token? Yes or no. It cannot express thresholds (holds at least 1,000 tokens), multiple conditions (holds Token A and NFT B), or cross-chain ownership (holds USDC on Ethereum and on Base). Every additional condition requires custom integration work.
It is platform-specific. Shopify's token gating plugin does not produce a result that Discord can consume. Discord's verification does not produce a result that a POS system can read. Each platform builds its own integration, checks the chain in its own way, and keeps the result to itself. There is no portable output.
It is not verifiable. When Shopify checks a wallet and grants access, there is no cryptographic proof that the check happened. No signature. No timestamp. No audit trail. You trust that the platform performed the check correctly. For a Discord channel, that level of trust is fine. For compliance workflows, financial decisions, or autonomous agent operations, it is not.
It is not composable. The result of a token gate cannot be passed to another system. If a Shopify store verifies a wallet, there is no way for a separate loyalty system to consume that verification result. Each system must re-verify from scratch. In a world of interconnected services and AI agents that make decisions on behalf of users, this is a fundamental limitation.
What on-chain attestation does differently
On-chain attestation takes the same basic operation (verifying on-chain conditions) and wraps it in an infrastructure-grade response. Instead of a simple yes/no that lives inside one platform, it produces a signed, timestamped, independently verifiable result that any system can consume.
Here is a call to the InsumerAPI attestation endpoint:
`curl -X POST https://api.insumermodel.com/v1/attest \
-H "X-API-Key: insr_live_YOUR_KEY_HERE" \
-H "Content-Type: application/json" \
-d '{
"wallet": "0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045",
"conditions": [
{
"type": "token_balance",
"chainId": 1,
"contractAddress": "0x1f9840a85d5aF5bf1D1762F925BDADdC4201F984",
"threshold": 1000,
"decimals": 18,
"label": "UNI on Ethereum"
}
]
}'`The response is not a simple boolean. It is a structured, signed attestation:
`{
"ok": true,
"data": {
"attestation": {
"id": "ATST-A7C3E",
"pass": true,
"results": [
{
"condition": 0,
"label": "UNI on Ethereum",
"type": "token_balance",
"chainId": 1,
"met": true,
"evaluatedCondition": {
"type": "token_balance",
"chainId": 1,
"contractAddress": "0x1f9840a85d5aF5bf1D1762F925BDADdC4201F984",
"operator": "gte",
"threshold": 1000,
"decimals": 18
},
"conditionHash": "0x3a7f1b2c...",
"blockNumber": "0x12f4a80",
"blockTimestamp": "2026-02-28T12:00:00.000Z"
}
],
"passCount": 1,
"failCount": 0,
"attestedAt": "2026-02-28T12:00:00.000Z",
"expiresAt": "2026-02-28T12:30:00.000Z"
},
"sig": "MEUCIQDk...base64...",
"kid": "insumer-attest-v1"
},
"meta": {
"creditsRemaining": 99,
"creditsCharged": 1,
"version": "1.0",
"timestamp": "2026-02-28T12:00:00.000Z"
}
}`Every field in that response exists to solve one of token gating's limitations. Here is how.
Difference 1: Signed results with ECDSA P-256
Every attestation response is signed with an ECDSA P-256 key. The `sig` field contains the signature, and the `kid` field identifies which key signed it. The signature covers the attestation ID, pass result, individual results, and timestamp. This means you can verify that the result came from InsumerAPI and was not tampered with after it was issued.
The signing key is discoverable through standard JWKS (JSON Web Key Set) endpoints. Any system that knows how to verify a JWS (JSON Web Signature) can validate an attestation result without contacting the API again.
`curl https://insumermodel.com/.well-known/jwks.json``{
"keys": [
{
"kty": "EC",
"crv": "P-256",
"kid": "insumer-attest-v1",
"use": "sig",
"x": "...",
"y": "..."
}
]
}`This is the same key discovery pattern used by OAuth providers, identity platforms, and enterprise SSO systems. It is also the same trust model used by certificate authorities: evaluate a condition, sign the result, publish the public key so anyone can verify. Any developer who has worked with JWT verification will recognize it immediately. The insumer-verify npm package handles this automatically, but you can also verify using any standard JOSE library in any language.
Why this matters: token gating produces no proof. On-chain attestation produces a cryptographic proof that can be stored, forwarded, and independently verified by any party at any time, even offline.
Difference 2: Multiple condition types
Token gating asks one question: does this wallet hold this token? On-chain attestation supports four condition types in a single call:
- `token_balance`. Verifies that a wallet holds at least a specified amount of an ERC-20 token on any of 32 supported chains.
- `nft_ownership`. Verifies that a wallet owns at least one NFT from a specific ERC-721 or ERC-1155 collection.
- `eas_attestation`. Verifies that a wallet has received a specific Ethereum Attestation Service attestation (used for identity, credentials, and compliance).
- `farcaster_id`. Verifies that a wallet is associated with a Farcaster account (social identity verification).
You can combine these in a single request. For example, verify that a wallet holds at least 100 USDC on Base and owns a Pudgy Penguins NFT and has a Coinbase Verified Account attestation. One API call, one signed response, all conditions evaluated.
Token gating cannot do this without custom code for each condition. Attestation handles it as a primitive.
Difference 3: Auditable results with IDs and timestamps
Every attestation has a unique ID (format `ATST-XXXXX`), an `attestedAt` timestamp, and an `expiresAt` timestamp. Attestations are valid for 30 minutes. This makes attestation results auditable. You can log which wallets were verified, when, and what conditions were checked. You can set policies around attestation freshness ("only accept attestations issued in the last 10 minutes").
Each result also includes a `conditionHash` — a SHA-256 hash of the canonical JSON of the evaluated condition. This lets any verifier confirm that the condition was not tampered with between issuance and consumption, without needing to contact the API.
Token gating has no concept of this. There is no record of when the check happened, no expiry, and no way to reference a specific verification event after the fact. For compliance-sensitive applications, this is a hard requirement that token gating simply cannot meet.
Difference 4: Offline verification with insumer-verify
Because attestation results are self-contained (the result, signature, key identifier, and condition hashes are all in the response), verification does not require a network call back to the API. The insumer-verify library runs four checks locally:
1. Signature. Verifies the ECDSA P-256 signature against the public key from JWKS.
2. Condition hashes. Recomputes the SHA-256 of each `evaluatedCondition` and compares it to the `conditionHash`.
3. Freshness. Checks `blockTimestamp` age against a caller-defined maximum (optional).
4. Expiry. Checks whether the 30-minute attestation window has elapsed.
This is critical for AI agent workflows where an agent receives an attestation result from another agent. The receiving agent does not need to trust the sending agent. It does not need to call InsumerAPI. It fetches the public key from the JWKS endpoint (or uses a cached copy) and verifies the signature locally. If all four checks pass, the result is authentic. Period.
Token gating has no equivalent. There is nothing to verify because there is no signed artifact to begin with.
Difference 5: 32 chains in one call
Token gating integrations are typically built for one chain. A Shopify plugin might check Ethereum. A Discord bot might check Polygon. Adding another chain means another integration.
InsumerAPI evaluates conditions across 30 EVM chains (including Ethereum, Base, Polygon, Arbitrum, Optimism, BNB Chain, Avalanche, and 23 more) plus Solana and XRP Ledger. Each condition in a request specifies a `chainId`, and the API routes to the correct chain automatically. One API key, one endpoint, one response format, regardless of which chains the conditions target.
The infrastructure shift
Token gating was the right first step. It proved that on-chain state could be used to gate access to real-world resources. But it was built as a feature inside individual platforms, not as infrastructure that platforms can build on.
On-chain attestation is the infrastructure layer. It produces results that are:
- Signed. Any party can verify the result came from the attestation provider.
- Timestamped. The result has a clear validity window.
- Portable. The result can be passed from system to system without re-verification.
- Multi-condition. One call can evaluate token holdings, NFT ownership, attestations, and social identity.
- Multi-chain. One call can span 32 chains.
- Offline-verifiable. No callback to the API required.
Enterprise systems, compliance workflows, and AI agents need all of these properties. They cannot build on a boolean that lives inside one Shopify plugin or one Discord bot. They need a verifiable primitive they can trust, store, forward, and audit.
Token gating was generation one. On-chain attestation is the infrastructure that everything else gets built on.

