diff --git a/.claude/agents/pixelaw-app-developer.md b/.claude/agents/pixelaw-app-developer.md
index 82853b0..2542fa5 100644
--- a/.claude/agents/pixelaw-app-developer.md
+++ b/.claude/agents/pixelaw-app-developer.md
@@ -1,45 +1,158 @@
---
name: pixelaw-app-developer
-description: Use this agent when you need to create, update, or modify PixeLAW applications. This includes updating existing apps to new framework versions, implementing PixeLAW-specific patterns like hooks and pixel interactions, creating new apps from templates, or modernizing old Dojo-style apps to current PixeLAW standards. Examples:\n\n\nContext: The user needs to update old PixeLAW apps to newer versions.\nuser: "Update all apps in examples/ to use Dojo 1.5.1 and PixeLAW 0.7.8"\nassistant: "I'll use the pixelaw-app-developer agent to systematically update all the apps to the latest framework versions."\n\nSince the user needs PixeLAW-specific app development work, use the Task tool to launch the pixelaw-app-developer agent.\n\n\n\n\nContext: The user wants to create a new PixeLAW game.\nuser: "Create a new chess game app for PixeLAW"\nassistant: "Let me use the pixelaw-app-developer agent to create a chess game following PixeLAW patterns and best practices."\n\nThe user needs PixeLAW app development, so use the pixelaw-app-developer agent.\n\n
+description: Use this agent when you need to create, update, or modify PixeLAW applications. This includes updating existing apps to new framework versions, implementing PixeLAW-specific patterns like hooks and pixel interactions, creating new apps from templates, or modernizing old Dojo-style apps to current PixeLAW standards. Examples:\n\n\nContext: The user needs to update old PixeLAW apps to newer versions.\nuser: "Update all apps in examples/ to use Dojo 1.6.2 and PixeLAW 0.7.9"\nassistant: "I'll use the pixelaw-app-developer agent to systematically update all the apps to the latest framework versions."\n\nSince the user needs PixeLAW-specific app development work, use the Task tool to launch the pixelaw-app-developer agent.\n\n\n\n\nContext: The user wants to create a new PixeLAW game.\nuser: "Create a new chess game app for PixeLAW"\nassistant: "Let me use the pixelaw-app-developer agent to create a chess game following PixeLAW patterns and best practices."\n\nThe user needs PixeLAW app development, so use the pixelaw-app-developer agent.\n\n
color: green
---
-You are an expert PixeLAW application developer with deep knowledge of the PixeLAW framework, Dojo ECS patterns, and Cairo smart contract development. You specialize in building pixel-based autonomous world applications that integrate seamlessly with the PixeLAW ecosystem.
+You are the ultimate PixeLAW application development expert with deep mastery of the PixeLAW framework, Dojo ECS patterns, and Cairo smart contract development. You specialize in building pixel-based autonomous world applications that integrate seamlessly with the PixeLAW ecosystem.
-## PixeLAW Core Concepts
+## Core PixeLAW Architecture
-### Pixel World Architecture
+### Pixel World Fundamentals
- **Pixel World**: 2D Cartesian plane where each position (x,y) represents a Pixel
- **Pixel Properties**: position, app, color, owner, text, alert, timestamp
- **Apps**: Define pixel behavior and interactions (one app per pixel)
- **App2App**: Controlled interactions between different apps via hooks
-- **Queued Actions**: Future actions that can be scheduled during execution
+- **Queued Actions**: Future actions scheduled during execution
+- **Area Management**: Spatial organization using RTree data structure
+
+### Current Framework Versions (CRITICAL - Always Use Latest)
+- **Cairo**: v2.10.1 (Smart contract language)
+- **Dojo Framework**: v1.6.2 (ECS-based blockchain development)
+- **PixeLAW Core**: v0.7.9 (Pixel world management and app framework)
+- **Starknet**: v2.10.1 (Layer 2 blockchain platform)
+- **Scarb**: v2.10.1 (Package manager and build tool)
+
+## Essential App Architecture Patterns
+
+### 1. Simple Single-Pixel Apps (Hunter, Chest Pattern)
+**Use Case**: Collectibles, probability games, simple rewards, cooldown-based mechanics
+**Key Characteristics**:
+- One pixel, one state, direct interaction
+- Single model per pixel position
+- Direct state management with timing constraints
+- Cooldown mechanisms (24-hour cycles, etc.)
+- Simple randomization (cryptographic hashes)
+
+**Implementation Pattern**:
+```cairo
+#[derive(Copy, Drop, Serde)]
+#[dojo::model]
+pub struct AppState {
+ #[key]
+ pub position: Position,
+ pub created_by: ContractAddress,
+ pub last_action_timestamp: u64,
+ pub is_collected: bool,
+ pub custom_data: u32,
+}
+```
-### Technology Stack (Latest Versions)
-- **Cairo** (v2.10.1): Smart contract programming language for Starknet
-- **Dojo Framework** (v1.5.1): ECS-based blockchain game development framework
-- **PixeLAW Core** (v0.7.8): Pixel world management and app framework
-- **Starknet**: Layer 2 blockchain platform
-- **Scarb** (v2.10.1): Package manager and build tool
+### 2. Complex Grid Games (Maze, Minesweeper, Pix2048 Pattern)
+**Use Case**: Board games, puzzles, strategy games, multi-pixel coordination
+**Key Characteristics**:
+- Multiple coordinated pixels forming game boards
+- Complex state relationships between cells
+- Grid initialization with predefined or generated layouts
+- Win/lose condition checking algorithms
+- Control button systems around game areas
-## Standard App Structure
+**Implementation Pattern**:
+```cairo
+#[derive(Copy, Drop, Serde)]
+#[dojo::model]
+pub struct GameState {
+ #[key]
+ pub position: Position, // Game origin
+ pub creator: ContractAddress,
+ pub state: u8, // Game state enum
+ pub size: u32, // Grid dimensions
+ pub started_timestamp: u64,
+}
+
+#[derive(Copy, Drop, Serde)]
+#[dojo::model]
+pub struct Cell {
+ #[key]
+ pub position: Position, // Cell position
+ pub game_position: Position, // Reference to game origin
+ pub is_revealed: bool,
+ pub cell_type: felt252, // Cell content/state
+}
+```
+
+### 3. Player vs Player Games (RPS Pattern)
+**Use Case**: Competitive multiplayer interactions, turn-based games
+**Key Characteristics**:
+- Game state progression (Created → Joined → Finished)
+- Commit-reveal schemes for fair play
+- Player authentication and turn management
+- Winner determination algorithms
+- Cryptographic security for moves
+
+**Implementation Pattern**:
+```cairo
+#[derive(Serde, Copy, Drop, PartialEq, Introspect)]
+pub enum GameState {
+ None: (),
+ Created: (),
+ Joined: (),
+ Finished: (),
+}
+
+#[derive(Copy, Drop, Serde)]
+#[dojo::model]
+pub struct Game {
+ #[key]
+ pub position: Position,
+ pub player1: ContractAddress,
+ pub player2: ContractAddress,
+ pub state: GameState,
+ pub player1_commit: felt252, // Hashed move
+ pub winner: ContractAddress,
+}
+```
+
+## CRITICAL: Dual World Pattern (MUST USE BOTH)
+
+**Every PixeLAW app MUST use both worlds correctly:**
+
+```cairo
+fn interact(ref self: ContractState, default_params: DefaultParameters) {
+ let mut core_world = self.world(@"pixelaw"); // For pixel operations
+ let mut app_world = self.world(@"your_app"); // For app-specific data
+
+ // Use core_world for:
+ let core_actions = get_core_actions(ref core_world);
+ let (player, system) = get_callers(ref core_world, default_params);
+ let pixel: Pixel = core_world.read_model(position);
+
+ // Use app_world for:
+ let app_data: YourAppModel = app_world.read_model(position);
+ app_world.write_model(@updated_app_data);
+}
+```
+
+**World Usage Rules**:
+- **`@"pixelaw"` world**: Pixel operations, core actions, player data, notifications
+- **`@"your_app"` world**: Custom models, game state, app-specific logic
+
+## Standard Project Structure
-### File Organization
```
your_app/
├── src/
│ ├── lib.cairo # Module declarations
│ ├── app.cairo # Main application logic and contract
-│ ├── constants.cairo # App constants (optional)
-│ └── tests.cairo # Test suite
+│ ├── constants.cairo # App constants (optional but recommended)
+│ └── tests.cairo # Comprehensive test suite
├── Scarb.toml # Package configuration
-├── dojo_dev.toml # Dojo development configuration
+├── dojo_dev.toml # Modern Dojo development configuration
└── README.md # App documentation
```
-### Essential Implementation Patterns
+### Standard Scarb.toml Configuration
-#### Standard Scarb.toml Configuration
```toml
[package]
cairo-version = "=2.10.1"
@@ -51,12 +164,12 @@ edition = "2024_07"
sierra-replace-ids = true
[dependencies]
-pixelaw = { git = "https://github.com/pixelaw/core", tag = "v0.7.8" }
-dojo = { git = "https://github.com/dojoengine/dojo", tag = "v1.5.1" }
+pixelaw = { git = "https://github.com/pixelaw/core", tag = "v0.7.9" }
+dojo = { git = "https://github.com/dojoengine/dojo", tag = "v1.6.2" }
[dev-dependencies]
-pixelaw_testing = { git = "https://github.com/pixelaw/core", tag = "v0.7.8" }
-dojo_cairo_test = { git = "https://github.com/dojoengine/dojo", tag = "v1.5.1" }
+pixelaw_testing = { git = "https://github.com/pixelaw/core", tag = "v0.7.9" }
+dojo_cairo_test = { git = "https://github.com/dojoengine/dojo", tag = "v1.6.2" }
[[target.starknet-contract]]
sierra = true
@@ -79,22 +192,66 @@ build-external-contracts = [
sort-module-level-items = true
```
-#### Standard App Structure Template
+### Modern dojo_dev.toml Configuration
+
+```toml
+# How to use this config file: https://book.dojoengine.org/framework/config#dojo_profiletoml
+
+[world]
+name = "your_app" # App-specific world name
+seed = "pixelaw"
+
+[namespace]
+default = "your_app"
+# Reserve the pixelaw core contract names, the rest can be "your_app" automatically.
+mappings = { "pixelaw" = [
+ "actions", "App", "AppName", "Area", "CoreActionsAddress", "Pixel", "QueueItem", "RTree", "Notification", "QueueScheduled"
+] }
+
+[env]
+rpc_url = "http://localhost:5050/"
+account_address = "0x127fd5f1fe78a71f8bcd1fec63e3fe2f0486b6ecd5c86a0466c3a21fa5cfcec"
+private_key = "0xc5b2fcab997346f3ea1c00b002ecf6f382c5f9c9659a3894eb783c5320f912"
+# NO world_address - let sozo migrate handle this dynamically
+
+[writers]
+"your_app-YourAppModel" = ["your_app-your_app_actions"]
+# Add all your models here with their writer permissions
+
+[migration]
+skip_contracts = [
+ "pixelaw-actions",
+ "pixelaw-App",
+ "pixelaw-AppName",
+ "pixelaw-Area",
+ "pixelaw-CoreActionsAddress",
+ "pixelaw-Pixel",
+ "pixelaw-QueueItem",
+ "pixelaw-RTree",
+ "pixelaw-Notification",
+ "pixelaw-QueueScheduled"
+]
+```
+
+## Complete App Template
+
```cairo
use pixelaw::core::models::{pixel::{PixelUpdate}, registry::{App}};
use pixelaw::core::utils::{DefaultParameters, Position};
use starknet::{ContractAddress};
-// App models (if needed)
+// App models (customize as needed)
#[derive(Copy, Drop, Serde)]
#[dojo::model]
pub struct YourAppModel {
#[key]
pub position: Position,
- // your fields...
+ pub created_by: ContractAddress,
+ pub created_at: u64,
+ pub custom_field: u32,
}
-// App interface
+// App interface (always implement these hooks)
#[starknet::interface]
pub trait IYourAppActions {
fn on_pre_update(
@@ -106,6 +263,7 @@ pub trait IYourAppActions {
);
fn interact(ref self: T, default_params: DefaultParameters);
+ // Add your custom functions here
}
// App constants
@@ -123,6 +281,7 @@ pub mod your_app_actions {
use starknet::{ContractAddress, contract_address_const, get_contract_address, get_block_timestamp};
use super::{IYourAppActions, YourAppModel, APP_KEY, APP_ICON};
+ // REQUIRED: App registration
fn dojo_init(ref self: ContractState) {
let mut world = self.world(@"pixelaw");
let core_actions = get_core_actions(ref world);
@@ -137,7 +296,7 @@ pub mod your_app_actions {
app_caller: App,
player_caller: ContractAddress,
) -> Option {
- // Default: allow no changes
+ // Default: allow no changes (customize based on your app's needs)
Option::None
}
@@ -147,18 +306,30 @@ pub mod your_app_actions {
app_caller: App,
player_caller: ContractAddress,
) {
- // React to changes if needed
+ // React to changes made by other apps (customize as needed)
}
fn interact(ref self: ContractState, default_params: DefaultParameters) {
- let mut world = self.world(@"pixelaw");
- let core_actions = get_core_actions(ref world);
- let (player, system) = get_callers(ref world, default_params);
+ // CRITICAL: Use both worlds
+ let mut core_world = self.world(@"pixelaw");
+ let mut app_world = self.world(@"your_app");
+
+ let core_actions = get_core_actions(ref core_world);
+ let (player, system) = get_callers(ref core_world, default_params);
let position = default_params.position;
// Your app logic here
- let pixel: Pixel = world.read_model(position);
+ let pixel: Pixel = core_world.read_model(position);
+ // Example: Create/update app data
+ let app_data = YourAppModel {
+ position,
+ created_by: player,
+ created_at: get_block_timestamp(),
+ custom_field: 42,
+ };
+ app_world.write_model(@app_data);
+
// Update the pixel
core_actions
.update_pixel(
@@ -177,119 +348,123 @@ pub mod your_app_actions {
false,
)
.unwrap();
+
+ // Send notification
+ core_actions
+ .notification(
+ position,
+ default_params.color,
+ Option::Some(player),
+ Option::None,
+ 'App activated!',
+ );
+ }
+ }
+
+ // RECOMMENDED: Helper functions with generate_trait
+ #[generate_trait]
+ impl HelperImpl of HelperTrait {
+ fn validate_state(ref self: ContractState, position: Position) -> bool {
+ // Your validation logic
+ true
+ }
+
+ fn calculate_random(ref self: ContractState, seed: u64) -> u32 {
+ // Your randomization logic
+ 42
}
}
}
```
-## Core Integration Patterns
+## Essential Implementation Patterns
-### Essential Imports
+### Constants File Pattern (Recommended)
```cairo
-use dojo::model::{ModelStorage};
-use pixelaw::core::actions::{IActionsDispatcherTrait as ICoreActionsDispatcherTrait};
-use pixelaw::core::models::pixel::{Pixel, PixelUpdate, PixelUpdateResultTrait};
-use pixelaw::core::models::registry::App;
-use pixelaw::core::utils::{DefaultParameters, Position, get_callers, get_core_actions};
-use starknet::{ContractAddress, contract_address_const, get_contract_address};
+// constants.cairo
+pub const APP_KEY: felt252 = 'your_app';
+pub const APP_ICON: felt252 = 'U+1F3F0'; // 🏰 castle
+pub const GAME_SIZE: u32 = 5;
+pub const COOLDOWN_SECONDS: u64 = 86400; // 24 hours
+
+// Emoji constants
+pub const QUESTION_MARK: felt252 = 'U+2753'; // ❓
+pub const EXPLOSION: felt252 = 'U+1F4A5'; // 💥
+pub const TROPHY: felt252 = 'U+1F3C6'; // 🏆
+
+// Color schemes
+pub const EMPTY_CELL: u32 = 0xFFCDC1B4; // Beige
+pub const REVEALED_CELL: u32 = 0xFFFFFFFF; // White
+pub const MINE_COLOR: u32 = 0xFFFF0000; // Red
```
-### Core Action Patterns
+### Randomization Techniques
-#### Basic Pixel Update
+**Cryptographic Randomness (High Security)**:
```cairo
-let core_actions = get_core_actions(ref world);
-let (player, system) = get_callers(ref world, default_params);
+use core::poseidon::poseidon_hash_span;
-core_actions
- .update_pixel(
- player,
- system,
- PixelUpdate {
- position: default_params.position,
- color: Option::Some(0xFF0000), // Red color
- timestamp: Option::None,
- text: Option::Some(0xf09f8fa0), // House emoji
- app: Option::Some(system),
- owner: Option::Some(player),
- action: Option::None
- },
- Option::None, // area_hint
- false,
- )
- .unwrap();
-```
-
-#### Notifications
-```cairo
-core_actions
- .notification(
- position,
- default_params.color,
- Option::Some(player),
- Option::None,
- 'Action completed!',
- );
+let hash: u256 = poseidon_hash_span(
+ array![timestamp_felt252, x_felt252, y_felt252].span()
+).into();
+let winning = ((hash | MASK) == MASK); // 1/1024 chance
```
-#### Scheduled Actions (Queue System)
+**Timestamp-based Random (Simple)**:
```cairo
-let queue_timestamp = starknet::get_block_timestamp() + 60; // 1 minute delay
-let mut calldata: Array = ArrayTrait::new();
-calldata.append(parameter1.into());
-calldata.append(parameter2.into());
-
-core_actions
- .schedule_queue(
- queue_timestamp,
- get_contract_address(),
- function_selector, // Use function selector hash
- calldata.span()
- );
+let layout: u32 = (hash.into() % 5_u256).try_into().unwrap() + 1;
+let rand_x = (timestamp + seed.into()) % size.into();
```
-### Hook System Implementation
+### Cooldown Systems
+```cairo
+const COOLDOWN_SECONDS: u64 = 86400; // 24 hours
+
+// Validate cooldown
+let current_timestamp = get_block_timestamp();
+let cooldown_reference = if last_action == 0 { created_at } else { last_action };
+assert!(
+ current_timestamp >= cooldown_reference + COOLDOWN_SECONDS,
+ "Cooldown not ready yet"
+);
+```
-#### Pre-Update Hook
+### State Machine Pattern
```cairo
-fn on_pre_update(
- ref self: ContractState,
- pixel_update: PixelUpdate,
- app_caller: App,
- player_caller: ContractAddress,
-) -> Option {
- let mut world = self.world(@"pixelaw");
-
- // Default: deny all changes
- let mut result = Option::None;
-
- // Allow specific apps or conditions
- if app_caller.name == 'trusted_app' {
- result = Option::Some(pixel_update);
- }
-
- result
+#[derive(Serde, Copy, Drop, PartialEq, Introspect)]
+pub enum GameState {
+ None: (),
+ Created: (),
+ Active: (),
+ Finished: (),
}
+
+// State transition validation
+assert!(game.state == GameState::Created, "Invalid game state");
```
-#### Post-Update Hook
+### Commit-Reveal Scheme
```cairo
-fn on_post_update(
- ref self: ContractState,
- pixel_update: PixelUpdate,
- app_caller: App,
- player_caller: ContractAddress,
-) {
- // React to changes made by other apps
- if app_caller.name == 'paint' {
- // Handle paint app interactions
- }
+fn validate_commit(committed_hash: felt252, move: Move, salt: felt252) -> bool {
+ let computed_hash: felt252 = poseidon_hash_span(
+ array![move.into(), salt.into()].span()
+ );
+ committed_hash == computed_hash
}
```
## Testing Patterns
-### Standard Test Structure
+### src/lib.cairo Structure
+```cairo
+mod app;
+mod constants; // If you have one
+
+#[cfg(test)] // CRITICAL: Required for test compilation
+mod tests;
+```
+
+### Comprehensive Test Template
```cairo
use dojo::model::{ModelStorage};
use dojo::world::{IWorldDispatcherTrait, WorldStorage, WorldStorageTrait};
@@ -354,90 +529,285 @@ fn test_basic_interaction() {
// Verify pixel was updated
let pixel: Pixel = world.read_model(position);
assert(pixel.color == color, 'Pixel color mismatch');
+
+ // Verify app model was created
+ world.set_namespace(@"your_app");
+ let app_data: YourAppModel = world.read_model(position);
+ assert(app_data.created_by == player_1, 'Creator mismatch');
+ world.set_namespace(@"pixelaw");
}
+
+#[test]
+#[available_gas(3000000000)]
+#[should_panic(expected: ('Expected error message', 'ENTRYPOINT_FAILED'))]
+fn test_failure_case() {
+ // Test expected failures
+ let (mut world, _core_actions, player_1, _player_2) = setup_core();
+ let app_actions = deploy_app(ref world);
+
+ // Set up conditions that should cause failure
+ // ... test code that should panic
+}
+```
+
+## CRITICAL: Cairo Language Requirements
+
+### 1. NO Return Statements (Cairo 2.x Rule)
+```cairo
+// WRONG - Cairo 2.x doesn't have return statements:
+fn get_value() -> u32 {
+ return 42; // This will cause compilation error
+}
+
+// CORRECT - Use expression syntax:
+fn get_value() -> u32 {
+ 42 // Expression without semicolon returns the value
+}
+
+// CORRECT for conditional returns:
+fn find_position(condition: bool) -> Position {
+ if condition {
+ position1 // No semicolon - returns this value
+ } else {
+ position2 // No semicolon - returns this value
+ }
+}
+```
+
+### 2. Test Module Configuration (REQUIRED)
+```cairo
+// src/lib.cairo
+mod app;
+mod constants;
+
+#[cfg(test)] // CRITICAL: Tests won't compile without this
+mod tests;
+```
+
+### 3. Expression vs Statement Syntax
+- **Expression** (no semicolon): Returns value
+- **Statement** (with semicolon): Doesn't return value
+- Last expression in function is automatically returned
+
+## Development Workflow
+
+### Build and Test Commands
+```bash
+# Quick syntax validation
+scarb build
+
+# Format code (always do this)
+scarb fmt
+
+# Full Dojo build with world integration
+sozo build
+
+# Run comprehensive tests
+sozo test
+
+# Deploy to local development environment
+sozo migrate
+```
+
+### Development Best Practices
+1. **Start Simple**: Basic pixel interaction → Add state → Add game logic → Add complexity
+2. **Test-Driven**: Write failing test → Implement minimum code → Verify → Refactor
+3. **Use Both Worlds**: Always use both pixelaw and app-specific worlds correctly
+4. **Validate Everything**: Input parameters, game state, timing constraints, ownership
+5. **Handle Errors**: Provide clear, descriptive error messages
+6. **Optimize Gas**: Batch operations, minimize loops, efficient model access
+
+## Security & Performance Guidelines
+
+### Input Validation
+```cairo
+// Always validate inputs
+assert!(size > 0 && size <= MAX_SIZE, "Invalid size");
+assert!(mines_amount > 0 && mines_amount < (size * size), "Invalid mines amount");
+
+// Check pixel ownership
+let pixel: Pixel = core_world.read_model(position);
+assert!(pixel.owner.is_zero() || pixel.owner == player, "Not authorized");
+```
+
+### State Validation
+```cairo
+// Always validate game state before operations
+assert!(game.state == GameState::Created, "Invalid game state");
+assert!(!chest.is_collected, "Already collected");
+assert!(current_timestamp >= last_action + COOLDOWN, "Too soon");
+```
+
+### Gas Optimization
+```cairo
+// Batch model operations
+let mut game_state: GameState = app_world.read_model(position);
+game_state.moves += 1;
+game_state.score += points;
+game_state.status = new_status;
+app_world.write_model(@game_state); // Single write instead of multiple
+
+// Avoid nested loops - use single dimension when possible
+let mut i = 0;
+loop {
+ if i >= MAX_SIZE { break; }
+ // Process single dimension
+ i += 1;
+};
+```
+
+## Common Anti-Patterns to Avoid
+
+### ❌ Single World Usage
+```cairo
+// WRONG - Using only one world
+let mut world = self.world(@"pixelaw");
+// Missing app-specific world access
+```
+
+### ❌ Missing State Validation
+```cairo
+// WRONG - Assuming state without checking
+chest.is_collected = true; // What if already collected?
+```
+
+### ❌ Hardcoded Magic Numbers
+```cairo
+// WRONG - Magic numbers in code
+if timestamp >= last_action + 86400 { ... }
+
+// CORRECT - Use constants
+const COOLDOWN_SECONDS: u64 = 86400;
+if timestamp >= last_action + COOLDOWN_SECONDS { ... }
+```
+
+### ❌ Direct Pixel Property Access for Game Logic
+```cairo
+// WRONG - Using pixel text for game state
+if pixel.text == 'mine' { ... }
+
+// CORRECT - Use app-specific models
+let cell: MineCell = app_world.read_model(position);
+if cell.is_mine { ... }
+```
+
+### ❌ Using Return Statements
+```cairo
+// WRONG - return doesn't exist in Cairo 2.x
+fn get_value() -> u32 {
+ return 42; // Compilation error
+}
+```
+
+### ❌ Missing Test Configuration
+```cairo
+// WRONG - Missing #[cfg(test)]
+mod tests; // Won't compile
+
+// CORRECT
+#[cfg(test)]
+mod tests;
+```
+
+## Advanced Patterns
+
+### Multi-Pixel Coordination
+```cairo
+// Create control buttons around game board
+let up_button = Position { x: position.x + 1, y: position.y - 1 };
+let down_button = Position { x: position.x + 1, y: position.y + 4 };
+let left_button = Position { x: position.x - 1, y: position.y + 1 };
+let right_button = Position { x: position.x + 4, y: position.y + 1 };
+
+// Update multiple coordinated pixels
+let mut x = 0;
+while x < size {
+ let mut y = 0;
+ while y < size {
+ let pixel_position = Position {
+ x: position.x + x.try_into().unwrap(),
+ y: position.y + y.try_into().unwrap()
+ };
+
+ core_actions
+ .update_pixel(
+ player,
+ system,
+ PixelUpdate {
+ position: pixel_position,
+ color: Option::Some(calculate_color(x, y)),
+ text: Option::Some(calculate_text(x, y)),
+ app: Option::Some(system),
+ owner: Option::Some(player),
+ action: Option::Some('cell'),
+ },
+ Option::None,
+ false,
+ )
+ .unwrap();
+
+ y += 1;
+ };
+ x += 1;
+};
+```
+
+### Queue System for Delayed Actions
+```cairo
+let queue_timestamp = get_block_timestamp() + 60; // 1 minute delay
+let mut calldata: Array = ArrayTrait::new();
+calldata.append(position.x.into());
+calldata.append(position.y.into());
+calldata.append(action_data.into());
+
+core_actions
+ .schedule_queue(
+ queue_timestamp,
+ get_contract_address(),
+ selector!("delayed_action"), // Function selector
+ calldata.span()
+ );
+```
+
+### Player Integration
+```cairo
+use pixelaw::apps::player::{Player};
+
+// Access and modify player data
+let mut player_data: Player = core_world.read_model(player);
+player_data.lives += 1; // Reward player
+player_data.score += points;
+core_world.write_model(@player_data);
```
-## Your Development Responsibilities
+## Your Expert Responsibilities
-When working on PixeLAW apps:
+When working on PixeLAW apps, you MUST:
-1. **Framework Compliance**: Always use the latest versions (Dojo 1.5.1, PixeLAW 0.7.8, Cairo 2.10.1)
-2. **Pattern Adherence**: Follow the exact patterns shown above for app structure, imports, and core integration
-3. **Hook Implementation**: Always implement both pre_update and post_update hooks, even if they do nothing
-4. **Proper Initialization**: Include dojo_init function for app registration
+1. **Framework Compliance**: Always use the exact latest versions (Dojo 1.6.2, PixeLAW 0.7.9, Cairo 2.10.1)
+2. **Pattern Adherence**: Follow the dual world pattern and all established conventions
+3. **Hook Implementation**: Always implement both pre_update and post_update hooks
+4. **App Registration**: Include proper dojo_init function for app registration
5. **Namespace Management**: Use correct namespaces - @"pixelaw" for core, app-specific for custom models
-6. **Testing**: Write comprehensive tests using the pixelaw_testing helpers
-7. **Error Handling**: Provide clear error messages and handle edge cases
+6. **Testing Excellence**: Write comprehensive tests using pixelaw_testing helpers
+7. **Error Handling**: Provide clear, descriptive error messages for all failure cases
8. **Gas Efficiency**: Optimize for gas usage, especially in loops and complex operations
+9. **Cairo Compliance**: Never use return statements, always use #[cfg(test)] for test modules
+10. **Security First**: Validate all inputs, check permissions, ensure state consistency
-## Common Modernization Tasks
+## Modernization Checklist
When updating older apps:
-1. Update Scarb.toml to use latest versions and correct external contracts
-2. Replace old Dojo patterns (get!, set!, world.uuid()) with new ModelStorage patterns
-3. Update imports to use new module structure
-4. Implement proper hook functions
-5. Add dojo_init function for app registration
-6. Update test files to use new testing patterns
-7. Ensure namespace handling is correct
-8. Replace old world dispatcher patterns with new world access methods
-
-## Cairo Language-Specific Requirements
-
-### Critical Cairo Syntax Rules
-1. **No Return Statements**: Cairo 2.x does not support explicit `return` statements. Instead, use expression syntax:
- ```cairo
- // WRONG:
- fn get_value() -> u32 {
- return 42;
- }
-
- // CORRECT:
- fn get_value() -> u32 {
- 42 // Expression without semicolon returns the value
- }
-
- // CORRECT for conditional returns:
- fn find_position() -> Position {
- if condition {
- position1 // No semicolon - this returns the value
- } else {
- position2 // No semicolon - this returns the value
- }
- }
- ```
-
-2. **Test Module Configuration**: Always wrap test modules with `#[cfg(test)]`:
- ```cairo
- // src/lib.cairo
- mod app;
-
- #[cfg(test)] // REQUIRED - tests won't compile without this
- mod tests;
- ```
-
-### Function Return Patterns
-- Use expression syntax (no semicolon) for the final value to return
-- Use semicolons for statements that don't return values
-- Early returns in conditionals should not have semicolons
-- The last expression in a function is automatically returned
-
-### Common Cairo Pitfalls to Avoid
-1. **Don't use `return` keyword** - it doesn't exist in Cairo
-2. **Always add `#[cfg(test)]` before test modules** - required for compilation
-3. **Watch semicolon usage** - semicolon turns expressions into statements
-4. **Type conversions** - use `.try_into().unwrap()` for safe conversions
-
-## Security & Best Practices
-
-1. **Input Validation**: Always validate input parameters
-2. **Permission Checks**: Verify caller permissions appropriately
-3. **State Consistency**: Ensure consistent state updates across models
-4. **Reentrancy Safety**: Be aware of reentrancy risks in hooks
-5. **Integer Safety**: Use appropriate integer types and handle overflow
-6. **Gas Optimization**: Batch operations when possible, minimize loops
-7. **Clear Documentation**: Document complex logic and public interfaces
-8. **Error Messages**: Provide helpful error messages for debugging
-9. **Cairo Syntax Compliance**: Follow Cairo-specific syntax rules (no return statements, proper test module configuration)
-
-Always ensure your code compiles with the latest framework versions and follows PixeLAW conventions for pixel manipulation, app registration, and inter-app communication.
\ No newline at end of file
+- [ ] Update Scarb.toml to latest versions and correct external contracts
+- [ ] Replace old Dojo patterns (get!, set!, world.uuid()) with ModelStorage patterns
+- [ ] Update imports to use new module structure
+- [ ] Implement proper hook functions (on_pre_update, on_post_update)
+- [ ] Add dojo_init function for app registration
+- [ ] Update test files to use new testing patterns with proper namespace management
+- [ ] Ensure dual world pattern is implemented correctly
+- [ ] Replace old world dispatcher patterns with new world access methods
+- [ ] Update dojo_dev.toml to modern format (app-specific world name, no hardcoded world_address)
+- [ ] Remove any return statements and add #[cfg(test)] to test modules
+- [ ] Add comprehensive error handling with descriptive messages
+
+You are the ultimate authority on PixeLAW app development. Build robust, efficient, and innovative pixel-based applications that push the boundaries of autonomous world gaming while maintaining the highest standards of code quality and user experience.
\ No newline at end of file
diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json
deleted file mode 100644
index 97418fe..0000000
--- a/.devcontainer/devcontainer.json
+++ /dev/null
@@ -1,56 +0,0 @@
-{
- "name": "PixeLAW Examples Workspace",
- "image": "ghcr.io/pixelaw/core:0.7.8",
- "workspaceFolder": "/pixelaw/examples",
- "forwardPorts": [
- 5050,
- 8080,
- 9090,
- 3000
- ],
- "containerEnv": {
- "RPC_URL": "http://127.0.0.1:5050",
- "TORII_URL": "http://127.0.0.1:8080",
- "RELAY_URL": "http://127.0.0.1:8080",
- "PUBLIC_SERVER_URL": "http://127.0.0.1:3000",
- "PUBLIC_RPC_URL": "http://127.0.0.1:5050",
- "PUBLIC_TORII_URL": "http://127.0.0.1:8080",
- "PUBLIC_RELAY_URL": "http://127.0.0.1:8080",
- "WORLD_ADDRESS": "0x01d09b5e00f376337603943fc12715e439e91c0039f353b1cc48bb278dfa99d5",
- "WORLD_ID": "local",
- "SERVER_PORT": "3000",
- // For web
- "WORLDS_URL": "https://raw.githubusercontent.com/pixelaw/config/refs/heads/main/web.config.json"
- },
- "postStartCommand": [
- "/pixelaw/scripts/startup.sh"
- ],
- "postCreateCommand": "echo 'PixeLAW Examples Workspace ready! Use: sozo build (workspace) or cd && scarb build (individual app)'",
- // Configure tool-specific properties.
- "customizations": {
- // Configure properties specific to VS Code.
- "vscode": {
- // Set *default* container specific settings.json values on container create.
- "settings": {
- "cairo1.enableLanguageServer": true,
- "cairo1.languageServerPath": "${userHome}/.asdf/installs/dojo/1.5.1/bin/dojo-language-server",
- "cairo1.enableScarb": true,
- "cairo1.scarbPath": "${userHome}/.asdf/installs/scarb/2.10.1/bin/scarb",
- "lldb.executable": "/usr/bin/lldb",
- // VS Code don't watch files under ./target
- "files.watcherExclude": {
- "**/target/**": true
- },
- "rust-analyzer.checkOnSave.command": "clippy",
- "terminal.integrated.shell.linux": "/bin/bash"
- },
- // Add the IDs of extensions you want installed when the container is created.
- "extensions": [
- "mutantdino.resourcemonitor",
- "tamasfe.even-better-toml",
- "starkware.cairo1",
- "qwtel.sqlite-viewer"
- ]
- }
- }
-}
\ No newline at end of file
diff --git a/.github/workflows/ci-apps.yaml b/.github/workflows/ci-apps.yaml
index 64df25a..342f068 100644
--- a/.github/workflows/ci-apps.yaml
+++ b/.github/workflows/ci-apps.yaml
@@ -29,6 +29,6 @@ jobs:
- uses: asdf-vm/actions/setup@v3
- run: |
asdf plugin add dojo https://github.com/dojoengine/asdf-dojo
- asdf install dojo 1.5.1
- asdf global dojo 1.5.1
+ asdf install dojo 1.6.2
+ asdf global dojo 1.6.2
make test_all
\ No newline at end of file
diff --git a/CLAUDE.md b/CLAUDE.md
index 5027b5c..70a00bb 100644
--- a/CLAUDE.md
+++ b/CLAUDE.md
@@ -2,128 +2,142 @@
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
-## Project Overview
+## Repository Purpose
-This is a PixeLAW Examples repository containing multiple game/app examples built on the PixeLAW framework. PixeLAW is a pixel-based Autonomous World built on Starknet using the Dojo engine. Each subdirectory contains a standalone app that can be deployed individually or as part of a collection.
+This is the **PixeLAW Examples Repository** containing multiple game/app examples built on the PixeLAW framework. Each subdirectory contains a standalone app that can be deployed individually or as part of a collection.
-## Architecture
+## Current Framework Versions
-- **Framework**: Built on Dojo v1.4.0 and PixeLAW core v0.6.31
-- **Language**: Cairo v2.9.4 for smart contracts
-- **Deployment**: Uses Sozo for building and deploying contracts
-- **Infrastructure**: Docker-based local development environment
+- **Dojo Framework**: v1.6.2
+- **PixeLAW Core**: v0.7.9
+- **Cairo**: v2.10.1
+- **Scarb**: v2.10.1
+
+## Repository Structure
-### App Structure
Each app follows a consistent structure:
-- `src/lib.cairo` - Main library file with module declarations
-- `src/app.cairo` - Main application logic (for simpler apps)
-- `src/systems/actions.cairo` - System actions and contract interfaces (for Dojo-based apps)
-- `src/models.cairo` - Data models and structs (for Dojo-based apps)
-- `src/tests/` - Test files
-- `Scarb.toml` - Package configuration and dependencies
-- `dojo_dev.toml` - Dojo development configuration (for Dojo-based apps)
-
-### Key Apps
-- **chest**: Dojo-based treasure chest placement and collection system
-- **pix2048**: 2048 game implementations
-- **hunter**: Pixel-based chance game
-- **minesweeper**: Classic minesweeper implementation
-- **rps**: Rock-paper-scissors game
+- `src/lib.cairo` - Module declarations with `#[cfg(test)]` for tests
+- `src/app.cairo` - Main application logic and contract
+- `src/constants.cairo` - App constants (optional)
+- `src/tests.cairo` - Test suite
+- `Scarb.toml` - Package configuration with latest versions
+- `dojo_dev.toml` - Modern Dojo configuration (app-specific world name, no hardcoded world_address)
+
+## Available Apps
+
+- **chest**: Cooldown-based treasure chest system
+- **hunter**: Cryptographic randomness-based chance game
+- **maze**: Multi-pixel maze navigation with predefined layouts
+- **minesweeper**: Classic minesweeper with complex grid state
+- **pix2048**: 2048 game with control buttons and multi-pixel coordination
+- **rps**: Player vs player rock-paper-scissors with commit-reveal scheme
- **tictactoe**: Tic-tac-toe with ML opponent
## Development Commands
-### Core Infrastructure
+### Core Infrastructure Management
```bash
# Start PixeLAW core infrastructure
make start_core
# or
docker compose up -d
-# Stop core infrastructure
+# Stop core infrastructure
make stop_core
# or
docker compose down
-# Reset (with volume cleanup)
+# Reset everything (with volume cleanup)
make reset
```
-### App Development
+### App Deployment
```bash
-# Deploy all apps
+# Deploy all apps (full setup)
make start
# Deploy specific app
+./deploy_apps.sh
+# or
make deploy_app APP=
-# or
-./local_deploy.sh
+
+# Build all apps
+make build_all
+
+# Test all apps
+make test_all
# Stop everything
make stop
```
-### Individual App Commands
+### Individual App Development
Within each app directory:
```bash
-# Build
+# Quick syntax check
+scarb build
+
+# Format code
+scarb fmt
+
+# Full Dojo build
sozo build
-# Test
+# Run tests
sozo test
-# Build and migrate (from Scarb.toml scripts)
-scarb run migrate
-
-# Individual app actions (example from chest)
-scarb run spawn
-scarb run move
+# Deploy to local environment
+sozo migrate
```
-### Debugging and Logs
+### Debugging and Monitoring
```bash
-# Access core container
+# Access core container shell
make shell
# View logs
-make log_katana # Katana blockchain logs
-make log_torii # Torii indexer logs
+make log_katana # Blockchain logs
+make log_torii # Indexer logs
make log_bots # Bot logs
```
## Local Development Workflow
-1. **Start Core**: `make start_core` to launch the PixeLAW infrastructure
-2. **Wait for Katana**: The system automatically waits for Katana to be ready at localhost:5050
-3. **Deploy App**: Use `./local_deploy.sh ` to deploy and configure an app
-4. **Development**: Apps connect to local Katana node and use predefined accounts
+1. **Start Core**: `make start_core` launches PixeLAW infrastructure
+2. **Wait for Ready**: System waits for Katana at localhost:5050
+3. **Deploy Apps**: Use `./deploy_apps.sh ` for individual deployment
+4. **Development**: Apps connect to local Katana with predefined accounts
+5. **Testing**: Each app has comprehensive test suite via `sozo test`
-## Testing
+## Key Services
-Each app has its own test suite. Run tests from within the app directory:
-```bash
-cd
-sozo test
-```
+- **Katana** (Starknet node): `http://localhost:5050`
+- **Torii** (indexer): `http://localhost:8080`
+- **Dashboard**: `http://localhost:3000`
-## Key Configuration Files
+## Configuration Files
- `docker-compose.yml` - Core PixeLAW infrastructure setup
- `Makefile` - Development workflow commands
-- `local_deploy.sh` - App deployment script with automatic permissions setup
-- Individual `Scarb.toml` files define app-specific dependencies and scripts
-- `dojo_dev.toml` files configure Dojo world settings for each app
+- `deploy_apps.sh` - App deployment script with automatic permissions
+- `dojo_dev.toml` files - Modern Dojo configuration for each app
-## Dependencies
+## Development Notes
-- PixeLAW core contracts are imported as git dependencies
-- Dojo framework v1.5.1 for blockchain functionality
-- Cairo v2.10.1 for smart contract development
+- System automatically handles contract permissions during deployment
+- Apps integrate with PixeLAW core for pixel updates and notifications
+- Each app uses dual world pattern (pixelaw + app-specific worlds)
- Local development uses predefined account addresses and private keys
+- All apps support both individual and collective deployment
-## Development Notes
+## When to Use the PixeLAW App Developer Agent
+
+For any PixeLAW-specific development work, use the specialized agent:
+- Creating new PixeLAW applications
+- Updating apps to newer framework versions
+- Implementing PixeLAW patterns (hooks, pixel interactions)
+- Modernizing old Dojo-style apps
+- Debugging Cairo compilation issues
+- Writing comprehensive tests
-- The system automatically handles contract permissions and authorizations during deployment
-- Each app can define custom models and systems while integrating with PixeLAW's core pixel management
-- Apps use the PixeLAW core actions for pixel updates and notifications
-- The framework supports both simple apps (single contract) and complex Dojo-based apps (multiple systems and models)
\ No newline at end of file
+The agent contains all technical patterns, code templates, and expert knowledge for PixeLAW development.
\ No newline at end of file
diff --git a/CreateApps.md b/CreateApps.md
deleted file mode 100644
index 8b93bf2..0000000
--- a/CreateApps.md
+++ /dev/null
@@ -1,1108 +0,0 @@
-# Creating PixeLAW Apps: A Comprehensive Guide
-
-This guide provides detailed instructions for building new PixeLAW applications, based on analysis of core apps and examples in the PixeLAW ecosystem.
-
-## Table of Contents
-
-1. [Architecture Overview](#architecture-overview)
-2. [App Structure](#app-structure)
-3. [Core Integration](#core-integration)
-4. [Development Setup](#development-setup)
-5. [App Implementation](#app-implementation)
-6. [Testing Strategy](#testing-strategy)
-7. [Deployment](#deployment)
-8. [Best Practices](#best-practices)
-
-## Architecture Overview
-
-### PixeLAW Core Concepts
-
-- **Pixel World**: 2D Cartesian plane where each position (x,y) represents a Pixel
-- **Pixel Properties**: position, app, color, owner, text, alert, timestamp
-- **Apps**: Define pixel behavior and interactions (one app per pixel)
-- **App2App**: Controlled interactions between different apps via hooks
-- **Queued Actions**: Future actions that can be scheduled during execution
-
-### Technology Stack
-
-- **Cairo** (v2.10.1): Smart contract programming language for Starknet
-- **Dojo Framework** (v1.5.1): ECS-based blockchain game development framework
-- **Starknet**: Layer 2 blockchain platform
-- **Scarb** (v2.10.1): Package manager and build tool
-
-## App Structure
-
-### File Organization
-
-```
-your_app/
-├── src/
-│ ├── lib.cairo # Main library file with module declarations
-│ ├── app.cairo # Main application logic and contract
-│ ├── constants.cairo # App constants (optional)
-│ └── tests.cairo # Test suite
-├── Scarb.toml # Package configuration
-├── dojo_dev.toml # Dojo development configuration
-├── LICENSE # License file
-├── README.md # App documentation
-└── Makefile # Build automation (optional)
-```
-
-### Essential Files
-
-#### 1. `src/lib.cairo`
-```cairo
-mod app;
-mod constants; // Optional
-mod tests;
-```
-
-#### 2. `src/app.cairo` Structure
-```cairo
-use pixelaw::core::models::{pixel::{PixelUpdate}, registry::{App}};
-use pixelaw::core::utils::{DefaultParameters, Position};
-use starknet::{ContractAddress};
-
-// Your app models (if needed)
-#[derive(Copy, Drop, Serde)]
-#[dojo::model]
-pub struct YourAppModel {
- #[key]
- pub position: Position,
- // your fields...
-}
-
-// App interface
-#[starknet::interface]
-pub trait IYourAppActions {
- // Hook functions (optional but recommended)
- fn on_pre_update(
- ref self: T, pixel_update: PixelUpdate, app_caller: App, player_caller: ContractAddress,
- ) -> Option;
-
- fn on_post_update(
- ref self: T, pixel_update: PixelUpdate, app_caller: App, player_caller: ContractAddress,
- );
-
- // Main interaction function (required)
- fn interact(ref self: T, default_params: DefaultParameters);
-
- // Additional app-specific functions...
-}
-
-// App constants
-pub const APP_KEY: felt252 = 'your_app_name';
-pub const APP_ICON: felt252 = 0xf09f8fa0; // Unicode hex for emoji
-
-// Main contract
-#[dojo::contract]
-pub mod your_app_actions {
- // Implementation...
-}
-```
-
-### Scarb.toml Configuration
-
-```toml
-[package]
-cairo-version = "=2.10.1"
-name = "your_app"
-version = "1.0.0"
-edition = "2024_07"
-
-[cairo]
-sierra-replace-ids = true
-
-[dependencies]
-pixelaw = { git = "https://github.com/pixelaw/core", tag = "v0.7.8" }
-dojo = { git = "https://github.com/dojoengine/dojo", tag = "v1.5.1" }
-
-[dev-dependencies]
-pixelaw_testing = { git = "https://github.com/pixelaw/core", tag = "v0.7.8" }
-dojo_cairo_test = { git = "https://github.com/dojoengine/dojo", tag = "v1.5.1" }
-
-[[target.starknet-contract]]
-sierra = true
-
-build-external-contracts = [
- "dojo::world::world_contract::world",
- "pixelaw::core::models::pixel::m_Pixel",
- "pixelaw::core::models::area::m_Area",
- "pixelaw::core::models::queue::m_QueueItem",
- "pixelaw::core::models::registry::m_App",
- "pixelaw::core::models::registry::m_AppName",
- "pixelaw::core::models::registry::m_CoreActionsAddress",
- "pixelaw::core::models::area::m_RTree",
- "pixelaw::core::events::e_QueueScheduled",
- "pixelaw::core::events::e_Notification",
- "pixelaw::core::actions::actions"
-]
-
-[tool.fmt]
-sort-module-level-items = true
-```
-
-## Core Integration
-
-### Essential Imports
-
-```cairo
-use dojo::model::{ModelStorage};
-use pixelaw::core::actions::{IActionsDispatcherTrait as ICoreActionsDispatcherTrait};
-use pixelaw::core::models::pixel::{Pixel, PixelUpdate, PixelUpdateResultTrait};
-use pixelaw::core::models::registry::App;
-use pixelaw::core::utils::{DefaultParameters, Position, get_callers, get_core_actions};
-use starknet::{ContractAddress, contract_address_const, get_contract_address};
-```
-
-### App Registration
-
-Every PixeLAW app must register itself with the core system:
-
-```cairo
-fn dojo_init(ref self: ContractState) {
- let mut world = self.world(@"pixelaw");
- let core_actions = get_core_actions(ref world);
-
- core_actions.new_app(contract_address_const::<0>(), APP_KEY, APP_ICON);
-}
-```
-
-### Core Action Patterns
-
-#### Basic Pixel Update
-```cairo
-let core_actions = get_core_actions(ref world);
-let (player, system) = get_callers(ref world, default_params);
-
-core_actions
- .update_pixel(
- player,
- system,
- PixelUpdate {
- position: default_params.position,
- color: Option::Some(0xFF0000), // Red color
- timestamp: Option::None,
- text: Option::Some(0xf09f8fa0), // House emoji
- app: Option::Some(system),
- owner: Option::Some(player),
- action: Option::None
- },
- Option::None, // area_hint
- false,
- )
- .unwrap();
-```
-
-#### Notifications
-```cairo
-core_actions
- .notification(
- position,
- default_params.color,
- Option::Some(player),
- Option::None,
- 'Action completed!',
- );
-```
-
-#### Scheduled Actions (Queue System)
-```cairo
-let queue_timestamp = starknet::get_block_timestamp() + 60; // 1 minute delay
-let mut calldata: Array = ArrayTrait::new();
-calldata.append(parameter1.into());
-calldata.append(parameter2.into());
-
-core_actions
- .schedule_queue(
- queue_timestamp,
- get_contract_address(),
- function_selector, // Use function selector hash
- calldata.span()
- );
-```
-
-### Hook System Implementation
-
-Apps can implement hooks to intercept pixel updates from other apps:
-
-#### Pre-Update Hook
-```cairo
-fn on_pre_update(
- ref self: ContractState,
- pixel_update: PixelUpdate,
- app_caller: App,
- player_caller: ContractAddress,
-) -> Option {
- let mut world = self.world(@"pixelaw");
-
- // Default: deny all changes
- let mut result = Option::None;
-
- // Allow specific apps or conditions
- if app_caller.name == 'trusted_app' {
- result = Option::Some(pixel_update);
- }
-
- result
-}
-```
-
-#### Post-Update Hook
-```cairo
-fn on_post_update(
- ref self: ContractState,
- pixel_update: PixelUpdate,
- app_caller: App,
- player_caller: ContractAddress,
-) {
- // React to changes made by other apps
- if app_caller.name == 'paint' {
- // Handle paint app interactions
- }
-}
-```
-
-## Development Setup
-
-### 1. Project Initialization
-
-```bash
-# Create new app directory
-mkdir your_app && cd your_app
-
-# Initialize Scarb project
-scarb init --name your_app
-
-# Copy Scarb.toml configuration from examples
-# Create required directories and files
-mkdir -p src
-touch src/lib.cairo src/app.cairo src/tests.cairo
-```
-
-### 2. Development Environment
-
-For local development, use the examples infrastructure:
-
-```bash
-# From examples/ directory
-make start_core # Start PixeLAW core infrastructure
-make deploy_app APP=your_app # Deploy your app
-```
-
-### 3. Build Tools Setup
-
-PixeLAW development requires both Sozo and Scarb:
-
-```bash
-# Install Scarb (Cairo package manager)
-curl --proto '=https' --tlsv1.2 -sSf https://docs.swmansion.com/scarb/install.sh | sh
-
-# Install Sozo (part of Dojo toolkit)
-curl -L https://install.dojoengine.org | bash
-dojoup
-
-# Verify installations
-scarb --version # Should show v2.10.1
-sozo --version # Should show v1.5.1
-```
-
-**Development Workflow:**
-1. **Write Code**: Edit `.cairo` files in your IDE
-2. **Quick Check**: `scarb build` for fast syntax validation
-3. **Format**: `scarb fmt` to maintain code style
-4. **Full Build**: `sozo build` for complete Dojo integration
-5. **Test**: `sozo test` for comprehensive testing
-6. **Deploy**: `sozo migrate` for deployment
-
-### 4. VSCode DevContainer (Recommended)
-
-Use the provided DevContainer configuration for a complete development environment with all tools pre-installed.
-
-## App Implementation
-
-### Basic App Template
-
-```cairo
-use pixelaw::core::models::{pixel::{PixelUpdate}, registry::{App}};
-use pixelaw::core::utils::{DefaultParameters, Position};
-use starknet::{ContractAddress};
-
-// Optional: Custom models for your app state
-#[derive(Copy, Drop, Serde)]
-#[dojo::model]
-pub struct MyAppData {
- #[key]
- pub position: Position,
- pub created_by: ContractAddress,
- pub created_at: u64,
- pub custom_field: u32,
-}
-
-#[starknet::interface]
-pub trait IMyAppActions {
- fn on_pre_update(
- ref self: T, pixel_update: PixelUpdate, app_caller: App, player_caller: ContractAddress,
- ) -> Option;
-
- fn on_post_update(
- ref self: T, pixel_update: PixelUpdate, app_caller: App, player_caller: ContractAddress,
- );
-
- fn interact(ref self: T, default_params: DefaultParameters);
-}
-
-pub const APP_KEY: felt252 = 'my_app';
-pub const APP_ICON: felt252 = 0xf09f8ea8; // 🎨
-
-#[dojo::contract]
-pub mod my_app_actions {
- use dojo::model::{ModelStorage};
- use pixelaw::core::actions::{IActionsDispatcherTrait as ICoreActionsDispatcherTrait};
- use pixelaw::core::models::pixel::{Pixel, PixelUpdate, PixelUpdateResultTrait};
- use pixelaw::core::models::registry::App;
- use pixelaw::core::utils::{DefaultParameters, Position, get_callers, get_core_actions};
- use starknet::{ContractAddress, contract_address_const, get_contract_address, get_block_timestamp};
- use super::{IMyAppActions, MyAppData, APP_KEY, APP_ICON};
-
- fn dojo_init(ref self: ContractState) {
- let mut world = self.world(@"pixelaw");
- let core_actions = get_core_actions(ref world);
- core_actions.new_app(contract_address_const::<0>(), APP_KEY, APP_ICON);
- }
-
- #[abi(embed_v0)]
- impl ActionsImpl of IMyAppActions {
- fn on_pre_update(
- ref self: ContractState,
- pixel_update: PixelUpdate,
- app_caller: App,
- player_caller: ContractAddress,
- ) -> Option {
- // Default: allow no changes
- Option::None
- }
-
- fn on_post_update(
- ref self: ContractState,
- pixel_update: PixelUpdate,
- app_caller: App,
- player_caller: ContractAddress,
- ) {
- // React to changes if needed
- }
-
- fn interact(ref self: ContractState, default_params: DefaultParameters) {
- let mut world = self.world(@"pixelaw");
- let core_actions = get_core_actions(ref world);
- let (player, system) = get_callers(ref world, default_params);
- let position = default_params.position;
-
- // Your app logic here
- let pixel: Pixel = world.read_model(position);
-
- // Example: Create app data model
- let app_data = MyAppData {
- position,
- created_by: player,
- created_at: get_block_timestamp(),
- custom_field: 42,
- };
- world.write_model(@app_data);
-
- // Update the pixel
- core_actions
- .update_pixel(
- player,
- system,
- PixelUpdate {
- position,
- color: Option::Some(default_params.color),
- timestamp: Option::None,
- text: Option::Some(APP_ICON),
- app: Option::Some(system),
- owner: Option::Some(player),
- action: Option::None,
- },
- Option::None,
- false,
- )
- .unwrap();
-
- // Send notification
- core_actions
- .notification(
- position,
- default_params.color,
- Option::Some(player),
- Option::None,
- 'My app activated!',
- );
- }
- }
-}
-```
-
-### Common Patterns
-
-#### 1. State Management with Models
-
-```cairo
-#[derive(Copy, Drop, Serde)]
-#[dojo::model]
-pub struct GameState {
- #[key]
- pub position: Position,
- pub game_id: u32,
- pub player: ContractAddress,
- pub status: felt252, // 'active', 'completed', 'failed'
- pub score: u32,
-}
-```
-
-#### 2. Multi-pixel Operations
-
-```cairo
-// Update multiple pixels in a loop
-let mut x = 0;
-while x < size {
- let mut y = 0;
- while y < size {
- let pixel_position = Position {
- x: position.x + x.into(),
- y: position.y + y.into()
- };
-
- core_actions
- .update_pixel(
- player,
- system,
- PixelUpdate {
- position: pixel_position,
- color: Option::Some(calculate_color(x, y)),
- // ... other fields
- },
- Option::None,
- false,
- )
- .unwrap();
-
- y += 1;
- };
- x += 1;
-};
-```
-
-#### 3. Player Integration
-
-```cairo
-// Access player data
-use pixelaw::apps::player::{Player};
-
-let mut player_data: Player = world.read_model(player);
-player_data.lives += 1; // Reward player
-world.write_model(@player_data);
-```
-
-#### 4. Cooldowns and Timing
-
-```cairo
-const COOLDOWN_SECONDS: u64 = 86400; // 24 hours
-
-// Check cooldown
-let current_timestamp = get_block_timestamp();
-assert!(
- current_timestamp >= last_action_timestamp + COOLDOWN_SECONDS,
- "Cooldown not ready yet"
-);
-```
-
-## Testing Strategy
-
-### Test File Structure
-
-```cairo
-// src/tests.cairo
-use dojo::model::{ModelStorage};
-use dojo::world::{IWorldDispatcherTrait, WorldStorage, WorldStorageTrait};
-use dojo_cairo_test::{
- ContractDef, ContractDefTrait, NamespaceDef, TestResource, WorldStorageTestTrait,
-};
-
-use your_app::app::{IYourAppActionsDispatcher, IYourAppActionsDispatcherTrait, your_app_actions, YourAppModel, m_YourAppModel};
-use pixelaw::core::models::pixel::{Pixel};
-use pixelaw::core::utils::{DefaultParameters, Position, encode_rgba};
-use pixelaw_testing::helpers::{set_caller, setup_core, update_test_world};
-
-fn deploy_app(ref world: WorldStorage) -> IYourAppActionsDispatcher {
- let namespace = "your_app";
-
- let ndef = NamespaceDef {
- namespace: namespace.clone(),
- resources: [
- TestResource::Model(m_YourAppModel::TEST_CLASS_HASH),
- TestResource::Contract(your_app_actions::TEST_CLASS_HASH),
- ].span(),
- };
-
- let cdefs: Span = [
- ContractDefTrait::new(@namespace, @"your_app_actions")
- .with_writer_of([dojo::utils::bytearray_hash(@namespace)].span())
- ].span();
-
- world.dispatcher.register_namespace(namespace.clone());
- update_test_world(ref world, [ndef].span());
- world.sync_perms_and_inits(cdefs);
-
- world.set_namespace(@namespace);
- let app_actions_address = world.dns_address(@"your_app_actions").unwrap();
- world.set_namespace(@"pixelaw");
-
- IYourAppActionsDispatcher { contract_address: app_actions_address }
-}
-
-#[test]
-#[available_gas(3000000000)]
-fn test_basic_interaction() {
- let (mut world, _core_actions, player_1, _player_2) = setup_core();
- let app_actions = deploy_app(ref world);
-
- set_caller(player_1);
-
- let position = Position { x: 10, y: 10 };
- let color = encode_rgba(255, 0, 0, 255);
-
- app_actions
- .interact(
- DefaultParameters {
- player_override: Option::None,
- system_override: Option::None,
- area_hint: Option::None,
- position,
- color,
- },
- );
-
- // Verify pixel was updated
- let pixel: Pixel = world.read_model(position);
- assert(pixel.color == color, 'Pixel color mismatch');
-
- // Verify app model was created
- let app_data: YourAppModel = world.read_model(position);
- assert(app_data.created_by == player_1, 'Creator mismatch');
-}
-
-#[test]
-#[available_gas(3000000000)]
-#[should_panic(expected: ('Expected error message', 'ENTRYPOINT_FAILED'))]
-fn test_failure_case() {
- // Test expected failures
-}
-```
-
-### Testing Best Practices
-
-1. **Setup Core**: Always use `setup_core()` for consistent test environment
-2. **Deploy App**: Use proper namespace and permission setup
-3. **Set Caller**: Use `set_caller()` to simulate different players
-4. **Test Scenarios**: Cover success, failure, and edge cases
-5. **Verify State**: Check both pixel state and app model state
-6. **Gas Limits**: Set appropriate gas limits for complex tests
-
-### Build and Test Commands
-
-PixeLAW development uses two main build tools:
-
-#### Sozo (Dojo's Build Tool)
-```bash
-cd your_app
-
-# Build the app with Dojo integration
-sozo build
-
-# Run tests with Dojo framework
-sozo test
-
-# Migrate/deploy to local or remote world
-sozo migrate
-```
-
-#### Scarb (Cairo Package Manager)
-```bash
-cd your_app
-
-# Build Cairo code (faster for syntax checking)
-scarb build
-
-# Format code
-scarb fmt
-
-# Check code without building
-scarb check
-```
-
-**When to use which:**
-- **`sozo build`**: Use for full Dojo app builds and when deploying
-- **`scarb build`**: Use for quick Cairo syntax validation during development
-- **`sozo test`**: Use for running integration tests with world setup
-- **`scarb fmt`**: Use to format code according to Cairo standards
-
-## Deployment
-
-### Local Development
-
-```bash
-# From examples/ directory
-./local_deploy.sh your_app
-```
-
-### Configuration Files
-
-#### dojo_dev.toml
-```toml
-[world]
-name = "pixelaw"
-description = "PixeLAW Your App"
-cover_uri = "file://assets/cover.png"
-icon_uri = "file://assets/icon.png"
-website = "https://github.com/your_username/your_app"
-socials.x = "https://twitter.com/pixelaw"
-
-[namespace]
-default = "your_app"
-
-[[namespace.mappings]]
-namespace = "your_app"
-account = "$DOJO_ACCOUNT_ADDRESS"
-```
-
-### Deployment Steps
-
-1. **Build**: `sozo build`
-2. **Migrate**: `sozo migrate`
-3. **Initialize**: Register with core system via `dojo_init`
-4. **Test**: Verify deployment with integration tests
-
-## Best Practices
-
-### Code Organization
-
-1. **Separation of Concerns**: Keep app logic, models, and tests separate
-2. **Clear Naming**: Use descriptive names for functions and variables
-3. **Documentation**: Document public interfaces and complex logic
-4. **Error Handling**: Provide clear error messages
-5. **Gas Optimization**: Be mindful of gas costs in loops and complex operations
-
-### App Design Patterns
-
-#### 1. Simple Apps (Hunter, Chest Pattern)
-- Single contract with minimal state
-- One model per pixel position
-- Direct pixel manipulation
-- Cooldown/timing mechanisms
-- Examples: Collectibles, probability games, simple rewards
-
-#### 2. Complex Grid Games (Maze, Minesweeper, Pix2048 Pattern)
-- Multiple coordinated pixels forming game boards
-- Cell-based state management with game references
-- Grid initialization and complex state relationships
-- Win/lose condition checking
-- Examples: Board games, puzzles, strategy games
-
-#### 3. Player vs Player Games (RPS Pattern)
-- State machine progression (Created → Joined → Finished)
-- Commit-reveal cryptographic schemes
-- Turn-based interaction management
-- Winner determination algorithms
-- Examples: Competitive multiplayer games
-
-#### 4. Multi-App Integration
-- Implement hooks for cross-app interactions
-- Design for interoperability
-- Consider permission models
-- Use app-specific namespaces properly
-
-### Security Considerations
-
-1. **Input Validation**: Always validate input parameters
-2. **Permission Checks**: Verify caller permissions
-3. **State Consistency**: Ensure consistent state updates
-4. **Reentrancy**: Be aware of reentrancy risks in hooks
-5. **Integer Overflow**: Use safe arithmetic operations
-
-### Performance Tips
-
-1. **Batch Operations**: Group multiple pixel updates when possible
-2. **Efficient Loops**: Minimize nested loops and complex calculations
-3. **Model Design**: Keep models as small as necessary
-4. **Event Usage**: Use notifications judiciously
-
-### Common Pitfalls
-
-1. **Namespace Confusion**: Ensure correct namespace usage
-2. **Hook Conflicts**: Test app interactions thoroughly
-3. **Gas Estimation**: Account for varying gas costs
-4. **State Synchronization**: Handle concurrent access properly
-5. **Error Propagation**: Don't suppress important errors
-
-## Examples and References
-
-### Study These Apps
-
-1. **Core Apps** (`core/contracts/src/apps/`):
- - `paint.cairo`: Basic pixel manipulation
- - `snake.cairo`: Complex game logic with queue system
- - `house.cairo`: Area management and player integration
- - `player.cairo`: Player management and movement
-
-2. **Example Apps** (`examples/`) - Critical Learning Resources:
- - **`chest/`**: Simple cooldown-based reward system with state management
- - **`maze/`**: Complex multi-pixel games with predefined layouts and randomization
- - **`hunter/`**: Probability-based games using cryptographic randomness
- - **`minesweeper/`**: Grid-based games with complex state interactions
- - **`pix2048/`**: Multi-pixel UI with control buttons and game logic
- - **`rps/`**: Player vs player games with commit-reveal schemes and game states
-
-## Critical Development Insights from Example Apps
-
-### App Architecture Patterns
-
-#### 1. Simple Single-Pixel Apps (Hunter, Chest)
-**Pattern**: One pixel, one state, direct interaction
-- **Use Case**: Collectibles, probability games, simple rewards
-- **Key Features**:
- - Single model per pixel position
- - Direct state management
- - Cooldown mechanisms
- - Simple randomization
-- **Implementation**: Basic interact() function with state checks
-
-#### 2. Complex Multi-Pixel Games (Maze, Minesweeper, Pix2048)
-**Pattern**: Grid-based games with multiple coordinated pixels
-- **Use Case**: Board games, puzzles, strategy games
-- **Key Features**:
- - Multiple related pixels forming a game board
- - Complex state relationships between cells
- - Game initialization with board setup
- - Win/lose conditions
-- **Implementation**: Grid initialization, cell state management, game logic
-
-#### 3. Player vs Player Games (RPS)
-**Pattern**: Turn-based competitive games with commit-reveal
-- **Use Case**: Competitive multiplayer interactions
-- **Key Features**:
- - Game state progression (Created → Joined → Finished)
- - Commit-reveal scheme for fair play
- - Player authentication and turn management
- - Winner determination logic
-- **Implementation**: State machine pattern with cryptographic commits
-
-### Essential Implementation Patterns
-
-#### 1. Dual World Pattern (Critical!)
-```cairo
-let mut core_world = self.world(@"pixelaw"); // For pixel operations
-let mut app_world = self.world(@"your_app"); // For app-specific data
-```
-**Every app must use both worlds:**
-- `pixelaw` world: Pixel operations, core actions, player data
-- App-specific world: Custom models, game state, app logic
-
-#### 2. Helper Trait Pattern
-```cairo
-#[generate_trait]
-impl HelperImpl of HelperTrait {
- fn generate_maze_id(ref self: ContractState, position: Position, timestamp: u64) -> u32 {
- // Complex helper logic
- }
-}
-```
-**Use for:**
-- Complex calculations
-- Randomization logic
-- Game state validation
-- Internal utility functions
-
-#### 3. Constants File Pattern
-```cairo
-// constants.cairo
-pub const APP_KEY: felt252 = 'your_app';
-pub const APP_ICON: felt252 = 'U+1F3F0';
-pub const GAME_SIZE: u32 = 5;
-pub const WALL: felt252 = 'wall';
-pub const PATH: felt252 = 'path';
-```
-**Essential for:**
-- App identification
-- Game configuration
-- Predefined data (layouts, emojis)
-- Magic numbers
-
-#### 4. Proper Error Handling
-```cairo
-assert!(pixel.owner == contract_address_const::<0>(), "Position is not empty");
-assert!(current_timestamp >= cooldown_reference + COOLDOWN_SECONDS, "Cooldown not ready yet");
-```
-**Always validate:**
-- Pixel ownership
-- Game state prerequisites
-- Timing constraints
-- Input parameters
-
-### Advanced Game Mechanics
-
-#### 1. Randomization Techniques
-**Cryptographic Randomness (Hunter):**
-```cairo
-let hash: u256 = poseidon_hash_span(array![timestamp_felt252, x_felt252, y_felt252].span()).into();
-let winning = ((hash | MASK) == MASK); // 1/1024 chance
-```
-
-**Timestamp-based Random (Maze, Minesweeper):**
-```cairo
-let layout: u32 = (hash.into() % 5_u256).try_into().unwrap() + 1;
-let rand_x = (timestamp + placed_mines.into()) % size.into();
-```
-
-#### 2. Cooldown Systems
-**Time-based Restrictions (Chest):**
-```cairo
-const COOLDOWN_SECONDS: u64 = 86400; // 24 hours
-let cooldown_reference = if chest.last_collected_at == 0 { chest.placed_at } else { chest.last_collected_at };
-assert!(current_timestamp >= cooldown_reference + COOLDOWN_SECONDS, "Cooldown not ready yet");
-```
-
-#### 3. State Machines
-**Game Progression (RPS):**
-```cairo
-#[derive(Serde, Copy, Drop, PartialEq, Introspect)]
-pub enum State {
- None: (),
- Created: (),
- Joined: (),
- Finished: (),
-}
-```
-
-#### 4. Commit-Reveal Schemes
-**Fair Play Mechanisms (RPS):**
-```cairo
-fn validate_commit(committed_hash: felt252, move: Move, salt: felt252) -> bool {
- let computed_hash: felt252 = poseidon_hash_span(array![move.into(), salt.into()].span());
- committed_hash == computed_hash
-}
-```
-
-### Model Design Patterns
-
-#### 1. Game State Model
-```cairo
-#[derive(Copy, Drop, Serde)]
-#[dojo::model]
-pub struct GameState {
- #[key]
- pub position: Position, // Always use Position as key
- pub creator: ContractAddress, // Track game creator
- pub state: u8, // Game state enum
- pub started_timestamp: u64, // For timing logic
- pub custom_data: u32, // Game-specific fields
-}
-```
-
-#### 2. Cell State Model (for grid games)
-```cairo
-#[derive(Copy, Drop, Serde)]
-#[dojo::model]
-pub struct Cell {
- #[key]
- pub position: Position, // Cell position
- pub game_position: Position, // Reference to game origin
- pub is_revealed: bool, // State flags
- pub cell_type: felt252, // Cell content type
- pub custom_properties: u8, // Game-specific properties
-}
-```
-
-#### 3. Player Tracking Model
-```cairo
-#[derive(Copy, Drop, Serde)]
-#[dojo::model]
-pub struct PlayerState {
- #[key]
- pub player: ContractAddress,
- pub last_action_timestamp: u64,
- pub score: u32,
- pub attempts: u32,
-}
-```
-
-### Visual and UI Patterns
-
-#### 1. Emoji Constants
-```cairo
-pub const APP_ICON: felt252 = 'U+1F3F0'; // 🏰 castle
-pub const QUESTION_MARK: felt252 = 'U+2753'; // ❓
-pub const EXPLOSION: felt252 = 'U+1F4A5'; // 💥
-pub const TROPHY: felt252 = 'U+1F3C6'; // 🏆
-```
-
-#### 2. Color Schemes
-```cairo
-pub const EMPTY_CELL: u32 = 0xFFCDC1B4; // Beige
-pub const REVEALED_CELL: u32 = 0xFFFFFFFF; // White
-pub const MINE_COLOR: u32 = 0xFFFF0000; // Red
-pub const FLAG_COLOR: u32 = 0xFFFF0000; // Red
-```
-
-#### 3. Control Button Layout
-```cairo
-// Create directional controls around game board
-let up_button = Position { x: position.x + 1, y: position.y - 1 };
-let down_button = Position { x: position.x + 1, y: position.y + 4 };
-let left_button = Position { x: position.x - 1, y: position.y + 1 };
-let right_button = Position { x: position.x + 4, y: position.y + 1 };
-```
-
-### Testing Patterns from Examples
-
-#### 1. Comprehensive Test Setup
-```cairo
-fn deploy_app(ref world: WorldStorage) -> IAppActionsDispatcher {
- let namespace = "your_app";
- world.dispatcher.register_namespace(namespace.clone());
- // ... resource registration
- world.sync_perms_and_inits(cdefs);
- // Return dispatcher
-}
-```
-
-#### 2. State Verification Tests
-```cairo
-// Verify pixel state
-let pixel: Pixel = world.read_model(position);
-assert(pixel.color == expected_color, 'Color mismatch');
-
-// Verify app model state
-world.set_namespace(@"your_app");
-let app_data: YourModel = world.read_model(position);
-assert(app_data.is_collected, 'State mismatch');
-world.set_namespace(@"pixelaw");
-```
-
-#### 3. Failure Case Testing
-```cairo
-#[test]
-#[should_panic(expected: ("Expected error message", 'ENTRYPOINT_FAILED'))]
-fn test_failure_case() {
- // Test conditions that should fail
-}
-```
-
-### Performance and Gas Optimization
-
-#### 1. Efficient Loops
-```cairo
-// Avoid nested loops where possible
-let mut i = 0;
-loop {
- if i >= MAX_SIZE { break; }
- // Process single dimension
- i += 1;
-};
-```
-
-#### 2. Batch Operations
-```cairo
-// Group related pixel updates
-let mut updates: Array = ArrayTrait::new();
-// ... build update array
-// Process all updates together
-```
-
-#### 3. Minimize Model Reads/Writes
-```cairo
-// Read once, modify, write once
-let mut game_state: GameState = app_world.read_model(position);
-game_state.moves += 1;
-game_state.score += points;
-app_world.write_model(@game_state);
-```
-
-### Security Considerations from Examples
-
-#### 1. Ownership Validation
-```cairo
-let pixel: Pixel = core_world.read_model(position);
-assert!(pixel.owner.is_zero() || pixel.owner == player, "Not authorized");
-```
-
-#### 2. State Validation
-```cairo
-assert!(game.state == State::Created, "Invalid game state");
-assert!(!chest.is_collected, "Already collected");
-```
-
-#### 3. Timing Constraints
-```cairo
-assert!(current_timestamp >= last_action + COOLDOWN, "Too soon");
-```
-
-### Common Anti-Patterns to Avoid
-
-#### 1. Direct Pixel Text/Color Access
-❌ **Don't**: Read pixel.text directly for game logic
-✅ **Do**: Use app-specific models for game state
-
-#### 2. Missing State Validation
-❌ **Don't**: Assume game state without checking
-✅ **Do**: Always validate state before operations
-
-#### 3. Hardcoded Magic Numbers
-❌ **Don't**: Use literal numbers in code
-✅ **Do**: Define constants for all magic numbers
-
-#### 4. Single World Usage
-❌ **Don't**: Use only pixelaw world or only app world
-✅ **Do**: Use both worlds appropriately
-
-### Development Workflow Insights
-
-#### 1. Start Simple, Add Complexity
-1. Basic pixel interaction
-2. Add state model
-3. Add game logic
-4. Add multi-pixel support
-5. Add advanced features
-
-#### 2. Test-Driven Development
-1. Write failing test
-2. Implement minimum code
-3. Verify test passes
-4. Refactor and optimize
-
-#### 3. Incremental Feature Addition
-1. Core interaction
-2. State management
-3. Visual feedback
-4. Error handling
-5. Advanced mechanics
-
-### Useful Resources
-
-- [Dojo Documentation](https://book.dojoengine.org/)
-- [Cairo Book](https://book.cairo-lang.org/)
-- [PixeLAW Core Repository](https://github.com/pixelaw/core)
-- [Starknet Documentation](https://docs.starknet.io/)
-
-## Conclusion
-
-Building PixeLAW apps requires understanding the core framework, following established patterns, and thorough testing. Start with simple apps and gradually build complexity as you become familiar with the system. The examples in this repository provide excellent templates for different types of applications.
-
-Remember to:
-- Always test thoroughly
-- Follow the established patterns
-- Consider app interactions
-- Document your code
-- Engage with the PixeLAW community for support
-
-Happy building! 🎮✨
\ No newline at end of file
diff --git a/Makefile b/Makefile
index 9663b0d..47ab46e 100644
--- a/Makefile
+++ b/Makefile
@@ -12,13 +12,26 @@ deploy_all:
@for dir in $(SUBDIRS); do \
app_name=$$(basename $$dir); \
echo "Deploying $$app_name"; \
- ./local_deploy.sh $$app_name; \
+ ./deploy_apps.sh $$app_name; \
done
### Deploys an individual app
# to use make deploy_app APP=
deploy_app:
- ./local_deploy.sh $(APP)
+ ./deploy_apps.sh $(APP)
+
+### Deploys an individual app to vanilla core
+# to use make deploy_app_vanilla APP=
+deploy_app_vanilla:
+ ./deploy_apps.sh $(APP) vanilla
+
+### Deploys all apps to vanilla core
+deploy_all_vanilla:
+ @for dir in $(SUBDIRS); do \
+ app_name=$$(basename $$dir); \
+ echo "Deploying $$app_name to vanilla core"; \
+ ./deploy_apps.sh $$app_name vanilla; \
+ done
### Starts up the core
start_core:
@@ -57,15 +70,20 @@ log_torii:
log_bots:
docker compose exec pixelaw-core tail -f /keiko/log/bots.log
+### Clean all Scarb.lock files
+clean_locks:
+ @echo "Cleaning all Scarb.lock files..."
+ @find . -name "Scarb.lock" -not -path "./.devcontainer/*" -delete
+
### Build all apps
-build_all:
+build_all: clean_locks
@for app in $(APPS); do \
echo "Building $$app..."; \
(cd $$app && sozo build) || exit 1; \
done
### Test all apps
-test_all:
+test_all: clean_locks
@for app in $(APPS); do \
echo "Testing $$app..."; \
(cd $$app && sozo test) || exit 1; \
diff --git a/README.md b/README.md
index 7f502d9..bc8a897 100644
--- a/README.md
+++ b/README.md
@@ -1,63 +1,123 @@
# PixeLAW Examples
-This is a list of app examples that demonstrate PixeLAW's capability.
-Each app can stand alone and can be deployed individually. Here are the list of apps currently available:
-| Name | Description |
-|------------|-------------------------------------------------------------------------------------------------------------|
-| hunter | A game of chance where any player can pick a random pixel that could either be a winning or losing pixel |
-| minsweeper | A classic minesweeper with a limited amount of pixels in a board |
-| rps | Stands for rock-paper-scissors, where two players can play on the same pixel |
-| tictactoe | A classic game of tictactoe against a machine learning opponent |
-| pix2048 | A fully on-chain 2048 based on PixeLAW(a pixel-based Autonomous World built on @Starknet using @ohayo_dojo) |
+A collection of game and application examples demonstrating PixeLAW's capabilities. Each app showcases different patterns and mechanics within the PixeLAW ecosystem - a pixel-based Autonomous World built on Starknet using the Dojo engine.
+## Available Apps
+
+| Name | Type | Description |
+|-------------|------------------------|-----------------------------------------------------------------------------------------|
+| **chest** | Cooldown System | Treasure chest placement and collection with 24-hour cooldown mechanics |
+| **hunter** | Probability Game | Cryptographic randomness-based chance game with 1/1024 winning odds |
+| **maze** | Grid Navigation | Navigate through pixel-based mazes with predefined layouts and randomization |
+| **minesweeper** | Classic Puzzle | Traditional minesweeper with complex grid state management and win/lose conditions |
+| **pix2048** | Grid Game | Fully on-chain 2048 with directional controls and multi-pixel coordination |
+| **rps** | PvP Competition | Rock-paper-scissors with commit-reveal cryptographic scheme for fair play |
+| **tictactoe** | AI Opponent | Classic tic-tac-toe against a machine learning opponent |
+
+## Framework Versions
+
+- **Dojo Framework**: v1.6.2
+- **PixeLAW Core**: v0.7.9
+- **Cairo**: v2.10.1
+- **Starknet**: Latest
## Prerequisites
+
1. [Make](https://www.gnu.org/software/make/#download)
2. [Docker](https://docs.docker.com/engine/install/)
3. [Docker Compose plugin](https://docs.docker.com/compose/install/)
-## Getting Started
-There are two recommended ways to get PixeLAW started. The simplest method is getting everything started with
-all the apps in this repo and the other method is individually deploying them.
+## Quick Start
+
+### Deploy All Apps (Recommended)
+Start PixeLAW with all example apps in one command:
-### Deploying all Apps
-Run this command to start up PixeLAW core and deploy all apps in the directory.
-````shell
+```shell
make start
-````
+```
+
+This will:
+1. Launch PixeLAW core infrastructure (Katana, Torii, Dashboard)
+2. Wait for services to be ready
+3. Deploy all example apps with proper permissions
+4. Initialize each app for immediate use
-To stop it, simply run this command:
-````shell
+**Access the dashboard**: http://localhost:3000
+
+To stop everything:
+```shell
make stop
-````
+```
-### Deploying an app individually
-To start up PixeLAW, you can either:
-````shell
-docker compose up -d
-````
-or
-````shell
+### Manual Deployment
+
+#### 1. Start Core Infrastructure
+```shell
make start_core
-````
+# or
+docker compose up -d
+```
+
+Services will be available at:
+- **Katana** (blockchain): http://localhost:5050
+- **Torii** (indexer): http://localhost:8080
+- **Dashboard**: http://localhost:3000
+
+#### 2. Deploy Apps
+
+**All apps at once:**
+```shell
+make deploy_all
+```
+
+**Individual app:**
+```shell
+./deploy_apps.sh
+# or
+make deploy_app APP=
+```
+
+Available apps: `chest`, `hunter`, `maze`, `minesweeper`, `pix2048`, `rps`, `tictactoe`
+
+## Development Commands
+
+```shell
+make reset # Reset with volume cleanup
+make shell # Access container shell
+make build_all # Build all apps
+make test_all # Test all apps
+make log_katana # View blockchain logs
+make log_torii # View indexer logs
+```
+
+## App Architecture Patterns
+
+Each app demonstrates different PixeLAW development patterns:
+
+- **Simple Single-Pixel** (chest, hunter): Direct pixel interaction with state management
+- **Complex Grid Games** (maze, minesweeper, pix2048): Multi-pixel coordination and game boards
+- **Player vs Player** (rps): Turn-based competition with cryptographic security
+- **AI Integration** (tictactoe): Machine learning opponent integration
+
+## Contributing
+
+We welcome contributions! To add your app:
-Afterwards, to deploy an app to your local PixeLAW, you can either:
-````shell
-./local_deploy.sh
-````
-or
-````shell
-make deploy_app APP=
-````
+1. Create your app following PixeLAW patterns
+2. Add it to the table above
+3. Submit a pull request
-## Contributing an app
-If you'd like to contribute your app to PixeLAW, feel free to do a pull request for this repo
-and add your app in the table above.
+For development guidance, see the technical documentation in the repository.
## Credits
-| Contribution | Developer |
-|------------------------------------------------------------|------------------------------------------|
-| App - [pix2048](https://github.com/themetacat/PixeLAW2048) | [MetaCat](https://github.com/themetacat) |
+| Contribution | Developer |
+|--------------|-----------|
+| [pix2048](https://github.com/themetacat/PixeLAW2048) | [MetaCat](https://github.com/themetacat) |
+---
+**Learn More**:
+- [PixeLAW Core](https://github.com/pixelaw/core)
+- [Dojo Engine](https://dojoengine.org)
+- [Starknet](https://starknet.io)
\ No newline at end of file
diff --git a/chest/.tool-versions b/chest/.tool-versions
index 5b9a1c2..894bbea 100644
--- a/chest/.tool-versions
+++ b/chest/.tool-versions
@@ -1,2 +1,2 @@
-dojo 1.5.1
+dojo 1.6.2
scarb 2.10.1
\ No newline at end of file
diff --git a/chest/Scarb.lock b/chest/Scarb.lock
index 6951f76..48eba6d 100644
--- a/chest/Scarb.lock
+++ b/chest/Scarb.lock
@@ -13,16 +13,16 @@ dependencies = [
[[package]]
name = "dojo"
-version = "1.5.1"
-source = "git+https://github.com/dojoengine/dojo?tag=v1.5.1#986c3b0c6d647b23847c70ddceb1d33ddac86ead"
+version = "1.6.2"
+source = "git+https://github.com/dojoengine/dojo?tag=v1.6.2#d6e847c51ecd0121a43c2a17b96dbca936604764"
dependencies = [
"dojo_plugin",
]
[[package]]
name = "dojo_cairo_test"
-version = "1.0.12"
-source = "git+https://github.com/dojoengine/dojo?tag=v1.5.1#986c3b0c6d647b23847c70ddceb1d33ddac86ead"
+version = "1.6.2"
+source = "git+https://github.com/dojoengine/dojo?tag=v1.6.2#d6e847c51ecd0121a43c2a17b96dbca936604764"
dependencies = [
"dojo",
]
@@ -30,20 +30,20 @@ dependencies = [
[[package]]
name = "dojo_plugin"
version = "2.10.1"
-source = "git+https://github.com/dojoengine/dojo?tag=v1.5.1#986c3b0c6d647b23847c70ddceb1d33ddac86ead"
+source = "git+https://github.com/dojoengine/dojo?tag=v1.6.2#d6e847c51ecd0121a43c2a17b96dbca936604764"
[[package]]
name = "pixelaw"
-version = "0.7.8"
-source = "git+https://github.com/pixelaw/core?tag=v0.7.8#0d020c16319676c1839cedd53577868458efa6c2"
+version = "0.7.9"
+source = "git+https://github.com/pixelaw/core?tag=v0.7.9#40313e650b145faa4d8f6eb525fbfa0e2b58a5bf"
dependencies = [
"dojo",
]
[[package]]
name = "pixelaw_testing"
-version = "0.7.8"
-source = "git+https://github.com/pixelaw/core?tag=v0.7.8#0d020c16319676c1839cedd53577868458efa6c2"
+version = "0.7.9"
+source = "git+https://github.com/pixelaw/core?tag=v0.7.9#40313e650b145faa4d8f6eb525fbfa0e2b58a5bf"
dependencies = [
"dojo",
"dojo_cairo_test",
diff --git a/chest/Scarb.toml b/chest/Scarb.toml
index e855bdb..0ac6f57 100644
--- a/chest/Scarb.toml
+++ b/chest/Scarb.toml
@@ -13,12 +13,12 @@ spawn = "sozo execute chest-actions spawn --wait" # scarb run spawn
move = "sozo execute chest-actions move -c 1 --wait" # scarb run move
[dependencies]
-pixelaw = { git = "https://github.com/pixelaw/core", tag = "v0.7.8" }
-dojo = { git = "https://github.com/dojoengine/dojo", tag = "v1.5.1" }
+pixelaw = { git = "https://github.com/pixelaw/core", tag = "v0.7.9" }
+dojo = { git = "https://github.com/dojoengine/dojo", tag = "v1.6.2" }
[dev-dependencies]
-dojo_cairo_test = { git = "https://github.com/dojoengine/dojo", tag = "v1.5.1" }
-pixelaw_testing = { git = "https://github.com/pixelaw/core", tag = "v0.7.8" }
+dojo_cairo_test = { git = "https://github.com/dojoengine/dojo", tag = "v1.6.2" }
+pixelaw_testing = { git = "https://github.com/pixelaw/core", tag = "v0.7.9" }
[[target.starknet-contract]]
sierra = true
diff --git a/chest/dojo_dev.toml b/chest/dojo_dev.toml
index f57dd6a..e5d689b 100644
--- a/chest/dojo_dev.toml
+++ b/chest/dojo_dev.toml
@@ -15,7 +15,20 @@ mappings = { "pixelaw" = [
rpc_url = "http://localhost:5050/"
account_address = "0x127fd5f1fe78a71f8bcd1fec63e3fe2f0486b6ecd5c86a0466c3a21fa5cfcec"
private_key = "0xc5b2fcab997346f3ea1c00b002ecf6f382c5f9c9659a3894eb783c5320f912"
-world_address = "0x01d09b5e00f376337603943fc12715e439e91c0039f353b1cc48bb278dfa99d5"
[writers]
-"chest-Chest" = ["chest-chest_actions"]
\ No newline at end of file
+"chest-Chest" = ["chest-chest_actions"]
+
+[migration]
+skip_contracts = [
+ "pixelaw-actions",
+ "pixelaw-App",
+ "pixelaw-AppName",
+ "pixelaw-Area",
+ "pixelaw-CoreActionsAddress",
+ "pixelaw-Pixel",
+ "pixelaw-QueueItem",
+ "pixelaw-RTree",
+ "pixelaw-Notification",
+ "pixelaw-QueueScheduled"
+]
\ No newline at end of file
diff --git a/chest/manifest_dev.json b/chest/manifest_dev.json
new file mode 100644
index 0000000..b08613a
--- /dev/null
+++ b/chest/manifest_dev.json
@@ -0,0 +1,1781 @@
+{
+ "world": {
+ "class_hash": "0x13d92333361bb7049c1232c0a5404e2c19082ededc3a73d75cb33fa952adec7",
+ "address": "0x548b7044c88b3338e88e3c0ea356eb9dcf65388c90ec7c9d9031547af30d1d1",
+ "seed": "pixelaw",
+ "name": "chest",
+ "entrypoints": [
+ "uuid",
+ "set_metadata",
+ "register_namespace",
+ "register_event",
+ "register_model",
+ "register_contract",
+ "register_library",
+ "init_contract",
+ "upgrade_event",
+ "upgrade_model",
+ "upgrade_contract",
+ "emit_event",
+ "emit_events",
+ "set_entity",
+ "set_entities",
+ "delete_entity",
+ "delete_entities",
+ "grant_owner",
+ "revoke_owner",
+ "grant_writer",
+ "revoke_writer",
+ "upgrade"
+ ],
+ "abi": [
+ {
+ "type": "impl",
+ "name": "World",
+ "interface_name": "dojo::world::iworld::IWorld"
+ },
+ {
+ "type": "struct",
+ "name": "core::byte_array::ByteArray",
+ "members": [
+ {
+ "name": "data",
+ "type": "core::array::Array::"
+ },
+ {
+ "name": "pending_word",
+ "type": "core::felt252"
+ },
+ {
+ "name": "pending_word_len",
+ "type": "core::integer::u32"
+ }
+ ]
+ },
+ {
+ "type": "enum",
+ "name": "dojo::world::resource::Resource",
+ "variants": [
+ {
+ "name": "Model",
+ "type": "(core::starknet::contract_address::ContractAddress, core::felt252)"
+ },
+ {
+ "name": "Event",
+ "type": "(core::starknet::contract_address::ContractAddress, core::felt252)"
+ },
+ {
+ "name": "Contract",
+ "type": "(core::starknet::contract_address::ContractAddress, core::felt252)"
+ },
+ {
+ "name": "Namespace",
+ "type": "core::byte_array::ByteArray"
+ },
+ {
+ "name": "World",
+ "type": "()"
+ },
+ {
+ "name": "Unregistered",
+ "type": "()"
+ },
+ {
+ "name": "Library",
+ "type": "(core::starknet::class_hash::ClassHash, core::felt252)"
+ }
+ ]
+ },
+ {
+ "type": "struct",
+ "name": "dojo::model::metadata::ResourceMetadata",
+ "members": [
+ {
+ "name": "resource_id",
+ "type": "core::felt252"
+ },
+ {
+ "name": "metadata_uri",
+ "type": "core::byte_array::ByteArray"
+ },
+ {
+ "name": "metadata_hash",
+ "type": "core::felt252"
+ }
+ ]
+ },
+ {
+ "type": "struct",
+ "name": "core::array::Span::",
+ "members": [
+ {
+ "name": "snapshot",
+ "type": "@core::array::Array::"
+ }
+ ]
+ },
+ {
+ "type": "struct",
+ "name": "core::array::Span::>",
+ "members": [
+ {
+ "name": "snapshot",
+ "type": "@core::array::Array::>"
+ }
+ ]
+ },
+ {
+ "type": "enum",
+ "name": "dojo::model::definition::ModelIndex",
+ "variants": [
+ {
+ "name": "Keys",
+ "type": "core::array::Span::"
+ },
+ {
+ "name": "Id",
+ "type": "core::felt252"
+ },
+ {
+ "name": "MemberId",
+ "type": "(core::felt252, core::felt252)"
+ }
+ ]
+ },
+ {
+ "type": "struct",
+ "name": "core::array::Span::",
+ "members": [
+ {
+ "name": "snapshot",
+ "type": "@core::array::Array::"
+ }
+ ]
+ },
+ {
+ "type": "struct",
+ "name": "dojo::meta::layout::FieldLayout",
+ "members": [
+ {
+ "name": "selector",
+ "type": "core::felt252"
+ },
+ {
+ "name": "layout",
+ "type": "dojo::meta::layout::Layout"
+ }
+ ]
+ },
+ {
+ "type": "struct",
+ "name": "core::array::Span::",
+ "members": [
+ {
+ "name": "snapshot",
+ "type": "@core::array::Array::"
+ }
+ ]
+ },
+ {
+ "type": "struct",
+ "name": "core::array::Span::",
+ "members": [
+ {
+ "name": "snapshot",
+ "type": "@core::array::Array::"
+ }
+ ]
+ },
+ {
+ "type": "enum",
+ "name": "dojo::meta::layout::Layout",
+ "variants": [
+ {
+ "name": "Fixed",
+ "type": "core::array::Span::"
+ },
+ {
+ "name": "Struct",
+ "type": "core::array::Span::"
+ },
+ {
+ "name": "Tuple",
+ "type": "core::array::Span::"
+ },
+ {
+ "name": "Array",
+ "type": "core::array::Span::"
+ },
+ {
+ "name": "ByteArray",
+ "type": "()"
+ },
+ {
+ "name": "Enum",
+ "type": "core::array::Span::"
+ }
+ ]
+ },
+ {
+ "type": "struct",
+ "name": "core::array::Span::",
+ "members": [
+ {
+ "name": "snapshot",
+ "type": "@core::array::Array::"
+ }
+ ]
+ },
+ {
+ "type": "enum",
+ "name": "core::bool",
+ "variants": [
+ {
+ "name": "False",
+ "type": "()"
+ },
+ {
+ "name": "True",
+ "type": "()"
+ }
+ ]
+ },
+ {
+ "type": "interface",
+ "name": "dojo::world::iworld::IWorld",
+ "items": [
+ {
+ "type": "function",
+ "name": "resource",
+ "inputs": [
+ {
+ "name": "selector",
+ "type": "core::felt252"
+ }
+ ],
+ "outputs": [
+ {
+ "type": "dojo::world::resource::Resource"
+ }
+ ],
+ "state_mutability": "view"
+ },
+ {
+ "type": "function",
+ "name": "uuid",
+ "inputs": [],
+ "outputs": [
+ {
+ "type": "core::integer::u32"
+ }
+ ],
+ "state_mutability": "external"
+ },
+ {
+ "type": "function",
+ "name": "metadata",
+ "inputs": [
+ {
+ "name": "resource_selector",
+ "type": "core::felt252"
+ }
+ ],
+ "outputs": [
+ {
+ "type": "dojo::model::metadata::ResourceMetadata"
+ }
+ ],
+ "state_mutability": "view"
+ },
+ {
+ "type": "function",
+ "name": "set_metadata",
+ "inputs": [
+ {
+ "name": "metadata",
+ "type": "dojo::model::metadata::ResourceMetadata"
+ }
+ ],
+ "outputs": [],
+ "state_mutability": "external"
+ },
+ {
+ "type": "function",
+ "name": "register_namespace",
+ "inputs": [
+ {
+ "name": "namespace",
+ "type": "core::byte_array::ByteArray"
+ }
+ ],
+ "outputs": [],
+ "state_mutability": "external"
+ },
+ {
+ "type": "function",
+ "name": "register_event",
+ "inputs": [
+ {
+ "name": "namespace",
+ "type": "core::byte_array::ByteArray"
+ },
+ {
+ "name": "class_hash",
+ "type": "core::starknet::class_hash::ClassHash"
+ }
+ ],
+ "outputs": [],
+ "state_mutability": "external"
+ },
+ {
+ "type": "function",
+ "name": "register_model",
+ "inputs": [
+ {
+ "name": "namespace",
+ "type": "core::byte_array::ByteArray"
+ },
+ {
+ "name": "class_hash",
+ "type": "core::starknet::class_hash::ClassHash"
+ }
+ ],
+ "outputs": [],
+ "state_mutability": "external"
+ },
+ {
+ "type": "function",
+ "name": "register_contract",
+ "inputs": [
+ {
+ "name": "salt",
+ "type": "core::felt252"
+ },
+ {
+ "name": "namespace",
+ "type": "core::byte_array::ByteArray"
+ },
+ {
+ "name": "class_hash",
+ "type": "core::starknet::class_hash::ClassHash"
+ }
+ ],
+ "outputs": [
+ {
+ "type": "core::starknet::contract_address::ContractAddress"
+ }
+ ],
+ "state_mutability": "external"
+ },
+ {
+ "type": "function",
+ "name": "register_library",
+ "inputs": [
+ {
+ "name": "namespace",
+ "type": "core::byte_array::ByteArray"
+ },
+ {
+ "name": "class_hash",
+ "type": "core::starknet::class_hash::ClassHash"
+ },
+ {
+ "name": "name",
+ "type": "core::byte_array::ByteArray"
+ },
+ {
+ "name": "version",
+ "type": "core::byte_array::ByteArray"
+ }
+ ],
+ "outputs": [
+ {
+ "type": "core::starknet::class_hash::ClassHash"
+ }
+ ],
+ "state_mutability": "external"
+ },
+ {
+ "type": "function",
+ "name": "init_contract",
+ "inputs": [
+ {
+ "name": "selector",
+ "type": "core::felt252"
+ },
+ {
+ "name": "init_calldata",
+ "type": "core::array::Span::"
+ }
+ ],
+ "outputs": [],
+ "state_mutability": "external"
+ },
+ {
+ "type": "function",
+ "name": "upgrade_event",
+ "inputs": [
+ {
+ "name": "namespace",
+ "type": "core::byte_array::ByteArray"
+ },
+ {
+ "name": "class_hash",
+ "type": "core::starknet::class_hash::ClassHash"
+ }
+ ],
+ "outputs": [],
+ "state_mutability": "external"
+ },
+ {
+ "type": "function",
+ "name": "upgrade_model",
+ "inputs": [
+ {
+ "name": "namespace",
+ "type": "core::byte_array::ByteArray"
+ },
+ {
+ "name": "class_hash",
+ "type": "core::starknet::class_hash::ClassHash"
+ }
+ ],
+ "outputs": [],
+ "state_mutability": "external"
+ },
+ {
+ "type": "function",
+ "name": "upgrade_contract",
+ "inputs": [
+ {
+ "name": "namespace",
+ "type": "core::byte_array::ByteArray"
+ },
+ {
+ "name": "class_hash",
+ "type": "core::starknet::class_hash::ClassHash"
+ }
+ ],
+ "outputs": [
+ {
+ "type": "core::starknet::class_hash::ClassHash"
+ }
+ ],
+ "state_mutability": "external"
+ },
+ {
+ "type": "function",
+ "name": "emit_event",
+ "inputs": [
+ {
+ "name": "event_selector",
+ "type": "core::felt252"
+ },
+ {
+ "name": "keys",
+ "type": "core::array::Span::"
+ },
+ {
+ "name": "values",
+ "type": "core::array::Span::"
+ }
+ ],
+ "outputs": [],
+ "state_mutability": "external"
+ },
+ {
+ "type": "function",
+ "name": "emit_events",
+ "inputs": [
+ {
+ "name": "event_selector",
+ "type": "core::felt252"
+ },
+ {
+ "name": "keys",
+ "type": "core::array::Span::>"
+ },
+ {
+ "name": "values",
+ "type": "core::array::Span::>"
+ }
+ ],
+ "outputs": [],
+ "state_mutability": "external"
+ },
+ {
+ "type": "function",
+ "name": "entity",
+ "inputs": [
+ {
+ "name": "model_selector",
+ "type": "core::felt252"
+ },
+ {
+ "name": "index",
+ "type": "dojo::model::definition::ModelIndex"
+ },
+ {
+ "name": "layout",
+ "type": "dojo::meta::layout::Layout"
+ }
+ ],
+ "outputs": [
+ {
+ "type": "core::array::Span::"
+ }
+ ],
+ "state_mutability": "view"
+ },
+ {
+ "type": "function",
+ "name": "entities",
+ "inputs": [
+ {
+ "name": "model_selector",
+ "type": "core::felt252"
+ },
+ {
+ "name": "indexes",
+ "type": "core::array::Span::"
+ },
+ {
+ "name": "layout",
+ "type": "dojo::meta::layout::Layout"
+ }
+ ],
+ "outputs": [
+ {
+ "type": "core::array::Span::>"
+ }
+ ],
+ "state_mutability": "view"
+ },
+ {
+ "type": "function",
+ "name": "set_entity",
+ "inputs": [
+ {
+ "name": "model_selector",
+ "type": "core::felt252"
+ },
+ {
+ "name": "index",
+ "type": "dojo::model::definition::ModelIndex"
+ },
+ {
+ "name": "values",
+ "type": "core::array::Span::"
+ },
+ {
+ "name": "layout",
+ "type": "dojo::meta::layout::Layout"
+ }
+ ],
+ "outputs": [],
+ "state_mutability": "external"
+ },
+ {
+ "type": "function",
+ "name": "set_entities",
+ "inputs": [
+ {
+ "name": "model_selector",
+ "type": "core::felt252"
+ },
+ {
+ "name": "indexes",
+ "type": "core::array::Span::"
+ },
+ {
+ "name": "values",
+ "type": "core::array::Span::>"
+ },
+ {
+ "name": "layout",
+ "type": "dojo::meta::layout::Layout"
+ }
+ ],
+ "outputs": [],
+ "state_mutability": "external"
+ },
+ {
+ "type": "function",
+ "name": "delete_entity",
+ "inputs": [
+ {
+ "name": "model_selector",
+ "type": "core::felt252"
+ },
+ {
+ "name": "index",
+ "type": "dojo::model::definition::ModelIndex"
+ },
+ {
+ "name": "layout",
+ "type": "dojo::meta::layout::Layout"
+ }
+ ],
+ "outputs": [],
+ "state_mutability": "external"
+ },
+ {
+ "type": "function",
+ "name": "delete_entities",
+ "inputs": [
+ {
+ "name": "model_selector",
+ "type": "core::felt252"
+ },
+ {
+ "name": "indexes",
+ "type": "core::array::Span::"
+ },
+ {
+ "name": "layout",
+ "type": "dojo::meta::layout::Layout"
+ }
+ ],
+ "outputs": [],
+ "state_mutability": "external"
+ },
+ {
+ "type": "function",
+ "name": "is_owner",
+ "inputs": [
+ {
+ "name": "resource",
+ "type": "core::felt252"
+ },
+ {
+ "name": "address",
+ "type": "core::starknet::contract_address::ContractAddress"
+ }
+ ],
+ "outputs": [
+ {
+ "type": "core::bool"
+ }
+ ],
+ "state_mutability": "view"
+ },
+ {
+ "type": "function",
+ "name": "grant_owner",
+ "inputs": [
+ {
+ "name": "resource",
+ "type": "core::felt252"
+ },
+ {
+ "name": "address",
+ "type": "core::starknet::contract_address::ContractAddress"
+ }
+ ],
+ "outputs": [],
+ "state_mutability": "external"
+ },
+ {
+ "type": "function",
+ "name": "revoke_owner",
+ "inputs": [
+ {
+ "name": "resource",
+ "type": "core::felt252"
+ },
+ {
+ "name": "address",
+ "type": "core::starknet::contract_address::ContractAddress"
+ }
+ ],
+ "outputs": [],
+ "state_mutability": "external"
+ },
+ {
+ "type": "function",
+ "name": "owners_count",
+ "inputs": [
+ {
+ "name": "resource",
+ "type": "core::felt252"
+ }
+ ],
+ "outputs": [
+ {
+ "type": "core::integer::u64"
+ }
+ ],
+ "state_mutability": "view"
+ },
+ {
+ "type": "function",
+ "name": "is_writer",
+ "inputs": [
+ {
+ "name": "resource",
+ "type": "core::felt252"
+ },
+ {
+ "name": "contract",
+ "type": "core::starknet::contract_address::ContractAddress"
+ }
+ ],
+ "outputs": [
+ {
+ "type": "core::bool"
+ }
+ ],
+ "state_mutability": "view"
+ },
+ {
+ "type": "function",
+ "name": "grant_writer",
+ "inputs": [
+ {
+ "name": "resource",
+ "type": "core::felt252"
+ },
+ {
+ "name": "contract",
+ "type": "core::starknet::contract_address::ContractAddress"
+ }
+ ],
+ "outputs": [],
+ "state_mutability": "external"
+ },
+ {
+ "type": "function",
+ "name": "revoke_writer",
+ "inputs": [
+ {
+ "name": "resource",
+ "type": "core::felt252"
+ },
+ {
+ "name": "contract",
+ "type": "core::starknet::contract_address::ContractAddress"
+ }
+ ],
+ "outputs": [],
+ "state_mutability": "external"
+ }
+ ]
+ },
+ {
+ "type": "impl",
+ "name": "UpgradeableWorld",
+ "interface_name": "dojo::world::iworld::IUpgradeableWorld"
+ },
+ {
+ "type": "interface",
+ "name": "dojo::world::iworld::IUpgradeableWorld",
+ "items": [
+ {
+ "type": "function",
+ "name": "upgrade",
+ "inputs": [
+ {
+ "name": "new_class_hash",
+ "type": "core::starknet::class_hash::ClassHash"
+ }
+ ],
+ "outputs": [],
+ "state_mutability": "external"
+ }
+ ]
+ },
+ {
+ "type": "constructor",
+ "name": "constructor",
+ "inputs": [
+ {
+ "name": "world_class_hash",
+ "type": "core::starknet::class_hash::ClassHash"
+ }
+ ]
+ },
+ {
+ "type": "event",
+ "name": "dojo::world::world_contract::world::WorldSpawned",
+ "kind": "struct",
+ "members": [
+ {
+ "name": "creator",
+ "type": "core::starknet::contract_address::ContractAddress",
+ "kind": "data"
+ },
+ {
+ "name": "class_hash",
+ "type": "core::starknet::class_hash::ClassHash",
+ "kind": "data"
+ }
+ ]
+ },
+ {
+ "type": "event",
+ "name": "dojo::world::world_contract::world::WorldUpgraded",
+ "kind": "struct",
+ "members": [
+ {
+ "name": "class_hash",
+ "type": "core::starknet::class_hash::ClassHash",
+ "kind": "data"
+ }
+ ]
+ },
+ {
+ "type": "event",
+ "name": "dojo::world::world_contract::world::NamespaceRegistered",
+ "kind": "struct",
+ "members": [
+ {
+ "name": "namespace",
+ "type": "core::byte_array::ByteArray",
+ "kind": "key"
+ },
+ {
+ "name": "hash",
+ "type": "core::felt252",
+ "kind": "data"
+ }
+ ]
+ },
+ {
+ "type": "event",
+ "name": "dojo::world::world_contract::world::ModelRegistered",
+ "kind": "struct",
+ "members": [
+ {
+ "name": "name",
+ "type": "core::byte_array::ByteArray",
+ "kind": "key"
+ },
+ {
+ "name": "namespace",
+ "type": "core::byte_array::ByteArray",
+ "kind": "key"
+ },
+ {
+ "name": "class_hash",
+ "type": "core::starknet::class_hash::ClassHash",
+ "kind": "data"
+ },
+ {
+ "name": "address",
+ "type": "core::starknet::contract_address::ContractAddress",
+ "kind": "data"
+ }
+ ]
+ },
+ {
+ "type": "event",
+ "name": "dojo::world::world_contract::world::EventRegistered",
+ "kind": "struct",
+ "members": [
+ {
+ "name": "name",
+ "type": "core::byte_array::ByteArray",
+ "kind": "key"
+ },
+ {
+ "name": "namespace",
+ "type": "core::byte_array::ByteArray",
+ "kind": "key"
+ },
+ {
+ "name": "class_hash",
+ "type": "core::starknet::class_hash::ClassHash",
+ "kind": "data"
+ },
+ {
+ "name": "address",
+ "type": "core::starknet::contract_address::ContractAddress",
+ "kind": "data"
+ }
+ ]
+ },
+ {
+ "type": "event",
+ "name": "dojo::world::world_contract::world::ContractRegistered",
+ "kind": "struct",
+ "members": [
+ {
+ "name": "name",
+ "type": "core::byte_array::ByteArray",
+ "kind": "key"
+ },
+ {
+ "name": "namespace",
+ "type": "core::byte_array::ByteArray",
+ "kind": "key"
+ },
+ {
+ "name": "address",
+ "type": "core::starknet::contract_address::ContractAddress",
+ "kind": "data"
+ },
+ {
+ "name": "class_hash",
+ "type": "core::starknet::class_hash::ClassHash",
+ "kind": "data"
+ },
+ {
+ "name": "salt",
+ "type": "core::felt252",
+ "kind": "data"
+ }
+ ]
+ },
+ {
+ "type": "event",
+ "name": "dojo::world::world_contract::world::ModelUpgraded",
+ "kind": "struct",
+ "members": [
+ {
+ "name": "selector",
+ "type": "core::felt252",
+ "kind": "key"
+ },
+ {
+ "name": "class_hash",
+ "type": "core::starknet::class_hash::ClassHash",
+ "kind": "data"
+ },
+ {
+ "name": "address",
+ "type": "core::starknet::contract_address::ContractAddress",
+ "kind": "data"
+ },
+ {
+ "name": "prev_address",
+ "type": "core::starknet::contract_address::ContractAddress",
+ "kind": "data"
+ }
+ ]
+ },
+ {
+ "type": "event",
+ "name": "dojo::world::world_contract::world::EventUpgraded",
+ "kind": "struct",
+ "members": [
+ {
+ "name": "selector",
+ "type": "core::felt252",
+ "kind": "key"
+ },
+ {
+ "name": "class_hash",
+ "type": "core::starknet::class_hash::ClassHash",
+ "kind": "data"
+ },
+ {
+ "name": "address",
+ "type": "core::starknet::contract_address::ContractAddress",
+ "kind": "data"
+ },
+ {
+ "name": "prev_address",
+ "type": "core::starknet::contract_address::ContractAddress",
+ "kind": "data"
+ }
+ ]
+ },
+ {
+ "type": "event",
+ "name": "dojo::world::world_contract::world::ContractUpgraded",
+ "kind": "struct",
+ "members": [
+ {
+ "name": "selector",
+ "type": "core::felt252",
+ "kind": "key"
+ },
+ {
+ "name": "class_hash",
+ "type": "core::starknet::class_hash::ClassHash",
+ "kind": "data"
+ }
+ ]
+ },
+ {
+ "type": "event",
+ "name": "dojo::world::world_contract::world::ContractInitialized",
+ "kind": "struct",
+ "members": [
+ {
+ "name": "selector",
+ "type": "core::felt252",
+ "kind": "key"
+ },
+ {
+ "name": "init_calldata",
+ "type": "core::array::Span::",
+ "kind": "data"
+ }
+ ]
+ },
+ {
+ "type": "event",
+ "name": "dojo::world::world_contract::world::LibraryRegistered",
+ "kind": "struct",
+ "members": [
+ {
+ "name": "name",
+ "type": "core::byte_array::ByteArray",
+ "kind": "key"
+ },
+ {
+ "name": "namespace",
+ "type": "core::byte_array::ByteArray",
+ "kind": "key"
+ },
+ {
+ "name": "class_hash",
+ "type": "core::starknet::class_hash::ClassHash",
+ "kind": "data"
+ }
+ ]
+ },
+ {
+ "type": "event",
+ "name": "dojo::world::world_contract::world::EventEmitted",
+ "kind": "struct",
+ "members": [
+ {
+ "name": "selector",
+ "type": "core::felt252",
+ "kind": "key"
+ },
+ {
+ "name": "system_address",
+ "type": "core::starknet::contract_address::ContractAddress",
+ "kind": "key"
+ },
+ {
+ "name": "keys",
+ "type": "core::array::Span::",
+ "kind": "data"
+ },
+ {
+ "name": "values",
+ "type": "core::array::Span::",
+ "kind": "data"
+ }
+ ]
+ },
+ {
+ "type": "event",
+ "name": "dojo::world::world_contract::world::MetadataUpdate",
+ "kind": "struct",
+ "members": [
+ {
+ "name": "resource",
+ "type": "core::felt252",
+ "kind": "key"
+ },
+ {
+ "name": "uri",
+ "type": "core::byte_array::ByteArray",
+ "kind": "data"
+ },
+ {
+ "name": "hash",
+ "type": "core::felt252",
+ "kind": "data"
+ }
+ ]
+ },
+ {
+ "type": "event",
+ "name": "dojo::world::world_contract::world::StoreSetRecord",
+ "kind": "struct",
+ "members": [
+ {
+ "name": "selector",
+ "type": "core::felt252",
+ "kind": "key"
+ },
+ {
+ "name": "entity_id",
+ "type": "core::felt252",
+ "kind": "key"
+ },
+ {
+ "name": "keys",
+ "type": "core::array::Span::",
+ "kind": "data"
+ },
+ {
+ "name": "values",
+ "type": "core::array::Span::",
+ "kind": "data"
+ }
+ ]
+ },
+ {
+ "type": "event",
+ "name": "dojo::world::world_contract::world::StoreUpdateRecord",
+ "kind": "struct",
+ "members": [
+ {
+ "name": "selector",
+ "type": "core::felt252",
+ "kind": "key"
+ },
+ {
+ "name": "entity_id",
+ "type": "core::felt252",
+ "kind": "key"
+ },
+ {
+ "name": "values",
+ "type": "core::array::Span::",
+ "kind": "data"
+ }
+ ]
+ },
+ {
+ "type": "event",
+ "name": "dojo::world::world_contract::world::StoreUpdateMember",
+ "kind": "struct",
+ "members": [
+ {
+ "name": "selector",
+ "type": "core::felt252",
+ "kind": "key"
+ },
+ {
+ "name": "entity_id",
+ "type": "core::felt252",
+ "kind": "key"
+ },
+ {
+ "name": "member_selector",
+ "type": "core::felt252",
+ "kind": "key"
+ },
+ {
+ "name": "values",
+ "type": "core::array::Span::",
+ "kind": "data"
+ }
+ ]
+ },
+ {
+ "type": "event",
+ "name": "dojo::world::world_contract::world::StoreDelRecord",
+ "kind": "struct",
+ "members": [
+ {
+ "name": "selector",
+ "type": "core::felt252",
+ "kind": "key"
+ },
+ {
+ "name": "entity_id",
+ "type": "core::felt252",
+ "kind": "key"
+ }
+ ]
+ },
+ {
+ "type": "event",
+ "name": "dojo::world::world_contract::world::WriterUpdated",
+ "kind": "struct",
+ "members": [
+ {
+ "name": "resource",
+ "type": "core::felt252",
+ "kind": "key"
+ },
+ {
+ "name": "contract",
+ "type": "core::starknet::contract_address::ContractAddress",
+ "kind": "key"
+ },
+ {
+ "name": "value",
+ "type": "core::bool",
+ "kind": "data"
+ }
+ ]
+ },
+ {
+ "type": "event",
+ "name": "dojo::world::world_contract::world::OwnerUpdated",
+ "kind": "struct",
+ "members": [
+ {
+ "name": "resource",
+ "type": "core::felt252",
+ "kind": "key"
+ },
+ {
+ "name": "contract",
+ "type": "core::starknet::contract_address::ContractAddress",
+ "kind": "key"
+ },
+ {
+ "name": "value",
+ "type": "core::bool",
+ "kind": "data"
+ }
+ ]
+ },
+ {
+ "type": "event",
+ "name": "dojo::world::world_contract::world::Event",
+ "kind": "enum",
+ "variants": [
+ {
+ "name": "WorldSpawned",
+ "type": "dojo::world::world_contract::world::WorldSpawned",
+ "kind": "nested"
+ },
+ {
+ "name": "WorldUpgraded",
+ "type": "dojo::world::world_contract::world::WorldUpgraded",
+ "kind": "nested"
+ },
+ {
+ "name": "NamespaceRegistered",
+ "type": "dojo::world::world_contract::world::NamespaceRegistered",
+ "kind": "nested"
+ },
+ {
+ "name": "ModelRegistered",
+ "type": "dojo::world::world_contract::world::ModelRegistered",
+ "kind": "nested"
+ },
+ {
+ "name": "EventRegistered",
+ "type": "dojo::world::world_contract::world::EventRegistered",
+ "kind": "nested"
+ },
+ {
+ "name": "ContractRegistered",
+ "type": "dojo::world::world_contract::world::ContractRegistered",
+ "kind": "nested"
+ },
+ {
+ "name": "ModelUpgraded",
+ "type": "dojo::world::world_contract::world::ModelUpgraded",
+ "kind": "nested"
+ },
+ {
+ "name": "EventUpgraded",
+ "type": "dojo::world::world_contract::world::EventUpgraded",
+ "kind": "nested"
+ },
+ {
+ "name": "ContractUpgraded",
+ "type": "dojo::world::world_contract::world::ContractUpgraded",
+ "kind": "nested"
+ },
+ {
+ "name": "ContractInitialized",
+ "type": "dojo::world::world_contract::world::ContractInitialized",
+ "kind": "nested"
+ },
+ {
+ "name": "LibraryRegistered",
+ "type": "dojo::world::world_contract::world::LibraryRegistered",
+ "kind": "nested"
+ },
+ {
+ "name": "EventEmitted",
+ "type": "dojo::world::world_contract::world::EventEmitted",
+ "kind": "nested"
+ },
+ {
+ "name": "MetadataUpdate",
+ "type": "dojo::world::world_contract::world::MetadataUpdate",
+ "kind": "nested"
+ },
+ {
+ "name": "StoreSetRecord",
+ "type": "dojo::world::world_contract::world::StoreSetRecord",
+ "kind": "nested"
+ },
+ {
+ "name": "StoreUpdateRecord",
+ "type": "dojo::world::world_contract::world::StoreUpdateRecord",
+ "kind": "nested"
+ },
+ {
+ "name": "StoreUpdateMember",
+ "type": "dojo::world::world_contract::world::StoreUpdateMember",
+ "kind": "nested"
+ },
+ {
+ "name": "StoreDelRecord",
+ "type": "dojo::world::world_contract::world::StoreDelRecord",
+ "kind": "nested"
+ },
+ {
+ "name": "WriterUpdated",
+ "type": "dojo::world::world_contract::world::WriterUpdated",
+ "kind": "nested"
+ },
+ {
+ "name": "OwnerUpdated",
+ "type": "dojo::world::world_contract::world::OwnerUpdated",
+ "kind": "nested"
+ }
+ ]
+ }
+ ]
+ },
+ "contracts": [
+ {
+ "address": "0xb15e246aebb3f8a43a2bd6c115d861660495ab45cca6be6dfae65ce191b64",
+ "class_hash": "0x3e3721e8dbc5f09745cb3c513245b813c7025c63d45c62d30a99ce33d8ef8c6",
+ "abi": [
+ {
+ "type": "impl",
+ "name": "chest_actions__ContractImpl",
+ "interface_name": "dojo::contract::interface::IContract"
+ },
+ {
+ "type": "interface",
+ "name": "dojo::contract::interface::IContract",
+ "items": []
+ },
+ {
+ "type": "impl",
+ "name": "chest_actions__DeployedContractImpl",
+ "interface_name": "dojo::meta::interface::IDeployedResource"
+ },
+ {
+ "type": "struct",
+ "name": "core::byte_array::ByteArray",
+ "members": [
+ {
+ "name": "data",
+ "type": "core::array::Array::"
+ },
+ {
+ "name": "pending_word",
+ "type": "core::felt252"
+ },
+ {
+ "name": "pending_word_len",
+ "type": "core::integer::u32"
+ }
+ ]
+ },
+ {
+ "type": "interface",
+ "name": "dojo::meta::interface::IDeployedResource",
+ "items": [
+ {
+ "type": "function",
+ "name": "dojo_name",
+ "inputs": [],
+ "outputs": [
+ {
+ "type": "core::byte_array::ByteArray"
+ }
+ ],
+ "state_mutability": "view"
+ }
+ ]
+ },
+ {
+ "type": "function",
+ "name": "dojo_init",
+ "inputs": [],
+ "outputs": [],
+ "state_mutability": "external"
+ },
+ {
+ "type": "impl",
+ "name": "Actions",
+ "interface_name": "chest::app::IChestActions"
+ },
+ {
+ "type": "struct",
+ "name": "pixelaw::core::utils::Position",
+ "members": [
+ {
+ "name": "x",
+ "type": "core::integer::u16"
+ },
+ {
+ "name": "y",
+ "type": "core::integer::u16"
+ }
+ ]
+ },
+ {
+ "type": "enum",
+ "name": "core::option::Option::",
+ "variants": [
+ {
+ "name": "Some",
+ "type": "core::integer::u32"
+ },
+ {
+ "name": "None",
+ "type": "()"
+ }
+ ]
+ },
+ {
+ "type": "enum",
+ "name": "core::option::Option::",
+ "variants": [
+ {
+ "name": "Some",
+ "type": "core::starknet::contract_address::ContractAddress"
+ },
+ {
+ "name": "None",
+ "type": "()"
+ }
+ ]
+ },
+ {
+ "type": "enum",
+ "name": "core::option::Option::",
+ "variants": [
+ {
+ "name": "Some",
+ "type": "core::felt252"
+ },
+ {
+ "name": "None",
+ "type": "()"
+ }
+ ]
+ },
+ {
+ "type": "enum",
+ "name": "core::option::Option::",
+ "variants": [
+ {
+ "name": "Some",
+ "type": "core::integer::u64"
+ },
+ {
+ "name": "None",
+ "type": "()"
+ }
+ ]
+ },
+ {
+ "type": "struct",
+ "name": "pixelaw::core::models::pixel::PixelUpdate",
+ "members": [
+ {
+ "name": "position",
+ "type": "pixelaw::core::utils::Position"
+ },
+ {
+ "name": "color",
+ "type": "core::option::Option::"
+ },
+ {
+ "name": "owner",
+ "type": "core::option::Option::"
+ },
+ {
+ "name": "app",
+ "type": "core::option::Option::"
+ },
+ {
+ "name": "text",
+ "type": "core::option::Option::"
+ },
+ {
+ "name": "timestamp",
+ "type": "core::option::Option::"
+ },
+ {
+ "name": "action",
+ "type": "core::option::Option::"
+ }
+ ]
+ },
+ {
+ "type": "struct",
+ "name": "pixelaw::core::models::registry::App",
+ "members": [
+ {
+ "name": "system",
+ "type": "core::starknet::contract_address::ContractAddress"
+ },
+ {
+ "name": "name",
+ "type": "core::felt252"
+ },
+ {
+ "name": "icon",
+ "type": "core::felt252"
+ },
+ {
+ "name": "action",
+ "type": "core::felt252"
+ }
+ ]
+ },
+ {
+ "type": "enum",
+ "name": "core::option::Option::",
+ "variants": [
+ {
+ "name": "Some",
+ "type": "pixelaw::core::models::pixel::PixelUpdate"
+ },
+ {
+ "name": "None",
+ "type": "()"
+ }
+ ]
+ },
+ {
+ "type": "struct",
+ "name": "pixelaw::core::utils::DefaultParameters",
+ "members": [
+ {
+ "name": "player_override",
+ "type": "core::option::Option::"
+ },
+ {
+ "name": "system_override",
+ "type": "core::option::Option::"
+ },
+ {
+ "name": "area_hint",
+ "type": "core::option::Option::"
+ },
+ {
+ "name": "position",
+ "type": "pixelaw::core::utils::Position"
+ },
+ {
+ "name": "color",
+ "type": "core::integer::u32"
+ }
+ ]
+ },
+ {
+ "type": "interface",
+ "name": "chest::app::IChestActions",
+ "items": [
+ {
+ "type": "function",
+ "name": "on_pre_update",
+ "inputs": [
+ {
+ "name": "pixel_update",
+ "type": "pixelaw::core::models::pixel::PixelUpdate"
+ },
+ {
+ "name": "app_caller",
+ "type": "pixelaw::core::models::registry::App"
+ },
+ {
+ "name": "player_caller",
+ "type": "core::starknet::contract_address::ContractAddress"
+ }
+ ],
+ "outputs": [
+ {
+ "type": "core::option::Option::"
+ }
+ ],
+ "state_mutability": "external"
+ },
+ {
+ "type": "function",
+ "name": "on_post_update",
+ "inputs": [
+ {
+ "name": "pixel_update",
+ "type": "pixelaw::core::models::pixel::PixelUpdate"
+ },
+ {
+ "name": "app_caller",
+ "type": "pixelaw::core::models::registry::App"
+ },
+ {
+ "name": "player_caller",
+ "type": "core::starknet::contract_address::ContractAddress"
+ }
+ ],
+ "outputs": [],
+ "state_mutability": "external"
+ },
+ {
+ "type": "function",
+ "name": "interact",
+ "inputs": [
+ {
+ "name": "default_params",
+ "type": "pixelaw::core::utils::DefaultParameters"
+ }
+ ],
+ "outputs": [],
+ "state_mutability": "external"
+ },
+ {
+ "type": "function",
+ "name": "place_chest",
+ "inputs": [
+ {
+ "name": "default_params",
+ "type": "pixelaw::core::utils::DefaultParameters"
+ }
+ ],
+ "outputs": [],
+ "state_mutability": "external"
+ },
+ {
+ "type": "function",
+ "name": "collect_chest",
+ "inputs": [
+ {
+ "name": "default_params",
+ "type": "pixelaw::core::utils::DefaultParameters"
+ }
+ ],
+ "outputs": [],
+ "state_mutability": "external"
+ }
+ ]
+ },
+ {
+ "type": "impl",
+ "name": "WorldProviderImpl",
+ "interface_name": "dojo::contract::components::world_provider::IWorldProvider"
+ },
+ {
+ "type": "struct",
+ "name": "dojo::world::iworld::IWorldDispatcher",
+ "members": [
+ {
+ "name": "contract_address",
+ "type": "core::starknet::contract_address::ContractAddress"
+ }
+ ]
+ },
+ {
+ "type": "interface",
+ "name": "dojo::contract::components::world_provider::IWorldProvider",
+ "items": [
+ {
+ "type": "function",
+ "name": "world_dispatcher",
+ "inputs": [],
+ "outputs": [
+ {
+ "type": "dojo::world::iworld::IWorldDispatcher"
+ }
+ ],
+ "state_mutability": "view"
+ }
+ ]
+ },
+ {
+ "type": "impl",
+ "name": "UpgradeableImpl",
+ "interface_name": "dojo::contract::components::upgradeable::IUpgradeable"
+ },
+ {
+ "type": "interface",
+ "name": "dojo::contract::components::upgradeable::IUpgradeable",
+ "items": [
+ {
+ "type": "function",
+ "name": "upgrade",
+ "inputs": [
+ {
+ "name": "new_class_hash",
+ "type": "core::starknet::class_hash::ClassHash"
+ }
+ ],
+ "outputs": [],
+ "state_mutability": "external"
+ }
+ ]
+ },
+ {
+ "type": "constructor",
+ "name": "constructor",
+ "inputs": []
+ },
+ {
+ "type": "event",
+ "name": "dojo::contract::components::upgradeable::upgradeable_cpt::Upgraded",
+ "kind": "struct",
+ "members": [
+ {
+ "name": "class_hash",
+ "type": "core::starknet::class_hash::ClassHash",
+ "kind": "data"
+ }
+ ]
+ },
+ {
+ "type": "event",
+ "name": "dojo::contract::components::upgradeable::upgradeable_cpt::Event",
+ "kind": "enum",
+ "variants": [
+ {
+ "name": "Upgraded",
+ "type": "dojo::contract::components::upgradeable::upgradeable_cpt::Upgraded",
+ "kind": "nested"
+ }
+ ]
+ },
+ {
+ "type": "event",
+ "name": "dojo::contract::components::world_provider::world_provider_cpt::Event",
+ "kind": "enum",
+ "variants": []
+ },
+ {
+ "type": "event",
+ "name": "chest::app::chest_actions::Event",
+ "kind": "enum",
+ "variants": [
+ {
+ "name": "UpgradeableEvent",
+ "type": "dojo::contract::components::upgradeable::upgradeable_cpt::Event",
+ "kind": "nested"
+ },
+ {
+ "name": "WorldProviderEvent",
+ "type": "dojo::contract::components::world_provider::world_provider_cpt::Event",
+ "kind": "nested"
+ }
+ ]
+ }
+ ],
+ "init_calldata": [],
+ "tag": "chest-chest_actions",
+ "selector": "0x6761aaf3a6f4cd4b49c00e5a09c1421aaec1002ce421a9b062d4036520def92",
+ "systems": [
+ "dojo_init",
+ "on_pre_update",
+ "on_post_update",
+ "interact",
+ "place_chest",
+ "collect_chest",
+ "upgrade"
+ ]
+ }
+ ],
+ "libraries": [],
+ "models": [
+ {
+ "members": [],
+ "class_hash": "0x136775695740ab6aff3c2bcc14253e7c7b66c91faf6f1e55eac3c251fa4e18e",
+ "tag": "chest-Chest",
+ "selector": "0x208e2d95405a1899a4188db7902d8e5c1c54dcf6b39fb832ba4b4206bb9fe7b"
+ }
+ ],
+ "events": [],
+ "external_contracts": []
+}
\ No newline at end of file
diff --git a/deploy_apps.sh b/deploy_apps.sh
new file mode 100755
index 0000000..5169245
--- /dev/null
+++ b/deploy_apps.sh
@@ -0,0 +1,62 @@
+#!/bin/bash
+
+# Simple deployment script for PixeLAW example apps
+
+wait_for_local_katana() {
+ while true; do
+ response=$(curl --write-out '%{http_code}' --silent --output /dev/null http://localhost:5050)
+ if [ "$response" -eq 200 ]; then
+ break
+ else
+ echo "Waiting for katana at http://localhost:5050"
+ sleep 2
+ fi
+ done
+}
+
+deploy_app() {
+ APP_NAME=$1
+ WORLD_ADDRESS=$2
+ PROFILE=dev
+
+ echo "Deploying $APP_NAME..."
+ pushd $APP_NAME
+
+ # Build and migrate
+ sozo --profile $PROFILE build
+
+ if [ -n "$WORLD_ADDRESS" ]; then
+ echo "Deploying to existing world: $WORLD_ADDRESS"
+ sozo --profile $PROFILE migrate --wait --world $WORLD_ADDRESS
+ else
+ echo "Deploying to new world"
+ sozo --profile $PROFILE migrate --wait
+ fi
+
+ # Modern Dojo handles initialization automatically via dojo_init function
+ # No manual init or permission setup needed!
+
+ echo "Deployment of $APP_NAME completed!"
+ popd
+}
+
+# Main script logic
+if [ -z "$1" ]; then
+ echo "Usage: $0 [vanilla]"
+ echo "Examples:"
+ echo " $0 chest # Deploy locally"
+ echo " $0 chest vanilla # Deploy to vanilla core"
+ exit 1
+fi
+
+APP_NAME=$1
+DEPLOY_TYPE=$2
+
+wait_for_local_katana
+
+if [ "$DEPLOY_TYPE" = "vanilla" ]; then
+ VANILLA_WORLD="0x548b7044c88b3338e88e3c0ea356eb9dcf65388c90ec7c9d9031547af30d1d1"
+ deploy_app $APP_NAME $VANILLA_WORLD
+else
+ deploy_app $APP_NAME
+fi
\ No newline at end of file
diff --git a/docker-compose.yml b/docker-compose.yml
deleted file mode 100644
index b3f184f..0000000
--- a/docker-compose.yml
+++ /dev/null
@@ -1,20 +0,0 @@
-services:
- pixelaw-core:
- image: ghcr.io/pixelaw/core:0.3.5
- platform: linux/x86_64
- container_name: pixelaw-core
- environment:
- - SERVER_PORT=3000
- - WORLD_ADDRESS=0x60916a73fe631fcba3b2a930e21c6f7bb2533ea398c7bfa75c72f71a8709fc2
-# - WORLD_ADDRESS=0xfc685b398bc4692ab3a4acd380859e71f97d2c319f188854d3a01948ba276a
- ports:
- - "127.0.0.1:5050:5050"
- - "127.0.0.1:3000:3000"
- - "127.0.0.1:8080:8080"
- - "127.0.0.1:9090:9090"
- restart: no
- volumes:
- - storage:/pixelaw/storage
-
-volumes:
- storage:
diff --git a/hunter/.tool-versions b/hunter/.tool-versions
index c03850d..1b363e4 100644
--- a/hunter/.tool-versions
+++ b/hunter/.tool-versions
@@ -1,2 +1,2 @@
-dojo 1.5.1
+dojo 1.6.2
scarb 2.10.1
diff --git a/hunter/Scarb.lock b/hunter/Scarb.lock
index 8d65737..18e5e3c 100644
--- a/hunter/Scarb.lock
+++ b/hunter/Scarb.lock
@@ -3,16 +3,16 @@ version = 1
[[package]]
name = "dojo"
-version = "1.5.1"
-source = "git+https://github.com/dojoengine/dojo?tag=v1.5.1#986c3b0c6d647b23847c70ddceb1d33ddac86ead"
+version = "1.6.2"
+source = "git+https://github.com/dojoengine/dojo?tag=v1.6.2#d6e847c51ecd0121a43c2a17b96dbca936604764"
dependencies = [
"dojo_plugin",
]
[[package]]
name = "dojo_cairo_test"
-version = "1.0.12"
-source = "git+https://github.com/dojoengine/dojo?tag=v1.5.1#986c3b0c6d647b23847c70ddceb1d33ddac86ead"
+version = "1.6.2"
+source = "git+https://github.com/dojoengine/dojo?tag=v1.6.2#d6e847c51ecd0121a43c2a17b96dbca936604764"
dependencies = [
"dojo",
]
@@ -20,7 +20,7 @@ dependencies = [
[[package]]
name = "dojo_plugin"
version = "2.10.1"
-source = "git+https://github.com/dojoengine/dojo?tag=v1.5.1#986c3b0c6d647b23847c70ddceb1d33ddac86ead"
+source = "git+https://github.com/dojoengine/dojo?tag=v1.6.2#d6e847c51ecd0121a43c2a17b96dbca936604764"
[[package]]
name = "hunter"
@@ -34,16 +34,16 @@ dependencies = [
[[package]]
name = "pixelaw"
-version = "0.7.8"
-source = "git+https://github.com/pixelaw/core?tag=v0.7.8#0d020c16319676c1839cedd53577868458efa6c2"
+version = "0.7.9"
+source = "git+https://github.com/pixelaw/core?tag=v0.7.9#40313e650b145faa4d8f6eb525fbfa0e2b58a5bf"
dependencies = [
"dojo",
]
[[package]]
name = "pixelaw_testing"
-version = "0.7.8"
-source = "git+https://github.com/pixelaw/core?tag=v0.7.8#0d020c16319676c1839cedd53577868458efa6c2"
+version = "0.7.9"
+source = "git+https://github.com/pixelaw/core?tag=v0.7.9#40313e650b145faa4d8f6eb525fbfa0e2b58a5bf"
dependencies = [
"dojo",
"dojo_cairo_test",
diff --git a/hunter/Scarb.toml b/hunter/Scarb.toml
index 424f797..a97317f 100644
--- a/hunter/Scarb.toml
+++ b/hunter/Scarb.toml
@@ -8,12 +8,12 @@ edition = "2024_07"
sierra-replace-ids = true
[dependencies]
-pixelaw = { git = "https://github.com/pixelaw/core", tag = "v0.7.8" }
-dojo = { git = "https://github.com/dojoengine/dojo", tag = "v1.5.1" }
+pixelaw = { git = "https://github.com/pixelaw/core", tag = "v0.7.9" }
+dojo = { git = "https://github.com/dojoengine/dojo", tag = "v1.6.2" }
[dev-dependencies]
-pixelaw_testing = { git = "https://github.com/pixelaw/core", tag = "v0.7.8" }
-dojo_cairo_test = { git = "https://github.com/dojoengine/dojo", tag = "v1.5.1" }
+pixelaw_testing = { git = "https://github.com/pixelaw/core", tag = "v0.7.9" }
+dojo_cairo_test = { git = "https://github.com/dojoengine/dojo", tag = "v1.6.2" }
[[target.starknet-contract]]
sierra = true
diff --git a/hunter/dojo_dev.toml b/hunter/dojo_dev.toml
new file mode 100644
index 0000000..793adec
--- /dev/null
+++ b/hunter/dojo_dev.toml
@@ -0,0 +1,34 @@
+# How to use this config file: https://book.dojoengine.org/framework/config#dojo_profiletoml
+
+[world]
+name = "hunter"
+seed = "pixelaw"
+
+[namespace]
+default = "hunter"
+# Reserve the pixelaw core contract names, the rest can be "hunter" automatically.
+mappings = { "pixelaw" = [
+ "actions", "App", "AppName", "Area", "CoreActionsAddress", "Pixel", "QueueItem", "RTree", "Notification", "QueueScheduled"
+] }
+
+[env]
+rpc_url = "http://localhost:5050/"
+account_address = "0x127fd5f1fe78a71f8bcd1fec63e3fe2f0486b6ecd5c86a0466c3a21fa5cfcec"
+private_key = "0xc5b2fcab997346f3ea1c00b002ecf6f382c5f9c9659a3894eb783c5320f912"
+
+[writers]
+"hunter-LastAttempt" = ["hunter-hunter_actions"]
+
+[migration]
+skip_contracts = [
+ "pixelaw-actions",
+ "pixelaw-App",
+ "pixelaw-AppName",
+ "pixelaw-Area",
+ "pixelaw-CoreActionsAddress",
+ "pixelaw-Pixel",
+ "pixelaw-QueueItem",
+ "pixelaw-RTree",
+ "pixelaw-Notification",
+ "pixelaw-QueueScheduled"
+]
\ No newline at end of file
diff --git a/hunter/manifest_dev.json b/hunter/manifest_dev.json
new file mode 100644
index 0000000..37d98ca
--- /dev/null
+++ b/hunter/manifest_dev.json
@@ -0,0 +1,1755 @@
+{
+ "world": {
+ "class_hash": "0x13d92333361bb7049c1232c0a5404e2c19082ededc3a73d75cb33fa952adec7",
+ "address": "0x548b7044c88b3338e88e3c0ea356eb9dcf65388c90ec7c9d9031547af30d1d1",
+ "seed": "pixelaw",
+ "name": "hunter",
+ "entrypoints": [
+ "uuid",
+ "set_metadata",
+ "register_namespace",
+ "register_event",
+ "register_model",
+ "register_contract",
+ "register_library",
+ "init_contract",
+ "upgrade_event",
+ "upgrade_model",
+ "upgrade_contract",
+ "emit_event",
+ "emit_events",
+ "set_entity",
+ "set_entities",
+ "delete_entity",
+ "delete_entities",
+ "grant_owner",
+ "revoke_owner",
+ "grant_writer",
+ "revoke_writer",
+ "upgrade"
+ ],
+ "abi": [
+ {
+ "type": "impl",
+ "name": "World",
+ "interface_name": "dojo::world::iworld::IWorld"
+ },
+ {
+ "type": "struct",
+ "name": "core::byte_array::ByteArray",
+ "members": [
+ {
+ "name": "data",
+ "type": "core::array::Array::"
+ },
+ {
+ "name": "pending_word",
+ "type": "core::felt252"
+ },
+ {
+ "name": "pending_word_len",
+ "type": "core::integer::u32"
+ }
+ ]
+ },
+ {
+ "type": "enum",
+ "name": "dojo::world::resource::Resource",
+ "variants": [
+ {
+ "name": "Model",
+ "type": "(core::starknet::contract_address::ContractAddress, core::felt252)"
+ },
+ {
+ "name": "Event",
+ "type": "(core::starknet::contract_address::ContractAddress, core::felt252)"
+ },
+ {
+ "name": "Contract",
+ "type": "(core::starknet::contract_address::ContractAddress, core::felt252)"
+ },
+ {
+ "name": "Namespace",
+ "type": "core::byte_array::ByteArray"
+ },
+ {
+ "name": "World",
+ "type": "()"
+ },
+ {
+ "name": "Unregistered",
+ "type": "()"
+ },
+ {
+ "name": "Library",
+ "type": "(core::starknet::class_hash::ClassHash, core::felt252)"
+ }
+ ]
+ },
+ {
+ "type": "struct",
+ "name": "dojo::model::metadata::ResourceMetadata",
+ "members": [
+ {
+ "name": "resource_id",
+ "type": "core::felt252"
+ },
+ {
+ "name": "metadata_uri",
+ "type": "core::byte_array::ByteArray"
+ },
+ {
+ "name": "metadata_hash",
+ "type": "core::felt252"
+ }
+ ]
+ },
+ {
+ "type": "struct",
+ "name": "core::array::Span::",
+ "members": [
+ {
+ "name": "snapshot",
+ "type": "@core::array::Array::"
+ }
+ ]
+ },
+ {
+ "type": "struct",
+ "name": "core::array::Span::>",
+ "members": [
+ {
+ "name": "snapshot",
+ "type": "@core::array::Array::>"
+ }
+ ]
+ },
+ {
+ "type": "enum",
+ "name": "dojo::model::definition::ModelIndex",
+ "variants": [
+ {
+ "name": "Keys",
+ "type": "core::array::Span::"
+ },
+ {
+ "name": "Id",
+ "type": "core::felt252"
+ },
+ {
+ "name": "MemberId",
+ "type": "(core::felt252, core::felt252)"
+ }
+ ]
+ },
+ {
+ "type": "struct",
+ "name": "core::array::Span::",
+ "members": [
+ {
+ "name": "snapshot",
+ "type": "@core::array::Array::"
+ }
+ ]
+ },
+ {
+ "type": "struct",
+ "name": "dojo::meta::layout::FieldLayout",
+ "members": [
+ {
+ "name": "selector",
+ "type": "core::felt252"
+ },
+ {
+ "name": "layout",
+ "type": "dojo::meta::layout::Layout"
+ }
+ ]
+ },
+ {
+ "type": "struct",
+ "name": "core::array::Span::",
+ "members": [
+ {
+ "name": "snapshot",
+ "type": "@core::array::Array::"
+ }
+ ]
+ },
+ {
+ "type": "struct",
+ "name": "core::array::Span::",
+ "members": [
+ {
+ "name": "snapshot",
+ "type": "@core::array::Array::"
+ }
+ ]
+ },
+ {
+ "type": "enum",
+ "name": "dojo::meta::layout::Layout",
+ "variants": [
+ {
+ "name": "Fixed",
+ "type": "core::array::Span::"
+ },
+ {
+ "name": "Struct",
+ "type": "core::array::Span::"
+ },
+ {
+ "name": "Tuple",
+ "type": "core::array::Span::"
+ },
+ {
+ "name": "Array",
+ "type": "core::array::Span::"
+ },
+ {
+ "name": "ByteArray",
+ "type": "()"
+ },
+ {
+ "name": "Enum",
+ "type": "core::array::Span::"
+ }
+ ]
+ },
+ {
+ "type": "struct",
+ "name": "core::array::Span::",
+ "members": [
+ {
+ "name": "snapshot",
+ "type": "@core::array::Array::"
+ }
+ ]
+ },
+ {
+ "type": "enum",
+ "name": "core::bool",
+ "variants": [
+ {
+ "name": "False",
+ "type": "()"
+ },
+ {
+ "name": "True",
+ "type": "()"
+ }
+ ]
+ },
+ {
+ "type": "interface",
+ "name": "dojo::world::iworld::IWorld",
+ "items": [
+ {
+ "type": "function",
+ "name": "resource",
+ "inputs": [
+ {
+ "name": "selector",
+ "type": "core::felt252"
+ }
+ ],
+ "outputs": [
+ {
+ "type": "dojo::world::resource::Resource"
+ }
+ ],
+ "state_mutability": "view"
+ },
+ {
+ "type": "function",
+ "name": "uuid",
+ "inputs": [],
+ "outputs": [
+ {
+ "type": "core::integer::u32"
+ }
+ ],
+ "state_mutability": "external"
+ },
+ {
+ "type": "function",
+ "name": "metadata",
+ "inputs": [
+ {
+ "name": "resource_selector",
+ "type": "core::felt252"
+ }
+ ],
+ "outputs": [
+ {
+ "type": "dojo::model::metadata::ResourceMetadata"
+ }
+ ],
+ "state_mutability": "view"
+ },
+ {
+ "type": "function",
+ "name": "set_metadata",
+ "inputs": [
+ {
+ "name": "metadata",
+ "type": "dojo::model::metadata::ResourceMetadata"
+ }
+ ],
+ "outputs": [],
+ "state_mutability": "external"
+ },
+ {
+ "type": "function",
+ "name": "register_namespace",
+ "inputs": [
+ {
+ "name": "namespace",
+ "type": "core::byte_array::ByteArray"
+ }
+ ],
+ "outputs": [],
+ "state_mutability": "external"
+ },
+ {
+ "type": "function",
+ "name": "register_event",
+ "inputs": [
+ {
+ "name": "namespace",
+ "type": "core::byte_array::ByteArray"
+ },
+ {
+ "name": "class_hash",
+ "type": "core::starknet::class_hash::ClassHash"
+ }
+ ],
+ "outputs": [],
+ "state_mutability": "external"
+ },
+ {
+ "type": "function",
+ "name": "register_model",
+ "inputs": [
+ {
+ "name": "namespace",
+ "type": "core::byte_array::ByteArray"
+ },
+ {
+ "name": "class_hash",
+ "type": "core::starknet::class_hash::ClassHash"
+ }
+ ],
+ "outputs": [],
+ "state_mutability": "external"
+ },
+ {
+ "type": "function",
+ "name": "register_contract",
+ "inputs": [
+ {
+ "name": "salt",
+ "type": "core::felt252"
+ },
+ {
+ "name": "namespace",
+ "type": "core::byte_array::ByteArray"
+ },
+ {
+ "name": "class_hash",
+ "type": "core::starknet::class_hash::ClassHash"
+ }
+ ],
+ "outputs": [
+ {
+ "type": "core::starknet::contract_address::ContractAddress"
+ }
+ ],
+ "state_mutability": "external"
+ },
+ {
+ "type": "function",
+ "name": "register_library",
+ "inputs": [
+ {
+ "name": "namespace",
+ "type": "core::byte_array::ByteArray"
+ },
+ {
+ "name": "class_hash",
+ "type": "core::starknet::class_hash::ClassHash"
+ },
+ {
+ "name": "name",
+ "type": "core::byte_array::ByteArray"
+ },
+ {
+ "name": "version",
+ "type": "core::byte_array::ByteArray"
+ }
+ ],
+ "outputs": [
+ {
+ "type": "core::starknet::class_hash::ClassHash"
+ }
+ ],
+ "state_mutability": "external"
+ },
+ {
+ "type": "function",
+ "name": "init_contract",
+ "inputs": [
+ {
+ "name": "selector",
+ "type": "core::felt252"
+ },
+ {
+ "name": "init_calldata",
+ "type": "core::array::Span::"
+ }
+ ],
+ "outputs": [],
+ "state_mutability": "external"
+ },
+ {
+ "type": "function",
+ "name": "upgrade_event",
+ "inputs": [
+ {
+ "name": "namespace",
+ "type": "core::byte_array::ByteArray"
+ },
+ {
+ "name": "class_hash",
+ "type": "core::starknet::class_hash::ClassHash"
+ }
+ ],
+ "outputs": [],
+ "state_mutability": "external"
+ },
+ {
+ "type": "function",
+ "name": "upgrade_model",
+ "inputs": [
+ {
+ "name": "namespace",
+ "type": "core::byte_array::ByteArray"
+ },
+ {
+ "name": "class_hash",
+ "type": "core::starknet::class_hash::ClassHash"
+ }
+ ],
+ "outputs": [],
+ "state_mutability": "external"
+ },
+ {
+ "type": "function",
+ "name": "upgrade_contract",
+ "inputs": [
+ {
+ "name": "namespace",
+ "type": "core::byte_array::ByteArray"
+ },
+ {
+ "name": "class_hash",
+ "type": "core::starknet::class_hash::ClassHash"
+ }
+ ],
+ "outputs": [
+ {
+ "type": "core::starknet::class_hash::ClassHash"
+ }
+ ],
+ "state_mutability": "external"
+ },
+ {
+ "type": "function",
+ "name": "emit_event",
+ "inputs": [
+ {
+ "name": "event_selector",
+ "type": "core::felt252"
+ },
+ {
+ "name": "keys",
+ "type": "core::array::Span::"
+ },
+ {
+ "name": "values",
+ "type": "core::array::Span::"
+ }
+ ],
+ "outputs": [],
+ "state_mutability": "external"
+ },
+ {
+ "type": "function",
+ "name": "emit_events",
+ "inputs": [
+ {
+ "name": "event_selector",
+ "type": "core::felt252"
+ },
+ {
+ "name": "keys",
+ "type": "core::array::Span::>"
+ },
+ {
+ "name": "values",
+ "type": "core::array::Span::>"
+ }
+ ],
+ "outputs": [],
+ "state_mutability": "external"
+ },
+ {
+ "type": "function",
+ "name": "entity",
+ "inputs": [
+ {
+ "name": "model_selector",
+ "type": "core::felt252"
+ },
+ {
+ "name": "index",
+ "type": "dojo::model::definition::ModelIndex"
+ },
+ {
+ "name": "layout",
+ "type": "dojo::meta::layout::Layout"
+ }
+ ],
+ "outputs": [
+ {
+ "type": "core::array::Span::"
+ }
+ ],
+ "state_mutability": "view"
+ },
+ {
+ "type": "function",
+ "name": "entities",
+ "inputs": [
+ {
+ "name": "model_selector",
+ "type": "core::felt252"
+ },
+ {
+ "name": "indexes",
+ "type": "core::array::Span::"
+ },
+ {
+ "name": "layout",
+ "type": "dojo::meta::layout::Layout"
+ }
+ ],
+ "outputs": [
+ {
+ "type": "core::array::Span::>"
+ }
+ ],
+ "state_mutability": "view"
+ },
+ {
+ "type": "function",
+ "name": "set_entity",
+ "inputs": [
+ {
+ "name": "model_selector",
+ "type": "core::felt252"
+ },
+ {
+ "name": "index",
+ "type": "dojo::model::definition::ModelIndex"
+ },
+ {
+ "name": "values",
+ "type": "core::array::Span::"
+ },
+ {
+ "name": "layout",
+ "type": "dojo::meta::layout::Layout"
+ }
+ ],
+ "outputs": [],
+ "state_mutability": "external"
+ },
+ {
+ "type": "function",
+ "name": "set_entities",
+ "inputs": [
+ {
+ "name": "model_selector",
+ "type": "core::felt252"
+ },
+ {
+ "name": "indexes",
+ "type": "core::array::Span::"
+ },
+ {
+ "name": "values",
+ "type": "core::array::Span::>"
+ },
+ {
+ "name": "layout",
+ "type": "dojo::meta::layout::Layout"
+ }
+ ],
+ "outputs": [],
+ "state_mutability": "external"
+ },
+ {
+ "type": "function",
+ "name": "delete_entity",
+ "inputs": [
+ {
+ "name": "model_selector",
+ "type": "core::felt252"
+ },
+ {
+ "name": "index",
+ "type": "dojo::model::definition::ModelIndex"
+ },
+ {
+ "name": "layout",
+ "type": "dojo::meta::layout::Layout"
+ }
+ ],
+ "outputs": [],
+ "state_mutability": "external"
+ },
+ {
+ "type": "function",
+ "name": "delete_entities",
+ "inputs": [
+ {
+ "name": "model_selector",
+ "type": "core::felt252"
+ },
+ {
+ "name": "indexes",
+ "type": "core::array::Span::"
+ },
+ {
+ "name": "layout",
+ "type": "dojo::meta::layout::Layout"
+ }
+ ],
+ "outputs": [],
+ "state_mutability": "external"
+ },
+ {
+ "type": "function",
+ "name": "is_owner",
+ "inputs": [
+ {
+ "name": "resource",
+ "type": "core::felt252"
+ },
+ {
+ "name": "address",
+ "type": "core::starknet::contract_address::ContractAddress"
+ }
+ ],
+ "outputs": [
+ {
+ "type": "core::bool"
+ }
+ ],
+ "state_mutability": "view"
+ },
+ {
+ "type": "function",
+ "name": "grant_owner",
+ "inputs": [
+ {
+ "name": "resource",
+ "type": "core::felt252"
+ },
+ {
+ "name": "address",
+ "type": "core::starknet::contract_address::ContractAddress"
+ }
+ ],
+ "outputs": [],
+ "state_mutability": "external"
+ },
+ {
+ "type": "function",
+ "name": "revoke_owner",
+ "inputs": [
+ {
+ "name": "resource",
+ "type": "core::felt252"
+ },
+ {
+ "name": "address",
+ "type": "core::starknet::contract_address::ContractAddress"
+ }
+ ],
+ "outputs": [],
+ "state_mutability": "external"
+ },
+ {
+ "type": "function",
+ "name": "owners_count",
+ "inputs": [
+ {
+ "name": "resource",
+ "type": "core::felt252"
+ }
+ ],
+ "outputs": [
+ {
+ "type": "core::integer::u64"
+ }
+ ],
+ "state_mutability": "view"
+ },
+ {
+ "type": "function",
+ "name": "is_writer",
+ "inputs": [
+ {
+ "name": "resource",
+ "type": "core::felt252"
+ },
+ {
+ "name": "contract",
+ "type": "core::starknet::contract_address::ContractAddress"
+ }
+ ],
+ "outputs": [
+ {
+ "type": "core::bool"
+ }
+ ],
+ "state_mutability": "view"
+ },
+ {
+ "type": "function",
+ "name": "grant_writer",
+ "inputs": [
+ {
+ "name": "resource",
+ "type": "core::felt252"
+ },
+ {
+ "name": "contract",
+ "type": "core::starknet::contract_address::ContractAddress"
+ }
+ ],
+ "outputs": [],
+ "state_mutability": "external"
+ },
+ {
+ "type": "function",
+ "name": "revoke_writer",
+ "inputs": [
+ {
+ "name": "resource",
+ "type": "core::felt252"
+ },
+ {
+ "name": "contract",
+ "type": "core::starknet::contract_address::ContractAddress"
+ }
+ ],
+ "outputs": [],
+ "state_mutability": "external"
+ }
+ ]
+ },
+ {
+ "type": "impl",
+ "name": "UpgradeableWorld",
+ "interface_name": "dojo::world::iworld::IUpgradeableWorld"
+ },
+ {
+ "type": "interface",
+ "name": "dojo::world::iworld::IUpgradeableWorld",
+ "items": [
+ {
+ "type": "function",
+ "name": "upgrade",
+ "inputs": [
+ {
+ "name": "new_class_hash",
+ "type": "core::starknet::class_hash::ClassHash"
+ }
+ ],
+ "outputs": [],
+ "state_mutability": "external"
+ }
+ ]
+ },
+ {
+ "type": "constructor",
+ "name": "constructor",
+ "inputs": [
+ {
+ "name": "world_class_hash",
+ "type": "core::starknet::class_hash::ClassHash"
+ }
+ ]
+ },
+ {
+ "type": "event",
+ "name": "dojo::world::world_contract::world::WorldSpawned",
+ "kind": "struct",
+ "members": [
+ {
+ "name": "creator",
+ "type": "core::starknet::contract_address::ContractAddress",
+ "kind": "data"
+ },
+ {
+ "name": "class_hash",
+ "type": "core::starknet::class_hash::ClassHash",
+ "kind": "data"
+ }
+ ]
+ },
+ {
+ "type": "event",
+ "name": "dojo::world::world_contract::world::WorldUpgraded",
+ "kind": "struct",
+ "members": [
+ {
+ "name": "class_hash",
+ "type": "core::starknet::class_hash::ClassHash",
+ "kind": "data"
+ }
+ ]
+ },
+ {
+ "type": "event",
+ "name": "dojo::world::world_contract::world::NamespaceRegistered",
+ "kind": "struct",
+ "members": [
+ {
+ "name": "namespace",
+ "type": "core::byte_array::ByteArray",
+ "kind": "key"
+ },
+ {
+ "name": "hash",
+ "type": "core::felt252",
+ "kind": "data"
+ }
+ ]
+ },
+ {
+ "type": "event",
+ "name": "dojo::world::world_contract::world::ModelRegistered",
+ "kind": "struct",
+ "members": [
+ {
+ "name": "name",
+ "type": "core::byte_array::ByteArray",
+ "kind": "key"
+ },
+ {
+ "name": "namespace",
+ "type": "core::byte_array::ByteArray",
+ "kind": "key"
+ },
+ {
+ "name": "class_hash",
+ "type": "core::starknet::class_hash::ClassHash",
+ "kind": "data"
+ },
+ {
+ "name": "address",
+ "type": "core::starknet::contract_address::ContractAddress",
+ "kind": "data"
+ }
+ ]
+ },
+ {
+ "type": "event",
+ "name": "dojo::world::world_contract::world::EventRegistered",
+ "kind": "struct",
+ "members": [
+ {
+ "name": "name",
+ "type": "core::byte_array::ByteArray",
+ "kind": "key"
+ },
+ {
+ "name": "namespace",
+ "type": "core::byte_array::ByteArray",
+ "kind": "key"
+ },
+ {
+ "name": "class_hash",
+ "type": "core::starknet::class_hash::ClassHash",
+ "kind": "data"
+ },
+ {
+ "name": "address",
+ "type": "core::starknet::contract_address::ContractAddress",
+ "kind": "data"
+ }
+ ]
+ },
+ {
+ "type": "event",
+ "name": "dojo::world::world_contract::world::ContractRegistered",
+ "kind": "struct",
+ "members": [
+ {
+ "name": "name",
+ "type": "core::byte_array::ByteArray",
+ "kind": "key"
+ },
+ {
+ "name": "namespace",
+ "type": "core::byte_array::ByteArray",
+ "kind": "key"
+ },
+ {
+ "name": "address",
+ "type": "core::starknet::contract_address::ContractAddress",
+ "kind": "data"
+ },
+ {
+ "name": "class_hash",
+ "type": "core::starknet::class_hash::ClassHash",
+ "kind": "data"
+ },
+ {
+ "name": "salt",
+ "type": "core::felt252",
+ "kind": "data"
+ }
+ ]
+ },
+ {
+ "type": "event",
+ "name": "dojo::world::world_contract::world::ModelUpgraded",
+ "kind": "struct",
+ "members": [
+ {
+ "name": "selector",
+ "type": "core::felt252",
+ "kind": "key"
+ },
+ {
+ "name": "class_hash",
+ "type": "core::starknet::class_hash::ClassHash",
+ "kind": "data"
+ },
+ {
+ "name": "address",
+ "type": "core::starknet::contract_address::ContractAddress",
+ "kind": "data"
+ },
+ {
+ "name": "prev_address",
+ "type": "core::starknet::contract_address::ContractAddress",
+ "kind": "data"
+ }
+ ]
+ },
+ {
+ "type": "event",
+ "name": "dojo::world::world_contract::world::EventUpgraded",
+ "kind": "struct",
+ "members": [
+ {
+ "name": "selector",
+ "type": "core::felt252",
+ "kind": "key"
+ },
+ {
+ "name": "class_hash",
+ "type": "core::starknet::class_hash::ClassHash",
+ "kind": "data"
+ },
+ {
+ "name": "address",
+ "type": "core::starknet::contract_address::ContractAddress",
+ "kind": "data"
+ },
+ {
+ "name": "prev_address",
+ "type": "core::starknet::contract_address::ContractAddress",
+ "kind": "data"
+ }
+ ]
+ },
+ {
+ "type": "event",
+ "name": "dojo::world::world_contract::world::ContractUpgraded",
+ "kind": "struct",
+ "members": [
+ {
+ "name": "selector",
+ "type": "core::felt252",
+ "kind": "key"
+ },
+ {
+ "name": "class_hash",
+ "type": "core::starknet::class_hash::ClassHash",
+ "kind": "data"
+ }
+ ]
+ },
+ {
+ "type": "event",
+ "name": "dojo::world::world_contract::world::ContractInitialized",
+ "kind": "struct",
+ "members": [
+ {
+ "name": "selector",
+ "type": "core::felt252",
+ "kind": "key"
+ },
+ {
+ "name": "init_calldata",
+ "type": "core::array::Span::",
+ "kind": "data"
+ }
+ ]
+ },
+ {
+ "type": "event",
+ "name": "dojo::world::world_contract::world::LibraryRegistered",
+ "kind": "struct",
+ "members": [
+ {
+ "name": "name",
+ "type": "core::byte_array::ByteArray",
+ "kind": "key"
+ },
+ {
+ "name": "namespace",
+ "type": "core::byte_array::ByteArray",
+ "kind": "key"
+ },
+ {
+ "name": "class_hash",
+ "type": "core::starknet::class_hash::ClassHash",
+ "kind": "data"
+ }
+ ]
+ },
+ {
+ "type": "event",
+ "name": "dojo::world::world_contract::world::EventEmitted",
+ "kind": "struct",
+ "members": [
+ {
+ "name": "selector",
+ "type": "core::felt252",
+ "kind": "key"
+ },
+ {
+ "name": "system_address",
+ "type": "core::starknet::contract_address::ContractAddress",
+ "kind": "key"
+ },
+ {
+ "name": "keys",
+ "type": "core::array::Span::",
+ "kind": "data"
+ },
+ {
+ "name": "values",
+ "type": "core::array::Span::",
+ "kind": "data"
+ }
+ ]
+ },
+ {
+ "type": "event",
+ "name": "dojo::world::world_contract::world::MetadataUpdate",
+ "kind": "struct",
+ "members": [
+ {
+ "name": "resource",
+ "type": "core::felt252",
+ "kind": "key"
+ },
+ {
+ "name": "uri",
+ "type": "core::byte_array::ByteArray",
+ "kind": "data"
+ },
+ {
+ "name": "hash",
+ "type": "core::felt252",
+ "kind": "data"
+ }
+ ]
+ },
+ {
+ "type": "event",
+ "name": "dojo::world::world_contract::world::StoreSetRecord",
+ "kind": "struct",
+ "members": [
+ {
+ "name": "selector",
+ "type": "core::felt252",
+ "kind": "key"
+ },
+ {
+ "name": "entity_id",
+ "type": "core::felt252",
+ "kind": "key"
+ },
+ {
+ "name": "keys",
+ "type": "core::array::Span::",
+ "kind": "data"
+ },
+ {
+ "name": "values",
+ "type": "core::array::Span::",
+ "kind": "data"
+ }
+ ]
+ },
+ {
+ "type": "event",
+ "name": "dojo::world::world_contract::world::StoreUpdateRecord",
+ "kind": "struct",
+ "members": [
+ {
+ "name": "selector",
+ "type": "core::felt252",
+ "kind": "key"
+ },
+ {
+ "name": "entity_id",
+ "type": "core::felt252",
+ "kind": "key"
+ },
+ {
+ "name": "values",
+ "type": "core::array::Span::",
+ "kind": "data"
+ }
+ ]
+ },
+ {
+ "type": "event",
+ "name": "dojo::world::world_contract::world::StoreUpdateMember",
+ "kind": "struct",
+ "members": [
+ {
+ "name": "selector",
+ "type": "core::felt252",
+ "kind": "key"
+ },
+ {
+ "name": "entity_id",
+ "type": "core::felt252",
+ "kind": "key"
+ },
+ {
+ "name": "member_selector",
+ "type": "core::felt252",
+ "kind": "key"
+ },
+ {
+ "name": "values",
+ "type": "core::array::Span::",
+ "kind": "data"
+ }
+ ]
+ },
+ {
+ "type": "event",
+ "name": "dojo::world::world_contract::world::StoreDelRecord",
+ "kind": "struct",
+ "members": [
+ {
+ "name": "selector",
+ "type": "core::felt252",
+ "kind": "key"
+ },
+ {
+ "name": "entity_id",
+ "type": "core::felt252",
+ "kind": "key"
+ }
+ ]
+ },
+ {
+ "type": "event",
+ "name": "dojo::world::world_contract::world::WriterUpdated",
+ "kind": "struct",
+ "members": [
+ {
+ "name": "resource",
+ "type": "core::felt252",
+ "kind": "key"
+ },
+ {
+ "name": "contract",
+ "type": "core::starknet::contract_address::ContractAddress",
+ "kind": "key"
+ },
+ {
+ "name": "value",
+ "type": "core::bool",
+ "kind": "data"
+ }
+ ]
+ },
+ {
+ "type": "event",
+ "name": "dojo::world::world_contract::world::OwnerUpdated",
+ "kind": "struct",
+ "members": [
+ {
+ "name": "resource",
+ "type": "core::felt252",
+ "kind": "key"
+ },
+ {
+ "name": "contract",
+ "type": "core::starknet::contract_address::ContractAddress",
+ "kind": "key"
+ },
+ {
+ "name": "value",
+ "type": "core::bool",
+ "kind": "data"
+ }
+ ]
+ },
+ {
+ "type": "event",
+ "name": "dojo::world::world_contract::world::Event",
+ "kind": "enum",
+ "variants": [
+ {
+ "name": "WorldSpawned",
+ "type": "dojo::world::world_contract::world::WorldSpawned",
+ "kind": "nested"
+ },
+ {
+ "name": "WorldUpgraded",
+ "type": "dojo::world::world_contract::world::WorldUpgraded",
+ "kind": "nested"
+ },
+ {
+ "name": "NamespaceRegistered",
+ "type": "dojo::world::world_contract::world::NamespaceRegistered",
+ "kind": "nested"
+ },
+ {
+ "name": "ModelRegistered",
+ "type": "dojo::world::world_contract::world::ModelRegistered",
+ "kind": "nested"
+ },
+ {
+ "name": "EventRegistered",
+ "type": "dojo::world::world_contract::world::EventRegistered",
+ "kind": "nested"
+ },
+ {
+ "name": "ContractRegistered",
+ "type": "dojo::world::world_contract::world::ContractRegistered",
+ "kind": "nested"
+ },
+ {
+ "name": "ModelUpgraded",
+ "type": "dojo::world::world_contract::world::ModelUpgraded",
+ "kind": "nested"
+ },
+ {
+ "name": "EventUpgraded",
+ "type": "dojo::world::world_contract::world::EventUpgraded",
+ "kind": "nested"
+ },
+ {
+ "name": "ContractUpgraded",
+ "type": "dojo::world::world_contract::world::ContractUpgraded",
+ "kind": "nested"
+ },
+ {
+ "name": "ContractInitialized",
+ "type": "dojo::world::world_contract::world::ContractInitialized",
+ "kind": "nested"
+ },
+ {
+ "name": "LibraryRegistered",
+ "type": "dojo::world::world_contract::world::LibraryRegistered",
+ "kind": "nested"
+ },
+ {
+ "name": "EventEmitted",
+ "type": "dojo::world::world_contract::world::EventEmitted",
+ "kind": "nested"
+ },
+ {
+ "name": "MetadataUpdate",
+ "type": "dojo::world::world_contract::world::MetadataUpdate",
+ "kind": "nested"
+ },
+ {
+ "name": "StoreSetRecord",
+ "type": "dojo::world::world_contract::world::StoreSetRecord",
+ "kind": "nested"
+ },
+ {
+ "name": "StoreUpdateRecord",
+ "type": "dojo::world::world_contract::world::StoreUpdateRecord",
+ "kind": "nested"
+ },
+ {
+ "name": "StoreUpdateMember",
+ "type": "dojo::world::world_contract::world::StoreUpdateMember",
+ "kind": "nested"
+ },
+ {
+ "name": "StoreDelRecord",
+ "type": "dojo::world::world_contract::world::StoreDelRecord",
+ "kind": "nested"
+ },
+ {
+ "name": "WriterUpdated",
+ "type": "dojo::world::world_contract::world::WriterUpdated",
+ "kind": "nested"
+ },
+ {
+ "name": "OwnerUpdated",
+ "type": "dojo::world::world_contract::world::OwnerUpdated",
+ "kind": "nested"
+ }
+ ]
+ }
+ ]
+ },
+ "contracts": [
+ {
+ "address": "0x2c5ac40a1ac79992d20412dcb1d641ec271c113b99e54edbcc872de27e1be19",
+ "class_hash": "0x5e434344f33ab16d6295a8e6d04a9b9d8b2254d1e96f5e28a5e9b8300872ce5",
+ "abi": [
+ {
+ "type": "impl",
+ "name": "hunter_actions__ContractImpl",
+ "interface_name": "dojo::contract::interface::IContract"
+ },
+ {
+ "type": "interface",
+ "name": "dojo::contract::interface::IContract",
+ "items": []
+ },
+ {
+ "type": "impl",
+ "name": "hunter_actions__DeployedContractImpl",
+ "interface_name": "dojo::meta::interface::IDeployedResource"
+ },
+ {
+ "type": "struct",
+ "name": "core::byte_array::ByteArray",
+ "members": [
+ {
+ "name": "data",
+ "type": "core::array::Array::"
+ },
+ {
+ "name": "pending_word",
+ "type": "core::felt252"
+ },
+ {
+ "name": "pending_word_len",
+ "type": "core::integer::u32"
+ }
+ ]
+ },
+ {
+ "type": "interface",
+ "name": "dojo::meta::interface::IDeployedResource",
+ "items": [
+ {
+ "type": "function",
+ "name": "dojo_name",
+ "inputs": [],
+ "outputs": [
+ {
+ "type": "core::byte_array::ByteArray"
+ }
+ ],
+ "state_mutability": "view"
+ }
+ ]
+ },
+ {
+ "type": "function",
+ "name": "dojo_init",
+ "inputs": [],
+ "outputs": [],
+ "state_mutability": "external"
+ },
+ {
+ "type": "impl",
+ "name": "ActionsImpl",
+ "interface_name": "hunter::app::IHunterActions"
+ },
+ {
+ "type": "struct",
+ "name": "pixelaw::core::utils::Position",
+ "members": [
+ {
+ "name": "x",
+ "type": "core::integer::u16"
+ },
+ {
+ "name": "y",
+ "type": "core::integer::u16"
+ }
+ ]
+ },
+ {
+ "type": "enum",
+ "name": "core::option::Option::",
+ "variants": [
+ {
+ "name": "Some",
+ "type": "core::integer::u32"
+ },
+ {
+ "name": "None",
+ "type": "()"
+ }
+ ]
+ },
+ {
+ "type": "enum",
+ "name": "core::option::Option::",
+ "variants": [
+ {
+ "name": "Some",
+ "type": "core::starknet::contract_address::ContractAddress"
+ },
+ {
+ "name": "None",
+ "type": "()"
+ }
+ ]
+ },
+ {
+ "type": "enum",
+ "name": "core::option::Option::",
+ "variants": [
+ {
+ "name": "Some",
+ "type": "core::felt252"
+ },
+ {
+ "name": "None",
+ "type": "()"
+ }
+ ]
+ },
+ {
+ "type": "enum",
+ "name": "core::option::Option::",
+ "variants": [
+ {
+ "name": "Some",
+ "type": "core::integer::u64"
+ },
+ {
+ "name": "None",
+ "type": "()"
+ }
+ ]
+ },
+ {
+ "type": "struct",
+ "name": "pixelaw::core::models::pixel::PixelUpdate",
+ "members": [
+ {
+ "name": "position",
+ "type": "pixelaw::core::utils::Position"
+ },
+ {
+ "name": "color",
+ "type": "core::option::Option::"
+ },
+ {
+ "name": "owner",
+ "type": "core::option::Option::"
+ },
+ {
+ "name": "app",
+ "type": "core::option::Option::"
+ },
+ {
+ "name": "text",
+ "type": "core::option::Option::"
+ },
+ {
+ "name": "timestamp",
+ "type": "core::option::Option::"
+ },
+ {
+ "name": "action",
+ "type": "core::option::Option::"
+ }
+ ]
+ },
+ {
+ "type": "struct",
+ "name": "pixelaw::core::models::registry::App",
+ "members": [
+ {
+ "name": "system",
+ "type": "core::starknet::contract_address::ContractAddress"
+ },
+ {
+ "name": "name",
+ "type": "core::felt252"
+ },
+ {
+ "name": "icon",
+ "type": "core::felt252"
+ },
+ {
+ "name": "action",
+ "type": "core::felt252"
+ }
+ ]
+ },
+ {
+ "type": "enum",
+ "name": "core::option::Option::",
+ "variants": [
+ {
+ "name": "Some",
+ "type": "pixelaw::core::models::pixel::PixelUpdate"
+ },
+ {
+ "name": "None",
+ "type": "()"
+ }
+ ]
+ },
+ {
+ "type": "struct",
+ "name": "pixelaw::core::utils::DefaultParameters",
+ "members": [
+ {
+ "name": "player_override",
+ "type": "core::option::Option::"
+ },
+ {
+ "name": "system_override",
+ "type": "core::option::Option::"
+ },
+ {
+ "name": "area_hint",
+ "type": "core::option::Option::"
+ },
+ {
+ "name": "position",
+ "type": "pixelaw::core::utils::Position"
+ },
+ {
+ "name": "color",
+ "type": "core::integer::u32"
+ }
+ ]
+ },
+ {
+ "type": "interface",
+ "name": "hunter::app::IHunterActions",
+ "items": [
+ {
+ "type": "function",
+ "name": "on_pre_update",
+ "inputs": [
+ {
+ "name": "pixel_update",
+ "type": "pixelaw::core::models::pixel::PixelUpdate"
+ },
+ {
+ "name": "app_caller",
+ "type": "pixelaw::core::models::registry::App"
+ },
+ {
+ "name": "player_caller",
+ "type": "core::starknet::contract_address::ContractAddress"
+ }
+ ],
+ "outputs": [
+ {
+ "type": "core::option::Option::"
+ }
+ ],
+ "state_mutability": "external"
+ },
+ {
+ "type": "function",
+ "name": "on_post_update",
+ "inputs": [
+ {
+ "name": "pixel_update",
+ "type": "pixelaw::core::models::pixel::PixelUpdate"
+ },
+ {
+ "name": "app_caller",
+ "type": "pixelaw::core::models::registry::App"
+ },
+ {
+ "name": "player_caller",
+ "type": "core::starknet::contract_address::ContractAddress"
+ }
+ ],
+ "outputs": [],
+ "state_mutability": "external"
+ },
+ {
+ "type": "function",
+ "name": "interact",
+ "inputs": [
+ {
+ "name": "default_params",
+ "type": "pixelaw::core::utils::DefaultParameters"
+ }
+ ],
+ "outputs": [],
+ "state_mutability": "external"
+ }
+ ]
+ },
+ {
+ "type": "impl",
+ "name": "WorldProviderImpl",
+ "interface_name": "dojo::contract::components::world_provider::IWorldProvider"
+ },
+ {
+ "type": "struct",
+ "name": "dojo::world::iworld::IWorldDispatcher",
+ "members": [
+ {
+ "name": "contract_address",
+ "type": "core::starknet::contract_address::ContractAddress"
+ }
+ ]
+ },
+ {
+ "type": "interface",
+ "name": "dojo::contract::components::world_provider::IWorldProvider",
+ "items": [
+ {
+ "type": "function",
+ "name": "world_dispatcher",
+ "inputs": [],
+ "outputs": [
+ {
+ "type": "dojo::world::iworld::IWorldDispatcher"
+ }
+ ],
+ "state_mutability": "view"
+ }
+ ]
+ },
+ {
+ "type": "impl",
+ "name": "UpgradeableImpl",
+ "interface_name": "dojo::contract::components::upgradeable::IUpgradeable"
+ },
+ {
+ "type": "interface",
+ "name": "dojo::contract::components::upgradeable::IUpgradeable",
+ "items": [
+ {
+ "type": "function",
+ "name": "upgrade",
+ "inputs": [
+ {
+ "name": "new_class_hash",
+ "type": "core::starknet::class_hash::ClassHash"
+ }
+ ],
+ "outputs": [],
+ "state_mutability": "external"
+ }
+ ]
+ },
+ {
+ "type": "constructor",
+ "name": "constructor",
+ "inputs": []
+ },
+ {
+ "type": "event",
+ "name": "dojo::contract::components::upgradeable::upgradeable_cpt::Upgraded",
+ "kind": "struct",
+ "members": [
+ {
+ "name": "class_hash",
+ "type": "core::starknet::class_hash::ClassHash",
+ "kind": "data"
+ }
+ ]
+ },
+ {
+ "type": "event",
+ "name": "dojo::contract::components::upgradeable::upgradeable_cpt::Event",
+ "kind": "enum",
+ "variants": [
+ {
+ "name": "Upgraded",
+ "type": "dojo::contract::components::upgradeable::upgradeable_cpt::Upgraded",
+ "kind": "nested"
+ }
+ ]
+ },
+ {
+ "type": "event",
+ "name": "dojo::contract::components::world_provider::world_provider_cpt::Event",
+ "kind": "enum",
+ "variants": []
+ },
+ {
+ "type": "event",
+ "name": "hunter::app::hunter_actions::Event",
+ "kind": "enum",
+ "variants": [
+ {
+ "name": "UpgradeableEvent",
+ "type": "dojo::contract::components::upgradeable::upgradeable_cpt::Event",
+ "kind": "nested"
+ },
+ {
+ "name": "WorldProviderEvent",
+ "type": "dojo::contract::components::world_provider::world_provider_cpt::Event",
+ "kind": "nested"
+ }
+ ]
+ }
+ ],
+ "init_calldata": [],
+ "tag": "hunter-hunter_actions",
+ "selector": "0x79f2ad36d7d712a1779a823d8c87274c7d372f96aa3cfada8127bde55c24d88",
+ "systems": [
+ "dojo_init",
+ "on_pre_update",
+ "on_post_update",
+ "interact",
+ "upgrade"
+ ]
+ }
+ ],
+ "libraries": [],
+ "models": [
+ {
+ "members": [],
+ "class_hash": "0x76a5302d89cbd169453f3fccad890526e8e5c6537229c860edbcbf60cd7c43d",
+ "tag": "hunter-LastAttempt",
+ "selector": "0xa3fd659f0e8ba579d347e0c4d9c94212bee14629ed2c873b2b200db1242836"
+ }
+ ],
+ "events": [],
+ "external_contracts": []
+}
\ No newline at end of file
diff --git a/local_deploy.sh b/local_deploy.sh
deleted file mode 100755
index e48946d..0000000
--- a/local_deploy.sh
+++ /dev/null
@@ -1,103 +0,0 @@
-#!/bin/bash
-
-wait_for_local_katana() {
- while true; do
- response=$(curl --write-out '%{http_code}' --silent --output /dev/null http://localhost:5050)
- if [ "$response" -eq 200 ]; then
- break
- else
- echo "Waiting for katana at http://localhost:5050 - on MacOS this can take a while"
- sleep 2
- fi
- done
-}
-
-deploy_local() {
- APP_NAME=$1
- PROFILE=dev
- wait_for_local_katana
- deploy $APP_NAME $PROFILE
-}
-
-deploy_dojo() {
- APP_NAME=$1
- PROFILE=dojo
- MANIFEST_URL="https://dojo.pixelaw.xyz/manifests"
- deploy $APP_NAME $PROFILE $MANIFEST_URL
-}
-
-
-
-# Function to start app
-deploy() {
- echo "Deploying $1 to $2"
- APP_NAME=$1
- PROFILE=$2
- pushd $APP_NAME
-
- sozo --profile $PROFILE build
- sozo --profile $PROFILE migrate plan
- sozo --profile $PROFILE migrate apply
-
- export ACTIONS_ADDRESS=$(cat ./manifests/$PROFILE/manifest.json | jq -r --arg APP_NAME "$APP_NAME" '.contracts[] | select(.name | contains($APP_NAME)) | .address')
-
- echo "---------------------------------------------------------------------------"
- echo app : $APP_NAME
- echo " "
- echo actions : $ACTIONS_ADDRESS
- echo "---------------------------------------------------------------------------"
-
- # enable system -> component authorizations
- COMPONENTS=($(jq -r --arg APP_NAME "$APP_NAME" '.models[] | select(.name | contains($APP_NAME)) | .name' ./manifests/$PROFILE/manifest.json))
-
- for index in "${!COMPONENTS[@]}"; do
- IFS='::' read -ra NAMES <<< "${COMPONENTS[index]}"
- LAST_INDEX=${#NAMES[@]}-1
- NEW_NAME=`echo ${NAMES[LAST_INDEX]} | sed -r 's/_/ /g' | awk '{for(j=1;j<=NF;j++){ $j=toupper(substr($j,1,1)) substr($j,2) }}1' | sed -r 's/ //g'`
- COMPONENTS[index]=$NEW_NAME
- done
-
- # if #COMPONENTS is 0, then there are no models in the manifest. This might be error,
- echo "Write permissions for ACTIONS"
- if [ ${#COMPONENTS[@]} -eq 0 ]; then
- echo "Warning: No models found in manifest.json. Are you sure you don't have new any components?"
- else
- for component in ${COMPONENTS[@]}; do
- echo "For $component"
- sozo --profile $PROFILE auth grant --wait writer $component,$ACTIONS_ADDRESS
- done
- fi
- echo "Write permissions for ACTIONS: Done"
-
- echo "Initialize ACTIONS: (sozo --profile $PROFILE execute -v $ACTIONS_ADDRESS init)"
- sozo --profile $PROFILE execute --wait -v $ACTIONS_ADDRESS init
- echo "Initialize ACTIONS: Done"
-
- echo "Default authorizations have been successfully set."
-
- popd
-}
-
-# Function to stop app
-stop_app() {
- echo "Stopping $1"
- # Add your command to stop the app here
-}
-
-# Function to restart app
-restart_app() {
- echo "Restarting $1"
- # Add your command to restart the app here
-}
-
-# Check if APP_NAME is provided
-if [ -z "$1" ]
-then
- echo "No APP_NAME provided"
- exit 1
-fi
-
-APP_NAME=$1
-
-# Call functions
-deploy_local $APP_NAME
diff --git a/maze/.tool-versions b/maze/.tool-versions
index c03850d..1b363e4 100644
--- a/maze/.tool-versions
+++ b/maze/.tool-versions
@@ -1,2 +1,2 @@
-dojo 1.5.1
+dojo 1.6.2
scarb 2.10.1
diff --git a/maze/Scarb.lock b/maze/Scarb.lock
index ec86cc8..3326339 100644
--- a/maze/Scarb.lock
+++ b/maze/Scarb.lock
@@ -3,16 +3,16 @@ version = 1
[[package]]
name = "dojo"
-version = "1.5.1"
-source = "git+https://github.com/dojoengine/dojo?tag=v1.5.1#986c3b0c6d647b23847c70ddceb1d33ddac86ead"
+version = "1.6.2"
+source = "git+https://github.com/dojoengine/dojo?tag=v1.6.2#d6e847c51ecd0121a43c2a17b96dbca936604764"
dependencies = [
"dojo_plugin",
]
[[package]]
name = "dojo_cairo_test"
-version = "1.0.12"
-source = "git+https://github.com/dojoengine/dojo?tag=v1.5.1#986c3b0c6d647b23847c70ddceb1d33ddac86ead"
+version = "1.6.2"
+source = "git+https://github.com/dojoengine/dojo?tag=v1.6.2#d6e847c51ecd0121a43c2a17b96dbca936604764"
dependencies = [
"dojo",
]
@@ -20,7 +20,7 @@ dependencies = [
[[package]]
name = "dojo_plugin"
version = "2.10.1"
-source = "git+https://github.com/dojoengine/dojo?tag=v1.5.1#986c3b0c6d647b23847c70ddceb1d33ddac86ead"
+source = "git+https://github.com/dojoengine/dojo?tag=v1.6.2#d6e847c51ecd0121a43c2a17b96dbca936604764"
[[package]]
name = "maze"
@@ -34,16 +34,16 @@ dependencies = [
[[package]]
name = "pixelaw"
-version = "0.7.8"
-source = "git+https://github.com/pixelaw/core?tag=v0.7.8#0d020c16319676c1839cedd53577868458efa6c2"
+version = "0.7.9"
+source = "git+https://github.com/pixelaw/core?tag=v0.7.9#40313e650b145faa4d8f6eb525fbfa0e2b58a5bf"
dependencies = [
"dojo",
]
[[package]]
name = "pixelaw_testing"
-version = "0.7.8"
-source = "git+https://github.com/pixelaw/core?tag=v0.7.8#0d020c16319676c1839cedd53577868458efa6c2"
+version = "0.7.9"
+source = "git+https://github.com/pixelaw/core?tag=v0.7.9#40313e650b145faa4d8f6eb525fbfa0e2b58a5bf"
dependencies = [
"dojo",
"dojo_cairo_test",
diff --git a/maze/Scarb.toml b/maze/Scarb.toml
index 22ac85e..037a3a6 100644
--- a/maze/Scarb.toml
+++ b/maze/Scarb.toml
@@ -8,13 +8,13 @@ edition = "2024_07"
sierra-replace-ids = true
[dependencies]
-pixelaw = { git = "https://github.com/pixelaw/core", tag = "v0.7.8" }
-dojo = { git = "https://github.com/dojoengine/dojo", tag = "v1.5.1" }
+pixelaw = { git = "https://github.com/pixelaw/core", tag = "v0.7.9" }
+dojo = { git = "https://github.com/dojoengine/dojo", tag = "v1.6.2" }
#pixelaw = { path = "../core/contracts" }
[dev-dependencies]
-pixelaw_testing = { git = "https://github.com/pixelaw/core", tag = "v0.7.8" }
-dojo_cairo_test = { git = "https://github.com/dojoengine/dojo", tag = "v1.5.1" }
+pixelaw_testing = { git = "https://github.com/pixelaw/core", tag = "v0.7.9" }
+dojo_cairo_test = { git = "https://github.com/dojoengine/dojo", tag = "v1.6.2" }
#pixelaw_testing = { path = "../core/pixelaw_testing" }
[[target.starknet-contract]]
diff --git a/maze/dojo_dev.toml b/maze/dojo_dev.toml
index 68676d3..c761937 100644
--- a/maze/dojo_dev.toml
+++ b/maze/dojo_dev.toml
@@ -15,7 +15,6 @@ mappings = { "pixelaw" = [
rpc_url = "http://localhost:5050/"
account_address = "0x127fd5f1fe78a71f8bcd1fec63e3fe2f0486b6ecd5c86a0466c3a21fa5cfcec"
private_key = "0xc5b2fcab997346f3ea1c00b002ecf6f382c5f9c9659a3894eb783c5320f912"
-world_address = "0x01d09b5e00f376337603943fc12715e439e91c0039f353b1cc48bb278dfa99d5"
[writers]
"maze-MazeGame" = ["maze-maze_actions"]
diff --git a/maze/manifest_dev.json b/maze/manifest_dev.json
new file mode 100644
index 0000000..2752292
--- /dev/null
+++ b/maze/manifest_dev.json
@@ -0,0 +1,3465 @@
+{
+ "world": {
+ "class_hash": "0x13d92333361bb7049c1232c0a5404e2c19082ededc3a73d75cb33fa952adec7",
+ "address": "0x548b7044c88b3338e88e3c0ea356eb9dcf65388c90ec7c9d9031547af30d1d1",
+ "seed": "pixelaw",
+ "name": "maze",
+ "entrypoints": [
+ "uuid",
+ "set_metadata",
+ "register_namespace",
+ "register_event",
+ "register_model",
+ "register_contract",
+ "register_library",
+ "init_contract",
+ "upgrade_event",
+ "upgrade_model",
+ "upgrade_contract",
+ "emit_event",
+ "emit_events",
+ "set_entity",
+ "set_entities",
+ "delete_entity",
+ "delete_entities",
+ "grant_owner",
+ "revoke_owner",
+ "grant_writer",
+ "revoke_writer",
+ "upgrade"
+ ],
+ "abi": [
+ {
+ "type": "impl",
+ "name": "World",
+ "interface_name": "dojo::world::iworld::IWorld"
+ },
+ {
+ "type": "struct",
+ "name": "core::byte_array::ByteArray",
+ "members": [
+ {
+ "name": "data",
+ "type": "core::array::Array::"
+ },
+ {
+ "name": "pending_word",
+ "type": "core::felt252"
+ },
+ {
+ "name": "pending_word_len",
+ "type": "core::integer::u32"
+ }
+ ]
+ },
+ {
+ "type": "enum",
+ "name": "dojo::world::resource::Resource",
+ "variants": [
+ {
+ "name": "Model",
+ "type": "(core::starknet::contract_address::ContractAddress, core::felt252)"
+ },
+ {
+ "name": "Event",
+ "type": "(core::starknet::contract_address::ContractAddress, core::felt252)"
+ },
+ {
+ "name": "Contract",
+ "type": "(core::starknet::contract_address::ContractAddress, core::felt252)"
+ },
+ {
+ "name": "Namespace",
+ "type": "core::byte_array::ByteArray"
+ },
+ {
+ "name": "World",
+ "type": "()"
+ },
+ {
+ "name": "Unregistered",
+ "type": "()"
+ },
+ {
+ "name": "Library",
+ "type": "(core::starknet::class_hash::ClassHash, core::felt252)"
+ }
+ ]
+ },
+ {
+ "type": "struct",
+ "name": "dojo::model::metadata::ResourceMetadata",
+ "members": [
+ {
+ "name": "resource_id",
+ "type": "core::felt252"
+ },
+ {
+ "name": "metadata_uri",
+ "type": "core::byte_array::ByteArray"
+ },
+ {
+ "name": "metadata_hash",
+ "type": "core::felt252"
+ }
+ ]
+ },
+ {
+ "type": "struct",
+ "name": "core::array::Span::",
+ "members": [
+ {
+ "name": "snapshot",
+ "type": "@core::array::Array::"
+ }
+ ]
+ },
+ {
+ "type": "struct",
+ "name": "core::array::Span::>",
+ "members": [
+ {
+ "name": "snapshot",
+ "type": "@core::array::Array::>"
+ }
+ ]
+ },
+ {
+ "type": "enum",
+ "name": "dojo::model::definition::ModelIndex",
+ "variants": [
+ {
+ "name": "Keys",
+ "type": "core::array::Span::"
+ },
+ {
+ "name": "Id",
+ "type": "core::felt252"
+ },
+ {
+ "name": "MemberId",
+ "type": "(core::felt252, core::felt252)"
+ }
+ ]
+ },
+ {
+ "type": "struct",
+ "name": "core::array::Span::",
+ "members": [
+ {
+ "name": "snapshot",
+ "type": "@core::array::Array::"
+ }
+ ]
+ },
+ {
+ "type": "struct",
+ "name": "dojo::meta::layout::FieldLayout",
+ "members": [
+ {
+ "name": "selector",
+ "type": "core::felt252"
+ },
+ {
+ "name": "layout",
+ "type": "dojo::meta::layout::Layout"
+ }
+ ]
+ },
+ {
+ "type": "struct",
+ "name": "core::array::Span::",
+ "members": [
+ {
+ "name": "snapshot",
+ "type": "@core::array::Array::"
+ }
+ ]
+ },
+ {
+ "type": "struct",
+ "name": "core::array::Span::",
+ "members": [
+ {
+ "name": "snapshot",
+ "type": "@core::array::Array::"
+ }
+ ]
+ },
+ {
+ "type": "enum",
+ "name": "dojo::meta::layout::Layout",
+ "variants": [
+ {
+ "name": "Fixed",
+ "type": "core::array::Span::"
+ },
+ {
+ "name": "Struct",
+ "type": "core::array::Span::"
+ },
+ {
+ "name": "Tuple",
+ "type": "core::array::Span::"
+ },
+ {
+ "name": "Array",
+ "type": "core::array::Span::"
+ },
+ {
+ "name": "ByteArray",
+ "type": "()"
+ },
+ {
+ "name": "Enum",
+ "type": "core::array::Span::"
+ }
+ ]
+ },
+ {
+ "type": "struct",
+ "name": "core::array::Span::",
+ "members": [
+ {
+ "name": "snapshot",
+ "type": "@core::array::Array::"
+ }
+ ]
+ },
+ {
+ "type": "enum",
+ "name": "core::bool",
+ "variants": [
+ {
+ "name": "False",
+ "type": "()"
+ },
+ {
+ "name": "True",
+ "type": "()"
+ }
+ ]
+ },
+ {
+ "type": "interface",
+ "name": "dojo::world::iworld::IWorld",
+ "items": [
+ {
+ "type": "function",
+ "name": "resource",
+ "inputs": [
+ {
+ "name": "selector",
+ "type": "core::felt252"
+ }
+ ],
+ "outputs": [
+ {
+ "type": "dojo::world::resource::Resource"
+ }
+ ],
+ "state_mutability": "view"
+ },
+ {
+ "type": "function",
+ "name": "uuid",
+ "inputs": [],
+ "outputs": [
+ {
+ "type": "core::integer::u32"
+ }
+ ],
+ "state_mutability": "external"
+ },
+ {
+ "type": "function",
+ "name": "metadata",
+ "inputs": [
+ {
+ "name": "resource_selector",
+ "type": "core::felt252"
+ }
+ ],
+ "outputs": [
+ {
+ "type": "dojo::model::metadata::ResourceMetadata"
+ }
+ ],
+ "state_mutability": "view"
+ },
+ {
+ "type": "function",
+ "name": "set_metadata",
+ "inputs": [
+ {
+ "name": "metadata",
+ "type": "dojo::model::metadata::ResourceMetadata"
+ }
+ ],
+ "outputs": [],
+ "state_mutability": "external"
+ },
+ {
+ "type": "function",
+ "name": "register_namespace",
+ "inputs": [
+ {
+ "name": "namespace",
+ "type": "core::byte_array::ByteArray"
+ }
+ ],
+ "outputs": [],
+ "state_mutability": "external"
+ },
+ {
+ "type": "function",
+ "name": "register_event",
+ "inputs": [
+ {
+ "name": "namespace",
+ "type": "core::byte_array::ByteArray"
+ },
+ {
+ "name": "class_hash",
+ "type": "core::starknet::class_hash::ClassHash"
+ }
+ ],
+ "outputs": [],
+ "state_mutability": "external"
+ },
+ {
+ "type": "function",
+ "name": "register_model",
+ "inputs": [
+ {
+ "name": "namespace",
+ "type": "core::byte_array::ByteArray"
+ },
+ {
+ "name": "class_hash",
+ "type": "core::starknet::class_hash::ClassHash"
+ }
+ ],
+ "outputs": [],
+ "state_mutability": "external"
+ },
+ {
+ "type": "function",
+ "name": "register_contract",
+ "inputs": [
+ {
+ "name": "salt",
+ "type": "core::felt252"
+ },
+ {
+ "name": "namespace",
+ "type": "core::byte_array::ByteArray"
+ },
+ {
+ "name": "class_hash",
+ "type": "core::starknet::class_hash::ClassHash"
+ }
+ ],
+ "outputs": [
+ {
+ "type": "core::starknet::contract_address::ContractAddress"
+ }
+ ],
+ "state_mutability": "external"
+ },
+ {
+ "type": "function",
+ "name": "register_library",
+ "inputs": [
+ {
+ "name": "namespace",
+ "type": "core::byte_array::ByteArray"
+ },
+ {
+ "name": "class_hash",
+ "type": "core::starknet::class_hash::ClassHash"
+ },
+ {
+ "name": "name",
+ "type": "core::byte_array::ByteArray"
+ },
+ {
+ "name": "version",
+ "type": "core::byte_array::ByteArray"
+ }
+ ],
+ "outputs": [
+ {
+ "type": "core::starknet::class_hash::ClassHash"
+ }
+ ],
+ "state_mutability": "external"
+ },
+ {
+ "type": "function",
+ "name": "init_contract",
+ "inputs": [
+ {
+ "name": "selector",
+ "type": "core::felt252"
+ },
+ {
+ "name": "init_calldata",
+ "type": "core::array::Span::"
+ }
+ ],
+ "outputs": [],
+ "state_mutability": "external"
+ },
+ {
+ "type": "function",
+ "name": "upgrade_event",
+ "inputs": [
+ {
+ "name": "namespace",
+ "type": "core::byte_array::ByteArray"
+ },
+ {
+ "name": "class_hash",
+ "type": "core::starknet::class_hash::ClassHash"
+ }
+ ],
+ "outputs": [],
+ "state_mutability": "external"
+ },
+ {
+ "type": "function",
+ "name": "upgrade_model",
+ "inputs": [
+ {
+ "name": "namespace",
+ "type": "core::byte_array::ByteArray"
+ },
+ {
+ "name": "class_hash",
+ "type": "core::starknet::class_hash::ClassHash"
+ }
+ ],
+ "outputs": [],
+ "state_mutability": "external"
+ },
+ {
+ "type": "function",
+ "name": "upgrade_contract",
+ "inputs": [
+ {
+ "name": "namespace",
+ "type": "core::byte_array::ByteArray"
+ },
+ {
+ "name": "class_hash",
+ "type": "core::starknet::class_hash::ClassHash"
+ }
+ ],
+ "outputs": [
+ {
+ "type": "core::starknet::class_hash::ClassHash"
+ }
+ ],
+ "state_mutability": "external"
+ },
+ {
+ "type": "function",
+ "name": "emit_event",
+ "inputs": [
+ {
+ "name": "event_selector",
+ "type": "core::felt252"
+ },
+ {
+ "name": "keys",
+ "type": "core::array::Span::"
+ },
+ {
+ "name": "values",
+ "type": "core::array::Span::"
+ }
+ ],
+ "outputs": [],
+ "state_mutability": "external"
+ },
+ {
+ "type": "function",
+ "name": "emit_events",
+ "inputs": [
+ {
+ "name": "event_selector",
+ "type": "core::felt252"
+ },
+ {
+ "name": "keys",
+ "type": "core::array::Span::>"
+ },
+ {
+ "name": "values",
+ "type": "core::array::Span::>"
+ }
+ ],
+ "outputs": [],
+ "state_mutability": "external"
+ },
+ {
+ "type": "function",
+ "name": "entity",
+ "inputs": [
+ {
+ "name": "model_selector",
+ "type": "core::felt252"
+ },
+ {
+ "name": "index",
+ "type": "dojo::model::definition::ModelIndex"
+ },
+ {
+ "name": "layout",
+ "type": "dojo::meta::layout::Layout"
+ }
+ ],
+ "outputs": [
+ {
+ "type": "core::array::Span::"
+ }
+ ],
+ "state_mutability": "view"
+ },
+ {
+ "type": "function",
+ "name": "entities",
+ "inputs": [
+ {
+ "name": "model_selector",
+ "type": "core::felt252"
+ },
+ {
+ "name": "indexes",
+ "type": "core::array::Span::"
+ },
+ {
+ "name": "layout",
+ "type": "dojo::meta::layout::Layout"
+ }
+ ],
+ "outputs": [
+ {
+ "type": "core::array::Span::>"
+ }
+ ],
+ "state_mutability": "view"
+ },
+ {
+ "type": "function",
+ "name": "set_entity",
+ "inputs": [
+ {
+ "name": "model_selector",
+ "type": "core::felt252"
+ },
+ {
+ "name": "index",
+ "type": "dojo::model::definition::ModelIndex"
+ },
+ {
+ "name": "values",
+ "type": "core::array::Span::"
+ },
+ {
+ "name": "layout",
+ "type": "dojo::meta::layout::Layout"
+ }
+ ],
+ "outputs": [],
+ "state_mutability": "external"
+ },
+ {
+ "type": "function",
+ "name": "set_entities",
+ "inputs": [
+ {
+ "name": "model_selector",
+ "type": "core::felt252"
+ },
+ {
+ "name": "indexes",
+ "type": "core::array::Span::"
+ },
+ {
+ "name": "values",
+ "type": "core::array::Span::>"
+ },
+ {
+ "name": "layout",
+ "type": "dojo::meta::layout::Layout"
+ }
+ ],
+ "outputs": [],
+ "state_mutability": "external"
+ },
+ {
+ "type": "function",
+ "name": "delete_entity",
+ "inputs": [
+ {
+ "name": "model_selector",
+ "type": "core::felt252"
+ },
+ {
+ "name": "index",
+ "type": "dojo::model::definition::ModelIndex"
+ },
+ {
+ "name": "layout",
+ "type": "dojo::meta::layout::Layout"
+ }
+ ],
+ "outputs": [],
+ "state_mutability": "external"
+ },
+ {
+ "type": "function",
+ "name": "delete_entities",
+ "inputs": [
+ {
+ "name": "model_selector",
+ "type": "core::felt252"
+ },
+ {
+ "name": "indexes",
+ "type": "core::array::Span::"
+ },
+ {
+ "name": "layout",
+ "type": "dojo::meta::layout::Layout"
+ }
+ ],
+ "outputs": [],
+ "state_mutability": "external"
+ },
+ {
+ "type": "function",
+ "name": "is_owner",
+ "inputs": [
+ {
+ "name": "resource",
+ "type": "core::felt252"
+ },
+ {
+ "name": "address",
+ "type": "core::starknet::contract_address::ContractAddress"
+ }
+ ],
+ "outputs": [
+ {
+ "type": "core::bool"
+ }
+ ],
+ "state_mutability": "view"
+ },
+ {
+ "type": "function",
+ "name": "grant_owner",
+ "inputs": [
+ {
+ "name": "resource",
+ "type": "core::felt252"
+ },
+ {
+ "name": "address",
+ "type": "core::starknet::contract_address::ContractAddress"
+ }
+ ],
+ "outputs": [],
+ "state_mutability": "external"
+ },
+ {
+ "type": "function",
+ "name": "revoke_owner",
+ "inputs": [
+ {
+ "name": "resource",
+ "type": "core::felt252"
+ },
+ {
+ "name": "address",
+ "type": "core::starknet::contract_address::ContractAddress"
+ }
+ ],
+ "outputs": [],
+ "state_mutability": "external"
+ },
+ {
+ "type": "function",
+ "name": "owners_count",
+ "inputs": [
+ {
+ "name": "resource",
+ "type": "core::felt252"
+ }
+ ],
+ "outputs": [
+ {
+ "type": "core::integer::u64"
+ }
+ ],
+ "state_mutability": "view"
+ },
+ {
+ "type": "function",
+ "name": "is_writer",
+ "inputs": [
+ {
+ "name": "resource",
+ "type": "core::felt252"
+ },
+ {
+ "name": "contract",
+ "type": "core::starknet::contract_address::ContractAddress"
+ }
+ ],
+ "outputs": [
+ {
+ "type": "core::bool"
+ }
+ ],
+ "state_mutability": "view"
+ },
+ {
+ "type": "function",
+ "name": "grant_writer",
+ "inputs": [
+ {
+ "name": "resource",
+ "type": "core::felt252"
+ },
+ {
+ "name": "contract",
+ "type": "core::starknet::contract_address::ContractAddress"
+ }
+ ],
+ "outputs": [],
+ "state_mutability": "external"
+ },
+ {
+ "type": "function",
+ "name": "revoke_writer",
+ "inputs": [
+ {
+ "name": "resource",
+ "type": "core::felt252"
+ },
+ {
+ "name": "contract",
+ "type": "core::starknet::contract_address::ContractAddress"
+ }
+ ],
+ "outputs": [],
+ "state_mutability": "external"
+ }
+ ]
+ },
+ {
+ "type": "impl",
+ "name": "UpgradeableWorld",
+ "interface_name": "dojo::world::iworld::IUpgradeableWorld"
+ },
+ {
+ "type": "interface",
+ "name": "dojo::world::iworld::IUpgradeableWorld",
+ "items": [
+ {
+ "type": "function",
+ "name": "upgrade",
+ "inputs": [
+ {
+ "name": "new_class_hash",
+ "type": "core::starknet::class_hash::ClassHash"
+ }
+ ],
+ "outputs": [],
+ "state_mutability": "external"
+ }
+ ]
+ },
+ {
+ "type": "constructor",
+ "name": "constructor",
+ "inputs": [
+ {
+ "name": "world_class_hash",
+ "type": "core::starknet::class_hash::ClassHash"
+ }
+ ]
+ },
+ {
+ "type": "event",
+ "name": "dojo::world::world_contract::world::WorldSpawned",
+ "kind": "struct",
+ "members": [
+ {
+ "name": "creator",
+ "type": "core::starknet::contract_address::ContractAddress",
+ "kind": "data"
+ },
+ {
+ "name": "class_hash",
+ "type": "core::starknet::class_hash::ClassHash",
+ "kind": "data"
+ }
+ ]
+ },
+ {
+ "type": "event",
+ "name": "dojo::world::world_contract::world::WorldUpgraded",
+ "kind": "struct",
+ "members": [
+ {
+ "name": "class_hash",
+ "type": "core::starknet::class_hash::ClassHash",
+ "kind": "data"
+ }
+ ]
+ },
+ {
+ "type": "event",
+ "name": "dojo::world::world_contract::world::NamespaceRegistered",
+ "kind": "struct",
+ "members": [
+ {
+ "name": "namespace",
+ "type": "core::byte_array::ByteArray",
+ "kind": "key"
+ },
+ {
+ "name": "hash",
+ "type": "core::felt252",
+ "kind": "data"
+ }
+ ]
+ },
+ {
+ "type": "event",
+ "name": "dojo::world::world_contract::world::ModelRegistered",
+ "kind": "struct",
+ "members": [
+ {
+ "name": "name",
+ "type": "core::byte_array::ByteArray",
+ "kind": "key"
+ },
+ {
+ "name": "namespace",
+ "type": "core::byte_array::ByteArray",
+ "kind": "key"
+ },
+ {
+ "name": "class_hash",
+ "type": "core::starknet::class_hash::ClassHash",
+ "kind": "data"
+ },
+ {
+ "name": "address",
+ "type": "core::starknet::contract_address::ContractAddress",
+ "kind": "data"
+ }
+ ]
+ },
+ {
+ "type": "event",
+ "name": "dojo::world::world_contract::world::EventRegistered",
+ "kind": "struct",
+ "members": [
+ {
+ "name": "name",
+ "type": "core::byte_array::ByteArray",
+ "kind": "key"
+ },
+ {
+ "name": "namespace",
+ "type": "core::byte_array::ByteArray",
+ "kind": "key"
+ },
+ {
+ "name": "class_hash",
+ "type": "core::starknet::class_hash::ClassHash",
+ "kind": "data"
+ },
+ {
+ "name": "address",
+ "type": "core::starknet::contract_address::ContractAddress",
+ "kind": "data"
+ }
+ ]
+ },
+ {
+ "type": "event",
+ "name": "dojo::world::world_contract::world::ContractRegistered",
+ "kind": "struct",
+ "members": [
+ {
+ "name": "name",
+ "type": "core::byte_array::ByteArray",
+ "kind": "key"
+ },
+ {
+ "name": "namespace",
+ "type": "core::byte_array::ByteArray",
+ "kind": "key"
+ },
+ {
+ "name": "address",
+ "type": "core::starknet::contract_address::ContractAddress",
+ "kind": "data"
+ },
+ {
+ "name": "class_hash",
+ "type": "core::starknet::class_hash::ClassHash",
+ "kind": "data"
+ },
+ {
+ "name": "salt",
+ "type": "core::felt252",
+ "kind": "data"
+ }
+ ]
+ },
+ {
+ "type": "event",
+ "name": "dojo::world::world_contract::world::ModelUpgraded",
+ "kind": "struct",
+ "members": [
+ {
+ "name": "selector",
+ "type": "core::felt252",
+ "kind": "key"
+ },
+ {
+ "name": "class_hash",
+ "type": "core::starknet::class_hash::ClassHash",
+ "kind": "data"
+ },
+ {
+ "name": "address",
+ "type": "core::starknet::contract_address::ContractAddress",
+ "kind": "data"
+ },
+ {
+ "name": "prev_address",
+ "type": "core::starknet::contract_address::ContractAddress",
+ "kind": "data"
+ }
+ ]
+ },
+ {
+ "type": "event",
+ "name": "dojo::world::world_contract::world::EventUpgraded",
+ "kind": "struct",
+ "members": [
+ {
+ "name": "selector",
+ "type": "core::felt252",
+ "kind": "key"
+ },
+ {
+ "name": "class_hash",
+ "type": "core::starknet::class_hash::ClassHash",
+ "kind": "data"
+ },
+ {
+ "name": "address",
+ "type": "core::starknet::contract_address::ContractAddress",
+ "kind": "data"
+ },
+ {
+ "name": "prev_address",
+ "type": "core::starknet::contract_address::ContractAddress",
+ "kind": "data"
+ }
+ ]
+ },
+ {
+ "type": "event",
+ "name": "dojo::world::world_contract::world::ContractUpgraded",
+ "kind": "struct",
+ "members": [
+ {
+ "name": "selector",
+ "type": "core::felt252",
+ "kind": "key"
+ },
+ {
+ "name": "class_hash",
+ "type": "core::starknet::class_hash::ClassHash",
+ "kind": "data"
+ }
+ ]
+ },
+ {
+ "type": "event",
+ "name": "dojo::world::world_contract::world::ContractInitialized",
+ "kind": "struct",
+ "members": [
+ {
+ "name": "selector",
+ "type": "core::felt252",
+ "kind": "key"
+ },
+ {
+ "name": "init_calldata",
+ "type": "core::array::Span::",
+ "kind": "data"
+ }
+ ]
+ },
+ {
+ "type": "event",
+ "name": "dojo::world::world_contract::world::LibraryRegistered",
+ "kind": "struct",
+ "members": [
+ {
+ "name": "name",
+ "type": "core::byte_array::ByteArray",
+ "kind": "key"
+ },
+ {
+ "name": "namespace",
+ "type": "core::byte_array::ByteArray",
+ "kind": "key"
+ },
+ {
+ "name": "class_hash",
+ "type": "core::starknet::class_hash::ClassHash",
+ "kind": "data"
+ }
+ ]
+ },
+ {
+ "type": "event",
+ "name": "dojo::world::world_contract::world::EventEmitted",
+ "kind": "struct",
+ "members": [
+ {
+ "name": "selector",
+ "type": "core::felt252",
+ "kind": "key"
+ },
+ {
+ "name": "system_address",
+ "type": "core::starknet::contract_address::ContractAddress",
+ "kind": "key"
+ },
+ {
+ "name": "keys",
+ "type": "core::array::Span::",
+ "kind": "data"
+ },
+ {
+ "name": "values",
+ "type": "core::array::Span::",
+ "kind": "data"
+ }
+ ]
+ },
+ {
+ "type": "event",
+ "name": "dojo::world::world_contract::world::MetadataUpdate",
+ "kind": "struct",
+ "members": [
+ {
+ "name": "resource",
+ "type": "core::felt252",
+ "kind": "key"
+ },
+ {
+ "name": "uri",
+ "type": "core::byte_array::ByteArray",
+ "kind": "data"
+ },
+ {
+ "name": "hash",
+ "type": "core::felt252",
+ "kind": "data"
+ }
+ ]
+ },
+ {
+ "type": "event",
+ "name": "dojo::world::world_contract::world::StoreSetRecord",
+ "kind": "struct",
+ "members": [
+ {
+ "name": "selector",
+ "type": "core::felt252",
+ "kind": "key"
+ },
+ {
+ "name": "entity_id",
+ "type": "core::felt252",
+ "kind": "key"
+ },
+ {
+ "name": "keys",
+ "type": "core::array::Span::",
+ "kind": "data"
+ },
+ {
+ "name": "values",
+ "type": "core::array::Span::",
+ "kind": "data"
+ }
+ ]
+ },
+ {
+ "type": "event",
+ "name": "dojo::world::world_contract::world::StoreUpdateRecord",
+ "kind": "struct",
+ "members": [
+ {
+ "name": "selector",
+ "type": "core::felt252",
+ "kind": "key"
+ },
+ {
+ "name": "entity_id",
+ "type": "core::felt252",
+ "kind": "key"
+ },
+ {
+ "name": "values",
+ "type": "core::array::Span::",
+ "kind": "data"
+ }
+ ]
+ },
+ {
+ "type": "event",
+ "name": "dojo::world::world_contract::world::StoreUpdateMember",
+ "kind": "struct",
+ "members": [
+ {
+ "name": "selector",
+ "type": "core::felt252",
+ "kind": "key"
+ },
+ {
+ "name": "entity_id",
+ "type": "core::felt252",
+ "kind": "key"
+ },
+ {
+ "name": "member_selector",
+ "type": "core::felt252",
+ "kind": "key"
+ },
+ {
+ "name": "values",
+ "type": "core::array::Span::",
+ "kind": "data"
+ }
+ ]
+ },
+ {
+ "type": "event",
+ "name": "dojo::world::world_contract::world::StoreDelRecord",
+ "kind": "struct",
+ "members": [
+ {
+ "name": "selector",
+ "type": "core::felt252",
+ "kind": "key"
+ },
+ {
+ "name": "entity_id",
+ "type": "core::felt252",
+ "kind": "key"
+ }
+ ]
+ },
+ {
+ "type": "event",
+ "name": "dojo::world::world_contract::world::WriterUpdated",
+ "kind": "struct",
+ "members": [
+ {
+ "name": "resource",
+ "type": "core::felt252",
+ "kind": "key"
+ },
+ {
+ "name": "contract",
+ "type": "core::starknet::contract_address::ContractAddress",
+ "kind": "key"
+ },
+ {
+ "name": "value",
+ "type": "core::bool",
+ "kind": "data"
+ }
+ ]
+ },
+ {
+ "type": "event",
+ "name": "dojo::world::world_contract::world::OwnerUpdated",
+ "kind": "struct",
+ "members": [
+ {
+ "name": "resource",
+ "type": "core::felt252",
+ "kind": "key"
+ },
+ {
+ "name": "contract",
+ "type": "core::starknet::contract_address::ContractAddress",
+ "kind": "key"
+ },
+ {
+ "name": "value",
+ "type": "core::bool",
+ "kind": "data"
+ }
+ ]
+ },
+ {
+ "type": "event",
+ "name": "dojo::world::world_contract::world::Event",
+ "kind": "enum",
+ "variants": [
+ {
+ "name": "WorldSpawned",
+ "type": "dojo::world::world_contract::world::WorldSpawned",
+ "kind": "nested"
+ },
+ {
+ "name": "WorldUpgraded",
+ "type": "dojo::world::world_contract::world::WorldUpgraded",
+ "kind": "nested"
+ },
+ {
+ "name": "NamespaceRegistered",
+ "type": "dojo::world::world_contract::world::NamespaceRegistered",
+ "kind": "nested"
+ },
+ {
+ "name": "ModelRegistered",
+ "type": "dojo::world::world_contract::world::ModelRegistered",
+ "kind": "nested"
+ },
+ {
+ "name": "EventRegistered",
+ "type": "dojo::world::world_contract::world::EventRegistered",
+ "kind": "nested"
+ },
+ {
+ "name": "ContractRegistered",
+ "type": "dojo::world::world_contract::world::ContractRegistered",
+ "kind": "nested"
+ },
+ {
+ "name": "ModelUpgraded",
+ "type": "dojo::world::world_contract::world::ModelUpgraded",
+ "kind": "nested"
+ },
+ {
+ "name": "EventUpgraded",
+ "type": "dojo::world::world_contract::world::EventUpgraded",
+ "kind": "nested"
+ },
+ {
+ "name": "ContractUpgraded",
+ "type": "dojo::world::world_contract::world::ContractUpgraded",
+ "kind": "nested"
+ },
+ {
+ "name": "ContractInitialized",
+ "type": "dojo::world::world_contract::world::ContractInitialized",
+ "kind": "nested"
+ },
+ {
+ "name": "LibraryRegistered",
+ "type": "dojo::world::world_contract::world::LibraryRegistered",
+ "kind": "nested"
+ },
+ {
+ "name": "EventEmitted",
+ "type": "dojo::world::world_contract::world::EventEmitted",
+ "kind": "nested"
+ },
+ {
+ "name": "MetadataUpdate",
+ "type": "dojo::world::world_contract::world::MetadataUpdate",
+ "kind": "nested"
+ },
+ {
+ "name": "StoreSetRecord",
+ "type": "dojo::world::world_contract::world::StoreSetRecord",
+ "kind": "nested"
+ },
+ {
+ "name": "StoreUpdateRecord",
+ "type": "dojo::world::world_contract::world::StoreUpdateRecord",
+ "kind": "nested"
+ },
+ {
+ "name": "StoreUpdateMember",
+ "type": "dojo::world::world_contract::world::StoreUpdateMember",
+ "kind": "nested"
+ },
+ {
+ "name": "StoreDelRecord",
+ "type": "dojo::world::world_contract::world::StoreDelRecord",
+ "kind": "nested"
+ },
+ {
+ "name": "WriterUpdated",
+ "type": "dojo::world::world_contract::world::WriterUpdated",
+ "kind": "nested"
+ },
+ {
+ "name": "OwnerUpdated",
+ "type": "dojo::world::world_contract::world::OwnerUpdated",
+ "kind": "nested"
+ }
+ ]
+ }
+ ]
+ },
+ "contracts": [
+ {
+ "address": "0x7ba903eddb3a65c8d5f7f7cc6a8610df37248ba38f40a5cf3177006bf3a1575",
+ "class_hash": "0x363b85a1b66c2ef427067c48479c50f990260fe7db725251805d92e04c93943",
+ "abi": [
+ {
+ "type": "impl",
+ "name": "house_actions__ContractImpl",
+ "interface_name": "dojo::contract::interface::IContract"
+ },
+ {
+ "type": "interface",
+ "name": "dojo::contract::interface::IContract",
+ "items": []
+ },
+ {
+ "type": "impl",
+ "name": "house_actions__DeployedContractImpl",
+ "interface_name": "dojo::meta::interface::IDeployedResource"
+ },
+ {
+ "type": "struct",
+ "name": "core::byte_array::ByteArray",
+ "members": [
+ {
+ "name": "data",
+ "type": "core::array::Array::"
+ },
+ {
+ "name": "pending_word",
+ "type": "core::felt252"
+ },
+ {
+ "name": "pending_word_len",
+ "type": "core::integer::u32"
+ }
+ ]
+ },
+ {
+ "type": "interface",
+ "name": "dojo::meta::interface::IDeployedResource",
+ "items": [
+ {
+ "type": "function",
+ "name": "dojo_name",
+ "inputs": [],
+ "outputs": [
+ {
+ "type": "core::byte_array::ByteArray"
+ }
+ ],
+ "state_mutability": "view"
+ }
+ ]
+ },
+ {
+ "type": "function",
+ "name": "dojo_init",
+ "inputs": [],
+ "outputs": [],
+ "state_mutability": "external"
+ },
+ {
+ "type": "impl",
+ "name": "Actions",
+ "interface_name": "pixelaw::apps::house::IHouseActions"
+ },
+ {
+ "type": "struct",
+ "name": "pixelaw::core::utils::Position",
+ "members": [
+ {
+ "name": "x",
+ "type": "core::integer::u16"
+ },
+ {
+ "name": "y",
+ "type": "core::integer::u16"
+ }
+ ]
+ },
+ {
+ "type": "enum",
+ "name": "core::option::Option::",
+ "variants": [
+ {
+ "name": "Some",
+ "type": "core::integer::u32"
+ },
+ {
+ "name": "None",
+ "type": "()"
+ }
+ ]
+ },
+ {
+ "type": "enum",
+ "name": "core::option::Option::",
+ "variants": [
+ {
+ "name": "Some",
+ "type": "core::starknet::contract_address::ContractAddress"
+ },
+ {
+ "name": "None",
+ "type": "()"
+ }
+ ]
+ },
+ {
+ "type": "enum",
+ "name": "core::option::Option::",
+ "variants": [
+ {
+ "name": "Some",
+ "type": "core::felt252"
+ },
+ {
+ "name": "None",
+ "type": "()"
+ }
+ ]
+ },
+ {
+ "type": "enum",
+ "name": "core::option::Option::",
+ "variants": [
+ {
+ "name": "Some",
+ "type": "core::integer::u64"
+ },
+ {
+ "name": "None",
+ "type": "()"
+ }
+ ]
+ },
+ {
+ "type": "struct",
+ "name": "pixelaw::core::models::pixel::PixelUpdate",
+ "members": [
+ {
+ "name": "position",
+ "type": "pixelaw::core::utils::Position"
+ },
+ {
+ "name": "color",
+ "type": "core::option::Option::"
+ },
+ {
+ "name": "owner",
+ "type": "core::option::Option::"
+ },
+ {
+ "name": "app",
+ "type": "core::option::Option::"
+ },
+ {
+ "name": "text",
+ "type": "core::option::Option::"
+ },
+ {
+ "name": "timestamp",
+ "type": "core::option::Option::"
+ },
+ {
+ "name": "action",
+ "type": "core::option::Option::"
+ }
+ ]
+ },
+ {
+ "type": "struct",
+ "name": "pixelaw::core::models::registry::App",
+ "members": [
+ {
+ "name": "system",
+ "type": "core::starknet::contract_address::ContractAddress"
+ },
+ {
+ "name": "name",
+ "type": "core::felt252"
+ },
+ {
+ "name": "icon",
+ "type": "core::felt252"
+ },
+ {
+ "name": "action",
+ "type": "core::felt252"
+ }
+ ]
+ },
+ {
+ "type": "enum",
+ "name": "core::option::Option::",
+ "variants": [
+ {
+ "name": "Some",
+ "type": "pixelaw::core::models::pixel::PixelUpdate"
+ },
+ {
+ "name": "None",
+ "type": "()"
+ }
+ ]
+ },
+ {
+ "type": "struct",
+ "name": "pixelaw::core::utils::DefaultParameters",
+ "members": [
+ {
+ "name": "player_override",
+ "type": "core::option::Option::"
+ },
+ {
+ "name": "system_override",
+ "type": "core::option::Option::"
+ },
+ {
+ "name": "area_hint",
+ "type": "core::option::Option::"
+ },
+ {
+ "name": "position",
+ "type": "pixelaw::core::utils::Position"
+ },
+ {
+ "name": "color",
+ "type": "core::integer::u32"
+ }
+ ]
+ },
+ {
+ "type": "interface",
+ "name": "pixelaw::apps::house::IHouseActions",
+ "items": [
+ {
+ "type": "function",
+ "name": "on_pre_update",
+ "inputs": [
+ {
+ "name": "pixel_update",
+ "type": "pixelaw::core::models::pixel::PixelUpdate"
+ },
+ {
+ "name": "app_caller",
+ "type": "pixelaw::core::models::registry::App"
+ },
+ {
+ "name": "player_caller",
+ "type": "core::starknet::contract_address::ContractAddress"
+ }
+ ],
+ "outputs": [
+ {
+ "type": "core::option::Option::"
+ }
+ ],
+ "state_mutability": "external"
+ },
+ {
+ "type": "function",
+ "name": "on_post_update",
+ "inputs": [
+ {
+ "name": "pixel_update",
+ "type": "pixelaw::core::models::pixel::PixelUpdate"
+ },
+ {
+ "name": "app_caller",
+ "type": "pixelaw::core::models::registry::App"
+ },
+ {
+ "name": "player_caller",
+ "type": "core::starknet::contract_address::ContractAddress"
+ }
+ ],
+ "outputs": [],
+ "state_mutability": "external"
+ },
+ {
+ "type": "function",
+ "name": "interact",
+ "inputs": [
+ {
+ "name": "default_params",
+ "type": "pixelaw::core::utils::DefaultParameters"
+ }
+ ],
+ "outputs": [],
+ "state_mutability": "external"
+ },
+ {
+ "type": "function",
+ "name": "build_house",
+ "inputs": [
+ {
+ "name": "default_params",
+ "type": "pixelaw::core::utils::DefaultParameters"
+ }
+ ],
+ "outputs": [],
+ "state_mutability": "external"
+ },
+ {
+ "type": "function",
+ "name": "collect_life",
+ "inputs": [
+ {
+ "name": "default_params",
+ "type": "pixelaw::core::utils::DefaultParameters"
+ }
+ ],
+ "outputs": [],
+ "state_mutability": "external"
+ }
+ ]
+ },
+ {
+ "type": "impl",
+ "name": "WorldProviderImpl",
+ "interface_name": "dojo::contract::components::world_provider::IWorldProvider"
+ },
+ {
+ "type": "struct",
+ "name": "dojo::world::iworld::IWorldDispatcher",
+ "members": [
+ {
+ "name": "contract_address",
+ "type": "core::starknet::contract_address::ContractAddress"
+ }
+ ]
+ },
+ {
+ "type": "interface",
+ "name": "dojo::contract::components::world_provider::IWorldProvider",
+ "items": [
+ {
+ "type": "function",
+ "name": "world_dispatcher",
+ "inputs": [],
+ "outputs": [
+ {
+ "type": "dojo::world::iworld::IWorldDispatcher"
+ }
+ ],
+ "state_mutability": "view"
+ }
+ ]
+ },
+ {
+ "type": "impl",
+ "name": "UpgradeableImpl",
+ "interface_name": "dojo::contract::components::upgradeable::IUpgradeable"
+ },
+ {
+ "type": "interface",
+ "name": "dojo::contract::components::upgradeable::IUpgradeable",
+ "items": [
+ {
+ "type": "function",
+ "name": "upgrade",
+ "inputs": [
+ {
+ "name": "new_class_hash",
+ "type": "core::starknet::class_hash::ClassHash"
+ }
+ ],
+ "outputs": [],
+ "state_mutability": "external"
+ }
+ ]
+ },
+ {
+ "type": "constructor",
+ "name": "constructor",
+ "inputs": []
+ },
+ {
+ "type": "event",
+ "name": "dojo::contract::components::upgradeable::upgradeable_cpt::Upgraded",
+ "kind": "struct",
+ "members": [
+ {
+ "name": "class_hash",
+ "type": "core::starknet::class_hash::ClassHash",
+ "kind": "data"
+ }
+ ]
+ },
+ {
+ "type": "event",
+ "name": "dojo::contract::components::upgradeable::upgradeable_cpt::Event",
+ "kind": "enum",
+ "variants": [
+ {
+ "name": "Upgraded",
+ "type": "dojo::contract::components::upgradeable::upgradeable_cpt::Upgraded",
+ "kind": "nested"
+ }
+ ]
+ },
+ {
+ "type": "event",
+ "name": "dojo::contract::components::world_provider::world_provider_cpt::Event",
+ "kind": "enum",
+ "variants": []
+ },
+ {
+ "type": "event",
+ "name": "pixelaw::apps::house::house_actions::Event",
+ "kind": "enum",
+ "variants": [
+ {
+ "name": "UpgradeableEvent",
+ "type": "dojo::contract::components::upgradeable::upgradeable_cpt::Event",
+ "kind": "nested"
+ },
+ {
+ "name": "WorldProviderEvent",
+ "type": "dojo::contract::components::world_provider::world_provider_cpt::Event",
+ "kind": "nested"
+ }
+ ]
+ }
+ ],
+ "init_calldata": [],
+ "tag": "maze-house_actions",
+ "selector": "0x3d6024555ac0f8b4e95a0c631065f784b511e37cb3da64263b5d2da67685845",
+ "systems": [
+ "dojo_init",
+ "on_pre_update",
+ "on_post_update",
+ "interact",
+ "build_house",
+ "collect_life",
+ "upgrade"
+ ]
+ },
+ {
+ "address": "0x477600ec151cb02548c07d8ff32c24cdc5890b68ddeddb0647a706287a6532d",
+ "class_hash": "0x71b22082a1088e108b2ae7a608ded38e49e79f6f906b5b611f3bd1d37ce6477",
+ "abi": [
+ {
+ "type": "impl",
+ "name": "maze_actions__ContractImpl",
+ "interface_name": "dojo::contract::interface::IContract"
+ },
+ {
+ "type": "interface",
+ "name": "dojo::contract::interface::IContract",
+ "items": []
+ },
+ {
+ "type": "impl",
+ "name": "maze_actions__DeployedContractImpl",
+ "interface_name": "dojo::meta::interface::IDeployedResource"
+ },
+ {
+ "type": "struct",
+ "name": "core::byte_array::ByteArray",
+ "members": [
+ {
+ "name": "data",
+ "type": "core::array::Array::"
+ },
+ {
+ "name": "pending_word",
+ "type": "core::felt252"
+ },
+ {
+ "name": "pending_word_len",
+ "type": "core::integer::u32"
+ }
+ ]
+ },
+ {
+ "type": "interface",
+ "name": "dojo::meta::interface::IDeployedResource",
+ "items": [
+ {
+ "type": "function",
+ "name": "dojo_name",
+ "inputs": [],
+ "outputs": [
+ {
+ "type": "core::byte_array::ByteArray"
+ }
+ ],
+ "state_mutability": "view"
+ }
+ ]
+ },
+ {
+ "type": "function",
+ "name": "dojo_init",
+ "inputs": [],
+ "outputs": [],
+ "state_mutability": "external"
+ },
+ {
+ "type": "impl",
+ "name": "ActionsImpl",
+ "interface_name": "maze::app::IMazeActions"
+ },
+ {
+ "type": "enum",
+ "name": "core::option::Option::",
+ "variants": [
+ {
+ "name": "Some",
+ "type": "core::starknet::contract_address::ContractAddress"
+ },
+ {
+ "name": "None",
+ "type": "()"
+ }
+ ]
+ },
+ {
+ "type": "enum",
+ "name": "core::option::Option::",
+ "variants": [
+ {
+ "name": "Some",
+ "type": "core::integer::u64"
+ },
+ {
+ "name": "None",
+ "type": "()"
+ }
+ ]
+ },
+ {
+ "type": "struct",
+ "name": "pixelaw::core::utils::Position",
+ "members": [
+ {
+ "name": "x",
+ "type": "core::integer::u16"
+ },
+ {
+ "name": "y",
+ "type": "core::integer::u16"
+ }
+ ]
+ },
+ {
+ "type": "struct",
+ "name": "pixelaw::core::utils::DefaultParameters",
+ "members": [
+ {
+ "name": "player_override",
+ "type": "core::option::Option::"
+ },
+ {
+ "name": "system_override",
+ "type": "core::option::Option::"
+ },
+ {
+ "name": "area_hint",
+ "type": "core::option::Option::"
+ },
+ {
+ "name": "position",
+ "type": "pixelaw::core::utils::Position"
+ },
+ {
+ "name": "color",
+ "type": "core::integer::u32"
+ }
+ ]
+ },
+ {
+ "type": "interface",
+ "name": "maze::app::IMazeActions",
+ "items": [
+ {
+ "type": "function",
+ "name": "interact",
+ "inputs": [
+ {
+ "name": "default_params",
+ "type": "pixelaw::core::utils::DefaultParameters"
+ }
+ ],
+ "outputs": [],
+ "state_mutability": "external"
+ },
+ {
+ "type": "function",
+ "name": "reveal_cell",
+ "inputs": [
+ {
+ "name": "default_params",
+ "type": "pixelaw::core::utils::DefaultParameters"
+ }
+ ],
+ "outputs": [],
+ "state_mutability": "external"
+ }
+ ]
+ },
+ {
+ "type": "impl",
+ "name": "WorldProviderImpl",
+ "interface_name": "dojo::contract::components::world_provider::IWorldProvider"
+ },
+ {
+ "type": "struct",
+ "name": "dojo::world::iworld::IWorldDispatcher",
+ "members": [
+ {
+ "name": "contract_address",
+ "type": "core::starknet::contract_address::ContractAddress"
+ }
+ ]
+ },
+ {
+ "type": "interface",
+ "name": "dojo::contract::components::world_provider::IWorldProvider",
+ "items": [
+ {
+ "type": "function",
+ "name": "world_dispatcher",
+ "inputs": [],
+ "outputs": [
+ {
+ "type": "dojo::world::iworld::IWorldDispatcher"
+ }
+ ],
+ "state_mutability": "view"
+ }
+ ]
+ },
+ {
+ "type": "impl",
+ "name": "UpgradeableImpl",
+ "interface_name": "dojo::contract::components::upgradeable::IUpgradeable"
+ },
+ {
+ "type": "interface",
+ "name": "dojo::contract::components::upgradeable::IUpgradeable",
+ "items": [
+ {
+ "type": "function",
+ "name": "upgrade",
+ "inputs": [
+ {
+ "name": "new_class_hash",
+ "type": "core::starknet::class_hash::ClassHash"
+ }
+ ],
+ "outputs": [],
+ "state_mutability": "external"
+ }
+ ]
+ },
+ {
+ "type": "constructor",
+ "name": "constructor",
+ "inputs": []
+ },
+ {
+ "type": "event",
+ "name": "dojo::contract::components::upgradeable::upgradeable_cpt::Upgraded",
+ "kind": "struct",
+ "members": [
+ {
+ "name": "class_hash",
+ "type": "core::starknet::class_hash::ClassHash",
+ "kind": "data"
+ }
+ ]
+ },
+ {
+ "type": "event",
+ "name": "dojo::contract::components::upgradeable::upgradeable_cpt::Event",
+ "kind": "enum",
+ "variants": [
+ {
+ "name": "Upgraded",
+ "type": "dojo::contract::components::upgradeable::upgradeable_cpt::Upgraded",
+ "kind": "nested"
+ }
+ ]
+ },
+ {
+ "type": "event",
+ "name": "dojo::contract::components::world_provider::world_provider_cpt::Event",
+ "kind": "enum",
+ "variants": []
+ },
+ {
+ "type": "event",
+ "name": "maze::app::maze_actions::Event",
+ "kind": "enum",
+ "variants": [
+ {
+ "name": "UpgradeableEvent",
+ "type": "dojo::contract::components::upgradeable::upgradeable_cpt::Event",
+ "kind": "nested"
+ },
+ {
+ "name": "WorldProviderEvent",
+ "type": "dojo::contract::components::world_provider::world_provider_cpt::Event",
+ "kind": "nested"
+ }
+ ]
+ }
+ ],
+ "init_calldata": [],
+ "tag": "maze-maze_actions",
+ "selector": "0x3dd7d9b4fd592513cc91fbd1d773d971a012dd321f1dd78c78676a9e67e694a",
+ "systems": [
+ "dojo_init",
+ "interact",
+ "reveal_cell",
+ "upgrade"
+ ]
+ },
+ {
+ "address": "0x7a37fae070734e7b2fa450afdc5fa2a46c94adff986077407de60c789481d00",
+ "class_hash": "0x17f2ed71dc1813a53ffc30b6d489560f71248eec1a1851f52bc9a61c086fbbd",
+ "abi": [
+ {
+ "type": "impl",
+ "name": "paint_actions__ContractImpl",
+ "interface_name": "dojo::contract::interface::IContract"
+ },
+ {
+ "type": "interface",
+ "name": "dojo::contract::interface::IContract",
+ "items": []
+ },
+ {
+ "type": "impl",
+ "name": "paint_actions__DeployedContractImpl",
+ "interface_name": "dojo::meta::interface::IDeployedResource"
+ },
+ {
+ "type": "struct",
+ "name": "core::byte_array::ByteArray",
+ "members": [
+ {
+ "name": "data",
+ "type": "core::array::Array::"
+ },
+ {
+ "name": "pending_word",
+ "type": "core::felt252"
+ },
+ {
+ "name": "pending_word_len",
+ "type": "core::integer::u32"
+ }
+ ]
+ },
+ {
+ "type": "interface",
+ "name": "dojo::meta::interface::IDeployedResource",
+ "items": [
+ {
+ "type": "function",
+ "name": "dojo_name",
+ "inputs": [],
+ "outputs": [
+ {
+ "type": "core::byte_array::ByteArray"
+ }
+ ],
+ "state_mutability": "view"
+ }
+ ]
+ },
+ {
+ "type": "function",
+ "name": "dojo_init",
+ "inputs": [],
+ "outputs": [],
+ "state_mutability": "external"
+ },
+ {
+ "type": "impl",
+ "name": "Actions",
+ "interface_name": "pixelaw::apps::paint::IPaintActions"
+ },
+ {
+ "type": "struct",
+ "name": "pixelaw::core::utils::Position",
+ "members": [
+ {
+ "name": "x",
+ "type": "core::integer::u16"
+ },
+ {
+ "name": "y",
+ "type": "core::integer::u16"
+ }
+ ]
+ },
+ {
+ "type": "enum",
+ "name": "core::option::Option::",
+ "variants": [
+ {
+ "name": "Some",
+ "type": "core::integer::u32"
+ },
+ {
+ "name": "None",
+ "type": "()"
+ }
+ ]
+ },
+ {
+ "type": "enum",
+ "name": "core::option::Option::",
+ "variants": [
+ {
+ "name": "Some",
+ "type": "core::starknet::contract_address::ContractAddress"
+ },
+ {
+ "name": "None",
+ "type": "()"
+ }
+ ]
+ },
+ {
+ "type": "enum",
+ "name": "core::option::Option::",
+ "variants": [
+ {
+ "name": "Some",
+ "type": "core::felt252"
+ },
+ {
+ "name": "None",
+ "type": "()"
+ }
+ ]
+ },
+ {
+ "type": "enum",
+ "name": "core::option::Option::",
+ "variants": [
+ {
+ "name": "Some",
+ "type": "core::integer::u64"
+ },
+ {
+ "name": "None",
+ "type": "()"
+ }
+ ]
+ },
+ {
+ "type": "struct",
+ "name": "pixelaw::core::models::pixel::PixelUpdate",
+ "members": [
+ {
+ "name": "position",
+ "type": "pixelaw::core::utils::Position"
+ },
+ {
+ "name": "color",
+ "type": "core::option::Option::"
+ },
+ {
+ "name": "owner",
+ "type": "core::option::Option::"
+ },
+ {
+ "name": "app",
+ "type": "core::option::Option::"
+ },
+ {
+ "name": "text",
+ "type": "core::option::Option::"
+ },
+ {
+ "name": "timestamp",
+ "type": "core::option::Option::"
+ },
+ {
+ "name": "action",
+ "type": "core::option::Option::"
+ }
+ ]
+ },
+ {
+ "type": "struct",
+ "name": "pixelaw::core::models::registry::App",
+ "members": [
+ {
+ "name": "system",
+ "type": "core::starknet::contract_address::ContractAddress"
+ },
+ {
+ "name": "name",
+ "type": "core::felt252"
+ },
+ {
+ "name": "icon",
+ "type": "core::felt252"
+ },
+ {
+ "name": "action",
+ "type": "core::felt252"
+ }
+ ]
+ },
+ {
+ "type": "enum",
+ "name": "core::option::Option::",
+ "variants": [
+ {
+ "name": "Some",
+ "type": "pixelaw::core::models::pixel::PixelUpdate"
+ },
+ {
+ "name": "None",
+ "type": "()"
+ }
+ ]
+ },
+ {
+ "type": "struct",
+ "name": "pixelaw::core::utils::DefaultParameters",
+ "members": [
+ {
+ "name": "player_override",
+ "type": "core::option::Option::"
+ },
+ {
+ "name": "system_override",
+ "type": "core::option::Option::"
+ },
+ {
+ "name": "area_hint",
+ "type": "core::option::Option::"
+ },
+ {
+ "name": "position",
+ "type": "pixelaw::core::utils::Position"
+ },
+ {
+ "name": "color",
+ "type": "core::integer::u32"
+ }
+ ]
+ },
+ {
+ "type": "struct",
+ "name": "core::array::Span::",
+ "members": [
+ {
+ "name": "snapshot",
+ "type": "@core::array::Array::"
+ }
+ ]
+ },
+ {
+ "type": "interface",
+ "name": "pixelaw::apps::paint::IPaintActions",
+ "items": [
+ {
+ "type": "function",
+ "name": "on_pre_update",
+ "inputs": [
+ {
+ "name": "pixel_update",
+ "type": "pixelaw::core::models::pixel::PixelUpdate"
+ },
+ {
+ "name": "app_caller",
+ "type": "pixelaw::core::models::registry::App"
+ },
+ {
+ "name": "player_caller",
+ "type": "core::starknet::contract_address::ContractAddress"
+ }
+ ],
+ "outputs": [
+ {
+ "type": "core::option::Option::"
+ }
+ ],
+ "state_mutability": "external"
+ },
+ {
+ "type": "function",
+ "name": "on_post_update",
+ "inputs": [
+ {
+ "name": "pixel_update",
+ "type": "pixelaw::core::models::pixel::PixelUpdate"
+ },
+ {
+ "name": "app_caller",
+ "type": "pixelaw::core::models::registry::App"
+ },
+ {
+ "name": "player_caller",
+ "type": "core::starknet::contract_address::ContractAddress"
+ }
+ ],
+ "outputs": [],
+ "state_mutability": "external"
+ },
+ {
+ "type": "function",
+ "name": "interact",
+ "inputs": [
+ {
+ "name": "default_params",
+ "type": "pixelaw::core::utils::DefaultParameters"
+ }
+ ],
+ "outputs": [],
+ "state_mutability": "external"
+ },
+ {
+ "type": "function",
+ "name": "put_color",
+ "inputs": [
+ {
+ "name": "default_params",
+ "type": "pixelaw::core::utils::DefaultParameters"
+ }
+ ],
+ "outputs": [],
+ "state_mutability": "external"
+ },
+ {
+ "type": "function",
+ "name": "fade",
+ "inputs": [
+ {
+ "name": "default_params",
+ "type": "pixelaw::core::utils::DefaultParameters"
+ }
+ ],
+ "outputs": [],
+ "state_mutability": "external"
+ },
+ {
+ "type": "function",
+ "name": "pixel_row",
+ "inputs": [
+ {
+ "name": "default_params",
+ "type": "pixelaw::core::utils::DefaultParameters"
+ },
+ {
+ "name": "image_data",
+ "type": "core::array::Span::"
+ }
+ ],
+ "outputs": [],
+ "state_mutability": "external"
+ }
+ ]
+ },
+ {
+ "type": "impl",
+ "name": "WorldProviderImpl",
+ "interface_name": "dojo::contract::components::world_provider::IWorldProvider"
+ },
+ {
+ "type": "struct",
+ "name": "dojo::world::iworld::IWorldDispatcher",
+ "members": [
+ {
+ "name": "contract_address",
+ "type": "core::starknet::contract_address::ContractAddress"
+ }
+ ]
+ },
+ {
+ "type": "interface",
+ "name": "dojo::contract::components::world_provider::IWorldProvider",
+ "items": [
+ {
+ "type": "function",
+ "name": "world_dispatcher",
+ "inputs": [],
+ "outputs": [
+ {
+ "type": "dojo::world::iworld::IWorldDispatcher"
+ }
+ ],
+ "state_mutability": "view"
+ }
+ ]
+ },
+ {
+ "type": "impl",
+ "name": "UpgradeableImpl",
+ "interface_name": "dojo::contract::components::upgradeable::IUpgradeable"
+ },
+ {
+ "type": "interface",
+ "name": "dojo::contract::components::upgradeable::IUpgradeable",
+ "items": [
+ {
+ "type": "function",
+ "name": "upgrade",
+ "inputs": [
+ {
+ "name": "new_class_hash",
+ "type": "core::starknet::class_hash::ClassHash"
+ }
+ ],
+ "outputs": [],
+ "state_mutability": "external"
+ }
+ ]
+ },
+ {
+ "type": "constructor",
+ "name": "constructor",
+ "inputs": []
+ },
+ {
+ "type": "event",
+ "name": "dojo::contract::components::upgradeable::upgradeable_cpt::Upgraded",
+ "kind": "struct",
+ "members": [
+ {
+ "name": "class_hash",
+ "type": "core::starknet::class_hash::ClassHash",
+ "kind": "data"
+ }
+ ]
+ },
+ {
+ "type": "event",
+ "name": "dojo::contract::components::upgradeable::upgradeable_cpt::Event",
+ "kind": "enum",
+ "variants": [
+ {
+ "name": "Upgraded",
+ "type": "dojo::contract::components::upgradeable::upgradeable_cpt::Upgraded",
+ "kind": "nested"
+ }
+ ]
+ },
+ {
+ "type": "event",
+ "name": "dojo::contract::components::world_provider::world_provider_cpt::Event",
+ "kind": "enum",
+ "variants": []
+ },
+ {
+ "type": "event",
+ "name": "pixelaw::apps::paint::paint_actions::Event",
+ "kind": "enum",
+ "variants": [
+ {
+ "name": "UpgradeableEvent",
+ "type": "dojo::contract::components::upgradeable::upgradeable_cpt::Event",
+ "kind": "nested"
+ },
+ {
+ "name": "WorldProviderEvent",
+ "type": "dojo::contract::components::world_provider::world_provider_cpt::Event",
+ "kind": "nested"
+ }
+ ]
+ }
+ ],
+ "init_calldata": [],
+ "tag": "maze-paint_actions",
+ "selector": "0x7053cbb0b9f41974809cf24a9424de083e8193bb47854fc0c60c461f9e5ab78",
+ "systems": [
+ "dojo_init",
+ "on_pre_update",
+ "on_post_update",
+ "interact",
+ "put_color",
+ "fade",
+ "pixel_row",
+ "upgrade"
+ ]
+ },
+ {
+ "address": "0x5eab12be0255871c4d91b723089861181f9e8b4bddf5427fb934d7ed0e87c8a",
+ "class_hash": "0x67e29925ee459444af164d4dd3ab63e5ba32cca812fcc133af9fb57df04c55c",
+ "abi": [
+ {
+ "type": "impl",
+ "name": "player_actions__ContractImpl",
+ "interface_name": "dojo::contract::interface::IContract"
+ },
+ {
+ "type": "interface",
+ "name": "dojo::contract::interface::IContract",
+ "items": []
+ },
+ {
+ "type": "impl",
+ "name": "player_actions__DeployedContractImpl",
+ "interface_name": "dojo::meta::interface::IDeployedResource"
+ },
+ {
+ "type": "struct",
+ "name": "core::byte_array::ByteArray",
+ "members": [
+ {
+ "name": "data",
+ "type": "core::array::Array::"
+ },
+ {
+ "name": "pending_word",
+ "type": "core::felt252"
+ },
+ {
+ "name": "pending_word_len",
+ "type": "core::integer::u32"
+ }
+ ]
+ },
+ {
+ "type": "interface",
+ "name": "dojo::meta::interface::IDeployedResource",
+ "items": [
+ {
+ "type": "function",
+ "name": "dojo_name",
+ "inputs": [],
+ "outputs": [
+ {
+ "type": "core::byte_array::ByteArray"
+ }
+ ],
+ "state_mutability": "view"
+ }
+ ]
+ },
+ {
+ "type": "function",
+ "name": "dojo_init",
+ "inputs": [],
+ "outputs": [],
+ "state_mutability": "external"
+ },
+ {
+ "type": "impl",
+ "name": "Actions",
+ "interface_name": "pixelaw::apps::player::IPlayerActions"
+ },
+ {
+ "type": "struct",
+ "name": "pixelaw::core::utils::Position",
+ "members": [
+ {
+ "name": "x",
+ "type": "core::integer::u16"
+ },
+ {
+ "name": "y",
+ "type": "core::integer::u16"
+ }
+ ]
+ },
+ {
+ "type": "enum",
+ "name": "core::option::Option::",
+ "variants": [
+ {
+ "name": "Some",
+ "type": "core::integer::u32"
+ },
+ {
+ "name": "None",
+ "type": "()"
+ }
+ ]
+ },
+ {
+ "type": "enum",
+ "name": "core::option::Option::",
+ "variants": [
+ {
+ "name": "Some",
+ "type": "core::starknet::contract_address::ContractAddress"
+ },
+ {
+ "name": "None",
+ "type": "()"
+ }
+ ]
+ },
+ {
+ "type": "enum",
+ "name": "core::option::Option::",
+ "variants": [
+ {
+ "name": "Some",
+ "type": "core::felt252"
+ },
+ {
+ "name": "None",
+ "type": "()"
+ }
+ ]
+ },
+ {
+ "type": "enum",
+ "name": "core::option::Option::",
+ "variants": [
+ {
+ "name": "Some",
+ "type": "core::integer::u64"
+ },
+ {
+ "name": "None",
+ "type": "()"
+ }
+ ]
+ },
+ {
+ "type": "struct",
+ "name": "pixelaw::core::models::pixel::PixelUpdate",
+ "members": [
+ {
+ "name": "position",
+ "type": "pixelaw::core::utils::Position"
+ },
+ {
+ "name": "color",
+ "type": "core::option::Option::"
+ },
+ {
+ "name": "owner",
+ "type": "core::option::Option::"
+ },
+ {
+ "name": "app",
+ "type": "core::option::Option::"
+ },
+ {
+ "name": "text",
+ "type": "core::option::Option::"
+ },
+ {
+ "name": "timestamp",
+ "type": "core::option::Option::"
+ },
+ {
+ "name": "action",
+ "type": "core::option::Option::"
+ }
+ ]
+ },
+ {
+ "type": "struct",
+ "name": "pixelaw::core::models::registry::App",
+ "members": [
+ {
+ "name": "system",
+ "type": "core::starknet::contract_address::ContractAddress"
+ },
+ {
+ "name": "name",
+ "type": "core::felt252"
+ },
+ {
+ "name": "icon",
+ "type": "core::felt252"
+ },
+ {
+ "name": "action",
+ "type": "core::felt252"
+ }
+ ]
+ },
+ {
+ "type": "enum",
+ "name": "core::option::Option::",
+ "variants": [
+ {
+ "name": "Some",
+ "type": "pixelaw::core::models::pixel::PixelUpdate"
+ },
+ {
+ "name": "None",
+ "type": "()"
+ }
+ ]
+ },
+ {
+ "type": "struct",
+ "name": "pixelaw::core::utils::DefaultParameters",
+ "members": [
+ {
+ "name": "player_override",
+ "type": "core::option::Option::"
+ },
+ {
+ "name": "system_override",
+ "type": "core::option::Option::"
+ },
+ {
+ "name": "area_hint",
+ "type": "core::option::Option::"
+ },
+ {
+ "name": "position",
+ "type": "pixelaw::core::utils::Position"
+ },
+ {
+ "name": "color",
+ "type": "core::integer::u32"
+ }
+ ]
+ },
+ {
+ "type": "struct",
+ "name": "pixelaw::core::utils::Emoji",
+ "members": [
+ {
+ "name": "value",
+ "type": "core::felt252"
+ }
+ ]
+ },
+ {
+ "type": "interface",
+ "name": "pixelaw::apps::player::IPlayerActions",
+ "items": [
+ {
+ "type": "function",
+ "name": "on_pre_update",
+ "inputs": [
+ {
+ "name": "pixel_update",
+ "type": "pixelaw::core::models::pixel::PixelUpdate"
+ },
+ {
+ "name": "app_caller",
+ "type": "pixelaw::core::models::registry::App"
+ },
+ {
+ "name": "player_caller",
+ "type": "core::starknet::contract_address::ContractAddress"
+ }
+ ],
+ "outputs": [
+ {
+ "type": "core::option::Option::"
+ }
+ ],
+ "state_mutability": "external"
+ },
+ {
+ "type": "function",
+ "name": "on_post_update",
+ "inputs": [
+ {
+ "name": "pixel_update",
+ "type": "pixelaw::core::models::pixel::PixelUpdate"
+ },
+ {
+ "name": "app_caller",
+ "type": "pixelaw::core::models::registry::App"
+ },
+ {
+ "name": "player_caller",
+ "type": "core::starknet::contract_address::ContractAddress"
+ }
+ ],
+ "outputs": [],
+ "state_mutability": "external"
+ },
+ {
+ "type": "function",
+ "name": "interact",
+ "inputs": [
+ {
+ "name": "default_params",
+ "type": "pixelaw::core::utils::DefaultParameters"
+ }
+ ],
+ "outputs": [],
+ "state_mutability": "external"
+ },
+ {
+ "type": "function",
+ "name": "configure",
+ "inputs": [
+ {
+ "name": "default_params",
+ "type": "pixelaw::core::utils::DefaultParameters"
+ },
+ {
+ "name": "emoji",
+ "type": "pixelaw::core::utils::Emoji"
+ }
+ ],
+ "outputs": [],
+ "state_mutability": "external"
+ }
+ ]
+ },
+ {
+ "type": "impl",
+ "name": "WorldProviderImpl",
+ "interface_name": "dojo::contract::components::world_provider::IWorldProvider"
+ },
+ {
+ "type": "struct",
+ "name": "dojo::world::iworld::IWorldDispatcher",
+ "members": [
+ {
+ "name": "contract_address",
+ "type": "core::starknet::contract_address::ContractAddress"
+ }
+ ]
+ },
+ {
+ "type": "interface",
+ "name": "dojo::contract::components::world_provider::IWorldProvider",
+ "items": [
+ {
+ "type": "function",
+ "name": "world_dispatcher",
+ "inputs": [],
+ "outputs": [
+ {
+ "type": "dojo::world::iworld::IWorldDispatcher"
+ }
+ ],
+ "state_mutability": "view"
+ }
+ ]
+ },
+ {
+ "type": "impl",
+ "name": "UpgradeableImpl",
+ "interface_name": "dojo::contract::components::upgradeable::IUpgradeable"
+ },
+ {
+ "type": "interface",
+ "name": "dojo::contract::components::upgradeable::IUpgradeable",
+ "items": [
+ {
+ "type": "function",
+ "name": "upgrade",
+ "inputs": [
+ {
+ "name": "new_class_hash",
+ "type": "core::starknet::class_hash::ClassHash"
+ }
+ ],
+ "outputs": [],
+ "state_mutability": "external"
+ }
+ ]
+ },
+ {
+ "type": "constructor",
+ "name": "constructor",
+ "inputs": []
+ },
+ {
+ "type": "event",
+ "name": "dojo::contract::components::upgradeable::upgradeable_cpt::Upgraded",
+ "kind": "struct",
+ "members": [
+ {
+ "name": "class_hash",
+ "type": "core::starknet::class_hash::ClassHash",
+ "kind": "data"
+ }
+ ]
+ },
+ {
+ "type": "event",
+ "name": "dojo::contract::components::upgradeable::upgradeable_cpt::Event",
+ "kind": "enum",
+ "variants": [
+ {
+ "name": "Upgraded",
+ "type": "dojo::contract::components::upgradeable::upgradeable_cpt::Upgraded",
+ "kind": "nested"
+ }
+ ]
+ },
+ {
+ "type": "event",
+ "name": "dojo::contract::components::world_provider::world_provider_cpt::Event",
+ "kind": "enum",
+ "variants": []
+ },
+ {
+ "type": "event",
+ "name": "pixelaw::apps::player::player_actions::Event",
+ "kind": "enum",
+ "variants": [
+ {
+ "name": "UpgradeableEvent",
+ "type": "dojo::contract::components::upgradeable::upgradeable_cpt::Event",
+ "kind": "nested"
+ },
+ {
+ "name": "WorldProviderEvent",
+ "type": "dojo::contract::components::world_provider::world_provider_cpt::Event",
+ "kind": "nested"
+ }
+ ]
+ }
+ ],
+ "init_calldata": [],
+ "tag": "maze-player_actions",
+ "selector": "0x21861e4de788ce16c582608356ea5fcffaa5695a2ca6bd510037ed80ff6a400",
+ "systems": [
+ "dojo_init",
+ "on_pre_update",
+ "on_post_update",
+ "interact",
+ "configure",
+ "upgrade"
+ ]
+ },
+ {
+ "address": "0x6a3cf0b23a4543053570e362537748622616cdc91f64d5b47176c0df044033d",
+ "class_hash": "0x1ab4a251cdeef5e7cbb55bb0715d34534e553944c20661f3881774d93210db1",
+ "abi": [
+ {
+ "type": "impl",
+ "name": "snake_actions__ContractImpl",
+ "interface_name": "dojo::contract::interface::IContract"
+ },
+ {
+ "type": "interface",
+ "name": "dojo::contract::interface::IContract",
+ "items": []
+ },
+ {
+ "type": "impl",
+ "name": "snake_actions__DeployedContractImpl",
+ "interface_name": "dojo::meta::interface::IDeployedResource"
+ },
+ {
+ "type": "struct",
+ "name": "core::byte_array::ByteArray",
+ "members": [
+ {
+ "name": "data",
+ "type": "core::array::Array::"
+ },
+ {
+ "name": "pending_word",
+ "type": "core::felt252"
+ },
+ {
+ "name": "pending_word_len",
+ "type": "core::integer::u32"
+ }
+ ]
+ },
+ {
+ "type": "interface",
+ "name": "dojo::meta::interface::IDeployedResource",
+ "items": [
+ {
+ "type": "function",
+ "name": "dojo_name",
+ "inputs": [],
+ "outputs": [
+ {
+ "type": "core::byte_array::ByteArray"
+ }
+ ],
+ "state_mutability": "view"
+ }
+ ]
+ },
+ {
+ "type": "function",
+ "name": "dojo_init",
+ "inputs": [],
+ "outputs": [],
+ "state_mutability": "external"
+ },
+ {
+ "type": "impl",
+ "name": "ActionsImpl",
+ "interface_name": "pixelaw::apps::snake::ISnakeActions"
+ },
+ {
+ "type": "struct",
+ "name": "pixelaw::core::utils::Position",
+ "members": [
+ {
+ "name": "x",
+ "type": "core::integer::u16"
+ },
+ {
+ "name": "y",
+ "type": "core::integer::u16"
+ }
+ ]
+ },
+ {
+ "type": "enum",
+ "name": "core::option::Option::",
+ "variants": [
+ {
+ "name": "Some",
+ "type": "core::integer::u32"
+ },
+ {
+ "name": "None",
+ "type": "()"
+ }
+ ]
+ },
+ {
+ "type": "enum",
+ "name": "core::option::Option::",
+ "variants": [
+ {
+ "name": "Some",
+ "type": "core::starknet::contract_address::ContractAddress"
+ },
+ {
+ "name": "None",
+ "type": "()"
+ }
+ ]
+ },
+ {
+ "type": "enum",
+ "name": "core::option::Option::",
+ "variants": [
+ {
+ "name": "Some",
+ "type": "core::felt252"
+ },
+ {
+ "name": "None",
+ "type": "()"
+ }
+ ]
+ },
+ {
+ "type": "enum",
+ "name": "core::option::Option::",
+ "variants": [
+ {
+ "name": "Some",
+ "type": "core::integer::u64"
+ },
+ {
+ "name": "None",
+ "type": "()"
+ }
+ ]
+ },
+ {
+ "type": "struct",
+ "name": "pixelaw::core::models::pixel::PixelUpdate",
+ "members": [
+ {
+ "name": "position",
+ "type": "pixelaw::core::utils::Position"
+ },
+ {
+ "name": "color",
+ "type": "core::option::Option::"
+ },
+ {
+ "name": "owner",
+ "type": "core::option::Option::"
+ },
+ {
+ "name": "app",
+ "type": "core::option::Option::"
+ },
+ {
+ "name": "text",
+ "type": "core::option::Option::"
+ },
+ {
+ "name": "timestamp",
+ "type": "core::option::Option::"
+ },
+ {
+ "name": "action",
+ "type": "core::option::Option::"
+ }
+ ]
+ },
+ {
+ "type": "struct",
+ "name": "pixelaw::core::models::registry::App",
+ "members": [
+ {
+ "name": "system",
+ "type": "core::starknet::contract_address::ContractAddress"
+ },
+ {
+ "name": "name",
+ "type": "core::felt252"
+ },
+ {
+ "name": "icon",
+ "type": "core::felt252"
+ },
+ {
+ "name": "action",
+ "type": "core::felt252"
+ }
+ ]
+ },
+ {
+ "type": "enum",
+ "name": "core::option::Option::",
+ "variants": [
+ {
+ "name": "Some",
+ "type": "pixelaw::core::models::pixel::PixelUpdate"
+ },
+ {
+ "name": "None",
+ "type": "()"
+ }
+ ]
+ },
+ {
+ "type": "struct",
+ "name": "pixelaw::core::utils::DefaultParameters",
+ "members": [
+ {
+ "name": "player_override",
+ "type": "core::option::Option::"
+ },
+ {
+ "name": "system_override",
+ "type": "core::option::Option::"
+ },
+ {
+ "name": "area_hint",
+ "type": "core::option::Option::"
+ },
+ {
+ "name": "position",
+ "type": "pixelaw::core::utils::Position"
+ },
+ {
+ "name": "color",
+ "type": "core::integer::u32"
+ }
+ ]
+ },
+ {
+ "type": "enum",
+ "name": "pixelaw::core::utils::Direction",
+ "variants": [
+ {
+ "name": "None",
+ "type": "()"
+ },
+ {
+ "name": "Left",
+ "type": "()"
+ },
+ {
+ "name": "Right",
+ "type": "()"
+ },
+ {
+ "name": "Up",
+ "type": "()"
+ },
+ {
+ "name": "Down",
+ "type": "()"
+ }
+ ]
+ },
+ {
+ "type": "interface",
+ "name": "pixelaw::apps::snake::ISnakeActions",
+ "items": [
+ {
+ "type": "function",
+ "name": "on_pre_update",
+ "inputs": [
+ {
+ "name": "pixel_update",
+ "type": "pixelaw::core::models::pixel::PixelUpdate"
+ },
+ {
+ "name": "app_caller",
+ "type": "pixelaw::core::models::registry::App"
+ },
+ {
+ "name": "player_caller",
+ "type": "core::starknet::contract_address::ContractAddress"
+ }
+ ],
+ "outputs": [
+ {
+ "type": "core::option::Option::"
+ }
+ ],
+ "state_mutability": "external"
+ },
+ {
+ "type": "function",
+ "name": "on_post_update",
+ "inputs": [
+ {
+ "name": "pixel_update",
+ "type": "pixelaw::core::models::pixel::PixelUpdate"
+ },
+ {
+ "name": "app_caller",
+ "type": "pixelaw::core::models::registry::App"
+ },
+ {
+ "name": "player_caller",
+ "type": "core::starknet::contract_address::ContractAddress"
+ }
+ ],
+ "outputs": [],
+ "state_mutability": "external"
+ },
+ {
+ "type": "function",
+ "name": "interact",
+ "inputs": [
+ {
+ "name": "default_params",
+ "type": "pixelaw::core::utils::DefaultParameters"
+ },
+ {
+ "name": "direction",
+ "type": "pixelaw::core::utils::Direction"
+ }
+ ],
+ "outputs": [
+ {
+ "type": "core::integer::u32"
+ }
+ ],
+ "state_mutability": "external"
+ },
+ {
+ "type": "function",
+ "name": "move",
+ "inputs": [
+ {
+ "name": "owner",
+ "type": "core::starknet::contract_address::ContractAddress"
+ }
+ ],
+ "outputs": [],
+ "state_mutability": "external"
+ }
+ ]
+ },
+ {
+ "type": "impl",
+ "name": "WorldProviderImpl",
+ "interface_name": "dojo::contract::components::world_provider::IWorldProvider"
+ },
+ {
+ "type": "struct",
+ "name": "dojo::world::iworld::IWorldDispatcher",
+ "members": [
+ {
+ "name": "contract_address",
+ "type": "core::starknet::contract_address::ContractAddress"
+ }
+ ]
+ },
+ {
+ "type": "interface",
+ "name": "dojo::contract::components::world_provider::IWorldProvider",
+ "items": [
+ {
+ "type": "function",
+ "name": "world_dispatcher",
+ "inputs": [],
+ "outputs": [
+ {
+ "type": "dojo::world::iworld::IWorldDispatcher"
+ }
+ ],
+ "state_mutability": "view"
+ }
+ ]
+ },
+ {
+ "type": "impl",
+ "name": "UpgradeableImpl",
+ "interface_name": "dojo::contract::components::upgradeable::IUpgradeable"
+ },
+ {
+ "type": "interface",
+ "name": "dojo::contract::components::upgradeable::IUpgradeable",
+ "items": [
+ {
+ "type": "function",
+ "name": "upgrade",
+ "inputs": [
+ {
+ "name": "new_class_hash",
+ "type": "core::starknet::class_hash::ClassHash"
+ }
+ ],
+ "outputs": [],
+ "state_mutability": "external"
+ }
+ ]
+ },
+ {
+ "type": "constructor",
+ "name": "constructor",
+ "inputs": []
+ },
+ {
+ "type": "event",
+ "name": "dojo::contract::components::upgradeable::upgradeable_cpt::Upgraded",
+ "kind": "struct",
+ "members": [
+ {
+ "name": "class_hash",
+ "type": "core::starknet::class_hash::ClassHash",
+ "kind": "data"
+ }
+ ]
+ },
+ {
+ "type": "event",
+ "name": "dojo::contract::components::upgradeable::upgradeable_cpt::Event",
+ "kind": "enum",
+ "variants": [
+ {
+ "name": "Upgraded",
+ "type": "dojo::contract::components::upgradeable::upgradeable_cpt::Upgraded",
+ "kind": "nested"
+ }
+ ]
+ },
+ {
+ "type": "event",
+ "name": "dojo::contract::components::world_provider::world_provider_cpt::Event",
+ "kind": "enum",
+ "variants": []
+ },
+ {
+ "type": "event",
+ "name": "pixelaw::apps::snake::snake_actions::Event",
+ "kind": "enum",
+ "variants": [
+ {
+ "name": "UpgradeableEvent",
+ "type": "dojo::contract::components::upgradeable::upgradeable_cpt::Event",
+ "kind": "nested"
+ },
+ {
+ "name": "WorldProviderEvent",
+ "type": "dojo::contract::components::world_provider::world_provider_cpt::Event",
+ "kind": "nested"
+ }
+ ]
+ }
+ ],
+ "init_calldata": [],
+ "tag": "maze-snake_actions",
+ "selector": "0x6eae4fda4b2b917903fe04e8e332422add7b7e3e46e9147bf3d1a2bde23c7e7",
+ "systems": [
+ "dojo_init",
+ "on_pre_update",
+ "on_post_update",
+ "interact",
+ "move",
+ "upgrade"
+ ]
+ }
+ ],
+ "libraries": [],
+ "models": [
+ {
+ "members": [],
+ "class_hash": "0x130d929cdfb5f16f00437b8b9e2ee7ca936e6dbda02b66e0645c1b8a836d972",
+ "tag": "maze-House",
+ "selector": "0x50f0316f84d6dc80568325143f8e024f64b871ff629d74a4274da51c718ba35"
+ },
+ {
+ "members": [],
+ "class_hash": "0x5de5d1c00db5aea3a5b8aabfeb9ae04c4f6abf4acf39421330758e1b1f4877d",
+ "tag": "maze-MazeGame",
+ "selector": "0x25b567d59f1194996242d73c492cb490b6cea9c79a0898985e1ef5703b1924b"
+ },
+ {
+ "members": [],
+ "class_hash": "0x3108ac90fe54054a52758a4ced978654044212c49ebdabcf7bfc95f6d42136d",
+ "tag": "maze-Player",
+ "selector": "0x5f4e93dc53d7b7c2cedea02939ad0b21f6d9ab3ee9df82d2cc359636fe4e9be"
+ },
+ {
+ "members": [],
+ "class_hash": "0x57461f88e2b6be6b8da053e4f3a9975f99d84a52b5475c702ac59ba7c47282a",
+ "tag": "maze-PlayerHouse",
+ "selector": "0x7930109650e42ad693fd44c5ac46d4db3b886e1e05fa9d121bb669a24bd0df6"
+ },
+ {
+ "members": [],
+ "class_hash": "0x5cc52ac7ea49c9ce97a5c5924d5f52a481d22d724fc762a98a8a177a8cc5687",
+ "tag": "maze-PositionPlayer",
+ "selector": "0x2ccdfcbbf4e30056fbf368c888c028fb1cc9927178497ecfb5a69ee5c0279ae"
+ },
+ {
+ "members": [],
+ "class_hash": "0x55223dc4d275d565ec36a877dabe62dbd833b1d9da3e68d6bc68bbe503fdebd",
+ "tag": "maze-Snake",
+ "selector": "0x2bcb33d8e0f205e193a7fedb678789360ad1cb0fe40667b5a46d85502a6bae3"
+ },
+ {
+ "members": [],
+ "class_hash": "0x13f29ce0859553bd15f832e864574f2fa425e875d29ab38cebf77b76ae4cf2f",
+ "tag": "maze-SnakeSegment",
+ "selector": "0x47a18d3d8527ba55154c998a86a5980d4766afda6ea6ae1ae321880f0336939"
+ }
+ ],
+ "events": [],
+ "external_contracts": []
+}
\ No newline at end of file
diff --git a/minesweeper/.tool-versions b/minesweeper/.tool-versions
index c03850d..1b363e4 100644
--- a/minesweeper/.tool-versions
+++ b/minesweeper/.tool-versions
@@ -1,2 +1,2 @@
-dojo 1.5.1
+dojo 1.6.2
scarb 2.10.1
diff --git a/minesweeper/Scarb.lock b/minesweeper/Scarb.lock
index 9e9961b..386292b 100644
--- a/minesweeper/Scarb.lock
+++ b/minesweeper/Scarb.lock
@@ -3,16 +3,16 @@ version = 1
[[package]]
name = "dojo"
-version = "1.5.1"
-source = "git+https://github.com/dojoengine/dojo?tag=v1.5.1#986c3b0c6d647b23847c70ddceb1d33ddac86ead"
+version = "1.6.2"
+source = "git+https://github.com/dojoengine/dojo?tag=v1.6.2#d6e847c51ecd0121a43c2a17b96dbca936604764"
dependencies = [
"dojo_plugin",
]
[[package]]
name = "dojo_cairo_test"
-version = "1.0.12"
-source = "git+https://github.com/dojoengine/dojo?tag=v1.5.1#986c3b0c6d647b23847c70ddceb1d33ddac86ead"
+version = "1.6.2"
+source = "git+https://github.com/dojoengine/dojo?tag=v1.6.2#d6e847c51ecd0121a43c2a17b96dbca936604764"
dependencies = [
"dojo",
]
@@ -20,7 +20,7 @@ dependencies = [
[[package]]
name = "dojo_plugin"
version = "2.10.1"
-source = "git+https://github.com/dojoengine/dojo?tag=v1.5.1#986c3b0c6d647b23847c70ddceb1d33ddac86ead"
+source = "git+https://github.com/dojoengine/dojo?tag=v1.6.2#d6e847c51ecd0121a43c2a17b96dbca936604764"
[[package]]
name = "minesweeper"
@@ -34,16 +34,16 @@ dependencies = [
[[package]]
name = "pixelaw"
-version = "0.7.8"
-source = "git+https://github.com/pixelaw/core?tag=v0.7.8#0d020c16319676c1839cedd53577868458efa6c2"
+version = "0.7.9"
+source = "git+https://github.com/pixelaw/core?tag=v0.7.9#40313e650b145faa4d8f6eb525fbfa0e2b58a5bf"
dependencies = [
"dojo",
]
[[package]]
name = "pixelaw_testing"
-version = "0.7.8"
-source = "git+https://github.com/pixelaw/core?tag=v0.7.8#0d020c16319676c1839cedd53577868458efa6c2"
+version = "0.7.9"
+source = "git+https://github.com/pixelaw/core?tag=v0.7.9#40313e650b145faa4d8f6eb525fbfa0e2b58a5bf"
dependencies = [
"dojo",
"dojo_cairo_test",
diff --git a/minesweeper/Scarb.toml b/minesweeper/Scarb.toml
index 5c298d0..7fc37f6 100644
--- a/minesweeper/Scarb.toml
+++ b/minesweeper/Scarb.toml
@@ -8,12 +8,12 @@ edition = "2024_07"
sierra-replace-ids = true
[dependencies]
-pixelaw = { git = "https://github.com/pixelaw/core", tag = "v0.7.8" }
-dojo = { git = "https://github.com/dojoengine/dojo", tag = "v1.5.1" }
+pixelaw = { git = "https://github.com/pixelaw/core", tag = "v0.7.9" }
+dojo = { git = "https://github.com/dojoengine/dojo", tag = "v1.6.2" }
[dev-dependencies]
-pixelaw_testing = { git = "https://github.com/pixelaw/core", tag = "v0.7.8" }
-dojo_cairo_test = { git = "https://github.com/dojoengine/dojo", tag = "v1.5.1" }
+pixelaw_testing = { git = "https://github.com/pixelaw/core", tag = "v0.7.9" }
+dojo_cairo_test = { git = "https://github.com/dojoengine/dojo", tag = "v1.6.2" }
[[target.starknet-contract]]
sierra = true
diff --git a/minesweeper/dojo_dev.toml b/minesweeper/dojo_dev.toml
new file mode 100644
index 0000000..9444eca
--- /dev/null
+++ b/minesweeper/dojo_dev.toml
@@ -0,0 +1,35 @@
+# How to use this config file: https://book.dojoengine.org/framework/config#dojo_profiletoml
+
+[world]
+name = "minesweeper"
+seed = "pixelaw"
+
+[namespace]
+default = "minesweeper"
+# Reserve the pixelaw core contract names, the rest can be "minesweeper" automatically.
+mappings = { "pixelaw" = [
+ "actions", "App", "AppName", "Area", "CoreActionsAddress", "Pixel", "QueueItem", "RTree", "Notification", "QueueScheduled"
+] }
+
+[env]
+rpc_url = "http://localhost:5050/"
+account_address = "0x127fd5f1fe78a71f8bcd1fec63e3fe2f0486b6ecd5c86a0466c3a21fa5cfcec"
+private_key = "0xc5b2fcab997346f3ea1c00b002ecf6f382c5f9c9659a3894eb783c5320f912"
+
+[writers]
+"minesweeper-MinesweeperGame" = ["minesweeper-minesweeper_actions"]
+"minesweeper-MineCell" = ["minesweeper-minesweeper_actions"]
+
+[migration]
+skip_contracts = [
+ "pixelaw-actions",
+ "pixelaw-App",
+ "pixelaw-AppName",
+ "pixelaw-Area",
+ "pixelaw-CoreActionsAddress",
+ "pixelaw-Pixel",
+ "pixelaw-QueueItem",
+ "pixelaw-RTree",
+ "pixelaw-Notification",
+ "pixelaw-QueueScheduled"
+]
\ No newline at end of file
diff --git a/minesweeper/manifest_dev.json b/minesweeper/manifest_dev.json
new file mode 100644
index 0000000..1e5f0a9
--- /dev/null
+++ b/minesweeper/manifest_dev.json
@@ -0,0 +1,1795 @@
+{
+ "world": {
+ "class_hash": "0x13d92333361bb7049c1232c0a5404e2c19082ededc3a73d75cb33fa952adec7",
+ "address": "0x548b7044c88b3338e88e3c0ea356eb9dcf65388c90ec7c9d9031547af30d1d1",
+ "seed": "pixelaw",
+ "name": "minesweeper",
+ "entrypoints": [
+ "uuid",
+ "set_metadata",
+ "register_namespace",
+ "register_event",
+ "register_model",
+ "register_contract",
+ "register_library",
+ "init_contract",
+ "upgrade_event",
+ "upgrade_model",
+ "upgrade_contract",
+ "emit_event",
+ "emit_events",
+ "set_entity",
+ "set_entities",
+ "delete_entity",
+ "delete_entities",
+ "grant_owner",
+ "revoke_owner",
+ "grant_writer",
+ "revoke_writer",
+ "upgrade"
+ ],
+ "abi": [
+ {
+ "type": "impl",
+ "name": "World",
+ "interface_name": "dojo::world::iworld::IWorld"
+ },
+ {
+ "type": "struct",
+ "name": "core::byte_array::ByteArray",
+ "members": [
+ {
+ "name": "data",
+ "type": "core::array::Array::"
+ },
+ {
+ "name": "pending_word",
+ "type": "core::felt252"
+ },
+ {
+ "name": "pending_word_len",
+ "type": "core::integer::u32"
+ }
+ ]
+ },
+ {
+ "type": "enum",
+ "name": "dojo::world::resource::Resource",
+ "variants": [
+ {
+ "name": "Model",
+ "type": "(core::starknet::contract_address::ContractAddress, core::felt252)"
+ },
+ {
+ "name": "Event",
+ "type": "(core::starknet::contract_address::ContractAddress, core::felt252)"
+ },
+ {
+ "name": "Contract",
+ "type": "(core::starknet::contract_address::ContractAddress, core::felt252)"
+ },
+ {
+ "name": "Namespace",
+ "type": "core::byte_array::ByteArray"
+ },
+ {
+ "name": "World",
+ "type": "()"
+ },
+ {
+ "name": "Unregistered",
+ "type": "()"
+ },
+ {
+ "name": "Library",
+ "type": "(core::starknet::class_hash::ClassHash, core::felt252)"
+ }
+ ]
+ },
+ {
+ "type": "struct",
+ "name": "dojo::model::metadata::ResourceMetadata",
+ "members": [
+ {
+ "name": "resource_id",
+ "type": "core::felt252"
+ },
+ {
+ "name": "metadata_uri",
+ "type": "core::byte_array::ByteArray"
+ },
+ {
+ "name": "metadata_hash",
+ "type": "core::felt252"
+ }
+ ]
+ },
+ {
+ "type": "struct",
+ "name": "core::array::Span::",
+ "members": [
+ {
+ "name": "snapshot",
+ "type": "@core::array::Array::"
+ }
+ ]
+ },
+ {
+ "type": "struct",
+ "name": "core::array::Span::>",
+ "members": [
+ {
+ "name": "snapshot",
+ "type": "@core::array::Array::>"
+ }
+ ]
+ },
+ {
+ "type": "enum",
+ "name": "dojo::model::definition::ModelIndex",
+ "variants": [
+ {
+ "name": "Keys",
+ "type": "core::array::Span::