@lsp-indexer/react playground

@lsp-indexer/indexer

The indexer is a Subsquid-based blockchain processor that listens to LUKSO L1 events, decodes them according to LSP standards, and writes normalized data to PostgreSQL. Hasura then exposes that database as a GraphQL API.


Architecture

graph LR
  A[LUKSO L1] --> B[Subsquid Gateway]
  B --> C[Indexer]
  C --> D[PostgreSQL]
  D --> E[Hasura GraphQL]
  C -.-> F[IPFS / HTTP]
  F -.-> C

Pipeline (6 steps)

  1. Extract — EventPlugins decode blockchain events into entities
  2. Persist Raw — Batch-insert all raw event entities
  3. Handle — EntityHandlers create derived entities (token names, tallies, NFT metadata)
  4. Persist Derived — Batch-insert handler output
  5. Verify — Batch supportsInterface() via Multicall3 to validate addresses
  6. Enrich — Batch-update FK references on already-persisted entities

Supported LSP Standards

StandardWhat it indexes
LSP0Universal Profiles (ERC725Account)
LSP3Profile metadata (name, description, images, links, tags)
LSP4Digital Asset metadata (token name, symbol, icons)
LSP5Received Assets (asset registry per profile)
LSP7Fungible token transfers and balances
LSP8NFT transfers, token IDs, and metadata
LSP12Issued Assets (assets created by a profile)
LSP26Follower system (follow/unfollow events)
LSP29Encrypted assets
LSP31URI decoding (multi-backend: IPFS, HTTP, base64)

Running with Docker

Prerequisites

  • Docker 24+ and Docker Compose v2
  • 8GB RAM minimum (PostgreSQL + Indexer + Hasura + Grafana)

Quick Start

git clone https://github.com/chillwhales/lsp-indexer.git
cd lsp-indexer

# Configure environment
cp .env.example .env
# Edit .env — at minimum set:
#   HASURA_GRAPHQL_ADMIN_SECRET=your-secret-here

# Start everything
cd docker
docker compose --env-file ../.env up -d

Services

ServicePortPurpose
PostgreSQL5432Database storage
Hasura8080GraphQL API + Console
IndexerBlockchain processor
Grafana3000Monitoring dashboards
LokiLog aggregation
PrometheusMetrics storage

Environment Variables

# Database
POSTGRES_USER=postgres
POSTGRES_PASSWORD=postgres
POSTGRES_DB=postgres

# Blockchain sources
SQD_GATEWAY=https://v2.archive.subsquid.io/network/lukso-mainnet
RPC_URL=https://rpc.lukso.sigmacore.io
RPC_RATE_LIMIT=10
FINALITY_CONFIRMATION=75

# IPFS & Metadata
IPFS_GATEWAY=https://api.universalprofile.cloud/ipfs/
METADATA_WORKER_POOL_SIZE=4

# Hasura
HASURA_GRAPHQL_ADMIN_SECRET=your-secret-here
HASURA_GRAPHQL_ENABLE_CONSOLE=true

Logs and Monitoring

# Follow indexer logs
docker compose --env-file ../.env logs -f indexer

# Open Hasura Console
open http://localhost:8080/console

# Open Grafana dashboards
open http://localhost:3000

Running from Source

For development on the indexer itself:

# Install dependencies
pnpm install

# Build codegen packages first
pnpm --filter=@chillwhales/abi build
pnpm --filter=@chillwhales/typeorm build

# Build the indexer
pnpm --filter=@chillwhales/indexer build

# Run (requires PostgreSQL and Hasura running)
cd packages/indexer
node lib/app/index.js

Hasura Configuration

On first startup, the indexer's entrypoint script automatically configures Hasura:

  • Tracks all tables as GraphQL types
  • Creates relationships between entities
  • Sets up public read access (no auth required for queries)
  • Configures subscriptions via WebSocket

After initial setup, the Hasura Console at http://localhost:8080/console lets you browse the schema, run queries, and inspect relationships.


Data Model

The indexer produces these main entity types:

EntityTableDescription
ProfileprofileUniversal Profiles with LSP3 metadata
DigitalAssetdigital_assetLSP7/LSP8 tokens with LSP4 metadata
NFTnftIndividual LSP8 token instances
OwnedAssetowned_assetProfile → asset ownership
OwnedTokenowned_tokenProfile → NFT token ownership
CreatorcreatorProfile → asset creator relationship
IssuedAssetissued_assetAssets issued by a profile
FollowfollowLSP26 follower relationships
TransfertransferLSP7 and LSP8 transfer events
DataChangeddata_changedERC725Y data key change events
EncryptedAssetencrypted_assetLSP29 encrypted asset metadata

Next Steps