Skip to content

rmrk-team/rmrk-indexer

Repository files navigation

RMRK Indexer

Note: This is a reference implementation example for indexing the RMRK protocol. It is provided as-is for educational and development purposes. For production deployments, please review and customize the code according to your specific requirements.

A high-performance indexer for the RMRK protocol built on Subsquid. This indexer processes EVM blockchain data for RMRK's advanced NFT standards (nestable, multi-asset, and equippable NFTs) and exposes it via a GraphQL API.

Features

  • Multi-Chain Support: Index RMRK NFTs across multiple EVM chains (Moonbeam, Moonbase Alpha, etc.)
  • Advanced NFT Standards:
    • Nestable NFTs: NFTs that can own other NFTs
    • Multi-Asset NFTs: NFTs with multiple asset representations
    • Equippable NFTs: NFTs with equipable parts/slots
  • High Performance: Utilizes Subsquid Archive for fast historical data sync
  • GraphQL API: Auto-generated GraphQL API with subscription support
  • Marketplace Integration: Indexes marketplace events (listings, bids, sales)
  • Reindexing Support: Optimized reindexing from cached raw blockchain logs
  • Rate Limiting: Configurable RPC rate limiting to work with various providers

Architecture

This is a monorepo built with:

Project Structure

rmrk-indexer/
├── apps/
│   └── evm-indexer/          # Main indexer application
│       ├── src/
│       │   ├── mapping/      # Event handlers
│       │   ├── model/        # TypeORM entities
│       │   ├── abi/          # Contract ABIs
│       │   ├── services/     # Business logic
│       │   └── processor.ts  # Main processor entry
│       ├── schema.graphql    # GraphQL schema definition
│       ├── db/migrations/    # Database migrations
│       └── assets/           # Static assets
├── libs/
│   ├── utils/               # Shared utilities
│   ├── eslint-config-server/# ESLint configuration
│   ├── jest-presets/        # Jest testing configuration
│   └── tsconfig/            # TypeScript configurations
└── scripts/                 # Build and deployment scripts

How It Works

  1. Processor fetches blockchain logs from RPC endpoint or Subsquid Archive
  2. Event Handlers transform raw logs into structured data
  3. TypeORM Store persists data to PostgreSQL
  4. GraphQL Server exposes data via auto-generated API

Prerequisites

  • Node.js: v16 or higher
  • Yarn: v1.22.19 (specified in package.json)
  • Docker & Docker Compose: For local PostgreSQL database
  • PostgreSQL: v12 or higher (via Docker or standalone)

Quick Start

1. Clone the Repository

git clone https://github.com/rmrk-team/rmrk-indexer.git
cd rmrk-indexer

2. Install Dependencies

yarn install

3. Configure Environment

cd apps/evm-indexer
cp .env.dev .env

Edit .env with your configuration:

# Chain Configuration
CHAIN=moonbase-alpha
CHAIN_WSS=wss://moonbeam-alpha.api.onfinality.io/ws?apikey=YOUR_API_KEY
FROM_BLOCK=4260920

# Contract Addresses
RMRK_REGISTRY_ADDRESS=0xCEd0e87a29A2570A5866f4a4F3e45fA1dd82FD53
RMRK_COLLECTION_UTILS_ADDRESS=0xad567e7Dd1DFEa4b7EB86E415C5E838c090c0a00
MARKETPLACE_CONTRACT_ADDRESS=0xc97FA8f2b52b95Cb88048910d7bc2BA44C067B4f
MARKETPLACE_CONTRACT_FROM_BLOCK=4472161

# Performance
RPC_RATE_LIMIT=400
RPC_MAX_BATCH_SIZE=100

# Features
RUN_EVENT_SYNC=true
IS_REINDEX_EVENT_FACADE_ENABLED=true
IS_SUBSQUID_ARCHIVE_ENABLED=true

# Database (Docker defaults)
DB_NAME=squid
DB_HOST=localhost
DB_PORT=5432
DB_USER=postgres
DB_PASS=postgres

4. Start Database

# From project root
docker compose -f docker-compose.evm.yaml up -d db

5. Build the Project

# From project root
yarn build

6. Run Database Migrations

# From project root
yarn db:migrate

7. Start the Indexer

# From project root
yarn processor:start

8. Start GraphQL Server (in separate terminal)

# From project root
yarn query-node:start

The GraphQL playground will be available at: http://localhost:4350/graphql

Configuration

Environment Variables

Variable Description Default Required
CHAIN EVM network to index -
CHAIN_WSS WebSocket RPC endpoint -
FROM_BLOCK Starting block number -
TO_BLOCK Ending block number -
RMRK_REGISTRY_ADDRESS RMRK Registry contract -
RMRK_COLLECTION_UTILS_ADDRESS Collection utils contract -
MARKETPLACE_CONTRACT_ADDRESS Marketplace contract -
MARKETPLACE_CONTRACT_FROM_BLOCK Marketplace start block -
RPC_RATE_LIMIT Requests per second 90
RPC_MAX_BATCH_SIZE Max batch call size 100
IS_SUBSQUID_ARCHIVE_ENABLED Use Subsquid Archive true
IS_REINDEX_EVENT_FACADE_ENABLED Enable reindexing mode false

Supported Networks

  • Moonbeam
  • Moonbase Alpha
  • Moonriver
  • Base
  • Base Sepolia
  • (Configurable for any EVM chain)

Development

Project Commands

# Build all packages
yarn build

# Build specific app
yarn build:evm-indexer

# Run tests
yarn test

# Lint code
cd apps/evm-indexer && npm run lint

Database Operations

# Apply migrations
yarn db:migrate

# Reset processor state
yarn db:state-schema-reset

# Generate new migration (after schema changes)
cd apps/evm-indexer
make migration

Schema Development

  1. Edit apps/evm-indexer/schema.graphql
  2. Generate TypeORM entities:
    cd apps/evm-indexer
    make codegen
  3. Generate migration:
    make migration
  4. Apply migration:
    make migrate

Adding New Events

  1. Add event ABI to apps/evm-indexer/src/abi/
  2. Generate TypeScript types:
    npx squid-evm-typegen --abi src/abi/YOUR_CONTRACT.json --output src/abi/yourContract.ts
  3. Add event topics to apps/evm-indexer/src/topics.ts
  4. Update processor in src/processorFactory.ts
  5. Create event handler in src/mapping/
  6. Register handler in src/mapping/contractHandler.ts

Local Development with Docker

# Start all services
docker compose -f docker-compose.evm.yaml up

# Stop services
docker compose -f docker-compose.evm.yaml down

# View logs
docker compose -f docker-compose.evm.yaml logs -f

Deployment

Using Docker

# Build image
docker compose -f docker-compose.evm.yaml build

# Run services
docker compose -f docker-compose.evm.yaml up -d

# Check status
docker compose -f docker-compose.evm.yaml ps

Environment-Specific Deployment

  1. Set environment variables for your target environment
  2. Build the project: yarn build
  3. Run migrations: yarn db:migrate
  4. Start processor: yarn processor:start
  5. Start GraphQL server: yarn query-node:start

Monitoring

  • Processor Logs: Monitor block processing progress
  • Database: Check _processor_status table for sync status
  • GraphQL: Access /graphql endpoint for API health

API Documentation

GraphQL Playground

Access the interactive GraphQL playground at http://localhost:4350/graphql

Example Queries

Get Collections

query GetCollections {
  collections(limit: 10, orderBy: id_ASC) {
    id
    name
    symbol
    owner
    totalSupply
    nfts {
      id
      tokenId
    }
  }
}

Get NFT with Assets

query GetNFT {
  nftById(id: "YOUR_NFT_ID") {
    id
    tokenId
    owner
    collection {
      name
    }
    assets {
      id
      metadata
      priority
    }
    children {
      id
      tokenId
    }
  }
}

Get Marketplace Listings

query GetListings {
  listings(where: { status_eq: ACTIVE }, limit: 20) {
    id
    price
    seller
    nft {
      id
      tokenId
      collection {
        name
      }
    }
  }
}

Subscribe to New Events

subscription NewEvents {
  events(limit: 1) {
    id
    eventType
    block {
      number
      timestamp
    }
  }
}

Reindexing

The indexer supports optimized reindexing from cached raw logs. See apps/evm-indexer/REINDEX.md for detailed instructions.

Quick Reindex

  1. Update LAST_SYNC_VERSION environment variable
  2. Run: yarn db:state-schema-reset

Testing

# Run all tests
yarn test

# Test specific block range
cd apps/evm-indexer
npm run testing 11525199 0x78642bde93e1d71087a1c3c842f9f5224d063ef1

Additional Resources

Acknowledgments

  • Subsquid for the indexing framework
  • RMRK for the NFT protocol

Made with ❤️ by the RMRK team

About

A high-performance indexer for the RMRK protocol built on Subsquid

Resources

License

Stars

Watchers

Forks