Skill v1.0.1
currentAutomated scan100/1001 files
version: "1.0.1" 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. allowed-tools: Read, Write, Bash, Grep
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 filteringmodels- Retrieve model definitionstransactions- 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 {playerremaininglast_direction}}}}
Get model metadata:
query {models {edges {node {idnameclassHashcontractAddress}}totalCount}}
Pagination
Cursor-based pagination:
query {entities(first: 10) {edges {cursornode {id}}pageInfo {hasNextPageendCursor}}}
Get next page:
query {entities(first: 10, after: "cursor_value") {edges {cursornode { 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...") {idupdatedAtmodels {__typename... on Position {vec {xy}}... on Moves {remaining}}}}
Event Stream
Monitor all world events:
subscription {eventEmitted {idkeysdatatransactionHash}}
Model Registration
Listen for new model registrations:
subscription {modelRegistered {idnamenamespace}}
SQL Access
Torii stores data in SQLite, accessible for complex queries.
Connect to database:
sqlite3 torii.db
Example queries:
-- Count entitiesSELECT COUNT(*) FROM entities;-- Custom aggregationsSELECT 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 entitiesconst positions = await client.getEntities({model: "Position",limit: 10});// Subscribe to updatesawait 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 {playerremaining}}}}`});
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.tomlworld_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 loginslot deployments create <PROJECT_NAME> torii --config torii.toml --version <DOJO_VERSION>
Manage
# Stream logsslot 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-clientskill) - Create optimized queries
- Set up subscriptions
- 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