Menu

Compliance Gating

Verify KYC attestations on-chain using EAS attestation conditions. Pre-configured compliance templates abstract away schema IDs, attester addresses, and decoder contracts.

Uses POST /v1/attest with pre-configured compliance templates.

Auth: X-API-Key, or Authorization: Wallet for EVM agents who bought their key via /v1/keys/buy. See Authentication →

Building this in Claude Code? Install the wallet auth skill and Claude will write correct, signature-verifying integration code on the first try.

smithery skill add douglasborthwick/insumer-skill

View on Smithery · GitHub repo

What this does

Use eas_attestation conditions with compliance templates to verify Coinbase Verifications, Gitcoin Passport status, and other on-chain identity attestations. One API call confirms identity without handling PII.

Compliance template attest call

POST /v1/attest
Node.js
const res = await fetch("https://api.insumermodel.com/v1/attest", {
  method: "POST",
  headers: { "Content-Type": "application/json", "x-api-key": "YOUR_API_KEY" },
  body: JSON.stringify({
    wallet: "0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045",
    conditions: [{
      type: "eas_attestation",
      template: "coinbase_verified_account",
      label: "KYC verified"
    }]
  })
});

const { data } = await res.json();
console.log(data.attestation.pass); // true if wallet has Coinbase KYC
Python
import requests

res = requests.post(
    "https://api.insumermodel.com/v1/attest",
    headers={"x-api-key": "YOUR_API_KEY"},
    json={
        "wallet": "0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045",
        "conditions": [{
            "type": "eas_attestation",
            "template": "coinbase_verified_account",
            "label": "KYC verified"
        }]
    }
)

data = res.json()["data"]
print(data["attestation"]["pass"])  # True if wallet has Coinbase KYC
curl
curl -X POST https://api.insumermodel.com/v1/attest \
  -H "Content-Type: application/json" \
  -H "x-api-key: YOUR_API_KEY" \
  -d '{
    "wallet": "0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045",
    "conditions": [{
      "type": "eas_attestation",
      "template": "coinbase_verified_account",
      "label": "KYC verified"
    }]
  }'

# Response: { "ok": true, "data": { "attestation": { "pass": true }, "sig": "...", "kid": "..." }, "meta": { "version": "1.0", ... } }

Compliance Templates

Each template maps to a specific EAS schema, attester address, and chain. Pass the template field instead of configuring those values manually.

coinbase_verified_account Base (8453)
Coinbase

Verify wallet has completed Coinbase KYC. Most widely issued on-chain identity attestation.

coinbase_verified_country Base (8453)
Coinbase

Verify country associated with Coinbase-verified wallet. For geo-restricted compliance gating.

coinbase_one Base (8453)
Coinbase

Verify Coinbase One membership status. Gate premium features for Coinbase One subscribers.

gitcoin_passport_score Optimism (10)
Gitcoin

Verify Gitcoin Passport humanity score is 20 or above. Uses GitcoinPassportDecoder contract. On-chain Sybil resistance.

gitcoin_passport_active Optimism (10)
Gitcoin

Check wallet has active Gitcoin Passport with any positive score. Lighter check for basic humanity verification.

Custom EAS Issuers

Templates cover Coinbase Verifications and Gitcoin Passport. To verify attestations from your own EAS schema, pass schemaId, attester, and indexer directly. The indexer is the load-bearing piece — without it, the verifier can't resolve attestation UIDs and the condition fails closed.

How resolution works

For a raw eas_attestation condition, the verifier:

  1. Calls getAttestationUid(address recipient, bytes32 schema) returns (bytes32) on your indexer contract (selector 0xab2717dd) to get the UID for (wallet, schema).
  2. Calls getAttestation(bytes32 uid) on the EAS contract for the target chain to fetch the attestation struct.
  3. Verifies recipient == wallet (auto-bound), revocationTime == 0, expirationTime == 0 || expirationTime > now, and (if specified) attester == condition.attester.

Recipient is not a request-side field. It auto-binds to the wallet being verified. An attestation issued with a different recipient (including 0x0) will fail the condition regardless of schema or attester match.

Deploying an indexer

Coinbase's EAS Verifications indexer is open source and the standard reference. Fork it, deploy on your target chain, and wire your issuance flow to write each new attestation's (recipient, schema) → uid mapping. The indexer must implement the getAttestationUid selector exactly — that's the single ABI requirement.

Once deployed, pass the indexer address as the indexer field. EAS contracts on supported chains: Base/Optimism (0x4200000000000000000000000000000000000021), Ethereum (0xA1207F3BBa224E2c9c3c6D5aF63D0eb1582Ce587), Arbitrum, Polygon, Avalanche.

Example condition

Custom EAS condition
{
  "type": "eas_attestation",
  "chainId": 8453,
  "schemaId": "0x78bfda217fd8dceeed9138bf9b867edf716aabec55b6f01eff1576eb02e9c863",
  "attester": "0x3Af7fb877e581CF013cb5b5A4C38D813D07D748c",
  "indexer": "<your indexer contract address>",
  "label": "Custom attestation"
}

Farcaster Identity

farcaster_id is a standalone condition type, not a template. It uses the IdRegistry contract on Optimism. The contract's idOf(address) method returns the wallet's Farcaster ID (FID), or 0 if unregistered. No contractAddress or chainId is needed in the condition.

Node.js
const res = await fetch("https://api.insumermodel.com/v1/attest", {
  method: "POST",
  headers: { "Content-Type": "application/json", "x-api-key": "YOUR_API_KEY" },
  body: JSON.stringify({
    wallet: "0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045",
    conditions: [{
      type: "farcaster_id",
      label: "Farcaster user"
    }]
  })
});

const { data } = await res.json();
console.log(data.attestation.pass); // true if wallet has a Farcaster ID
Python
import requests

res = requests.post(
    "https://api.insumermodel.com/v1/attest",
    headers={"x-api-key": "YOUR_API_KEY"},
    json={
        "wallet": "0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045",
        "conditions": [{
            "type": "farcaster_id",
            "label": "Farcaster user"
        }]
    }
)

data = res.json()["data"]
print(data["attestation"]["pass"])  # True if wallet has a Farcaster ID
curl
curl -X POST https://api.insumermodel.com/v1/attest \
  -H "Content-Type: application/json" \
  -H "x-api-key: YOUR_API_KEY" \
  -d '{
    "wallet": "0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045",
    "conditions": [{
      "type": "farcaster_id",
      "label": "Farcaster user"
    }]
  }'

# Response: { "ok": true, "data": { "attestation": { "pass": true }, "sig": "...", "kid": "..." }, "meta": { "version": "1.0", ... } }

Gating Patterns

Combine compliance templates with other condition types in the same conditions array. The attestation passes only when ALL conditions are met. This lets you gate on KYC status and token holdings together for regulated use cases.

Node.js
const res = await fetch("https://api.insumermodel.com/v1/attest", {
  method: "POST",
  headers: { "Content-Type": "application/json", "x-api-key": "YOUR_API_KEY" },
  body: JSON.stringify({
    wallet: "0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045",
    conditions: [
      {
        type: "eas_attestation",
        template: "coinbase_verified_account",
        label: "KYC verified"
      },
      {
        type: "token_balance",
        contractAddress: "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48",
        chainId: 1,
        threshold: 1000,
        decimals: 6,
        label: "Holds 1000+ USDC"
      }
    ]
  })
});

const { data } = await res.json();
// pass is true only when BOTH conditions are met
console.log(data.attestation.pass);
Python
import requests

res = requests.post(
    "https://api.insumermodel.com/v1/attest",
    headers={"x-api-key": "YOUR_API_KEY"},
    json={
        "wallet": "0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045",
        "conditions": [
            {
                "type": "eas_attestation",
                "template": "coinbase_verified_account",
                "label": "KYC verified"
            },
            {
                "type": "token_balance",
                "contractAddress": "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48",
                "chainId": 1,
                "threshold": 1000,
                "decimals": 6,
                "label": "Holds 1000+ USDC"
            }
        ]
    }
)

data = res.json()["data"]
# pass is True only when BOTH conditions are met
print(data["attestation"]["pass"])
curl
curl -X POST https://api.insumermodel.com/v1/attest \
  -H "Content-Type: application/json" \
  -H "x-api-key: YOUR_API_KEY" \
  -d '{
    "wallet": "0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045",
    "conditions": [
      {
        "type": "eas_attestation",
        "template": "coinbase_verified_account",
        "label": "KYC verified"
      },
      {
        "type": "token_balance",
        "contractAddress": "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48",
        "chainId": 1,
        "threshold": 1000,
        "decimals": 6,
        "label": "Holds 1000+ USDC"
      }
    ]
  }'

# pass is true only when BOTH conditions are met