CtrlK
BlogDocsLog inGet started
Tessl Logo

dojo-indexer

Set up and configure Torii indexer for GraphQL queries, gRPC subscriptions, and SQL access. Use when indexing your deployed world for client queries or real-time updates.

Install with Tessl CLI

npx tessl i github:dojoengine/book --skill dojo-indexer
What are skills?

84

Does it follow best practices?

Validation for skill structure

SKILL.md
Review
Evals

Dojo Indexer (Torii)

Set up and use Torii, the Dojo indexer, for efficient querying and real-time subscriptions to your world state.

When to Use This Skill

  • "Set up Torii indexer"
  • "Configure GraphQL for my world"
  • "Create subscriptions for entity updates"
  • "Query world state efficiently"

What This Skill Does

Manages Torii indexer:

  • Start and configure Torii
  • Create GraphQL queries
  • Set up real-time subscriptions
  • Access SQL database directly

Quick Start

Start Torii:

torii --world <WORLD_ADDRESS>

This starts Torii with default settings:

  • GraphQL API at http://localhost:8080/graphql
  • gRPC API at http://localhost:8080
  • In-memory database (for development)

With Controller indexing (recommended):

torii --world <WORLD_ADDRESS> --indexing.controllers

Production configuration:

torii --world <WORLD_ADDRESS> --db-dir ./torii-db --indexing.controllers

What is Torii?

Torii is the Dojo indexer that:

  • Watches blockchain for world events
  • Indexes model state changes
  • Provides GraphQL API for queries
  • Provides gRPC API for subscriptions
  • Offers SQL access for complex queries

Why use Torii:

  • Faster than direct RPC queries
  • Complex queries (filters, pagination)
  • Real-time subscriptions
  • Type-safe GraphQL schema

GraphQL API

Torii provides GraphQL endpoint at http://localhost:8080/graphql

Use the GraphiQL IDE in your browser to explore the schema and test queries.

Schema Structure

Torii generates two types of queries:

Generic Queries:

  • entities - Access all entities with filtering
  • models - Retrieve model definitions
  • transactions - Query indexed transactions

Model-Specific Queries:

  • {modelName}Models - Custom queries for each model
  • Example: positionModels, movesModels

Basic Queries

Get all entities of a model:

query {
    movesModels {
        edges {
            node {
                player
                remaining
                last_direction
            }
        }
    }
}

Get model metadata:

query {
    models {
        edges {
            node {
                id
                name
                classHash
                contractAddress
            }
        }
        totalCount
    }
}

Pagination

Cursor-based pagination:

query {
    entities(first: 10) {
        edges {
            cursor
            node {
                id
            }
        }
        pageInfo {
            hasNextPage
            endCursor
        }
    }
}

Get next page:

query {
    entities(first: 10, after: "cursor_value") {
        edges {
            cursor
            node { id }
        }
    }
}

Offset/limit pagination:

query {
    entities(offset: 20, limit: 10) {
        edges {
            node { id }
        }
        totalCount
    }
}

Real-time Subscriptions

Subscribe to world state changes via WebSocket.

Entity Updates

subscription {
    entityUpdated(id: "0x54f58...") {
        id
        updatedAt
        models {
            __typename
            ... on Position {
                vec {
                    x
                    y
                }
            }
            ... on Moves {
                remaining
            }
        }
    }
}

Event Stream

Monitor all world events:

subscription {
    eventEmitted {
        id
        keys
        data
        transactionHash
    }
}

Model Registration

Listen for new model registrations:

subscription {
    modelRegistered {
        id
        name
        namespace
    }
}

SQL Access

Torii stores data in SQLite, accessible for complex queries.

Connect to database:

sqlite3 torii.db

Example queries:

-- Count entities
SELECT COUNT(*) FROM entities;

-- Custom aggregations
SELECT AVG(value) FROM model_data WHERE model_name = 'Health';

Client Integration

JavaScript/TypeScript

import { createClient } from '@dojoengine/torii-client';

const client = await createClient({
    rpcUrl: "http://localhost:5050",
    toriiUrl: "http://localhost:8080",
    worldAddress: WORLD_ADDRESS,
});

// Query entities
const positions = await client.getEntities({
    model: "Position",
    limit: 10
});

// Subscribe to updates
await client.onEntityUpdated(
    [{ model: "Position", keys: [playerId] }],
    (entity) => console.log("Position updated:", entity)
);

Apollo Client (GraphQL)

import { ApolloClient, InMemoryCache, gql } from '@apollo/client';

const client = new ApolloClient({
    uri: 'http://localhost:8080/graphql',
    cache: new InMemoryCache(),
});

const { data } = await client.query({
    query: gql`
        query GetMoves {
            movesModels {
                edges {
                    node {
                        player
                        remaining
                    }
                }
            }
        }
    `
});

Configuration Options

OptionDescriptionDefault
--worldWorld contract addressOptional (since Torii 1.6.0)
--rpcRPC endpoint URLhttp://localhost:5050
--db-dirDatabase directoryIn-memory
--configPath to TOML configuration fileNone
--http.cors_originsCORS origins*

Slot Deployment (Remote)

Slot provides hosted Torii instances. Slot requires a TOML configuration file.

Create Configuration

# torii.toml
world_address = "<WORLD_ADDRESS>"
rpc = "<RPC_URL>"

[indexing]
controllers = true

See the Torii configuration guide for all TOML options (indexing, polling, namespaces, etc.).

Deploy

slot auth login

slot deployments create <PROJECT_NAME> torii --config torii.toml --version <DOJO_VERSION>

Manage

# Stream logs
slot deployments logs <PROJECT_NAME> torii -f

# Delete and recreate (safe — all data is on-chain)
slot deployments delete <PROJECT_NAME> torii

Development Workflow

Terminal 1: Start Katana

katana --dev --dev.no-fee

Terminal 2: Deploy world

sozo build && sozo migrate

Terminal 3: Start Torii

torii --world <WORLD_ADDRESS> --http.cors_origins "*"

Troubleshooting

"Connection refused"

  • Check Torii is running
  • Verify port (default 8080)
  • Check firewall rules

"World not found"

  • Verify world address is correct
  • Check RPC URL is accessible
  • Ensure world is deployed

"Slow queries"

  • Use model-specific queries instead of generic entities
  • Use pagination
  • Request only needed fields

Next Steps

After Torii setup:

  1. Integrate with client (dojo-client skill)
  2. Create optimized queries
  3. Set up subscriptions
  4. Monitor performance

Related Skills

  • dojo-deploy: Deploy world first
  • dojo-client: Use Torii in clients
  • dojo-world: Configure what Torii indexes
  • dojo-migrate: Restart Torii after migrations
Repository
dojoengine/book
Last updated
Created

Is this your skill?

If you maintain this skill, you can claim it as your own. Once claimed, you can manage eval scenarios, bundle related skills, attach documentation or rules, and ensure cross-agent compatibility.