npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@nirholas/subgraph

v1.0.0

Published

Subgraph for Agent0 SDK - ERC-8004 Agent Discovery and Trust

Downloads

36

Readme

Agent0 SDK Subgraph

npm version

A multi-chain subgraph for indexing ERC-8004 Trustless Agents protocol data, providing GraphQL APIs for agent discovery, reputation tracking, and validation across 8 networks.

Bug reports & feedback: Telegram: Agent0 channel | Email: [email protected]

🌐 Supported Networks

| Network | Chain ID | Status | Endpoint | |---------|----------|--------|----------| | Ethereum Mainnet | 1 | ✅ Deployed | Endpoint | | Ethereum Sepolia | 11155111 | ✅ Deployed | Endpoint | | Base Sepolia | 84532 | ⛔️ Contracts not deployed | - | | Polygon Amoy | 80002 | ⛔️ Contracts not deployed | - | | Linea Sepolia | 59141 | ⛔️ Contracts not deployed | - | | Hedera Testnet | 296 | ⛔️ Contracts not deployed | - | | HyperEVM Testnet | 998 | ⛔️ Contracts not deployed | - | | SKALE Base Sepolia | 1351057110 | ⛔️ Contracts not deployed | - |

Note: The Graph Gateway endpoints require authentication (API key / authorization header). If you see an “auth error”, use the gateway form https://gateway.thegraph.com/api/<API_KEY>/subgraphs/id/<SUBGRAPH_ID>.

🚀 Quick Start

Prerequisites

  • Node.js 16+
  • The Graph CLI: npm install -g @graphprotocol/graph-cli

Installation

# Install dependencies
npm install

# Validate network configurations
npm run validate

# Generate manifests for all networks
npm run generate

# Build all network deployments
npm run build:all

🛠️ Multi-Chain Development

This subgraph uses a template-based multi-chain architecture inspired by Messari's subgraph infrastructure, enabling a single codebase to deploy across 8 networks with minimal duplication.

Architecture Overview

📁 Project Structure
├── config/
│   ├── networks/                 # Network-specific configurations
│   │   ├── eth-sepolia.json      # Contract addresses, start blocks
│   │   ├── base-sepolia.json
│   │   └── ... (8 networks)
│   └── subgraph.template.yaml    # Mustache template for manifests
├── deployments/
│   ├── deployment.json           # Master deployment tracking
│   └── generated/                # Generated subgraph.yaml files
│       ├── erc-8004-eth-sepolia/
│       ├── erc-8004-base-sepolia/
│       └── ... (8 deployments)
├── src/                          # Shared handler code (95%+ reuse)
└── scripts/                      # Build automation

Key Commands

Development Workflow

# Validate all network configurations
npm run validate

# Generate manifests from template
npm run generate

# Build all deployments (runs codegen + build for each network)
npm run build:all

# Build single deployment
DEPLOYMENT=erc-8004-base-sepolia npm run build:single

Adding a New Network

  1. Create network config: config/networks/new-network.json
{
  "network": "new-network",
  "chainId": "123456",
  "displayName": "New Network",
  "identityRegistry": {
    "address": "0x...",
    "startBlock": 1
  },
  "reputationRegistry": {
    "address": "0x...",
    "startBlock": 1
  },
  "validationRegistry": {
    "address": "0x...",
    "startBlock": 1
  },
  "graphNode": {
    "network": "new-network"
  }
}
  1. Add to deployments/deployment.json
{
  "erc-8004": {
    "deployments": {
      "erc-8004-new-network": {
        "network": "new-network",
        "status": "prod",
        "configFile": "config/networks/new-network.json",
        "versions": {
          "schema": "1.0.0",
          "subgraph": "1.0.0"
        }
      }
    }
  }
}
  1. Add chain ID mapping in src/utils/chain.ts
if (network == "new-network") {
  return 123456  // New Network chain ID
}
  1. Add contract addresses in src/contract-addresses.ts
if (chainId.equals(BigInt.fromI32(123456))) {
  return new ContractAddresses(
    Bytes.fromHexString("0x..."),  // Identity
    Bytes.fromHexString("0x..."),  // Reputation
    Bytes.fromHexString("0x...")   // Validation
  )
}
  1. Generate and build: npm run build:all

Time to add new network: < 5 minutes

Deployment

# Deploy to The Graph Studio (requires auth token)
# Set your deployment key first:
# npx graph auth --studio <DEPLOY_KEY>

# Deploy specific network
DEPLOYMENT=erc-8004-eth-sepolia npm run deploy

# Deploy to Graph Studio (recommended; lets you set a release label)
# STUDIO_SLUG=<your-studio-subgraph-slug> DEPLOYMENT=erc-8004-eth-sepolia VERSION_LABEL=<your-release-label> npm run deploy:studio

# Or deploy locally for testing
npm run create-local && npm run deploy-local

📊 Overview

This subgraph indexes data from three core smart contracts implementing the ERC-8004 standard:

| Contract | Purpose | Events Indexed | |----------|---------|----------------| | IdentityRegistry | Agent registration and metadata management | Registered, MetadataSet, UriUpdated, Transfer | | ReputationRegistry | Feedback and reputation tracking | NewFeedback, FeedbackRevoked, ResponseAppended | | ValidationRegistry | Agent validation and attestation | ValidationRequest, ValidationResponse |

Key Features

  • 🔍 Comprehensive Agent Data - On-chain registration with rich off-chain metadata
  • 📊 Real-time Reputation - Live feedback scoring and response tracking
  • Validation Tracking - Complete validation lifecycle with status management
  • 📁 IPFS Integration - Native JSON parsing via File Data Sources
  • 🔄 Rich Relationships - Connected data through derived fields and references
  • 🌐 Multi-Chain Support - Single codebase deploying to 8 networks

🏗️ Architecture

The subgraph uses a hybrid on-chain/off-chain architecture:

On-Chain Entities (Mutable)

Core blockchain data stored directly from contract events:

Agent Entity

type Agent @entity(immutable: false) {
  id: ID!                    # "chainId:agentId"
  chainId: BigInt!           # Blockchain identifier
  agentId: BigInt!          # Agent ID on the chain
  agentURI: String          # Registration file URI
  agentURIType: String      # "ipfs", "https", "http", "unknown"
  owner: Bytes!             # Agent owner address
  operators: [Bytes!]!      # Authorized operators
  createdAt: BigInt!
  updatedAt: BigInt!
  totalFeedback: BigInt!    # Computed feedback count
  lastActivity: BigInt!     # Last activity timestamp
  registrationFile: AgentRegistrationFile  # Link to off-chain data
  feedback: [Feedback!]!
  validations: [Validation!]!
  metadata: [AgentMetadata!]!
}

Feedback Entity

type Feedback @entity(immutable: false) {
  id: ID!                    # "chainId:agentId:clientAddress:index"
  agent: Agent!
  clientAddress: Bytes!      # Feedback author
  score: Int!                # 0-100 score
  tag1: String              # Primary category tag
  tag2: String              # Secondary category tag
  feedbackUri: String        # IPFS/HTPPS URI for rich content
  feedbackURIType: String
  feedbackHash: Bytes!
  isRevoked: Boolean!
  createdAt: BigInt!
  revokedAt: BigInt
  feedbackFile: FeedbackFile  # Link to off-chain data
  responses: [FeedbackResponse!]!
}

Validation Entity

type Validation @entity(immutable: false) {
  id: ID!                    # requestHash
  agent: Agent!
  validatorAddress: Bytes!
  requestUri: String
  requestHash: Bytes!
  response: Int              # 0-100 score (0 = pending)
  responseUri: String
  responseHash: Bytes
  tag: String                # Human-readable validation tag
  status: ValidationStatus!  # PENDING, COMPLETED, EXPIRED
  createdAt: BigInt!
  updatedAt: BigInt!
}

enum ValidationStatus {
  PENDING
  COMPLETED
  EXPIRED
}

Off-Chain Entities (Immutable from IPFS)

Rich metadata fetched from IPFS/HTTPS URIs:

AgentRegistrationFile

type AgentRegistrationFile @entity(immutable: true) {
  id: ID!                    # Format: "transactionHash:cid"
  cid: String!               # IPFS CID (for querying by content)
  agentId: String!          # "chainId:agentId"
  name: String              # Agent display name
  description: String        # Agent description
  image: String             # Profile image URL
  active: Boolean           # Is agent active
  x402Support: Boolean      # Supports x402 payments
  supportedTrusts: [String!]!  # Trust models: "reputation", "cryptoeconomic", "tee-attestation"
  mcpEndpoint: String       # Model Context Protocol endpoint
  mcpVersion: String
  mcpTools: [String!]!      # Available MCP tools
  mcpPrompts: [String!]!    # Available MCP prompts
  mcpResources: [String!]!   # Available MCP resources
  a2aEndpoint: String       # Agent-to-Agent endpoint
  a2aVersion: String
  a2aSkills: [String!]!     # Available A2A skills
  ens: String               # ENS name
  did: String               # Decentralized identifier
  agentWallet: Bytes        # Agent wallet address
  agentWalletChainId: BigInt # Wallet chain ID
  createdAt: BigInt!
}

FeedbackFile

type FeedbackFile @entity(immutable: true) {
  id: ID!                    # Format: "transactionHash:cid"
  cid: String!               # IPFS CID (for querying by content)
  feedbackId: String!       # "chainId:agentId:clientAddress:index"
  text: String              # Detailed feedback text
  capability: String        # Capability being rated
  name: String             # Client name
  skill: String            # Skill being evaluated
  task: String             # Task context
  context: String          # Additional context
  proofOfPaymentFromAddress: String
  proofOfPaymentToAddress: String
  proofOfPaymentChainId: String
  proofOfPaymentTxHash: String
  tag1: String             # Fallback if on-chain tags empty
  tag2: String
  createdAt: BigInt!
}

Analytics & Aggregation Entities

AgentStats

type AgentStats @entity(immutable: false) {
  id: ID!                    # "chainId:agentId"
  agent: Agent!
  totalFeedback: BigInt!
  averageScore: BigDecimal!
  scoreDistribution: [Int!]! # [0-20, 21-40, 41-60, 61-80, 81-100]
  totalValidations: BigInt!
  completedValidations: BigInt!
  averageValidationScore: BigDecimal!
  lastActivity: BigInt!
  updatedAt: BigInt!
}

Protocol

type Protocol @entity(immutable: false) {
  id: ID!                    # "chainId"
  chainId: BigInt!
  name: String!              # Chain name (e.g., "Ethereum", "Base")
  identityRegistry: Bytes!
  reputationRegistry: Bytes!
  validationRegistry: Bytes!
  totalAgents: BigInt!
  totalFeedback: BigInt!
  totalValidations: BigInt!
  agents: [Agent!]!
  tags: [String!]!
  updatedAt: BigInt!
}

GlobalStats

type GlobalStats @entity(immutable: false) {
  id: ID!                    # "global"
  totalAgents: BigInt!
  totalFeedback: BigInt!
  totalValidations: BigInt!
  totalProtocols: BigInt!
  agents: [Agent!]!
  tags: [String!]!
  updatedAt: BigInt!
}

🔍 Query Examples

Get Complete Agent Profile

query GetCompleteAgentDetails($agentId: ID!) {
  agent(id: $agentId) {
    id
    chainId
    agentId
    owner
    agentURI
    createdAt
    updatedAt
    totalFeedback
    lastActivity
    
    registrationFile {
      name
      description
      image
      active
      x402Support
      supportedTrusts
      mcpEndpoint
      mcpVersion
      mcpTools
      a2aEndpoint
      a2aVersion
      a2aSkills
      ens
      did
      agentWallet
      agentWalletChainId
    }
    
    feedback(where: { isRevoked: false }, first: 10) {
      score
      tag1
      tag2
      clientAddress
      createdAt
      feedbackFile {
        text
        capability
        skill
        task
        context
      }
      responses {
        responder
        createdAt
      }
    }
    
    validations(orderBy: createdAt, orderDirection: desc) {
      validatorAddress
      response
      status
      tag
      createdAt
    }
  }
}

Find MCP-Compatible Agents

query GetAllMCPAgents {
  agentRegistrationFiles(
    where: { mcpEndpoint_not: null, active: true }
    first: 100
  ) {
    id
    agentId
    name
    description
    mcpEndpoint
    mcpVersion
    mcpTools
    supportedTrusts
  }
}

Search for High-Rated Feedback

query GetHighRatedFeedback($minScore: Int!) {
  feedbacks(
    where: { isRevoked: false, score_gte: $minScore }
    first: 100
    orderBy: score
    orderDirection: desc
  ) {
    id
    score
    tag1
    tag2
    agent {
      id
      registrationFile {
        name
        description
      }
    }
    feedbackFile {
      text
      capability
      skill
    }
    responses {
      responder
      createdAt
    }
  }
}

Find Agents by Trust Model

query FindAgentsByTrustModel($trustModel: String!) {
  agentRegistrationFiles(
    where: { supportedTrusts_contains: [$trustModel], active: true }
    first: 50
  ) {
    agentId
    name
    description
    supportedTrusts
  }
}

Get Global Statistics

query GetProtocolStats {
  globalStats(id: "global") {
    totalAgents
    totalFeedback
    totalValidations
    totalProtocols
    tags
    updatedAt
  }
}

📁 IPFS File Data Sources

The subgraph uses File Data Sources to parse off-chain content:

RegistrationFile Data Source

  • Handler: src/registration-file.ts
  • Trigger: When agentURI points to IPFS/HTTPS content
  • Output: AgentRegistrationFile entity
  • Data Parsed: Metadata, capabilities, endpoints, identity information

FeedbackFile Data Source

  • Handler: src/feedback-file.ts
  • Trigger: When feedbackUri points to IPFS/HTTPS content
  • Output: FeedbackFile entity
  • Data Parsed: Detailed feedback text, proof of payment, context

Supported URI Formats

  • IPFS: ipfs://QmHash... or bare QmHash...
  • HTTPS: https://example.com/file.json
  • HTTP: http://example.com/file.json

🔄 Data Flow

  1. On-chain Events → Contract events trigger indexing
  2. URI Detection → Subgraph detects IPFS/HTTPS URIs
  3. File Fetching → File Data Sources fetch and parse JSON
  4. Entity Creation → Immutable file entities created
  5. Relationship Links → On-chain entities link to file entities
  6. Statistics Update → Aggregate statistics computed

⚙️ Configuration

Contract Addresses

Addresses are managed in src/contract-addresses.ts for dynamic per-chain resolution.

🚀 Development

Local Development

Important: Local development requires Docker. The old graph node CLI command is no longer supported. Use Docker Compose as described below.

Prerequisites:

Setup Steps:

  1. Start local Graph node, IPFS, and PostgreSQL using Docker Compose:
docker compose up -d
  1. Wait for services to be ready (this may take a minute):
# Check service status
docker compose ps
  1. Create local subgraph:
npm run create-local
  1. Deploy locally:
npm run deploy-local
  1. Query local endpoint:
# Simple query (just IDs)
curl -X POST \
  -H "Content-Type: application/json" \
  -d '{"query": "{ agents(first: 5) { id } }"}' \
  http://localhost:8000/subgraphs/name/agent0-sdk/agent0-sdk

# Complete query with agent name (note: name is in registrationFile, not directly on Agent)
curl -X POST \
  -H "Content-Type: application/json" \
  -d '{"query": "{ agents(first: 5) { id registrationFile { name description } } }"}' \
  http://localhost:8000/subgraphs/name/agent0-sdk/agent0-sdk

Testing Queries

See examples/queries.graphql for comprehensive query examples:

  • Complete agent profiles with relationships
  • MCP/A2A protocol filtering
  • Feedback analysis and search
  • Global statistics and analytics
  • Trust model filtering

📚 Additional Resources

📄 License

Agent0 SDK is MIT-licensed public good brought to you by Marco De Rossi in collaboration with Consensys, 🦊 MetaMask and Agent0, Inc. We are looking for co-maintainers. Please reach out if you want to help.

Thanks also to Edge & Node (The Graph), Protocol Labs and Pinata for their support.