Skip to main content
This guide explains how to integrate a new blockchain network into Graph Node. Chain integration involves implementing the Blockchain trait and providing chain-specific adapters for data ingestion and trigger processing.

Overview

Graph Node uses a modular architecture that allows different blockchain networks to be integrated by implementing a set of core traits. Each chain integration lives in the chain/ directory and provides:
  • Data source definitions
  • Trigger types and filtering
  • Block stream implementation
  • Runtime adapters for contract calls
  • Block ingestion from RPC or Firehose

Architecture

The chain integration architecture consists of several key components:
  1. Chain Adapter: Connects to blockchain nodes and converts data
  2. Block Stream: Provides event-driven streaming of blocks
  3. Trigger Processing: Matches blockchain events to subgraph handlers
  4. Runtime: Executes subgraph code in WASM sandbox
  5. Store: Persists entities with block-level granularity

Project Structure

Each chain integration follows this structure:

Core Traits

Blockchain Trait

The Blockchain trait is the primary interface that all chains must implement:

Block Trait

Blocks must implement the Block trait:

Implementation Steps

Extension Points

Custom Node Capabilities

Define chain-specific node capabilities:

Custom Decoder Hooks

Implement decoder hooks for preprocessing data:

Subgraph Manifest Schema

Define the YAML schema for your chain:

Testing

Unit Tests

Write unit tests for core components:

Integration Tests

Create integration tests in tests/integration-tests/:

Runner Tests

Create runner tests in store/test-store/tests/chain/mychain/:

Examples

Ethereum Implementation

See chain/ethereum/ for a full-featured reference implementation with:
  • RPC and Firehose support
  • Event, call, and block handlers
  • Call caching
  • Reorg handling
  • Trace support

NEAR Implementation

See chain/near/ for a simpler Firehose-only implementation:
  • Receipt-based triggers
  • No dynamic data sources
  • Account filtering (exact and partial matches)

Common Patterns

Handling Reorgs

Block Caching

Configuration

Add chain configuration to config.toml:

Best Practices

  • Error Handling: Use Result types and provide context with anyhow
  • Async/Await: Use async_trait for trait implementations
  • Logging: Use structured logging with slog
  • Caching: Cache frequently accessed data (blocks, receipts)
  • Metrics: Add Prometheus metrics for monitoring
  • Testing: Write comprehensive unit and integration tests
  • Documentation: Document chain-specific behavior and limitations

Performance Optimization

Batch Loading

Parallel Processing

Use FuturesOrdered for parallel processing:

Debugging

Enable Debug Logging

Common Issues

Block not found: Ensure block ingestion is running and synced Trigger mismatch: Check filter implementation and data source matching logic Reorg issues: Verify is_on_main_chain and ancestor_block implementations

See Also