Agent Skills: Dojo Indexer (Torii)

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.

UncategorizedID: dojoengine/book/dojo-indexer

Install this agent skill to your local

pnpm dlx add-skill https://github.com/dojoengine/book/tree/HEAD/skills/dojo-indexer

Skill Files

Browse the full folder contents for dojo-indexer.

Download Skill

Loading file tree…

skills/dojo-indexer/SKILL.md

Skill Metadata

Name
dojo-indexer
Description
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.

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

| Option | Description | Default | |--------|-------------|---------| | --world | World contract address | Optional (since Torii 1.6.0) | | --rpc | RPC endpoint URL | http://localhost:5050 | | --db-dir | Database directory | In-memory | | --config | Path to TOML configuration file | None | | --http.cors_origins | CORS 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