This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
Dojo Starter React — a template for building on-chain apps with Dojo Engine + Starknet + React. It provides dual authentication (Cartridge Controller + burner/guest accounts), type-safe contract interaction via auto-generated bindings, and Torii indexer integration for GraphQL queries.
npm install --legacy-peer-deps # Install dependencies (--legacy-peer-deps is required)
npm run dev # Start Vite dev server (localhost:5173)
npm run build # TypeScript check + Vite production build
npm run test # Run tests with Vitest
npm run generate # Generate TS bindings from Cairo contracts via sozoRequires Node >= 20. Local development also requires Katana (localhost:5050) and Torii (localhost:8080) running, unless using a Slot deployment via VITE_SLOT_INSTANCE.
The app initializes asynchronously via setup() before rendering. Providers are nested in this order:
StarknetProvider → QueryClientProvider → ChakraBaseProvider → WalletProvider → DojoProvider → BrowserRouter
If setup() fails (e.g., Katana/Torii not running), a fallback error UI is rendered instead.
- setup.ts — Async initialization: creates ToriiClient, DojoProvider, BurnerManager, and wires up the world from generated bindings. Returns
SetupResultpassed to context providers. - DojoContext.tsx — Provides
useDojo()hook. Returns{ setup, account, masterAccount }. Theaccountobject wraps burner/controller account withcreate,list,select,clearmethods. - WalletContext.tsx — Manages authentication state machine. Tracks
connectionStatus("selecting" | "connecting_burner" | "connecting_controller") and persistsaccountTypeto localStorage. Guest mode (connectAsGuest) is only available whenVITE_CHAINis not "mainnet" or "sepolia". - accountStore.tsx — Zustand store for active account state, synced by DojoContext effects.
- controller/ — Cartridge Controller configuration.
policies.tsauto-generates session key policies by introspecting the generated contract bindings.controller.tsconfigures chain ID (mainnet/sepolia/slot).
These are regenerated by npm run generate from manifest_slot.json:
- contracts.gen.ts — Typed system call functions (execute transactions + view calls)
- defineContractComponents.ts — RECS component definitions for Torii sync
- models.gen.ts — TypeScript interfaces matching Cairo models
After regenerating, the hardcoded namespace string must be replaced with DOJO_NAMESPACE from env (see docs/adapting-contracts.md).
- With
VITE_SLOT_INSTANCEset: URLs resolve tohttps://api.cartridge.gg/x/{instance}/katana|torii - Without it: defaults to
localhost:5050(RPC) andlocalhost:8080(Torii)
Executing contract calls:
const { setup: { client }, account: { account } } = useDojo();
await client.system_name.method_name(account, ...args);With loading/error state: Use useContractActions() hook from src/hooks/useContractActions.ts.
GraphQL queries to Torii: Use graphql-request with the graphqlUrl from cartridgeUrls.ts. Query names follow {namespace}{ModelName}Models.
Adding new pages: Create in src/pages/, register route in src/AppRoutes.tsx.
Configured via .env (see .env_example):
| Variable | Purpose |
|---|---|
VITE_SLOT_INSTANCE |
Cartridge Slot deployment name (blank = local) |
VITE_DOJO_NAMESPACE |
Namespace for contract calls |
VITE_MASTER_ADDRESS / VITE_MASTER_PRIVATE_KEY |
Master account for burner creation |
VITE_CHAIN |
"mainnet", "sepolia", or blank for Slot |
VITE_CONTROLLER_PRESET |
Cartridge Controller preset name |
VITE_ENABLE_VRF |
Enable VRF policy ("true"/"false") |
- Build Cairo contracts with
sozo buildto getmanifest.json - Copy manifest to
manifest_slot.json - Run
npm run generateto regenerate TypeScript bindings - Replace hardcoded namespace strings in generated files with
DOJO_NAMESPACEenv variable - Use the new typed client methods via
useDojo()
See docs/adapting-contracts.md for detailed steps.
- UI: Chakra UI v2, Framer Motion, React Router v6, Sonner (toasts)
- State: Zustand (account), React Query (server state), React Context (dojo/wallet)
- Blockchain: Dojo Engine 1.8.x, Starknet.js 8.5, @starknet-react/core 5.x, Cartridge Controller 0.13.x
- Build: Vite 6 with WASM + top-level-await plugins