Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
71 changes: 71 additions & 0 deletions etc/architecture/overview.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
# Dojo.js Architecture Overview

## High-Level Components

Dojo.js is organized as a set of focused packages that cooperate to index, query, and interact with Dojo worlds on Starknet.

- **@dojoengine/sdk** orchestrates Torii clients, message signing flows, and schema-aware queries for both web and node runtimes.
- **@dojoengine/core** exposes the `DojoProvider`, a thin Starknet RPC wrapper that performs direct world contract reads and invokes.
- **@dojoengine/grpc** supplies a rich gRPC client with streaming subscriptions and data mappers for Torii indexer interactions.
- **@dojoengine/internal** concentrates shared schema utilities, query builders, pagination helpers, and token tooling used by the SDK.
- **@dojoengine/state** and **@dojoengine/react** provide state management and UI bindings, enabling entity streaming and optimistic updates in applications.
- **Tooling packages** such as `@dojoengine/create-burner`, `@dojoengine/predeployed-connector`, and `@dojoengine/create-dojo` enhance developer experience with wallet utilities and project scaffolding.

## Runtime Flow

```mermaid
flowchart LR
subgraph OnChain
World[Dojo World Contracts]
end

subgraph Indexer & Messaging
ToriiIndexer[Torii Service\nHTTP/WebSocket/gRPC]
end

subgraph CoreClient
CoreProvider[@dojoengine/core\nRpcProvider & World ABI]
ToriiWasm[@dojoengine/torii-wasm\n+ torii-client shim]
GrpcClient[@dojoengine/grpc\nToriiGrpcClient]
Internal[@dojoengine/internal\nSchema & Query Toolkit]
SDK[@dojoengine/sdk\ninit/createSDK]
end

subgraph App Integrations
StatePkg[@dojoengine/state\nZustand & RECS stores]
ReactPkg[@dojoengine/react\nHooks & RX bindings]
Burner[@dojoengine/create-burner\nLocal wallets]
Predeployed[@dojoengine/predeployed-connector\nInjected connector]
UtilsPkg[@dojoengine/utils]
end

subgraph Tooling
Scaffolder[@dojoengine/create-dojo\nCLI scaffolds]
Examples[Examples & Templates]
end

World -- events & state --> ToriiIndexer
CoreProvider -- invoke/call --> World
ToriiIndexer -- queries/subscriptions --> ToriiWasm
ToriiIndexer -- gRPC streams --> GrpcClient
ToriiWasm --> SDK
GrpcClient --> SDK
Internal --> SDK
SDK --> StatePkg
SDK --> ReactPkg
StatePkg --> ReactPkg
SDK --> Burner
SDK --> Predeployed
SDK --> UtilsPkg
Scaffolder --> Examples
Burner --> ReactPkg
Predeployed --> ReactPkg
```

## Key Responsibilities

1. Torii indexes on-chain world events and exposes them via WASM bindings and gRPC streams for consumption by the SDK.
2. The SDK coordinates Torii clients, message signing, and schema-driven parsing to provide a cohesive developer surface.
3. `DojoProvider` gives direct Starknet RPC access when applications need to call world contracts outside the indexer path.
4. Application layers like React hooks and Zustand stores sit on top of the SDK to deliver real-time entity state to UIs.
5. Wallet tooling and scaffolding packages round out the developer workflow for building and testing Dojo-powered apps.
62 changes: 62 additions & 0 deletions etc/architecture/whats-next.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
# What's Next for Dojo.js

This roadmap captures the near-to-mid term architecture initiatives planned for the main branch. Each stream lists intent, key activities, and expected outcomes to inform prioritisation and sequencing.

## 1. Revamped Type System

- **Objective**: Replace the existing world/type plumbing with the new type system in `packages/core/src/types` to improve safety and compatibility with Cairo models.
- **Key Steps**:
1. Audit current exports and downstream usage across `core`, `sdk`, `state`, and `react` packages.
2. Implement adapters or codemods to bridge the new types with legacy consumers while migration is in progress.
3. Expand compiler/test coverage to prevent regressions (e.g., schema parsing, manifests, provider actions).
- **Deliverables**: Updated type definitions, migration guide, comprehensive test suite for the new abstractions.

## 2. Framework-Agnostic Application Bindings

- **Objective**: Reduce React-specific hooks in favour of framework-agnostic bindings that can power multiple UI layers.
- **Key Steps**:
1. Extract core data subscription logic (currently in `@dojoengine/react`) into reusable primitives (signals, observables, store interfaces).
2. Provide thin React adapters while enabling alternative bindings (e.g., Solid, Vue, Svelte) to consume the same core APIs.
3. Update examples and documentation to highlight the framework-neutral approach.
- **Deliverables**: Core binding package with React wrapper, updated samples, migration notes.

## 3. Abstract Starknet.js Dependencies

- **Objective**: Introduce an abstraction layer over Starknet.js so that downstream packages can swap providers or polyfill functionality.
- **Key Steps**:
1. Identify all points where Starknet.js types/classes are imported directly (providers, accounts, signing flows).
2. Define an interface-based contract (e.g., `IStarknetTransport`, `Signer`, `AccountAdapter`) and implement default Starknet.js adapters.
3. Provide dependency injection hooks in SDK/provider constructors and document how to supply alternative transports.
- **Deliverables**: Adapter interfaces, default Starknet.js implementation, updated dependency guidelines.

## 4. TanStack/DB Integration

- **Objective**: Leverage TanStack DB for richer client-side entity persistence, caching, and querying.
- **Key Steps**:
1. Experiment with a proof-of-concept mapping Torii entity snapshots into TanStack DB tables.
2. Define schema generation rules based on Dojo manifests and integrate with state management.
3. Expose opt-in APIs within the SDK or a companion package for consuming TanStack DB features.
- **Deliverables**: Prototype integration, API surface proposal, pilot example demonstrating offline/query benefits.

## 5. Native gRPC Client Enhancements

- **Objective**: Continue maturing the native gRPC client for reliability and feature completeness.
- **Key Steps**:
1. Close remaining parity gaps with Torii WASM client (subscriptions, controllers, token operations).
2. Harden connection lifecycle management (reconnects, backoff, streaming ergonomics).
3. Ship performance benchmarks and cross-platform validation (Node, Bun, browser with WASM transport).
- **Deliverables**: Stable gRPC client API, resilience improvements, documentation and benchmarks.

## 6. Frontend Observability Integrations

- **Objective**: Provide opt-in hooks to plug observability tools (Sentry, PostHog, etc.) into Dojo.js-powered apps.
- **Key Steps**:
1. Define instrumentation points (SDK events, subscription lifecycle, transaction workflows).
2. Create lightweight adapters for popular observability providers with configuration patterns.
3. Document best practices and privacy considerations for instrumenting on-chain interactions.
- **Deliverables**: Observability integration guide, reference adapters, example instrumentation snippets.

## Cross-Cutting Considerations

- Prioritise documentation and migration notes alongside each feature.
- Invest in automated tests and benchmarks as new abstractions are introduced to safeguard performance and developer experience.
13 changes: 13 additions & 0 deletions etc/knowledge-base.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# Dojo.js Knowledge Base

## Architecture Snapshot (Main Branch)

- Reference diagram: [docs/architecture/overview.md](architecture/overview.md)
- Highlights:
- `@dojoengine/sdk` connects Torii indexer clients, message signing, and schema parsing for app consumption.
- `@dojoengine/core` offers the `DojoProvider` Starknet RPC interface for direct world contract access.
- `@dojoengine/grpc` provides streaming access to Torii via the `ToriiGrpcClient` and related mappers.
- UI/state layers (`@dojoengine/state`, `@dojoengine/react`) build on the SDK for entity subscriptions and optimistic updates.
- Tooling packages (`create-burner`, `predeployed-connector`, `create-dojo`) streamline wallet setup and application scaffolding.

_Last updated: 2025-09-25T13:27:58Z
11 changes: 5 additions & 6 deletions examples/example-vite-react-sdk/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import { WalletAccount } from "./wallet-account.tsx";
import { useSystemCalls } from "./useSystemCalls.ts";
import { Events } from "./events.tsx";
import { HistoricalEvents } from "./historical-events.tsx";
import { dojoProvider } from "./types.ts";

/**
* Main application component that provides game functionality and UI.
Expand All @@ -20,10 +21,9 @@ import { HistoricalEvents } from "./historical-events.tsx";
* @param props.sdk - The Dojo SDK instance configured with the game schema
*/
function App() {
const { useDojoStore, client } = useDojoSDK();
const { useDojoStore } = useDojoSDK();
const { account } = useAccount();
const entities = useDojoStore((state) => state.entities);
console.log(entities);

const { spawn } = useSystemCalls();

Expand Down Expand Up @@ -117,10 +117,9 @@ function App() {
className={`${col} h-12 w-12 bg-gray-600 rounded-full shadow-md active:shadow-inner active:bg-gray-500 focus:outline-none text-2xl font-bold text-gray-200`}
key={idx}
onClick={async () => {
await client.actions.move(
account!,
direction
);
await dojoProvider.move(account!, {
direction: direction,
});
}}
Comment on lines 119 to 123
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Guard move when wallet is disconnected.

Prevents crashes from account! and improves UX.

-                                    onClick={async () => {
-                                        await dojoProvider.move(account!, {
-                                            direction: direction,
-                                        });
-                                    }}
+                                    onClick={async () => {
+                                        if (!account) {
+                                            console.warn("Connect wallet to move.");
+                                            return;
+                                        }
+                                        await dojoProvider.move(account, { direction });
+                                    }}
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
onClick={async () => {
await client.actions.move(
account!,
direction
);
await dojoProvider.move(account!, {
direction: direction,
});
}}
onClick={async () => {
if (!account) {
console.warn("Connect wallet to move.");
return;
}
await dojoProvider.move(account, { direction });
}}
🤖 Prompt for AI Agents
In examples/example-vite-react-sdk/src/App.tsx around lines 119 to 123, the
onClick handler calls dojoProvider.move(account!, ...) using a non-null
assertion which will crash when wallet is disconnected; guard the handler by
checking that account is defined before calling move (e.g. early return if
!account), remove the non-null assertion, and optionally disable the button or
show a connect-wallet prompt when account is falsy to improve UX.

>
{label}
Expand Down
Loading
Loading