- Package Manager: pnpm 10.5.2
- Build Orchestration: Turbo
- Workspaces:
client/,packages/*,contracts/
| Package | Type | Description |
|---|---|---|
@cartridge/client |
React App | Frontend marketplace |
@cartridge/arcade |
SDK | TypeScript SDK (packages/arcade-ts) |
@cartridge/models |
Types | Generated Dojo models |
contracts/ |
Cairo | Main smart contracts |
packages/achievement/ |
Cairo | Achievement system |
packages/collection/ |
Cairo | NFT collections |
packages/controller/ |
Cairo | Account abstraction |
packages/orderbook/ |
Cairo | Marketplace orderbook |
packages/registry/ |
Cairo | Game registry |
packages/social/ |
Cairo | Guilds, alliances |
packages/leaderboard/ |
Cairo | Leaderboard system |
packages/quest/ |
Cairo | Quest system |
client/ → @cartridge/arcade (workspace)
→ @dojoengine/*, starknet, @cartridge/ui
packages/arcade-ts/ → @dojoengine/sdk, starknet
- React 19 + TypeScript + Vite
- Zustand (state), TanStack Router
- @cartridge/ui components
- @tanstack/react-virtual
- tsup (ESM/CJS/IIFE)
- DojoEngine SDK, starknet.js
- Cairo 2.13.1, Dojo 1.8.0
- Scarb 2.13.1
# Development
pnpm dev # Watch mode (all packages)
# Build
pnpm build # Build all
pnpm build:scarb # Cairo contracts only
# Testing
pnpm test # All tests
pnpm test:ts # TypeScript only
pnpm test:cairo # Cairo only
pnpm test:watch # Watch mode
# Linting & Formatting
pnpm lint # Fix issues
pnpm lint:check # Check only (CI)
pnpm format # Fix formatting
pnpm format:check # Check only (CI)
# Type Checking
pnpm type:check # TypeScriptfeatures/{name}/
├── index.ts # Exports
├── use{Name}ViewModel.ts # Business logic hook
└── use{Name}ViewModel.test.ts # Tests
Hook Structure:
export interface DashboardViewModel {
items: Item[];
isLoading: boolean;
}
export function useDashboardViewModel(): DashboardViewModel {
// useMemo for computed values
// Return interface-typed object
}arcade.ts- SDK contextmarketplace.ts- Marketplace state*-fetcher.ts- Data fetching
#[starknet::component]
mod BuyableComponent {
#[storage]
struct Storage { ... }
#[embeddable_as(BuyableImpl)]
impl Buyable<TContractState, +HasComponent<TContractState>> {
fn buy(ref self: ComponentState<TContractState>) { ... }
}
}- Client: jsdom environment
- SDK: node environment
- Integration tests:
RUN_INTEGRATION_TESTS=true
describe("useFeatureViewModel", () => {
it("returns expected state", () => {
const { result } = renderHook(() => useFeatureViewModel());
expect(result.current.isLoading).toBe(true);
});
});#[test]
fn test_feature() {
let world = spawn_test_world!(...);
// Execute and assert
}Format: type(scope): description
Types: feat, fix, refactor, test, docs, chore, style
Scopes: client, arcade-ts, contracts, marketplace, registry, social
Examples:
feat(marketplace): add metadata filtering
fix(client): resolve token display bug
refactor(arcade-ts): simplify torii client
- Format check →
pnpm format:check:ts - Lint check →
pnpm lint:check:ts - Build + Test
Triggers on *.cairo, Scarb.* changes:
- Format check →
scarb fmt --check - Lint check
- Build + Test →
scarb build && scarb test
- Components:
PascalCase.tsx - Hooks:
use{Name}.ts - Tests:
*.test.ts
- Modules:
snake_case.cairo - Interfaces:
interface.cairo