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
"
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: Integrate with client ( dojo-client skill) Create optimized queries Set up subscriptions Monitor performance