Data Queries

Querying the Subgraph

Use The Graph Protocol subgraph for fast, indexed queries of creator tokens, attestations, and illuminations.

Subgraph Endpoint

The Influence Protocol subgraph is deployed on The Graph Network:

https://api.thegraph.com/subgraphs/name/aaronvick/radiant

The subgraph indexes events from TokenLinkRegistry, RelationalResolver, and IlluminationRegistry.

Basic Query Setup

async function querySubgraph<T>(query: string, variables?: Record<string, unknown>): Promise<T> {
  const endpoint = 'https://api.thegraph.com/subgraphs/name/aaronvick/radiant';
  
  const res = await fetch(endpoint, {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({ query, variables }),
  });
  
  const json = await res.json();
  if (json.errors) {
    throw new Error(json.errors.map((e: any) => e.message).join('; '));
  }
  
  return json.data;
}

Query Creator Tokens

Get all active creator tokens linked to the protocol:

const query = `
  {
    creatorTokens(where: { active: true }, first: 100) {
      id
      symbol
      name
      admin
      linkedAt
      linkedFid
      attestationCount
      holderCount
    }
  }
`;

const data = await querySubgraph(query);
console.log(data.creatorTokens);

Query Attestations

Get attestations for a specific creator token:

const query = `
  {
    attestations(
      where: { creatorToken: "0x..." }
      first: 50
      orderBy: timestamp
      orderDirection: desc
    ) {
      id
      creatorToken {
        id
        symbol
        name
      }
      participant
      text
      timestamp
      illuminationCount
    }
  }
`;

const data = await querySubgraph(query);

Query Participant Attestations

Get all attestations for a specific participant:

const query = `
  {
    attestations(
      where: { participant: "0x..." }
      first: 100
      orderBy: timestamp
      orderDirection: desc
    ) {
      id
      creatorToken {
        id
        symbol
        name
      }
      text
      timestamp
      illuminationCount
    }
  }
`;

const data = await querySubgraph(query);

Query Illuminations

Get illuminations (token burns) for an attestation:

const query = `
  {
    illuminations(
      where: { attestation: "0x..." }
      first: 50
      orderBy: timestamp
      orderDirection: desc
    ) {
      id
      attestation {
        id
        creatorToken {
          symbol
        }
      }
      token
      amount
      timestamp
    }
  }
`;

const data = await querySubgraph(query);

Query Token Holders

Get all holders of a creator token:

const query = `
  {
    tokenHolders(
      where: { 
        token: "0x..."
        balance_gt: "0"
      }
      first: 100
      orderBy: balance
      orderDirection: desc
    ) {
      id
      address
      balance
      firstPurchaseTime
      token {
        symbol
        name
      }
    }
  }
`;

const data = await querySubgraph(query);

Aggregate Queries

Get dashboard statistics and aggregate data:

const query = `
  {
    # Total active creators
    creatorTokens(where: { active: true }) {
      id
    }
    
    # Tokens with attestations
    creatorTokens(where: { attestationCount_gt: 0 }) {
      id
      attestationCount
    }
    
    # Recent attestations
    attestations(
      first: 10
      orderBy: timestamp
      orderDirection: desc
    ) {
      id
      creatorToken {
        symbol
      }
      timestamp
    }
  }
`;

const data = await querySubgraph(query);
const totalCreators = data.creatorTokens.length;

Filtering and Pagination

Use GraphQL variables for dynamic queries:

const query = `
  query GetAttestations($token: String!, $first: Int!, $skip: Int!) {
    attestations(
      where: { creatorToken: $token }
      first: $first
      skip: $skip
      orderBy: timestamp
      orderDirection: desc
    ) {
      id
      participant
      timestamp
    }
  }
`;

const variables = {
  token: '0x...',
  first: 50,
  skip: 0,
};

const data = await querySubgraph(query, variables);

Subgraph Schema

The subgraph exposes these main entities:

CreatorToken - Linked creator tokens with metadata
TokenHolder - ERC20 balance tracking per token
Attestation - Influence attestations with creator/participant links
Illumination - Token burns associated with attestations

When to Use Subgraph vs Contracts

Use Subgraph For:

  • Dashboard displays and analytics
  • Historical queries and time-series data
  • Aggregate statistics (counts, totals)
  • Pagination and filtering large datasets
  • Fast reads without RPC rate limits

Use Contracts For:

  • Real-time validation before transactions
  • Writing attestations and illuminations
  • Calculating influence metrics (IlluminationAnalyzer)
  • Building visualization graphs (VisualizationAssembler)
  • When subgraph is unavailable or lagging

Agent Notes

  • Subgraph queries are eventually consistent; there may be a delay (typically seconds) after on-chain events.
  • Always handle subgraph errors gracefully and fall back to contract queries when needed.
  • Use pagination (first and skip) for large result sets to avoid timeouts.
  • Addresses in subgraph are lowercase; normalize before comparing with contract addresses.
  • BigInt values are returned as strings; convert to numbers or BigInt as needed.